blob: 00d3d3fc1458b8b48ba2c92dc0023b6fe200212c [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 Pedrole076b3f2021-07-20 16:45:57 +0200683 /* Whether to enable dyn TS SDCCH8 tests. Can be dropped completely and enable
684 unconditionally once new version of osmo-bsc is released (current
685 version: 1.7.0) */
686 boolean mp_enable_dyn_sdcch8_test := true;
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100687 /* Value set in osmo-bsc.cfg "ms max power" */
688 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100689}
690
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200691friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200692
693 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200694 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200695 pars.aoip := true;
696 } else {
697 pars.aoip := false;
698 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100699 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200700 pars.mscpool.bssap_idx := bssap_idx;
Philipp Maier48604732018-10-09 15:00:37 +0200701
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200702 /* BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2 */
703 pars.expect_tsc := 2;
704
Philipp Maier48604732018-10-09 15:00:37 +0200705 return pars;
706}
707
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200708/* Convenience functions for rate counters using g_ctr_msc. */
709
710private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
711 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
712 log("initial msc rate counters: ", g_ctr_msc);
713}
714
715private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200716 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200717}
718
719/* f_ctrs_msc_init();
720 * f_do_thing(on_msc := 0);
721 * f_do_thing(on_msc := 0);
722 * f_do_other(on_msc := 1);
723 * f_ctrs_msc_add(0, "thing", 2);
724 * f_ctrs_msc_add(1, "other");
725 * f_ctrs_msc_verify();
726 */
727private function f_ctrs_msc_verify() runs on test_CT {
728 log("verifying msc rate counters: ", g_ctr_msc);
729 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
730}
731
732/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
733 * f_ctrs_msc_init();
734 * f_do_thing(on_msc := 0);
735 * f_do_thing(on_msc := 0);
736 * f_do_thing(on_msc := 0);
737 * f_ctrs_msc_expect(0, "thing", 3);
738 */
739private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
740 f_ctrs_msc_add(msc_nr, countername, val);
741 f_ctrs_msc_verify();
742}
743
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000744/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
745
746private function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
747 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
748 log("initial bts rate counters: ", g_ctr_bts);
749 f_ctrs_bsc_init(counternames);
750}
751
752private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
753 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
754 f_ctrs_bsc_add(countername, val);
755}
756
757/* f_ctrs_bsc_and_bts_init();
758 * f_do_thing(on_bts := 0);
759 * f_do_thing(on_bts := 0);
760 * f_do_other(on_bts := 1);
761 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
762 * f_ctrs_bsc_and_bts_add(1, "other");
763 * f_ctrs_bsc_and_bts_verify();
764 */
765private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
766 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
767 f_ctrs_bsc_verify();
768}
769
770/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
771 * f_ctrs_bsc_and_bts_init();
772 * f_do_thing(on_bts := 0);
773 * f_do_thing(on_bts := 0);
774 * f_do_thing(on_bts := 0);
775 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
776 */
777private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
778 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
779 f_ctrs_bsc_and_bts_verify();
780}
781
782
783/* Convenience functions for rate counters using g_ctr_bsc. */
784
785private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
786 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
787 log("initial bsc rate counters: ", g_ctr_bsc);
788}
789
790private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
791 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
792}
793
794/* f_ctrs_bsc_init();
795 * f_do_thing();
796 * f_do_thing();
797 * f_do_other();
798 * f_ctrs_bsc_add("thing", 2);
799 * f_ctrs_bsc_add("other");
800 * f_ctrs_bsc_verify();
801 */
802private function f_ctrs_bsc_verify() runs on test_CT {
803 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
804}
805
806/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
807 * f_ctrs_bsc_init();
808 * f_do_thing();
809 * f_ctrs_bsc_expect("thing", 1);
810 */
811private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
812 f_ctrs_bsc_add(countername, val);
813 f_ctrs_bsc_verify();
814}
815
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200816
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200817friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200818 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100819 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200820 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100821}
822
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200823private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100824 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200825 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100826 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200827 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
828 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100829 T.start;
830 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200831 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
832 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200833 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100834 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200835 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200836 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100837 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200838 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200839 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100840 repeat;
841 }
842 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200843 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200844 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200845 /* If we received a RESET after ours was sent, it
846 may be a race condition where the other peer beacame
847 available after we sent it, but we are in a desired
848 state anyway, so go forward. */
849 if (not reset_received) {
850 setverdict(fail);
851 }
852 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100853 }
Harald Welte28d943e2017-11-25 15:00:50 +0100854}
855
Harald Welteae026692017-12-09 01:03:01 +0100856type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100857 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100858 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100859 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100860 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100861 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100862 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100863 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100864 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100865}
866
Harald Welte21b46bd2017-12-17 19:46:32 +0100867/*! Start the IPA/RSL related bits for one IPA_Client.
868 * \param clnt IPA_Client for which to establish
869 * \param bsc_host IP address / hostname of the BSC
870 * \param bsc_port TCP port number of the BSC
871 * \param i number identifying this BTS
872 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100873function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
874 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100875runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100876 timer T := 10.0;
877
Harald Welte96c94412017-12-09 03:12:45 +0100878 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100879 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
880 clnt.ccm_pars := c_IPA_default_ccm_pars;
881 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
882 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100883 if (handler_mode) {
884 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100885 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100886 }
Harald Welteae026692017-12-09 01:03:01 +0100887
888 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100889 if (handler_mode) {
890 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
891 } else {
892 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
893 }
Harald Welteae026692017-12-09 01:03:01 +0100894
Harald Welte5d1a2202017-12-13 19:51:29 +0100895 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100896 if (handler_mode) {
897 clnt.vc_RSL.start(RSL_Emulation.main());
898 return;
899 }
Harald Welteae026692017-12-09 01:03:01 +0100900
901 /* wait for IPA RSL link to connect and send ID ACK */
902 T.start;
903 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700904 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100905 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700906 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100907 }
Harald Welte60e823a2017-12-10 14:10:59 +0100908 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100909 [] IPA_RSL[i].receive { repeat }
910 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100911 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200912 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100913 }
914 }
915}
916
Harald Welte12055472018-03-17 20:10:08 +0100917function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
918 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
919 return;
920 }
921 clnt.vc_IPA.stop;
922 if (isbound(clnt.vc_RSL)) {
923 clnt.vc_RSL.stop;
924 }
925}
926
Harald Welte21b46bd2017-12-17 19:46:32 +0100927/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100928function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
929 timer T := secs_max;
930 T.start;
931 while (true) {
932 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
933 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100934 /* the 'degraded' state exists from OML connection time, and we have to wait
935 * until all MO's are initialized */
936 T.start(1.0);
937 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100938 return;
939 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100940 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100941 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100942 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200943 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100944 }
945 }
946}
947
Harald Welte21b46bd2017-12-17 19:46:32 +0100948/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100949altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100950 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100951 [] T_guard.timeout {
952 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200953 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100954 }
Harald Welte60e823a2017-12-10 14:10:59 +0100955 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200956 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100957 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200958 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100959 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100960 }
Harald Welte28d943e2017-11-25 15:00:50 +0100961}
962
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100963altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200964 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100965 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +0200966 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100967 }
968}
969
Daniel Willmann191e0d92018-01-17 12:44:35 +0100970function f_init_mgcp(charstring id) runs on test_CT {
971 id := id & "-MGCP";
972
973 var MGCPOps ops := {
974 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
975 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
976 };
977 var MGCP_conn_parameters mgcp_pars := {
978 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +0100979 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +0100980 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200981 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +0200982 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
983 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200984 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +0100985 };
986
987 vc_MGCP := MGCP_Emulation_CT.create(id);
988 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
989}
990
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200991/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
992 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
993 * OsmuxCID IE.
994 */
995private function f_vty_allow_osmux(boolean allow) runs on test_CT {
996 f_vty_enter_cfg_msc(BSCVTY, 0);
997 if (allow) {
998 f_vty_transceive(BSCVTY, "osmux on");
999 } else {
1000 f_vty_transceive(BSCVTY, "osmux off");
1001 }
1002 f_vty_transceive(BSCVTY, "exit");
1003 f_vty_transceive(BSCVTY, "exit");
1004 g_osmux_enabled := allow;
1005}
1006
Max2253c0b2018-11-06 19:28:05 +01001007function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001008 if (BSCVTY.checkstate("Mapped")) {
1009 /* skip initialization if already executed once */
1010 return;
1011 }
Harald Weltebc03c762018-02-12 18:09:38 +01001012 map(self:BSCVTY, system:BSCVTY);
1013 f_vty_set_prompts(BSCVTY);
1014 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001015 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1016 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001017}
1018
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001019friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001020{
1021 // log on TTCN3 log output
1022 log(log_msg);
1023 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001024 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001025}
1026
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001027private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1028{
1029 if (rsl_idx >= lengthof(g_system_information)) {
1030 g_system_information[rsl_idx] := SystemInformationConfig_omit
1031 }
1032 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1033}
1034
1035altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1036 var ASP_RSL_Unitdata rx_rsl_ud;
1037
1038 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1039 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1040 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1041 repeat;
1042 }
1043 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1044 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1045 repeat;
1046 }
1047 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1048 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1049 repeat;
1050 }
1051 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1052 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1053 repeat;
1054 }
1055
1056 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1057 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1058 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1059 repeat;
1060 }
1061 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1062 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1063 repeat;
1064 }
1065 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1066 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1067 repeat;
1068 }
1069 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1070 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1071 repeat;
1072 }
1073}
1074
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001075/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1076private type record of boolean my_BooleanList;
1077
1078private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1079{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001080 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1081
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001082 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001083 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1084 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1085 * stepping into that config node. */
1086 log("msc ", msc_nr, " is not configured, skipping");
1087 continue;
1088 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001089 f_vty_enter_cfg_msc(pt, msc_nr);
1090 if (allow_attach_list[msc_nr]) {
1091 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1092 f_vty_transceive(pt, "allow-attach", strict := false);
1093 } else {
1094 f_vty_transceive(pt, "no allow-attach", strict := false);
1095 }
1096 f_vty_transceive(pt, "exit");
1097 f_vty_transceive(pt, "exit");
1098 }
1099}
1100
Harald Welte21b46bd2017-12-17 19:46:32 +01001101/* global initialization function
1102 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001103 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1104 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1105 */
1106function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001107 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001108 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001109
Harald Welteae026692017-12-09 01:03:01 +01001110 if (g_initialized) {
1111 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001112 }
Harald Welteae026692017-12-09 01:03:01 +01001113 g_initialized := true;
1114
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001115 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001116 activate(as_Tguard());
1117
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001118 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001119 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001120
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001121 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001122 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1123
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001124 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1125 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1126 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1127 }
1128
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001129 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001130 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001131 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1132 * MSC-side BSSAP emulation */
1133 if (handler_mode) {
1134 var RanOps ranops := MSC_RanOps;
1135 ranops.use_osmux := g_osmux_enabled;
1136 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1137 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1138 f_ran_adapter_start(g_bssap[bssap_idx]);
1139 } else {
1140 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1141 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1142 f_ran_adapter_start(g_bssap[bssap_idx]);
1143 f_legacy_bssap_reset();
1144 }
Harald Welte67089ee2018-01-17 22:19:03 +01001145 }
Harald Welted5833a82018-05-27 16:52:56 +02001146
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001147 if (mp_enable_lcs_tests) {
1148 if (handler_mode) {
1149 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1150 } else {
1151 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1152 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1153 }
1154 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001155 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001156
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001157 /* start the test with exactly all enabled MSCs allowed to attach */
1158 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1159
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001160 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001161
Daniel Willmann191e0d92018-01-17 12:44:35 +01001162 f_init_mgcp("VirtMSC");
1163
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001164 for (var integer i := 0; i < nr_bts; i := i+1) {
1165 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001166 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001167}
Harald Welte696ddb62017-12-08 14:01:43 +01001168
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001169function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1170runs on test_CT {
1171 /* wait until osmo-bts-omldummy has respawned */
1172 f_wait_oml(bts_idx, "degraded", 5.0);
1173
1174 /* start RSL connection */
1175 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1176 /* wait until BSC tells us "connected" */
1177 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001178}
1179
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001180function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1181 template SystemInformationConfig expect_si)
1182runs on test_CT {
1183 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1184
1185 f_init_bts(bts_idx, handler_mode);
1186
1187 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1188 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1189 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1190 */
1191 f_sleep(5.0);
1192 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1193
1194 deactivate(sysinfo);
1195
1196 if (match(g_system_information[bts_idx], expect_si)) {
1197 setverdict(pass);
1198 } else {
1199 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1200 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1201 setverdict(fail, "received SI does not match expectations");
1202 return;
1203 }
1204}
1205
Maxd4e56962018-10-31 19:08:25 +01001206/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001207function 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 +01001208runs on test_CT return RSL_Message {
1209 var ASP_RSL_Unitdata rx_rsl_ud;
1210 timer T := t_secs;
1211
1212 T.start;
1213 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001214 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001215 T.stop;
1216 }
1217 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001218 [] T.timeout {
1219 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001220 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001221 }
Harald Welteae026692017-12-09 01:03:01 +01001222 }
1223 return rx_rsl_ud.rsl;
1224}
1225
Harald Welte21b46bd2017-12-17 19:46:32 +01001226/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001227function 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 +01001228runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001229 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001230}
1231
1232
Harald Welte4003d112017-12-09 22:35:39 +01001233/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001234testcase TC_chan_act_noreply() runs on test_CT {
1235 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001236 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001237
Harald Welte89d42e82017-12-17 16:42:41 +01001238 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001239
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001240 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001241 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001242 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001243}
1244
Harald Welte4003d112017-12-09 22:35:39 +01001245/* verify if the "chreq:total" counter increments as expected */
1246testcase TC_chan_act_counter() runs on test_CT {
1247 var BSSAP_N_UNITDATA_ind ud_ind;
1248 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001249 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001250
Harald Welte89d42e82017-12-17 16:42:41 +01001251 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001252
1253 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001254 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001255 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001256 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1257
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001258 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001259}
1260
Harald Welteae026692017-12-09 01:03:01 +01001261/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001262private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001263 var RSL_Message rx_rsl;
1264
Harald Welteae026692017-12-09 01:03:01 +01001265 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001266 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001267
1268 /* expect BSC to disable the channel again if there's no RLL EST IND */
1269 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1270
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001271 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001272}
1273
Philipp Maier9c60a622020-07-09 15:08:46 +02001274/* Normal variant */
1275testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001276 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001277 f_TC_chan_act_ack_noest();
1278}
1279
1280/* Emergency call variant */
1281testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1282 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001283 f_init(1);
1284 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001285 f_TC_chan_act_ack_noest(ra := 'A5'O);
1286}
1287
Philipp Maier606f07d2020-08-12 17:21:58 +02001288/* Emergency call variant, but emergency calls are not allowed */
1289testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1290 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1291
1292 var RSL_Message rx_rsl;
1293 var GsmRrMessage rr;
1294
1295 f_init(1);
1296 f_vty_allow_emerg_bts(false, 0);
1297
1298 IPA_RSL[0].clear;
1299 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1300
1301 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1302 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1303 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1304 setverdict(pass);
1305 } else {
1306 setverdict(fail, "immediate assignment not rejected");
1307 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001308
1309 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001310}
1311
Harald Welteae026692017-12-09 01:03:01 +01001312/* Test behavior if MSC never answers to CR */
1313testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001314 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1315 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001316 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001317 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001318
Harald Welte89d42e82017-12-17 16:42:41 +01001319 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001320
1321 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001322 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001323
1324 var octetstring l3 := '00010203040506'O
1325 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1326
1327 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1328
1329 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001330 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001331 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001332 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001333}
1334
1335/* Test behavior if MSC answers with CREF to CR */
1336testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1337 var BSSAP_N_CONNECT_ind rx_c_ind;
1338 var RSL_Message rx_rsl;
1339
Harald Welte89d42e82017-12-17 16:42:41 +01001340 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001341
1342 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001343 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001344
1345 var octetstring l3 := '00010203040506'O
1346 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1347
1348 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1349 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1350
1351 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001352 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001353 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001354}
1355
Harald Welte618ef642017-12-14 14:58:20 +01001356/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1357testcase TC_chan_act_nack() runs on test_CT {
1358 var RSL_Message rx_rsl;
1359 var integer chact_nack;
1360
Harald Welte89d42e82017-12-17 16:42:41 +01001361 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001362
1363 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1364
1365 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1366 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1367 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1368
1369 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1370
1371 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1372 f_sleep(0.5);
1373
1374 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1375
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001376 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001377}
1378
Harald Welte799c97b2017-12-14 17:50:30 +01001379/* Test for channel exhaustion due to RACH overload */
1380testcase TC_chan_exhaustion() runs on test_CT {
1381 var ASP_RSL_Unitdata rsl_ud;
1382 var integer i;
1383 var integer chreq_total, chreq_nochan;
1384
Harald Welte89d42e82017-12-17 16:42:41 +01001385 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001386
1387 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1388 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1389
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001390 /* GSM 04.08 Table 9.9a:
1391 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1392 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001393 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 +01001394 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001395 }
1396
1397 IPA_RSL[0].clear;
1398
Harald Weltedd8cbf32018-01-28 12:07:52 +01001399 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001400 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001401
1402 /* now expect additional channel activations to fail */
1403 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1404
1405 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001406 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001407 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1408 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001409 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001410 var GsmRrMessage rr;
1411 /* match on IMM ASS REJ */
1412 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1413 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1414 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001415 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001416 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1417 chreq_nochan+1);
1418 setverdict(pass);
1419 } else {
1420 repeat;
1421 }
1422 }
1423 [] IPA_RSL[0].receive { repeat; }
1424 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001425 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001426}
1427
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001428/* Test channel deactivation due to silence from MS */
1429testcase TC_chan_deact_silence() runs on test_CT {
1430 var RslChannelNr chan_nr;
1431
1432 f_init(1);
1433
1434 /* Request for a dedicated channel */
1435 chan_nr := f_chreq_act_ack('23'O);
1436
1437 /* Wait some time until the channel is released */
1438 f_sleep(2.0);
1439
1440 /* Expect CHANnel RELease */
1441 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001442 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001443 log("Received CHANnel RELease");
1444 setverdict(pass);
1445 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001446 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001447 /* See OS#3709, OsmoBSC should not send Immediate
1448 * Assignment Reject since a dedicated channel was
1449 * already allocated, and Immediate Assignment was
1450 * already sent. */
1451 setverdict(fail, "Unexpected Immediate Assignment!");
1452 }
1453 [] IPA_RSL[0].receive {
1454 setverdict(fail, "Unexpected RSL message!");
1455 }
1456 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001457 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001458}
1459
Harald Weltecfe2c962017-12-15 12:09:32 +01001460/***********************************************************************
1461 * Assignment Testing
1462 ***********************************************************************/
1463
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001464/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1465 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001466testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001467 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001468
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001469 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1470 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001471 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001472 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001473}
1474
Harald Welte16a4adf2017-12-14 18:54:01 +01001475/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001476testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001477 var BSSAP_N_CONNECT_ind rx_c_ind;
1478 var RSL_Message rx_rsl;
1479 var DchanTuple dt;
1480
Harald Welte89d42e82017-12-17 16:42:41 +01001481 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001482
1483 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001484 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001485 /* send assignment without AoIP IEs */
1486 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1487 } else {
1488 /* Send assignmetn without CIC in IPA case */
1489 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1490 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1491 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1492 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001493 alt {
1494 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1495 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1496 }
Harald Welte235ebf12017-12-15 14:18:16 +01001497 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001498 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1499 setverdict(pass);
1500 }
1501 [] BSSAP.receive { repeat; }
1502 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001503 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001504}
1505
Harald Welteed848512018-05-24 22:27:58 +02001506/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001507function 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 +02001508 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001509 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001510 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001511 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001512 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001513 if (osmux_enabled) {
1514 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1515 } else {
1516 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1517 }
Harald Welteed848512018-05-24 22:27:58 +02001518 } else {
1519 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001520 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001521 }
1522 return ass_cmd;
1523}
1524
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001525function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001526 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1527 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001528 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001529
1530 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1531 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1532 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1533 var template BSSMAP_IE_KC128 kc128 := omit;
1534 if (ispresent(enc)) {
1535 var TestHdlrEncrParams v_enc := valueof(enc);
1536 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1537 chosenEncryptionAlgorithm := valueof(
1538 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001539 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001540 if (ispresent(v_enc.enc_kc128)) {
1541 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1542 }
1543 }
1544
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001545 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001546 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001547 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001548 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1549 encryptionInformation := encryptionInformation,
1550 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1551 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001552 } else {
1553 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001554 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1555 encryptionInformation := encryptionInformation,
1556 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1557 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001558 }
1559 return ho_req;
1560}
1561
Harald Welteed848512018-05-24 22:27:58 +02001562/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001563function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001564 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001565 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001566 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001567 if (expect_osmux) {
1568 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1569 } else {
1570 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1571 }
Harald Welteed848512018-05-24 22:27:58 +02001572 } else {
1573 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001574 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001575 }
1576 return exp_compl;
1577}
1578
Harald Welte235ebf12017-12-15 14:18:16 +01001579/* Run everything required up to sending a caller-specified assignment command and expect response */
1580function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1581runs on test_CT {
1582 var BSSAP_N_CONNECT_ind rx_c_ind;
1583 var RSL_Message rx_rsl;
1584 var DchanTuple dt;
1585
Harald Welte89d42e82017-12-17 16:42:41 +01001586 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001587
1588 dt := f_est_dchan('23'O, 23, '00000000'O);
1589 /* send assignment without AoIP IEs */
1590 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1591 alt {
1592 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1593 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1594 setverdict(pass);
1595 } else {
1596 setverdict(fail, fail_text);
1597 }
1598 }
1599 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1600 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1601 setverdict(pass);
1602 } else {
1603 setverdict(fail, fail_text);
1604 }
1605 }
1606 [] BSSAP.receive { repeat; }
1607 }
1608}
1609testcase TC_assignment_csd() runs on test_CT {
1610 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001611 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001612 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1613 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1614 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001615 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001616}
1617
1618testcase TC_assignment_ctm() runs on test_CT {
1619 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001620 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001621 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1622 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1623 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001624 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001625}
1626
Harald Welte4003d112017-12-09 22:35:39 +01001627type record DchanTuple {
1628 integer sccp_conn_id,
1629 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001630}
1631
Harald Welted6939652017-12-13 21:02:46 +01001632/* Send CHAN RQD and wait for allocation; acknowledge it */
1633private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1634runs on test_CT return RslChannelNr {
1635 var RSL_Message rx_rsl;
1636 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1637 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1638 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1639 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001640 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001641 return chan_nr;
1642}
1643
Harald Welte4003d112017-12-09 22:35:39 +01001644/* helper function to establish a dedicated channel via BTS and MSC */
1645function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1646runs on test_CT return DchanTuple {
1647 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001648 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001649
Harald Welte4003d112017-12-09 22:35:39 +01001650 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001651 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001652
1653 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1654
1655 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1656 dt.sccp_conn_id := rx_c_ind.connectionId;
1657 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1658
1659 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001660}
1661
Harald Welte641fcbe2018-06-14 10:58:35 +02001662/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1663private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1664 var RSL_Message rx_rsl;
1665 /* expect BSC to disable the channel */
1666 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1667 /* respond with CHAN REL ACK */
1668 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1669
1670 /* expect Clear Complete from BSC */
1671 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1672
1673 /* MSC disconnects as instructed. */
1674 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1675}
1676
Harald Welte4003d112017-12-09 22:35:39 +01001677/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1678testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001679 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001680 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001681
Harald Welte89d42e82017-12-17 16:42:41 +01001682 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001683
Harald Welte4003d112017-12-09 22:35:39 +01001684 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1685
1686 /* simulate RLL REL IND */
1687 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1688
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001689 /* expect Clear Request on MSC side */
1690 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1691
1692 /* Instruct BSC to clear channel */
1693 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1694 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1695
Harald Welte4003d112017-12-09 22:35:39 +01001696 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001697 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001698
1699 /* wait for SCCP emulation to do its job */
1700 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001701
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001702 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001703}
1704
1705/* Test behavior of channel release after CONN FAIL IND from BTS */
1706testcase TC_chan_rel_conn_fail() runs on test_CT {
1707 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001708 var DchanTuple dt;
1709
Harald Welte89d42e82017-12-17 16:42:41 +01001710 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001711
1712 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1713
1714 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001715 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 +01001716 /* TODO: different cause values? */
1717
Harald Welte4003d112017-12-09 22:35:39 +01001718 /* expect Clear Request from BSC */
1719 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1720
1721 /* Instruct BSC to clear channel */
1722 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1723 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1724
Harald Welte6ff76ea2018-01-28 13:08:01 +01001725 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001726 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001727
1728 /* wait for SCCP emulation to do its job */
1729 f_sleep(1.0);
1730
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001731 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001732}
1733
Harald Welte99f3ca02018-06-14 13:40:29 +02001734/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1735/* See also https://www.osmocom.org/issues/3182 */
1736testcase TC_early_conn_fail() runs on test_CT {
1737 var RSL_Message rx_rsl;
1738 var DchanTuple dt;
1739
1740 f_init(1);
1741
1742 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001743 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001744
1745 /* BTS->BSC: simulate CONN FAIL IND */
1746 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1747
1748 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1749 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1750
1751 /* BTS<-BSC: respond with CHAN REL ACK */
1752 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1753
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001754 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001755}
1756
1757/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1758/* See also https://www.osmocom.org/issues/3182 */
1759testcase TC_late_conn_fail() runs on test_CT {
1760 var RSL_Message rx_rsl;
1761 var DchanTuple dt;
1762
1763 f_init(1);
1764
1765 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1766
1767 /* BSC<-MSC: Instruct BSC to clear connection */
1768 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1769
1770 /* BTS->BSC: expect BSC to deactivate SACCH */
1771 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1772
1773 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1774 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1775
1776 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1777 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1778 /* BTS->BSC: respond with CHAN REL ACK */
1779 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1780
1781 /* BSC->MSC: expect Clear Complete from BSC */
1782 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1783
1784 /* BSC<-MSC: MSC disconnects as requested. */
1785 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1786
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001787 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001788}
1789
Oliver Smithaf03bef2021-08-24 15:34:51 +02001790private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1791 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1792 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1793
1794 f_statsd_reset();
1795
1796 /* Establish SDCCH */
1797 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1798 f_establish_fully(ass_cmd, exp_fail);
1799
1800 /* Expect stats to be 0 */
1801 var StatsDExpects expect := {
1802 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1803 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1804 };
1805 f_statsd_expect(expect);
1806
1807 /* Simulate CONN FAIL IND on SDCCH */
1808 RSL.send(ts_ASP_RSL_UD(
1809 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1810 IPAC_PROTO_RSL_TRX0));
1811
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001812 f_sleep(1.0);
1813
Oliver Smithaf03bef2021-08-24 15:34:51 +02001814 /* Expect stats to be 1 */
1815 expect := {
1816 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1817 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1818 };
1819 f_statsd_expect(expect);
1820}
1821testcase TC_stats_conn_fail() runs on test_CT {
1822 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1823 var MSC_ConnHdlr vc_conn;
1824
1825 f_init(1, true);
1826 f_sleep(1.0);
1827
1828 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1829 vc_conn.done;
1830
1831 f_shutdown_helper();
1832}
1833
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001834function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001835 boolean expect_deact_sacch := true,
1836 boolean expect_rr_chan_rel := true,
1837 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001838 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001839 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001840 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001841 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001842
1843 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001844 var boolean got_deact_sacch := false;
1845 var boolean got_rr_chan_rel := false;
1846 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001847 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001848 var RSL_IE_Body l3_ie;
1849 var PDU_ML3_NW_MS l3;
1850 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001851 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1852 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001853 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001854 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001855 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001856 repeat;
1857 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001858 [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 +01001859 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001860
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001861 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1862 setverdict(fail, "cannot find L3");
1863 mtc.stop;
1864 }
1865 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1866
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001867 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001868 var CellSelIndValue cells := dec_CellSelIndValue(
1869 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1870
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001871 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1872 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001873 setverdict(pass);
1874 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001875 log("EXPECTED CELLS: ", expect_cells);
1876 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001877 }
1878 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001879
1880 if (not istemplatekind(expect_rr_cause, "omit")) {
1881 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1882 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1883 if (match(got_cause, expect_rr_cause)) {
1884 setverdict(pass);
1885 } else {
1886 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1887 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1888 }
1889 }
Harald Welte99787102019-02-04 10:41:36 +01001890 repeat;
1891 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001892 [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 +01001893 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001894
1895 if (not istemplatekind(expect_rr_cause, "omit")) {
1896 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1897 setverdict(fail, "cannot find L3");
1898 mtc.stop;
1899 }
1900 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1901
1902 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1903 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1904 if (match(got_cause, expect_rr_cause)) {
1905 setverdict(pass);
1906 } else {
1907 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1908 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1909 }
1910 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001911 repeat;
1912 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001913 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001914 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001915 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001916 if (handle_rll_rel) {
1917 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1918 }
Harald Welte91d54a52018-01-28 15:35:07 +01001919 repeat;
1920 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001921 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001922 /* respond with CHAN REL ACK */
1923 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1924 }
1925 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001926 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001927 repeat;
1928 }
1929 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001930
1931 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
1932 " got_rll_rel_req=", got_rll_rel_req);
1933
1934 if (expect_deact_sacch != got_deact_sacch) {
1935 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
1936 }
1937 if (expect_rr_chan_rel != got_rr_chan_rel) {
1938 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
1939 }
1940 if (expect_rll_rel_req != got_rll_rel_req) {
1941 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
1942 }
Harald Welte91d54a52018-01-28 15:35:07 +01001943}
1944
Harald Welte4003d112017-12-09 22:35:39 +01001945/* Test behavior of channel release after hard Clear Command from MSC */
1946testcase TC_chan_rel_hard_clear() runs on test_CT {
1947 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001948 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01001949
Harald Welte89d42e82017-12-17 16:42:41 +01001950 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001951
1952 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1953
1954 /* Instruct BSC to clear channel */
1955 var BssmapCause cause := 0;
1956 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1957
1958 /* expect Clear Complete from BSC on A */
1959 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1960 /* release the SCCP connection */
1961 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1962 }
1963
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001964 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001965 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001966}
1967
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001968function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
1969 var BSSAP_N_DATA_ind rx_di;
1970 var DchanTuple dt;
1971
1972 f_init(1);
1973
1974 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1975 /* Send CommonID with some random PLMN (BSC doesn't take it into account
1976 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
1977 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
1978
1979 /* Instruct BSC to clear channel */
1980 var BssmapCause cause := 0;
1981 if (tx_csfb_ind) {
1982 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
1983 } else {
1984 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1985 }
1986
1987 /* expect Clear Complete from BSC on A */
1988 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1989 /* release the SCCP connection */
1990 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1991 }
1992
1993 /* 1 neighbor is added by default in osmo-bts.cfg and
1994 SystemInformationConfig_default, use that: */
1995 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
1996
1997 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
1998 f_shutdown_helper();
1999}
2000
2001/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2002 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2003 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2004 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2005 Indicator or not shouldn't matter at all. */
2006testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2007 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2008}
2009
2010/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2011 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2012 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2013 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2014testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2015 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2016}
2017
2018/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2019 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2020 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2021 CSFB Indicator should not be used anymore, and hence, there should be no
2022 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2023 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002024testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2025 var BSSAP_N_DATA_ind rx_di;
2026 var DchanTuple dt;
2027
2028 f_init(1);
2029
2030 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2031
2032 /* Instruct BSC to clear channel */
2033 var BssmapCause cause := 0;
2034 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2035
2036 /* expect Clear Complete from BSC on A */
2037 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2038 /* release the SCCP connection */
2039 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2040 }
2041
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002042 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002043 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002044}
2045
Harald Welted8c36cd2017-12-09 23:05:31 +01002046/* Test behavior of channel release after hard RLSD from MSC */
2047testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002048 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002049
Harald Welte89d42e82017-12-17 16:42:41 +01002050 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002051
2052 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2053
2054 /* release the SCCP connection */
2055 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2056
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002057 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002058 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002059}
2060
Harald Welte550daf92018-06-11 19:22:13 +02002061/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2062testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2063 var DchanTuple dt;
2064
2065 f_init(1);
2066
2067 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2068
2069 /* release the SCCP connection */
2070 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2071
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002072 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002073 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002074}
2075
Harald Welte85804d42017-12-10 14:11:58 +01002076/* Test behavior of channel release after BSSMAP RESET from MSC */
2077testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002078 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002079
Harald Welte89d42e82017-12-17 16:42:41 +01002080 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002081
2082 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2083
2084 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2085 IPA_RSL[0].clear;
2086
2087 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002088 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 +01002089 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002090 [] 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 +01002091 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2092 }
2093
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002094 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002095 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002096}
2097
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002098/* Verify T(iar) triggers and releases the channel */
2099testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2100 var DchanTuple dt;
2101
2102 /* Set T(iar) in BSC low enough that it will trigger before other side
2103 has time to keep alive with a T(ias). Keep recommended ratio of
2104 T(iar) >= T(ias)*2 */
2105 g_bsc_sccp_timer_ias := 2;
2106 g_bsc_sccp_timer_iar := 5;
2107
2108 f_init(1);
2109
2110 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2111 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002112 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002113}
2114
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002115private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2116runs on test_CT
2117{
2118 var DchanTuple dt;
2119
2120 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2121 var BssmapCause cause := 0;
2122 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2123 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2124 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2125 }
2126
2127 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 +02002128}
2129
2130/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2131testcase TC_chan_rel_rr_cause() runs on test_CT {
2132 f_init(1);
2133
2134 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2135 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2136 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2137 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2138 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2139 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002140
2141 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002142}
2143
Harald Welte5cd20ed2017-12-13 21:03:20 +01002144/* Test behavior if RSL EST IND for non-active channel */
2145testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2146 timer T := 2.0;
2147
Harald Welte89d42e82017-12-17 16:42:41 +01002148 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002149
2150 var octetstring l3 := '00010203040506'O;
2151 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2152 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2153
2154 T.start;
2155 alt {
2156 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2157 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2158 }
2159 [] BSSAP.receive {}
2160 [] IPA_RSL[0].receive {}
2161 [] T.timeout {}
2162 }
2163
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002164 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002165}
2166
2167/* Test behavior if RSL EST IND for invalid SAPI */
2168testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2169 var RslChannelNr chan_nr;
2170
Harald Welte89d42e82017-12-17 16:42:41 +01002171 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002172
2173 chan_nr := f_chreq_act_ack()
2174
2175 var octetstring l3 := '00010203040506'O;
2176 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2177
2178 timer T := 2.0;
2179 T.start;
2180 alt {
2181 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2182 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2183 }
2184 [] BSSAP.receive { repeat; }
2185 [] IPA_RSL[0].receive { repeat; }
2186 [] T.timeout {}
2187 }
2188
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002189 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002190}
2191
2192/* Test behavior if RSL EST IND for invalid SAPI */
2193testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2194 timer T := 2.0;
2195
Harald Welte89d42e82017-12-17 16:42:41 +01002196 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002197
2198 var RslChannelNr chan_nr := f_chreq_act_ack();
2199
2200 var octetstring l3 := '00010203040506'O;
2201 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2202
2203 T.start;
2204 alt {
2205 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2206 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2207 }
2208 [] BSSAP.receive { repeat; }
2209 [] IPA_RSL[0].receive { repeat; }
2210 [] T.timeout {}
2211 }
2212
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002213 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002214}
2215
2216/* Test behavior if RSL EST IND for invalid SACCH */
2217testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2218 timer T := 2.0;
2219
Harald Welte89d42e82017-12-17 16:42:41 +01002220 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002221
2222 var RslChannelNr chan_nr := f_chreq_act_ack();
2223
2224 var octetstring l3 := '00010203040506'O;
2225 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2226
2227 T.start;
2228 alt {
2229 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2230 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2231 }
2232 [] BSSAP.receive { repeat; }
2233 [] IPA_RSL[0].receive { repeat; }
2234 [] T.timeout {}
2235 }
2236
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002237 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002238}
2239
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002240/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2241private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2242 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2243 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2244
2245 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2246 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2247
2248 f_establish_fully(ass_cmd, exp_compl);
2249
2250 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2251 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2252 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2253 BSSAP.receive(PDU_BSSAP:{
2254 discriminator := '1'B,
2255 spare := '0000000'B,
2256 dlci := 'C3'O,
2257 lengthIndicator := ?,
2258 pdu := { dtap := '0904'O }
2259 });
2260
2261 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2262 for (var integer i := 0; i < 32; i := i + 1) {
2263 var octetstring l3 := '09'O & f_rnd_octstring(14);
2264 var template (value) RslLinkId link_id;
2265 var template (value) OCT1 dlci;
2266
2267 if (i mod 2 == 0) {
2268 /* SAPI0 on FACCH or SDCCH */
2269 link_id := ts_RslLinkID_DCCH(0);
2270 dlci := '80'O;
2271 } else {
2272 /* SAPI3 on SACCH */
2273 link_id := ts_RslLinkID_SACCH(3);
2274 dlci := 'C3'O;
2275 }
2276
2277 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002278 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002279 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002280 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002281 }
2282}
2283testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2284 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2285 var MSC_ConnHdlr vc_conn;
2286
2287 f_init(1, true);
2288 f_sleep(1.0);
2289
2290 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2291 vc_conn.done;
2292
2293 f_shutdown_helper();
2294}
2295
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002296private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2297 template myBSSMAP_Cause cause := ?,
2298 float T_val := 2.0)
2299runs on test_CT {
2300 var BSSAP_N_DATA_ind rx_di;
2301 timer T;
2302
2303 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2304 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2305
2306 T.start(T_val);
2307 alt {
2308 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2309 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2310 if (not match(rx_cause, tr_cause)) {
2311 setverdict(fail, "Rx unexpected Cause IE: ",
2312 rx_cause, " vs expected ", tr_cause);
2313 }
2314 setverdict(pass);
2315 }
2316 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2317 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2318 }
2319 [] T.timeout {
2320 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2321 }
2322 }
2323}
2324
2325/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2326testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2327 var octetstring rnd_data := f_rnd_octstring(16);
2328 var RSL_Message rx_rsl;
2329 var DchanTuple dt;
2330
2331 f_init(1);
2332
2333 /* MS establishes a SAPI=0 link on DCCH */
2334 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2335
2336 /* MSC sends some data on (not yet established) SAPI=3 link */
2337 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2338 /* BSC attempts to establish a SAPI=3 link on DCCH */
2339 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2340
2341 /* MS sends unexpected RELease INDication on SAPI=3 */
2342 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2343 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2344 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2345
2346 /* Clean up the connection */
2347 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2348 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2349
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002350 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002351}
2352
2353/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2354testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2355 var octetstring rnd_data := f_rnd_octstring(16);
2356 var RSL_Message rx_rsl;
2357 var DchanTuple dt;
2358
2359 f_init(1);
2360
2361 /* MS establishes a SAPI=0 link on DCCH */
2362 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2363
2364 /* MSC sends some data on (not yet established) SAPI=3 link */
2365 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2366 /* BSC attempts to establish a SAPI=3 link on DCCH */
2367 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2368
2369 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2370 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2371 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2372 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2373
2374 /* Clean up the connection */
2375 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2376 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2377
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002378 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002379}
2380
2381/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2382testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2383 var octetstring rnd_data := f_rnd_octstring(16);
2384 var RSL_Message rx_rsl;
2385 var DchanTuple dt;
2386
2387 f_init(1);
2388
2389 /* MS establishes a SAPI=0 link on DCCH */
2390 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2391
2392 /* MSC sends some data on (not yet established) SAPI=3 link */
2393 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2394 /* BSC attempts to establish a SAPI=3 link on DCCH */
2395 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2396
2397 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2398 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2399
2400 /* Clean up the connection */
2401 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2402 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2403
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002404 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002405}
2406
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002407testcase TC_si_default() runs on test_CT {
2408 f_init(0);
2409 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002410 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002411}
Harald Welte4003d112017-12-09 22:35:39 +01002412
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002413/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2414 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2415private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2416{
2417 select (earfcn_index) {
2418 case (0) {
2419 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2420 return 111;
2421 }
2422 case (1) {
2423 return 1;
2424 }
2425 case (2) {
2426 return 0;
2427 }
2428 case (3) {
2429 return 65535;
2430 }
2431 case else {
2432 return 23 * (earfcn_index - 3);
2433 }
2434 }
2435}
2436
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002437function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2438 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002439
2440 f_init(0);
2441
2442 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2443 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002444 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2445 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002446 }
2447
2448 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2449
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002450 if (not istemplatekind(expect_cells, "omit")) {
2451 /* Also check that RR Channel Release contains these EARFCNs.
2452 * (copied code from TC_chan_rel_hard_clear_csfb) */
2453 var BSSAP_N_DATA_ind rx_di;
2454 var DchanTuple dt;
2455
2456 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002457 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2458 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2459 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002460
2461 /* Instruct BSC to clear channel */
2462 var BssmapCause cause := 0;
2463 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2464
2465 /* expect Clear Complete from BSC on A */
2466 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2467 /* release the SCCP connection */
2468 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2469 }
2470
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002471 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 +02002472 }
2473
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002474 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002475 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 +02002476 }
2477}
2478
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002479private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2480{
2481 var template SI2quaterRestOctetsList si2quater := {};
2482 var integer si2quater_count := (count + 2) / 3;
2483
2484 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002485 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002486 var integer index := i / 3;
2487 var integer earfcn_index := i mod 3;
2488 if (index >= lengthof(si2quater)) {
2489 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2490 }
2491 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);
2492 }
2493
2494 return si2quater;
2495}
2496
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002497private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2498{
2499 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2500
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002501 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002502 for (var integer i := 0; i < count; i := i + 1) {
2503 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002504 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002505 }
2506
2507 return tr_CellSelIndValue_EUTRAN(cells);
2508}
2509
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002510private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2511{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002512 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002513 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002514 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2515 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002516}
2517
2518testcase TC_si2quater_2_earfcns() runs on test_CT {
2519 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002520 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002521}
2522
2523testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002524 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002525 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002526}
2527
2528testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002529 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002530 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002531}
2532
2533testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002534 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002535 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002536}
2537
2538testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002539 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002540 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002541}
2542
2543testcase TC_si2quater_12_earfcns() runs on test_CT {
2544 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002545 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002546}
2547
2548testcase TC_si2quater_23_earfcns() runs on test_CT {
2549 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002550 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002551}
2552
2553testcase TC_si2quater_32_earfcns() runs on test_CT {
2554 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002555 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002556}
2557
2558testcase TC_si2quater_33_earfcns() runs on test_CT {
2559 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002560 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002561}
2562
2563testcase TC_si2quater_42_earfcns() runs on test_CT {
2564 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002565 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002566}
2567
2568testcase TC_si2quater_48_earfcns() runs on test_CT {
2569 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002570 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002571}
2572
2573/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2574 * 48 EARFCNs. */
2575testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002576 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002577 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2578 f_init(0);
2579
2580 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002581 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2582 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002583 }
2584
2585 /* The 49th EARFCN no longer fits, expect VTY error */
2586 f_vty_enter_cfg_bts(BSCVTY, 0);
2587 var charstring vty_error;
2588 vty_error := f_vty_transceive_ret(BSCVTY,
2589 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2590 f_vty_transceive(BSCVTY, "end");
2591
2592 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2593 log("Got expected VTY error: ", vty_error);
2594 setverdict(pass);
2595 } else {
2596 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2597 }
2598
2599 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2600
2601 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002602 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 +02002603 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002604 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002605}
2606
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002607private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2608{
2609 var uint8_t count := 0;
2610 for (var integer i := 5; i < 16; i := i + 1) {
2611 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2612 count := count + 1;
2613 }
2614 }
2615 return count;
2616}
2617
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002618private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2619{
2620 var ASP_RSL_Unitdata rx_rsl_ud;
2621 var SystemInformationType1 last_si1;
2622
2623 timer T := 30.0;
2624 T.start;
2625 alt {
2626 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2627 tr_RSL_BCCH_INFO,
2628 tr_RSL_NO_SACCH_FILL,
2629 tr_RSL_SACCH_FILL))
2630 ) -> value rx_rsl_ud {
2631 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2632 if (g_system_information[rsl_idx].si1 == omit) {
2633 repeat;
2634 }
2635 last_si1 := g_system_information[rsl_idx].si1;
2636 g_system_information[rsl_idx].si1 := omit;
2637 T.stop;
2638 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002639 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002640 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2641 }
2642 return last_si1;
2643}
2644
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002645/* verify ACC rotate feature */
2646testcase TC_si_acc_rotate() runs on test_CT {
2647 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002648 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002649 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002650 var uint8_t count;
2651 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2652
2653 f_init(0, guard_timeout := 60.0);
2654
2655 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2656 "access-control-class-rotate 3",
2657 "access-control-class-rotate-quantum 1"});
2658
2659 /* Init and get first sysinfo */
2660 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2661
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002662 for (var integer i:= 0; i < 20; i := i + 1) {
2663 last_si1 := f_recv_next_si1(0);
2664 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002665 count := f_acc09_count_allowed(acc);
2666 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2667
2668 if (count != 3) {
2669 log("RSL: EXPECTED SI ACC len=3");
2670 setverdict(fail, "received SI does not match expectations");
2671 break;
2672 }
2673
2674 for (var integer j := 0; j < 10; j := j + 1) {
2675 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2676 times_allowed[j] := times_allowed[j] + 1;
2677 }
2678 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002679 }
2680
2681 for (var integer j := 0; j < 10; j := j + 1) {
2682 log("ACC", j, " allowed ", times_allowed[j], " times" );
2683 if (j != 5 and times_allowed[j] < 3) {
2684 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2685 } else if (j == 5 and times_allowed[j] > 0) {
2686 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2687 }
2688 }
2689
2690 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2691 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002692 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002693}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002694
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002695/* verify ACC startup ramp+rotate feature */
2696testcase TC_si_acc_ramp_rotate() runs on test_CT {
2697 var template SystemInformationConfig sic := SystemInformationConfig_default;
2698 var SystemInformationType1 last_si1;
2699 var AccessControlClass acc;
2700 var ASP_RSL_Unitdata rx_rsl_ud;
2701 var uint8_t count;
2702 var uint8_t prev_count;
2703 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2704
2705 f_init(0, guard_timeout := 80.0);
2706
2707 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2708 "access-control-class-rotate 0",
2709 "access-control-class-rotate-quantum 1",
2710 "access-control-class-ramping",
2711 "access-control-class-ramping-step-interval 5",
2712 "access-control-class-ramping-step-size 5"});
2713
2714 /* Init and get first sysinfo */
2715 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2716 last_si1 := g_system_information[0].si1;
2717 acc := last_si1.rach_control.acc;
2718 count := f_acc09_count_allowed(acc);
2719 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2720 while (count > 0) {
2721 last_si1 := f_recv_next_si1(0);
2722 acc := last_si1.rach_control.acc;
2723 count := f_acc09_count_allowed(acc);
2724 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2725 }
2726
2727 /* Increase adm subset size, we should see ramping start up */
2728 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2729 prev_count := 0;
2730 while (true) {
2731 last_si1 := f_recv_next_si1(0);
2732 acc := last_si1.rach_control.acc;
2733 count := f_acc09_count_allowed(acc);
2734 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2735
2736 if (prev_count > count) {
2737 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2738 break;
2739 }
2740
2741 if (count == 9) {
2742 break; /* Maximum reached (10 - 1 perm barred), done here */
2743 }
2744
2745 prev_count := count;
2746 }
2747
2748 setverdict(pass);
2749
2750 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2751 "rach access-control-class 4 allowed",
2752 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002753 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002754}
2755
Harald Welte4003d112017-12-09 22:35:39 +01002756testcase TC_ctrl_msc_connection_status() runs on test_CT {
2757 var charstring ctrl_resp;
2758
Harald Welte89d42e82017-12-17 16:42:41 +01002759 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002760
2761 /* See https://osmocom.org/issues/2729 */
2762 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002763 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002764}
2765
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002766testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2767 var charstring ctrl_resp;
2768
2769 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002770
2771 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002772 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002773}
2774
Harald Welte4003d112017-12-09 22:35:39 +01002775testcase TC_ctrl() runs on test_CT {
2776 var charstring ctrl_resp;
2777
Harald Welte89d42e82017-12-17 16:42:41 +01002778 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002779
2780 /* all below values must match the osmo-bsc.cfg config file used */
2781
Harald Welte6a129692018-03-17 17:30:14 +01002782 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2783 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002784 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002785
2786 var integer bts_nr := 0;
2787 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2788 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2789 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2790 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2791 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2792 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2793 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2794
2795 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2796 f_sleep(2.0);
2797 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2798 setverdict(fail, "oml-uptime not incrementing as expected");
2799 }
2800 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2801
2802 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2803
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002804 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002805}
2806
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002807/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2808 "location-state" over the SCCPlite IPA conn */
2809testcase TC_ctrl_location() runs on test_CT {
2810 var MSC_ConnHdlr vc_conn;
2811 var integer bts_nr := 0;
2812
2813 f_init(1, true);
2814 f_sleep(1.0);
2815
2816 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2817 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2818 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2819
2820 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2821 f_sleep(2.0);
2822
2823 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2824 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2825 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
2826
2827 /* should match the one from config */
2828 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
2829
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002830 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002831}
2832
Harald Welte6f521d82017-12-11 19:52:02 +01002833
2834/***********************************************************************
2835 * Paging Testing
2836 ***********************************************************************/
2837
2838type record Cell_Identity {
2839 GsmMcc mcc,
2840 GsmMnc mnc,
2841 GsmLac lac,
2842 GsmCellId ci
2843};
Harald Welte24135bd2018-03-17 19:27:53 +01002844private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01002845private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01002846
Harald Welte5d1a2202017-12-13 19:51:29 +01002847type set of integer BtsIdList;
2848
2849private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
2850 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
2851 if (bts_id == bts_ids[j]) {
2852 return true;
2853 }
2854 }
2855 return false;
2856}
Harald Welte6f521d82017-12-11 19:52:02 +01002857
2858/* core paging test helper function; used by most paging test cases */
2859private function f_pageing_helper(hexstring imsi,
2860 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01002861 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01002862 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002863 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01002864{
2865 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002866 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01002867 var RSL_Message rx_rsl;
2868 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01002869 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01002870
2871 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01002872
2873 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01002874 for (i := 0; i < NUM_BTS; i := i + 1) {
2875 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01002876 }
Harald Welte6f521d82017-12-11 19:52:02 +01002877
2878 if (isvalue(rsl_chneed)) {
2879 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
2880 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
2881 } else {
2882 bssmap_chneed := omit;
2883 }
2884
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002885 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
2886 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01002887
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002888 if (not istemplatekind(tmsi, "omit")) {
2889 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002890 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002891 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002892 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002893
Harald Welte5d1a2202017-12-13 19:51:29 +01002894 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002895 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01002896 /* check channel type, paging group */
2897 if (rx_rsl.ies[1].body.paging_group != paging_group) {
2898 setverdict(fail, "Paging for wrong paging group");
2899 }
2900 if (ispresent(rsl_chneed) and
2901 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
2902 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
2903 }
Harald Welte6f521d82017-12-11 19:52:02 +01002904 }
Harald Welte2fccd982018-01-31 15:48:19 +01002905 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01002906 /* do a quick check on all not-included BTSs if they received paging */
2907 for (i := 0; i < NUM_BTS; i := i + 1) {
2908 timer T := 0.1;
2909 if (f_bts_in_list(i, bts_ids)) {
2910 continue;
2911 }
2912 T.start;
2913 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002914 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01002915 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
2916 }
2917 [] IPA_RSL[i].receive { repeat; }
2918 [] T.timeout { }
2919 }
Harald Welte6f521d82017-12-11 19:52:02 +01002920 }
2921
2922 setverdict(pass);
2923}
2924
Harald Welte5d1a2202017-12-13 19:51:29 +01002925const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01002926const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01002927const BtsIdList c_BtsId_LAC1 := { 0, 1 };
2928const BtsIdList c_BtsId_LAC2 := { 2 };
2929
Harald Welte6f521d82017-12-11 19:52:02 +01002930/* PAGING by IMSI + TMSI */
2931testcase TC_paging_imsi_nochan() runs on test_CT {
2932 var BSSMAP_FIELD_CellIdentificationList cid_list;
2933 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01002934 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002935 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002936}
2937
2938/* PAGING by IMSI + TMSI */
2939testcase TC_paging_tmsi_nochan() runs on test_CT {
2940 var BSSMAP_FIELD_CellIdentificationList cid_list;
2941 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002942 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002943 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002944}
2945
2946/* Paging with different "channel needed' values */
2947testcase TC_paging_tmsi_any() runs on test_CT {
2948 var BSSMAP_FIELD_CellIdentificationList cid_list;
2949 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002950 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002951 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002952}
2953testcase TC_paging_tmsi_sdcch() runs on test_CT {
2954 var BSSMAP_FIELD_CellIdentificationList cid_list;
2955 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002956 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002957 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002958}
2959testcase TC_paging_tmsi_tch_f() runs on test_CT {
2960 var BSSMAP_FIELD_CellIdentificationList cid_list;
2961 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002962 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002963 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002964}
2965testcase TC_paging_tmsi_tch_hf() runs on test_CT {
2966 var BSSMAP_FIELD_CellIdentificationList cid_list;
2967 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002968 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002969 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002970}
2971
2972/* Paging by CGI */
2973testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
2974 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2975 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002976 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002977 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002978}
2979
2980/* Paging by LAC+CI */
2981testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
2982 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2983 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002984 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002985 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002986}
2987
2988/* Paging by CI */
2989testcase TC_paging_imsi_nochan_ci() runs on test_CT {
2990 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2991 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002992 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002993 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002994}
2995
2996/* Paging by LAI */
2997testcase TC_paging_imsi_nochan_lai() runs on test_CT {
2998 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2999 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003000 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003001 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003002}
3003
3004/* Paging by LAC */
3005testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3006 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3007 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003008 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003009 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003010}
3011
3012/* Paging by "all in BSS" */
3013testcase TC_paging_imsi_nochan_all() runs on test_CT {
3014 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3015 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003016 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003017 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003018}
3019
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003020/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003021testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3022 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3023 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 +01003024 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003025 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003026}
Harald Welte6f521d82017-12-11 19:52:02 +01003027
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003028/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003029testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3030 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3031 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003032 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003033 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003034}
3035
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003036/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003037testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3038 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3039 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003040 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003041 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003042}
3043
Harald Welte6f521d82017-12-11 19:52:02 +01003044/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003045testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3046 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3047 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3048 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003049 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003050}
3051
3052/* Paging on empty list: Verify none of them page */
3053testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3054 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3055 cid_list := { cIl_LAC := { } };
3056 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003057 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003058}
3059
Stefan Sperling049a86e2018-03-20 15:51:00 +01003060/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3061testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3062 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3063 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3064 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3065 f_shutdown_helper();
3066}
3067
Harald Welte6f521d82017-12-11 19:52:02 +01003068/* Verify paging retransmission interval + count */
3069/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003070/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003071
Harald Weltee65d40e2017-12-13 00:09:06 +01003072/* Verify PCH load */
3073testcase TC_paging_imsi_load() runs on test_CT {
3074 var BSSMAP_FIELD_CellIdentificationList cid_list;
3075 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003076 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003077 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003078 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003079
3080 /* tell BSC there is no paging space anymore */
3081 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003082 f_sleep(0.2);
3083 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003084
3085 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3086 * there would be 8 retransmissions during 4 seconds */
3087 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003088 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003089 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003090 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003091 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003092 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003093 }
Harald Welte2caa1062018-03-17 18:19:05 +01003094 [] T_retrans.timeout {
3095 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3096 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3097 T_retrans.start;
3098 repeat;
3099 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003100 [] T.timeout {
3101 setverdict(pass);
3102 }
3103 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003104
3105 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003106}
3107
Harald Welte235ebf12017-12-15 14:18:16 +01003108/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003109testcase TC_paging_counter() runs on test_CT {
3110 var BSSMAP_FIELD_CellIdentificationList cid_list;
3111 timer T := 4.0;
3112 var integer i;
3113 var integer paging_attempted_bsc;
3114 var integer paging_attempted_bts[NUM_BTS];
3115 var integer paging_expired_bts[NUM_BTS];
3116 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3117
3118 f_init();
3119
3120 /* read counters before paging */
3121 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3122 for (i := 0; i < NUM_BTS; i := i+1) {
3123 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3124 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3125 }
3126
3127 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3128
3129 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3130 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3131 for (i := 0; i < NUM_BTS; i := i+1) {
3132 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3133 paging_attempted_bts[i]+1);
3134 }
3135
3136 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3137 f_sleep(12.0);
3138 for (i := 0; i < NUM_BTS; i := i+1) {
3139 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3140 paging_expired_bts[i]+1);
3141 }
Harald Welte1ff69992017-12-14 12:31:17 +01003142
Philipp Maier282ca4b2018-02-27 17:17:00 +01003143 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003144}
3145
3146
Harald Welte10985002017-12-12 09:29:15 +01003147/* Verify paging stops after A-RESET */
3148testcase TC_paging_imsi_a_reset() runs on test_CT {
3149 var BSSMAP_FIELD_CellIdentificationList cid_list;
3150 timer T := 3.0;
3151 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003152 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003153
3154 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003155 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 +01003156 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003157 [] 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 +01003158 [] BSSAP.receive { repeat; }
3159 }
3160
Daniel Willmanncbef3982018-07-30 09:22:40 +02003161 /* Wait to avoid a possible race condition if a paging message is
3162 * received right before the reset ACK. */
3163 f_sleep(0.2);
3164
Harald Welte10985002017-12-12 09:29:15 +01003165 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003166 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3167 IPA_RSL[i].clear;
3168 }
Harald Welte10985002017-12-12 09:29:15 +01003169
3170 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3171 T.start;
3172 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003173 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003174 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003175 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003176 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003177 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003178 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003179 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003180 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003181 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003182 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003183 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003184 }
Harald Welte10985002017-12-12 09:29:15 +01003185 [] T.timeout {
3186 setverdict(pass);
3187 }
3188 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003189
3190 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003191}
Harald Welteae026692017-12-09 01:03:01 +01003192
Philipp Maierf45824a2019-08-14 14:44:10 +02003193/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3194 * paging response we can not know which MSC is in charge, so we will blindly
3195 * pick the first configured MSC. This behavior is required in order to make
3196 * MT-CSFB calls working because in those cases the BSC can not know that the
3197 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3198 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003199 */
3200testcase TC_paging_resp_unsol() runs on test_CT {
3201
3202 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003203 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003204
3205 var BSSAP_N_CONNECT_ind rx_c_ind;
3206 var DchanTuple dt;
3207 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003208 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003209
3210 /* Send CHAN RQD and wait for allocation; acknowledge it */
3211 dt.rsl_chan_nr := f_chreq_act_ack();
3212
3213 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3214 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3215
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003216
Philipp Maierf45824a2019-08-14 14:44:10 +02003217 /* Expevct a CR with a matching Paging response on the A-Interface */
3218 T.start;
3219 alt {
3220 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3221 setverdict(pass);
3222 }
3223 [] BSSAP.receive {
3224 setverdict(fail, "Received unexpected message on A-Interface!");
3225 }
3226 [] T.timeout {
3227 setverdict(fail, "Received nothing on A-Interface!");
3228 }
3229 }
3230
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003231 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003232}
3233
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003234/* Test RSL link drop causes counter increment */
3235testcase TC_rsl_drop_counter() runs on test_CT {
3236 var integer rsl_fail;
3237
Harald Welte89d42e82017-12-17 16:42:41 +01003238 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003239
3240 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3241
3242 bts[0].rsl.vc_IPA.stop;
3243
3244 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3245
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003246 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003247}
3248
3249/* TODO: Test OML link drop causes counter increment */
3250
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003251/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3252function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3253 timer T := 10.0;
3254
3255 bts[0].rsl.id := "IPA-0-RSL";
3256 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3257 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3258 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003259 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003260
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003261 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003262
3263 f_init_mgcp("VirtMSC");
3264
3265 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3266 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3267 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3268 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3269
3270 /* wait for IPA OML link to connect and then disconnect */
3271 T.start;
3272 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003273 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003274 T.stop;
3275 return true;
3276 }
3277 [] IPA_RSL[0].receive { repeat }
3278 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003279 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003280 }
3281 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003282 return false;
3283}
3284
3285/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3286testcase TC_rsl_unknown_unit_id() runs on test_CT {
3287 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3288 setverdict(pass);
3289 } else {
3290 setverdict(fail, "Timeout RSL waiting for connection to close");
3291 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003292 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003293}
3294
3295
3296/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3297testcase TC_oml_unknown_unit_id() runs on test_CT {
3298 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3299 setverdict(pass);
3300 } else {
3301 setverdict(fail, "Timeout OML waiting for connection to close");
3302 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003303 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003304}
3305
3306
Harald Weltec1a2fff2017-12-17 11:06:19 +01003307/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003308 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003309 ***********************************************************************/
3310
Harald Welte6811d102019-04-14 22:23:14 +02003311import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003312import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003313import from RSL_Emulation all;
3314import from MSC_ConnectionHandler all;
3315
3316type function void_fn(charstring id) runs on MSC_ConnHdlr;
3317
Harald Welte336820c2018-05-31 20:34:52 +02003318/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003319private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3320 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003321 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003322 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003323 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003324 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003325 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3326 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3327 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003328 if (isvalue(bts[2])) {
3329 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3330 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3331 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003332 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003333 if (mp_enable_lcs_tests) {
3334 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3335 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3336 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003337 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003338 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003339 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003340}
3341
Neels Hofmeyrda436782021-07-20 22:09:06 +02003342function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003343runs on test_CT return MSC_ConnHdlr {
3344 var charstring id := testcasename();
3345 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003346 var integer bssap_idx := 0;
3347 if (isvalue(pars)) {
3348 bssap_idx := valueof(pars).mscpool.bssap_idx;
3349 }
Harald Welte336820c2018-05-31 20:34:52 +02003350 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003351 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003352 return vc_conn;
3353}
3354
3355function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3356runs on test_CT return MSC_ConnHdlr {
3357 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003358 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003359 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003360 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003361 return vc_conn;
3362}
3363
Neels Hofmeyrda436782021-07-20 22:09:06 +02003364function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3365runs on test_CT return MSC_ConnHdlr {
3366 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3367}
3368
Harald Weltea0630032018-03-20 21:09:55 +01003369/* first function inside ConnHdlr component; sets g_pars + starts function */
3370private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3371runs on MSC_ConnHdlr {
3372 if (isvalue(pars)) {
3373 g_pars := valueof(pars);
3374 }
3375 fn.apply(id);
3376}
3377
Oliver Smith26a3db72021-07-09 13:51:29 +02003378private function f_vty_encryption_a5(charstring options) runs on test_CT {
3379 f_vty_transceive(BSCVTY, "configure terminal");
3380 f_vty_transceive(BSCVTY, "network");
3381 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3382 f_vty_transceive(BSCVTY, "exit");
3383 f_vty_transceive(BSCVTY, "exit");
3384}
3385
3386private function f_vty_encryption_a5_reset() runs on test_CT {
3387 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3388 f_vty_encryption_a5("0 1 3");
3389}
3390
Harald Welte3c86ea02018-05-10 22:28:05 +02003391/* Establish signalling channel (non-assignment case) followed by cipher mode */
3392private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003393 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3394 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003395 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003396 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3397 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3398 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3399 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003400
Philipp Maier23000732018-05-18 11:25:37 +02003401 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003402}
3403testcase TC_ciph_mode_a5_0() runs on test_CT {
3404 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003405 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003406 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3407
3408 f_init(1, true);
3409 f_sleep(1.0);
3410 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3411 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003412 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003413}
3414testcase TC_ciph_mode_a5_1() runs on test_CT {
3415 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003416 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003417 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3418
3419 f_init(1, true);
3420 f_sleep(1.0);
3421 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3422 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003423 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003424}
Oliver Smith50b98122021-07-09 15:00:28 +02003425/* OS#4975: verify that A5/2 is preferred over A5/0 */
3426testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3427 var MSC_ConnHdlr vc_conn;
3428 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3429
3430 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3431 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3432
3433 f_init(1, true);
3434 f_vty_encryption_a5("0 1 2 3");
3435 f_sleep(1.0);
3436 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3437 vc_conn.done;
3438 f_vty_encryption_a5_reset();
3439 f_shutdown_helper();
3440}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003441/* OS#4975: verify that A5/1 is preferred over A5/2 */
3442testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3443 var MSC_ConnHdlr vc_conn;
3444 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3445
3446 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3447 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3448
3449 f_init(1, true);
3450 f_vty_encryption_a5("1 2");
3451 f_sleep(1.0);
3452 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3453 vc_conn.done;
3454 f_vty_encryption_a5_reset();
3455 f_shutdown_helper();
3456}
Harald Welte3c86ea02018-05-10 22:28:05 +02003457testcase TC_ciph_mode_a5_3() runs on test_CT {
3458 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003459 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003460 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3461
3462 f_init(1, true);
3463 f_sleep(1.0);
3464 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3465 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003466 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003467}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003468/* Establish a Signalling channel with A5/4 encryption. */
3469testcase TC_ciph_mode_a5_4() runs on test_CT {
3470 var MSC_ConnHdlr vc_conn;
3471 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3472 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003473
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003474 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003475 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003476 f_sleep(1.0);
3477 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3478 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003479 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003480 f_shutdown_helper();
3481}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003482/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3483private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3484 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3485 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3486 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3487 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3488
3489 f_establish_fully(ass_cmd, exp_compl);
3490}
3491testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3492 var MSC_ConnHdlr vc_conn;
3493 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3494
3495 f_init(1, true);
3496 f_sleep(1.0);
3497 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3498 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003499 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003500}
3501
Harald Welte3c86ea02018-05-10 22:28:05 +02003502
3503/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003504private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003505 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3506 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003507
Harald Welte552620d2017-12-16 23:21:36 +01003508 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3509 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003510
Harald Weltea0630032018-03-20 21:09:55 +01003511 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003512}
Harald Welte552620d2017-12-16 23:21:36 +01003513testcase TC_assignment_fr_a5_0() runs on test_CT {
3514 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003515 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003516 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003517
Harald Welte89d42e82017-12-17 16:42:41 +01003518 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003519 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003520 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003521 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003522 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003523}
Harald Welte552620d2017-12-16 23:21:36 +01003524testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003525 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003526 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003527 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003528
Harald Welte89d42e82017-12-17 16:42:41 +01003529 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003530 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003531 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3532 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003533 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003534}
3535testcase TC_assignment_fr_a5_3() runs on test_CT {
3536 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003537 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003538 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003539
Harald Welte651fcdc2018-05-10 20:23:16 +02003540 f_init(1, true);
3541 f_sleep(1.0);
3542 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003543 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003544 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003545}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003546/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3547testcase TC_assignment_fr_a5_4() runs on test_CT {
3548 var MSC_ConnHdlr vc_conn;
3549 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3550 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3551
3552 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003553 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003554 f_sleep(1.0);
3555 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3556 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003557 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003558 f_shutdown_helper();
3559}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003560
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003561/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3562testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3563 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3564 var MSC_ConnHdlr vc_conn;
3565
3566 f_init(1, true);
3567 f_sleep(1.0);
3568
3569 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3570 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3571 vc_conn.done;
3572 f_shutdown_helper();
3573}
3574
Harald Welte552620d2017-12-16 23:21:36 +01003575/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3576private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003577 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003578 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003579 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003580
3581 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003582 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3583
Harald Weltea0630032018-03-20 21:09:55 +01003584 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003585}
Harald Welte552620d2017-12-16 23:21:36 +01003586testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3587 var MSC_ConnHdlr vc_conn;
3588
Harald Welte89d42e82017-12-17 16:42:41 +01003589 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003590 f_sleep(1.0);
3591
Harald Welte8863fa12018-05-10 20:15:27 +02003592 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003593 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003594 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003595}
3596
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003597private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3598 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3599 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003600
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003601 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3602 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3603
3604 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3605
3606 var BSSMAP_FIELD_CodecType codecType;
3607 timer T := 10.0;
3608
3609 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3610 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3611
3612 f_create_chan_and_exp();
3613 /* we should now have a COMPL_L3 at the MSC */
3614
3615 var template PDU_BSSAP exp_l3_compl;
3616 exp_l3_compl := tr_BSSMAP_ComplL3()
3617 if (g_pars.aoip == false) {
3618 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3619 } else {
3620 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3621 }
3622 T.start;
3623 alt {
3624 [] BSSAP.receive(exp_l3_compl);
3625 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3626 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3627 }
3628 [] T.timeout {
3629 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3630 }
3631 }
3632
3633 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003634 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003635}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003636testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3637 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003638 var MSC_ConnHdlr vc_conn;
3639
Harald Welte89d42e82017-12-17 16:42:41 +01003640 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003641 f_sleep(1.0);
3642
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003643 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003644 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003645 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003646 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003647}
3648
3649
Harald Welte4532e0a2017-12-23 02:05:44 +01003650private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003651 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003652 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003653 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003654 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003655
3656 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003657 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003658
3659 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003660 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3661 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003662 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3663 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3664 };
3665 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003666}
3667
3668testcase TC_assignment_sign() runs on test_CT {
3669 var MSC_ConnHdlr vc_conn;
3670
3671 f_init(1, true);
3672 f_sleep(1.0);
3673
Harald Welte8863fa12018-05-10 20:15:27 +02003674 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003675 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003676 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003677}
3678
Harald Welte60aa5762018-03-21 19:33:13 +01003679/***********************************************************************
3680 * Codec (list) testing
3681 ***********************************************************************/
3682
3683/* check if the given rsl_mode is compatible with the a_elem */
3684private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3685return boolean {
3686 select (a_elem.codecType) {
3687 case (GSM_FR) {
3688 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3689 return true;
3690 }
3691 }
3692 case (GSM_HR) {
3693 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3694 return true;
3695 }
3696 }
3697 case (GSM_EFR) {
3698 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3699 return true;
3700 }
3701 }
3702 case (FR_AMR) {
3703 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3704 return true;
3705 }
3706 }
3707 case (HR_AMR) {
3708 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3709 return true;
3710 }
3711 }
3712 case else { }
3713 }
3714 return false;
3715}
3716
3717/* check if the given rsl_mode is compatible with the a_list */
3718private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3719return boolean {
3720 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3721 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3722 return true;
3723 }
3724 }
3725 return false;
3726}
3727
3728/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003729function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003730return BSSMAP_IE_ChannelType {
3731 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3732 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3733 select (a_elem.codecType) {
3734 case (GSM_FR) {
3735 ret.channelRateAndType := ChRate_TCHF;
3736 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3737 }
3738 case (GSM_HR) {
3739 ret.channelRateAndType := ChRate_TCHH;
3740 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3741 }
3742 case (GSM_EFR) {
3743 ret.channelRateAndType := ChRate_TCHF;
3744 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3745 }
3746 case (FR_AMR) {
3747 ret.channelRateAndType := ChRate_TCHF;
3748 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3749 }
3750 case (HR_AMR) {
3751 ret.channelRateAndType := ChRate_TCHH;
3752 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3753 }
3754 case else {
3755 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003756 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003757 }
3758 }
3759 return ret;
3760}
3761
Harald Weltea63b9102018-03-22 20:36:16 +01003762private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3763return template RSL_IE_Body {
3764 var template RSL_IE_Body mode_ie := {
3765 chan_mode := {
3766 len := ?,
3767 reserved := ?,
3768 dtx_d := ?,
3769 dtx_u := ?,
3770 spd_ind := RSL_SPDI_SPEECH,
3771 ch_rate_type := -,
3772 coding_alg_rate := -
3773 }
3774 }
3775
3776 select (a_elem.codecType) {
3777 case (GSM_FR) {
3778 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3779 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3780 }
3781 case (GSM_HR) {
3782 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3783 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3784 }
3785 case (GSM_EFR) {
3786 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3787 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3788 }
3789 case (FR_AMR) {
3790 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3791 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3792 }
3793 case (HR_AMR) {
3794 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3795 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3796 }
3797 }
3798 return mode_ie;
3799}
3800
Harald Welte60aa5762018-03-21 19:33:13 +01003801type record CodecListTest {
3802 BSSMAP_IE_SpeechCodecList codec_list,
3803 charstring id
3804}
3805type record of CodecListTest CodecListTests
3806
3807private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003808 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3809 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003810
3811 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003812 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003813 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3814 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3815 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003816 if (isvalue(g_pars.expect_mr_s0_s7)) {
3817 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3818 g_pars.expect_mr_s0_s7;
3819 }
Harald Welte79f3f542018-05-25 20:02:37 +02003820 }
Harald Welte60aa5762018-03-21 19:33:13 +01003821 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3822 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003823 log("expecting ASS COMPL like this: ", exp_compl);
3824
3825 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01003826
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003827 if (not g_pars.expect_channel_mode_modify) {
3828 /* Verify that the RSL-side activation actually matches our expectations */
3829 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01003830
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003831 var RSL_IE_Body mode_ie;
3832 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
3833 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02003834 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003835 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003836 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
3837 if (not match(mode_ie, t_mode_ie)) {
3838 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
3839 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003840 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003841
3842 var RSL_IE_Body mr_conf;
3843 if (g_pars.expect_mr_conf_ie != omit) {
3844 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
3845 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
3846 mtc.stop;
3847 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003848 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003849
3850 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
3851 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
3852 g_pars.expect_mr_conf_ie);
3853 }
3854 } else {
3855 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
3856 log("found RSL MR CONFIG IE: ", mr_conf);
3857 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
3858 mtc.stop;
3859 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003860 }
3861 }
Harald Welte60aa5762018-03-21 19:33:13 +01003862}
3863
Philipp Maierd0e64b02019-03-13 14:15:23 +01003864private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
3865
3866 var PDU_BSSAP ass_cmd := f_gen_ass_req();
3867 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
3868
3869 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003870 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01003871 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3872 }
3873 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3874 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
3875 log("expecting ASS FAIL like this: ", exp_fail);
3876
3877 f_establish_fully(ass_cmd, exp_fail);
3878}
3879
Harald Welte60aa5762018-03-21 19:33:13 +01003880testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003881 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003882 var MSC_ConnHdlr vc_conn;
3883
3884 f_init(1, true);
3885 f_sleep(1.0);
3886
3887 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003888 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003889 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003890 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003891}
3892
3893testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003894 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003895 var MSC_ConnHdlr vc_conn;
3896
3897 f_init(1, true);
3898 f_sleep(1.0);
3899
3900 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003901 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003902 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003903 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003904}
3905
3906testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003907 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003908 var MSC_ConnHdlr vc_conn;
3909
3910 f_init(1, true);
3911 f_sleep(1.0);
3912
3913 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003914 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003915 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003916 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003917}
3918
Philipp Maierd0e64b02019-03-13 14:15:23 +01003919/* Allow 5,90k only (current default config) */
3920private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003921 f_vty_cfg_msc(BSCVTY, 0, {
3922 "amr-config 12_2k forbidden",
3923 "amr-config 10_2k forbidden",
3924 "amr-config 7_95k forbidden",
3925 "amr-config 7_40k forbidden",
3926 "amr-config 6_70k forbidden",
3927 "amr-config 5_90k allowed",
3928 "amr-config 5_15k forbidden",
3929 "amr-config 4_75k forbidden"
3930 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003931}
3932
3933/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
3934 * ("Config-NB-Code = 1") */
3935private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003936 f_vty_cfg_msc(BSCVTY, 0, {
3937 "amr-config 12_2k allowed",
3938 "amr-config 10_2k forbidden",
3939 "amr-config 7_95k forbidden",
3940 "amr-config 7_40k allowed",
3941 "amr-config 6_70k forbidden",
3942 "amr-config 5_90k allowed",
3943 "amr-config 5_15k forbidden",
3944 "amr-config 4_75k allowed"
3945 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003946}
3947
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003948private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
3949 var charstring tch;
3950 if (fr) {
3951 tch := "tch-f";
3952 } else {
3953 tch := "tch-h";
3954 }
3955 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
3956}
3957
3958/* Set the AMR start-mode for this TCH back to the default configuration. */
3959private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
3960 f_vty_amr_start_mode_set(fr, "auto");
3961}
3962
Harald Welte60aa5762018-03-21 19:33:13 +01003963testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003964 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003965 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02003966
3967 /* Note: This setups the codec configuration. The parameter payload in
3968 * mr_conf must be consistant with the parameter codecElements in pars
3969 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003970 var RSL_IE_Body mr_conf := {
3971 other := {
3972 len := 2,
3973 payload := '2804'O
3974 }
3975 };
Harald Welte60aa5762018-03-21 19:33:13 +01003976
Philipp Maier7695a0d2018-09-27 17:52:14 +02003977 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01003978 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02003979 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
3980 pars.expect_mr_conf_ie := mr_conf;
3981
Harald Welte60aa5762018-03-21 19:33:13 +01003982 f_init(1, true);
3983 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003984 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01003985
Harald Welte8863fa12018-05-10 20:15:27 +02003986 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003987 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003988
3989 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01003990 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003991}
3992
3993testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003994 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003995 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02003996
3997 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003998 var RSL_IE_Body mr_conf := {
3999 other := {
4000 len := 2,
4001 payload := '2804'O
4002 }
4003 };
Harald Welte60aa5762018-03-21 19:33:13 +01004004
Philipp Maier7695a0d2018-09-27 17:52:14 +02004005 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004006 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004007 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4008 pars.expect_mr_conf_ie := mr_conf;
4009
Harald Welte60aa5762018-03-21 19:33:13 +01004010 f_init(1, true);
4011 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004012 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004013
Harald Welte8863fa12018-05-10 20:15:27 +02004014 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004015 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004016
4017 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004018 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004019}
4020
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004021/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4022testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4023 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4024 var MSC_ConnHdlr vc_conn;
4025
4026 f_init(1, true);
4027 f_sleep(1.0);
4028
4029 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4030 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4031 * expecting a Channel Mode Modify if the channel type is compatible. */
4032 f_disable_all_sdcch();
4033 f_disable_all_tch_h();
4034
4035 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4036 pars.expect_channel_mode_modify := true;
4037 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4038 vc_conn.done;
4039
4040 f_enable_all_sdcch();
4041 f_enable_all_tch();
4042 f_shutdown_helper();
4043}
4044
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004045/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4046testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4047 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4048 var MSC_ConnHdlr vc_conn;
4049
4050 var RSL_IE_Body mr_conf := {
4051 other := {
4052 len := 2,
4053 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4054 }
4055 };
4056
4057 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4058 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4059 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4060 pars.expect_mr_conf_ie := mr_conf;
4061
4062 f_init(1, true);
4063 f_sleep(1.0);
4064
4065 /* First set nonzero start mode bits */
4066 f_vty_amr_start_mode_set(true, "4");
4067 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4068 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4069 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4070 f_vty_amr_start_mode_set(true, "auto");
4071
4072 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4073 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004074
4075 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4076 f_vty_amr_start_mode_set(true, "1");
4077 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004078 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004079}
4080
Neels Hofmeyr21863562020-11-26 00:34:33 +00004081function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4082 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004083runs on test_CT {
4084
4085 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4086 var MSC_ConnHdlr vc_conn;
4087
4088 /* See note above */
4089 var RSL_IE_Body mr_conf := {
4090 other := {
4091 len := lengthof(mrconf),
4092 payload := mrconf
4093 }
4094 };
4095
4096 if (fr) {
4097 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4098 } else {
4099 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4100 }
4101 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4102 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4103 pars.expect_mr_conf_ie := mr_conf;
4104 pars.expect_mr_s0_s7 := exp_s8_s0;
4105
4106 f_init(1, true);
4107 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004108 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004109 f_sleep(1.0);
4110
4111 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4112 vc_conn.done;
4113 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004114 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004115}
4116
4117function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4118runs on test_CT {
4119
4120 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4121 var MSC_ConnHdlr vc_conn;
4122
4123 if (fr) {
4124 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4125 } else {
4126 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4127 }
4128 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4129 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4130
4131 f_init(1, true);
4132 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004133 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004134 f_sleep(1.0);
4135
4136 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4137 vc_conn.done;
4138 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004139 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004140}
4141
4142
4143/* Set S1, we expect an AMR multirate configuration IE with all four rates
4144 * set. */
4145testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004146 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004147 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004148}
4149
4150/* Set S1, we expect an AMR multirate configuration IE with the lower three
4151 * rates set. */
4152testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004153 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004154 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004155}
4156
4157/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4158 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4159testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004160 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004161 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004162}
4163
4164/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4165 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4166testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004167 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004168 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004169}
4170
4171/* The following block of tests selects more and more rates until all four
4172 * possible rates are in the active set (full rate) */
4173testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004174 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'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_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004179 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004180 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004181}
4182
4183testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004184 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004185 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004186}
4187
4188testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004189 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004190 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004191}
4192
4193/* The following block of tests selects more and more rates until all three
4194 * possible rates are in the active set (half rate) */
4195testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004196 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004197 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004198}
4199
4200testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004201 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004202 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004203}
4204
4205testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004206 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004207 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004208}
4209
4210/* The following block tests what happens when the MSC does offer rate
4211 * configurations that are not supported by the BSC. Normally such situations
4212 * should not happen because the MSC gets informed by the BSC in advance via
4213 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4214 * to offer rates that are not applicable anyway. */
4215
4216testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004217 /* Try to include 12,2k in into the active set even though the channel
4218 * is half rate only. The BSC is expected to remove the 12,0k */
4219 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004220 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004221}
4222
4223testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004224 /* See what happens when all rates are selected at once. Since then
4225 * Also S1 is selected, this setting will be prefered and we should
4226 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4227 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004228 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004229}
4230
4231testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004232 /* Same as above, but with S1 missing, the MSC is then expected to
4233 * select the currently supported rates, which are also 12.2k, 7,40k,
4234 * 5,90k, and 4,75k, into the active set. */
4235 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004236 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004237}
4238
4239testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004240 /* Try to select no rates at all */
4241 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004242 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004243}
4244
4245testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004246 /* Try to select only unsupported rates */
4247 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004248 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004249}
4250
4251testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004252 /* Try to select 12,2k for half rate */
4253 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004254 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004255}
4256
Neels Hofmeyr21863562020-11-26 00:34:33 +00004257testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4258 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4259 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004260 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004261}
4262
4263testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4264 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4265 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004266 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004267}
4268
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004269testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004270 /* "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 +00004271 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4272 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004273 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004274}
4275
4276testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004277 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4278 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004279 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004280 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004281}
4282
Philipp Maierac09bfc2019-01-08 13:41:39 +01004283private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004284 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4285 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4286 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4287 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004288}
4289
4290private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004291 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4292 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004293}
4294
4295private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004296 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4297 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4298 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4299 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4300 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4301 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004302}
4303
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004304private function f_disable_all_sdcch() runs on test_CT {
4305 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4306 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4307 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4308 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4309}
4310
4311private function f_enable_all_sdcch() runs on test_CT {
4312 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4313 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4314 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4315 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4316}
4317
Philipp Maierac09bfc2019-01-08 13:41:39 +01004318/* Allow HR only */
4319private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4320 g_pars := f_gen_test_hdlr_pars();
4321 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4322 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4323 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4324 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4325 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4326 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4327 f_establish_fully(ass_cmd, exp_compl);
4328}
4329
4330/* Allow FR only */
4331private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4332 g_pars := f_gen_test_hdlr_pars();
4333 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4334 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4335 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4336 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4337 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4338 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4339 f_establish_fully(ass_cmd, exp_compl);
4340}
4341
4342/* Allow HR only (expect assignment failure) */
4343private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4344 g_pars := f_gen_test_hdlr_pars();
4345 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4346 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4347 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4348 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4349 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4350 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4351 f_establish_fully(ass_cmd, exp_fail);
4352}
4353
4354/* Allow FR only (expect assignment failure) */
4355private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4356 g_pars := f_gen_test_hdlr_pars();
4357 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4358 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4359 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4360 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4361 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4362 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4363 f_establish_fully(ass_cmd, exp_fail);
4364}
4365
4366/* Allow FR and HR, but prefer FR */
4367private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4368 g_pars := f_gen_test_hdlr_pars();
4369 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4370 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4371 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4372 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4373 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4374 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4375 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4376 f_establish_fully(ass_cmd, exp_compl);
4377}
4378
4379/* Allow FR and HR, but prefer HR */
4380private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4381 g_pars := f_gen_test_hdlr_pars();
4382 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4383 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4384 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4385 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4386 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4387 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4388 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4389 f_establish_fully(ass_cmd, exp_compl);
4390}
4391
4392/* Allow FR and HR, but prefer FR */
4393private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4394 g_pars := f_gen_test_hdlr_pars();
4395 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4396 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4397 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4398 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4399 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4400 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4401 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4402 f_establish_fully(ass_cmd, exp_compl);
4403}
4404
4405/* Allow FR and HR, but prefer HR */
4406private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4407 g_pars := f_gen_test_hdlr_pars();
4408 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4409 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4410 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4411 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4412 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4413 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4414 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4415 f_establish_fully(ass_cmd, exp_compl);
4416}
4417
4418/* Request a HR channel while all FR channels are exhausted, this is expected
4419 * to work without conflicts */
4420testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4421 var MSC_ConnHdlr vc_conn;
4422 f_init(1, true);
4423 f_sleep(1.0);
4424 f_enable_all_tch();
4425 f_disable_all_tch_f();
4426 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4427 vc_conn.done;
4428 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004429 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004430}
4431
4432/* Request a FR channel while all FR channels are exhausted, this is expected
4433 * to fail. */
4434testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4435 var MSC_ConnHdlr vc_conn;
4436 f_init(1, true);
4437 f_sleep(1.0);
4438 f_enable_all_tch();
4439 f_disable_all_tch_f();
4440 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4441 vc_conn.done;
4442 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004443 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004444}
4445
4446/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4447 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4448testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4449 var MSC_ConnHdlr vc_conn;
4450 f_init(1, true);
4451 f_sleep(1.0);
4452 f_enable_all_tch();
4453 f_disable_all_tch_f();
4454 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4455 vc_conn.done;
4456 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004457 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004458}
4459
4460/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4461 * are exhausted, this is expected to work without conflicts. */
4462testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4463 var MSC_ConnHdlr vc_conn;
4464 f_init(1, true);
4465 f_sleep(1.0);
4466 f_enable_all_tch();
4467 f_disable_all_tch_f();
4468 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4469 vc_conn.done;
4470 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004471 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004472}
4473
4474/* Request a FR channel while all HR channels are exhausted, this is expected
4475 * to work without conflicts */
4476testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4477 var MSC_ConnHdlr vc_conn;
4478 f_init(1, true);
4479 f_sleep(1.0);
4480 f_enable_all_tch();
4481 f_disable_all_tch_h();
4482 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4483 vc_conn.done;
4484 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004485 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004486}
4487
4488/* Request a HR channel while all HR channels are exhausted, this is expected
4489 * to fail. */
4490testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4491 var MSC_ConnHdlr vc_conn;
4492 f_init(1, true);
4493 f_sleep(1.0);
4494 f_enable_all_tch();
4495 f_disable_all_tch_h();
4496 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4497 vc_conn.done;
4498 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004499 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004500}
4501
4502/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4503 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4504testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4505 var MSC_ConnHdlr vc_conn;
4506 f_init(1, true);
4507 f_sleep(1.0);
4508 f_enable_all_tch();
4509 f_disable_all_tch_h();
4510 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4511 vc_conn.done;
4512 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004513 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004514}
4515
4516/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4517 * are exhausted, this is expected to work without conflicts. */
4518testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4519 var MSC_ConnHdlr vc_conn;
4520 f_init(1, true);
4521 f_sleep(1.0);
4522 f_enable_all_tch();
4523 f_disable_all_tch_h();
4524 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4525 vc_conn.done;
4526 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004527 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004528}
4529
4530/* Allow FR and HR, but prefer HR */
4531private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4532 g_pars := f_gen_test_hdlr_pars();
4533 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4534 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4535 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4536 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4537 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4538 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4539 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4540 f_establish_fully(ass_cmd, exp_compl);
4541}
4542
4543/* Allow FR and HR, but prefer FR */
4544private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4545 g_pars := f_gen_test_hdlr_pars();
4546 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4547 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4548 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4549 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4550 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4551 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4552 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4553 f_establish_fully(ass_cmd, exp_compl);
4554}
4555
4556/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4557 * HR, which is the prefered type, is selected. */
4558testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4559 var MSC_ConnHdlr vc_conn;
4560 f_init(1, true);
4561 f_sleep(1.0);
4562 f_enable_all_tch();
4563 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4564 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004565 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004566}
4567
4568/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4569 * FR, which is the prefered type, is selected. */
4570testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4571 var MSC_ConnHdlr vc_conn;
4572 f_init(1, true);
4573 f_sleep(1.0);
4574 f_enable_all_tch();
4575 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4576 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004577 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004578}
4579
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004580/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4581private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4582 g_pars := f_gen_test_hdlr_pars();
4583 g_pars.ra := '02'O; /* RA containing reason=LU */
4584
4585 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4586 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4587 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4588 var template uint3_t tsc := ?;
4589
4590 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4591 f_create_bssmap_exp(l3_enc);
4592 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4593 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4594
4595 /* we should now have a COMPL_L3 at the MSC */
4596 timer T := 10.0;
4597 T.start;
4598 alt {
4599 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4600 [] T.timeout {
4601 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4602 }
4603 }
4604}
4605testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4606 var MSC_ConnHdlr vc_conn;
4607 f_init(1, true);
4608 f_sleep(1.0);
4609 f_disable_all_sdcch();
4610 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4611 vc_conn.done;
4612 f_enable_all_sdcch();
4613 f_shutdown_helper();
4614}
4615
4616/* Request a signalling channel with all SDCCH exhausted, it is
4617 expected that no TCH will be selected for signalling and assigment will fail
4618 because it's dictated by VTY config */
4619testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4620 var RSL_Message rsl_unused, rsl_msg;
4621 var GsmRrMessage rr;
4622 f_init(1, false);
4623 f_sleep(1.0);
4624 f_vty_allow_tch_for_signalling(false, 0);
4625 f_disable_all_sdcch();
4626
4627 /* RA containing reason=LU */
4628 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4629 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4630 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4631 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4632 setverdict(fail, "Expected reject");
4633 }
4634
4635 f_vty_allow_tch_for_signalling(true, 0);
4636 f_enable_all_sdcch();
4637 f_shutdown_helper();
4638}
4639
4640/* Request a voice channel with all SDCCH exhausted, it is
4641 * expected that TCH channel will be allocated since the VTY option is only
4642 * aimed at signalling requests */
4643private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4644 g_pars := f_gen_test_hdlr_pars();
4645 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4646
4647 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4648 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4649 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4650 var template uint3_t tsc := ?;
4651
4652 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4653 f_create_bssmap_exp(l3_enc);
4654 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4655 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4656
4657 /* we should now have a COMPL_L3 at the MSC */
4658 timer T := 10.0;
4659 T.start;
4660 alt {
4661 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4662 [] T.timeout {
4663 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4664 }
4665 }
4666}
4667testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4668 var MSC_ConnHdlr vc_conn;
4669 f_init(1, true);
4670 f_sleep(1.0);
4671 f_vty_allow_tch_for_signalling(false, 0);
4672 f_disable_all_sdcch();
4673
4674 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4675 vc_conn.done;
4676
4677 f_vty_allow_tch_for_signalling(true, 0);
4678 f_enable_all_sdcch();
4679 f_shutdown_helper();
4680}
4681
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004682testcase TC_assignment_osmux() runs on test_CT {
4683 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4684 var MSC_ConnHdlr vc_conn;
4685
4686 /* See note above */
4687 var RSL_IE_Body mr_conf := {
4688 other := {
4689 len := 2,
4690 payload := '2804'O
4691 }
4692 };
4693
4694 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4695 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4696 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4697 pars.expect_mr_conf_ie := mr_conf;
4698 pars.use_osmux := true;
4699
4700 f_init(1, true, true);
4701 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004702 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004703
4704 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4705 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004706
4707 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004708 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004709}
4710
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004711/* test the procedure of the MSC requesting a Classmark Update:
4712 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4713 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004714private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004715 g_pars := f_gen_test_hdlr_pars();
4716
Harald Weltea0630032018-03-20 21:09:55 +01004717 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004718 /* we should now have a COMPL_L3 at the MSC */
4719 BSSAP.receive(tr_BSSMAP_ComplL3);
4720
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004721 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4722 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4723
Harald Welte898113b2018-01-31 18:32:21 +01004724 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4725 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4726 setverdict(pass);
4727}
4728testcase TC_classmark() runs on test_CT {
4729 var MSC_ConnHdlr vc_conn;
4730 f_init(1, true);
4731 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004732 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004733 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004734 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004735}
4736
Harald Welteeddf0e92020-06-21 19:42:15 +02004737/* Send a CommonID from the simulated MSC and verify that the information is used to
4738 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4739private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4740 g_pars := f_gen_test_hdlr_pars();
4741 f_MscConnHdlr_init_vty();
4742
4743 f_create_chan_and_exp();
4744 /* we should now have a COMPL_L3 at the MSC */
4745 BSSAP.receive(tr_BSSMAP_ComplL3);
4746
4747 /* Send CommonID */
4748 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4749
4750 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4751 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4752 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4753
4754 setverdict(pass);
4755}
4756testcase TC_common_id() runs on test_CT {
4757 var MSC_ConnHdlr vc_conn;
4758 f_init(1, true);
4759 f_sleep(1.0);
4760 vc_conn := f_start_handler(refers(f_tc_common_id));
4761 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004762 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004763}
4764
Harald Weltee3bd6582018-01-31 22:51:25 +01004765private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004766 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004767 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004768 /* we should now have a COMPL_L3 at the MSC */
4769 BSSAP.receive(tr_BSSMAP_ComplL3);
4770
Harald Weltee3bd6582018-01-31 22:51:25 +01004771 /* send the single message we want to send */
4772 f_rsl_send_l3(l3);
4773}
4774
4775private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4776 timer T := sec;
4777 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004778 T.start;
4779 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004780 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4781 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004782 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004783 }
4784 [] T.timeout {
4785 setverdict(pass);
4786 }
4787 }
4788}
4789
Harald Weltee3bd6582018-01-31 22:51:25 +01004790/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4791private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4792 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4793 f_bssap_expect_nothing();
4794}
Harald Welte898113b2018-01-31 18:32:21 +01004795testcase TC_unsol_ass_fail() runs on test_CT {
4796 var MSC_ConnHdlr vc_conn;
4797 f_init(1, true);
4798 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004799 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004800 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004801 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004802}
Harald Welte552620d2017-12-16 23:21:36 +01004803
Harald Welteea99a002018-01-31 20:46:43 +01004804
4805/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4806private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004807 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4808 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004809}
4810testcase TC_unsol_ass_compl() runs on test_CT {
4811 var MSC_ConnHdlr vc_conn;
4812 f_init(1, true);
4813 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004814 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004815 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004816 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004817}
4818
4819
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004820/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4821private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004822 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4823 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004824}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004825testcase TC_unsol_ho_fail() runs on test_CT {
4826 var MSC_ConnHdlr vc_conn;
4827 f_init(1, true);
4828 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004829 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004830 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004831 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004832}
4833
4834
Harald Weltee3bd6582018-01-31 22:51:25 +01004835/* short message from MS should be ignored */
4836private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004837 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004838 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01004839 /* we should now have a COMPL_L3 at the MSC */
4840 BSSAP.receive(tr_BSSMAP_ComplL3);
4841
4842 /* send short message */
4843 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
4844 f_bssap_expect_nothing();
4845}
4846testcase TC_err_82_short_msg() runs on test_CT {
4847 var MSC_ConnHdlr vc_conn;
4848 f_init(1, true);
4849 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004850 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01004851 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004852 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01004853}
4854
4855
Harald Weltee9e02e42018-01-31 23:36:25 +01004856/* 24.008 8.4 Unknown message must trigger RR STATUS */
4857private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
4858 f_est_single_l3(ts_RRM_UL_REL('00'O));
4859 timer T := 3.0
4860 alt {
4861 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
4862 setverdict(pass);
4863 }
4864 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01004865 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01004866 }
4867}
4868testcase TC_err_84_unknown_msg() runs on test_CT {
4869 var MSC_ConnHdlr vc_conn;
4870 f_init(1, true);
4871 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004872 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01004873 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004874 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01004875}
4876
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004877/***********************************************************************
4878 * Handover
4879 ***********************************************************************/
4880
Harald Welte94e0c342018-04-07 11:33:23 +02004881/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
4882private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
4883runs on test_CT {
4884 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4885 " timeslot "&int2str(ts_nr)&" ";
4886 f_vty_transceive(BSCVTY, cmd & suffix);
4887}
4888
Harald Welte261af4b2018-02-12 21:20:39 +01004889/* 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 +07004890private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
4891 uint8_t bts_nr, uint8_t trx_nr,
4892 in RslChannelNr chan_nr)
4893{
Harald Welte261af4b2018-02-12 21:20:39 +01004894 /* FIXME: resolve those from component-global state */
4895 var integer ts_nr := chan_nr.tn;
4896 var integer ss_nr;
4897 if (ischosen(chan_nr.u.ch0)) {
4898 ss_nr := 0;
4899 } else if (ischosen(chan_nr.u.lm)) {
4900 ss_nr := chan_nr.u.lm.sub_chan;
4901 } else if (ischosen(chan_nr.u.sdcch4)) {
4902 ss_nr := chan_nr.u.sdcch4.sub_chan;
4903 } else if (ischosen(chan_nr.u.sdcch8)) {
4904 ss_nr := chan_nr.u.sdcch8.sub_chan;
4905 } else {
4906 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02004907 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01004908 }
4909
4910 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4911 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004912 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01004913}
4914
Neels Hofmeyr91401012019-07-11 00:42:35 +02004915/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
4916 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
4917 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
4918 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
4919 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004920private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
4921 in RslChannelNr chan_nr, uint8_t new_bts_nr)
4922{
4923 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01004924}
4925
4926/* intra-BSC hand-over between BTS0 and BTS1 */
4927private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004928 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4929 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01004930
4931 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4932 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4933
Harald Weltea0630032018-03-20 21:09:55 +01004934 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02004935 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01004936
4937 var HandoverState hs := {
4938 rr_ho_cmpl_seen := false,
4939 handover_done := false,
4940 old_chan_nr := -
4941 };
4942 /* issue hand-over command on VTY */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004943 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01004944 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
4945 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004946
4947 /* From the MGW perspective, a handover is is characterized by
4948 * performing one MDCX operation with the MGW. So we expect to see
4949 * one more MDCX during handover. */
4950 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
4951
Harald Welte261af4b2018-02-12 21:20:39 +01004952 alt {
4953 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01004954 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004955
Philipp Maier4dae0652018-11-12 12:03:26 +01004956 /* Since this is an internal handover we expect the BSC to inform the
4957 * MSC about the event */
4958 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
4959
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004960 /* Check the amount of MGCP transactions is still consistant with the
4961 * test expectation */
4962 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02004963
4964 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
4965 * g_chan_nr to the new lchan that was handed over to. It lives in bts 1, so look it up at RSL1_PROC. */
4966 f_verify_encr_info(f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr));
4967
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01004968 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01004969}
4970
4971testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02004972 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01004973 var MSC_ConnHdlr vc_conn;
4974 f_init(2, true);
4975 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004976
4977 f_ctrs_bsc_and_bts_init();
4978
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02004979 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01004980 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004981
4982 /* from f_establish_fully() */
4983 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4984 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4985 /* from handover */
4986 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4987 f_ctrs_bsc_and_bts_add(0, "handover:completed");
4988 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
4989 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
4990 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004991 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01004992}
Harald Weltee9e02e42018-01-31 23:36:25 +01004993
Oliver Smith7eabd312021-07-12 14:18:56 +02004994function 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 +02004995 var MSC_ConnHdlr vc_conn;
4996 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4997 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
4998
4999 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005000 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005001 f_sleep(1.0);
5002
5003 f_ctrs_bsc_and_bts_init();
5004
5005 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5006 vc_conn.done;
5007
5008 /* from f_establish_fully() */
5009 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5010 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5011 /* from handover */
5012 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5013 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5014 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5015 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5016 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005017 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005018 f_shutdown_helper();
5019}
5020
5021testcase TC_ho_int_a5_0() runs on test_CT {
5022 f_tc_ho_int_a5('01'O);
5023}
5024
5025testcase TC_ho_int_a5_1() runs on test_CT {
5026 f_tc_ho_int_a5('02'O);
5027}
5028
5029testcase TC_ho_int_a5_3() runs on test_CT {
5030 f_tc_ho_int_a5('08'O);
5031}
5032
5033testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005034 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005035}
5036
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005037/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5038private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5039 g_pars := f_gen_test_hdlr_pars();
5040 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5041 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005042
5043 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5044 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5045
5046 f_establish_fully(ass_cmd, exp_compl);
5047 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5048
5049 var HandoverState hs := {
5050 rr_ho_cmpl_seen := false,
5051 handover_done := false,
5052 old_chan_nr := -
5053 };
5054 /* issue hand-over command on VTY */
5055 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5056 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5057 f_rslem_suspend(RSL1_PROC);
5058
5059 /* From the MGW perspective, a handover is is characterized by
5060 * performing one MDCX operation with the MGW. So we expect to see
5061 * one more MDCX during handover. */
5062 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5063
5064 var RSL_Message rsl;
5065 var PDU_ML3_NW_MS l3;
5066 var RslChannelNr new_chan_nr;
5067 var GsmArfcn arfcn;
5068 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5069 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5070 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5071 setverdict(fail, "Expected handoverCommand");
5072 mtc.stop;
5073 }
5074 }
5075 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5076 new_chan_nr, arfcn);
5077
5078 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5079
5080 /* resume processing of RSL DChan messages, which was temporarily suspended
5081 * before performing a hand-over */
5082 f_rslem_resume(RSL1_PROC);
5083 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5084
5085 f_sleep(1.0);
5086
5087 /* Handover fails because no HANDO DET appears on the new lchan,
5088 * and the old lchan reports a Radio Link Failure. */
5089 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5090
5091 var PDU_BSSAP rx_clear_request;
5092 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5093 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5094 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5095
5096 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5097
5098 var MgcpCommand mgcp;
5099 interleave {
5100 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5101 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005102 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005103 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005104 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005105 }
5106 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005107 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005108 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005109 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005110 }
5111 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5112 }
5113
5114 f_sleep(0.5);
5115 setverdict(pass);
5116}
5117testcase TC_ho_int_radio_link_failure() runs on test_CT {
5118 var MSC_ConnHdlr vc_conn;
5119 f_init(2, true);
5120 f_sleep(1.0);
5121
5122 f_ctrs_bsc_and_bts_init();
5123
5124 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5125 vc_conn.done;
5126
5127 /* from f_establish_fully() */
5128 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5129 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5130 /* from handover */
5131 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5132 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5133 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5134 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
5135 f_ctrs_bsc_and_bts_verify();
5136 f_shutdown_helper();
5137}
5138
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005139/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005140private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005141 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005142 var template MgcpResponse mgcp_resp;
5143 var MGCP_RecvFrom mrf;
5144 var template MgcpMessage msg_resp;
5145 var template MgcpMessage msg_dlcx := {
5146 command := tr_DLCX()
5147 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005148
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005149 if (g_pars.aoip) {
5150 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005151 log("Got first DLCX: ", mgcp);
5152 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005153 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005154
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005155 MGCP.receive(tr_DLCX()) -> value mgcp {
5156 log("Got second DLCX: ", mgcp);
5157 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5158 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005159 } else {
5160 /* For SCCPLite, BSC doesn't handle the MSC-side */
5161 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5162 log("Got first DLCX: ", mrf.msg.command);
5163 msg_resp := {
5164 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5165 }
5166 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5167 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005168 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005169}
5170
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005171private 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 +01005172
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005173 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005174 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5175
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005176 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005177
5178 f_sleep(0.5);
5179 /* The MSC negotiates Handover Request and Handover Request Ack with
5180 * the other BSS and comes back with a BSSMAP Handover Command
5181 * containing an RR Handover Command coming from the target BSS... */
5182
5183 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5184 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5185 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5186 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5187 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5188
5189 /* expect the Handover Command to go out on RR */
5190 var RSL_Message rsl_ho_cmd
5191 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5192 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5193 var RSL_IE_Body rsl_ho_cmd_l3;
5194 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5195 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5196 setverdict(fail);
5197 } else {
5198 log("Found L3 Info: ", rsl_ho_cmd_l3);
5199 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5200 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5201 setverdict(fail);
5202 } else {
5203 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5204 setverdict(pass);
5205 }
5206 }
5207
5208 /* When the other BSS has reported a completed handover, this side is
5209 * torn down. */
5210
5211 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5212 var BssmapCause cause := enum2int(cause_val);
5213 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5214
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005215 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005216
5217 interleave {
5218 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5219 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5220 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005221 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005222 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005223 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005224}
5225
5226private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5227 g_pars := f_gen_test_hdlr_pars();
5228 var PDU_BSSAP ass_req := f_gen_ass_req();
5229 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5230 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5231 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5232 f_establish_fully(ass_req, exp_compl);
5233
5234 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005235}
5236testcase TC_ho_out_of_this_bsc() runs on test_CT {
5237 var MSC_ConnHdlr vc_conn;
5238
5239 f_init(1, true);
5240 f_sleep(1.0);
5241
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005242 f_ctrs_bsc_and_bts_init();
5243
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005244 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5245 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005246
5247 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5248 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5249 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5250 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5251 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5252 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5253 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005254 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005255}
5256
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005257private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5258 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005259 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005260 octetstring l3 := '0123456789'O)
5261runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005262 /* The old lchan and conn should still be active. See that arbitrary L3
5263 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005264 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005265 var template PDU_BSSAP exp_data := {
5266 discriminator := '1'B,
5267 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005268 dlci := dlci,
5269 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005270 pdu := {
5271 dtap := l3
5272 }
5273 };
5274 BSSAP.receive(exp_data);
5275 setverdict(pass);
5276}
5277
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005278private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5279 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005280 template (value) OCT1 dlci := '00'O,
5281 octetstring l3 := '0123456789'O)
5282runs on MSC_ConnHdlr {
5283 BSSAP.send(PDU_BSSAP:{
5284 discriminator := '1'B,
5285 spare := '0000000'B,
5286 dlci := dlci,
5287 lengthIndicator := lengthof(l3),
5288 pdu := {
5289 dtap := l3
5290 }
5291 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005292 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005293 setverdict(pass);
5294}
5295
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005296/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5297 * simply never sends a BSSMAP Handover Command. */
5298private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005299 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005300
5301 var PDU_BSSAP ass_req := f_gen_ass_req();
5302 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5303 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5304 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5305 f_establish_fully(ass_req, exp_compl);
5306
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005307 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005308 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5309
5310 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5311
5312 /* osmo-bsc should time out 10 seconds after the handover started.
5313 * Let's give it a bit extra. */
5314 f_sleep(15.0);
5315
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005316 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005317 f_sleep(1.0);
5318}
5319testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5320 var MSC_ConnHdlr vc_conn;
5321
5322 f_init(1, true);
5323 f_sleep(1.0);
5324
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005325 f_ctrs_bsc_and_bts_init();
5326
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005327 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5328 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005329
5330 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5331 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5332 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5333 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5334 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5335 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5336 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005337 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005338}
5339
5340/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5341 * RR Handover Failure. */
5342private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005343 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005344
5345 var PDU_BSSAP ass_req := f_gen_ass_req();
5346 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5347 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5348 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5349 f_establish_fully(ass_req, exp_compl);
5350
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005351 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005352 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5353
5354 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5355
5356 f_sleep(0.5);
5357 /* The MSC negotiates Handover Request and Handover Request Ack with
5358 * the other BSS and comes back with a BSSMAP Handover Command
5359 * containing an RR Handover Command coming from the target BSS... */
5360
5361 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5362 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5363 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5364 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5365 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5366
5367 /* expect the Handover Command to go out on RR */
5368 var RSL_Message rsl_ho_cmd
5369 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5370 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5371 var RSL_IE_Body rsl_ho_cmd_l3;
5372 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5373 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5374 setverdict(fail);
5375 } else {
5376 log("Found L3 Info: ", rsl_ho_cmd_l3);
5377 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5378 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5379 setverdict(fail);
5380 } else {
5381 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5382 setverdict(pass);
5383 }
5384 }
5385
5386 f_sleep(0.2);
5387 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5388
5389 /* Should tell the MSC about the failure */
5390 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5391
5392 f_sleep(1.0);
5393
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005394 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005395 f_sleep(1.0);
5396
5397 setverdict(pass);
5398 f_sleep(1.0);
5399}
5400testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5401 var MSC_ConnHdlr vc_conn;
5402
5403 f_init(1, true);
5404 f_sleep(1.0);
5405
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005406 f_ctrs_bsc_and_bts_init();
5407
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005408 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5409 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005410
5411 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5412 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5413 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5414 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5415 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5416 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5417 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005418 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005419}
5420
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005421/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5422 * (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 +02005423 * and the lchan is released. */
5424private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005425 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005426
5427 var PDU_BSSAP ass_req := f_gen_ass_req();
5428 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5429 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5430 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5431 f_establish_fully(ass_req, exp_compl);
5432
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005433 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005434 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5435
5436 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5437
5438 f_sleep(0.5);
5439 /* The MSC negotiates Handover Request and Handover Request Ack with
5440 * the other BSS and comes back with a BSSMAP Handover Command
5441 * containing an RR Handover Command coming from the target BSS... */
5442
5443 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5444 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5445 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5446 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5447 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5448
5449 /* expect the Handover Command to go out on RR */
5450 var RSL_Message rsl_ho_cmd
5451 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5452 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5453 var RSL_IE_Body rsl_ho_cmd_l3;
5454 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5455 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5456 setverdict(fail);
5457 } else {
5458 log("Found L3 Info: ", rsl_ho_cmd_l3);
5459 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5460 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5461 setverdict(fail);
5462 } else {
5463 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5464 setverdict(pass);
5465 }
5466 }
5467
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005468 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5469 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5470 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005471
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005472 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005473 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5474 log("Got BSSMAP Clear Request");
5475 /* Instruct BSC to clear channel */
5476 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5477 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5478
5479 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005480 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005481 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5482 log("Got Deact SACCH");
5483 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005484 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005485 log("Got RR Release");
5486 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005487 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005488 log("Got RF Chan Rel");
5489 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005490 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005491 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005492 }
5493
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005494 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005495 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005496
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005497 setverdict(pass);
5498 f_sleep(1.0);
5499}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005500testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005501 var MSC_ConnHdlr vc_conn;
5502
5503 f_init(1, true);
5504 f_sleep(1.0);
5505
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005506 f_ctrs_bsc_and_bts_init();
5507
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005508 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005509 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005510
5511 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5512 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5513 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5514 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5515 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5516 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5517 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005518 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005519}
5520
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005521private 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 +01005522 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5523 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5524 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5525 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5526 * before we get started. */
5527 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5528 f_rslem_register(0, new_chan_nr);
5529 g_chan_nr := new_chan_nr;
5530 f_sleep(1.0);
5531
5532 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5533 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5534 activate(as_Media());
5535
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005536 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005537 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005538 oldToNewBSSIEs := oldToNewBSSIEs,
5539 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005540 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005541
5542 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5543
5544 var PDU_BSSAP rx_bssap;
5545 var octetstring ho_command_str;
5546
5547 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005548
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005549 /* we're sure that the channel activation is done now, verify the encryption parameters in it */
5550 f_verify_encr_info(f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr));
5551
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005552 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5553 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5554 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5555 log("L3 Info in HO Request Ack is ", ho_command);
5556
5557 var GsmArfcn arfcn;
5558 var RslChannelNr actual_new_chan_nr;
5559 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5560 actual_new_chan_nr, arfcn);
5561
5562 if (actual_new_chan_nr != new_chan_nr) {
5563 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5564 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5565 setverdict(fail);
5566 return;
5567 }
5568 log("Handover Command chan_nr is", actual_new_chan_nr);
5569
5570 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5571 * tells the MS to handover to the new lchan. Here comes the new MS on
5572 * the new lchan with a Handover RACH: */
5573
5574 /* send handover detect */
5575
5576 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5577
5578 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5579
5580 /* send handover complete over the new channel */
5581
5582 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5583 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5584 enc_PDU_ML3_MS_NW(l3_tx)));
5585
5586 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005587 setverdict(pass);
5588}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005589
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005590private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005591 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005592 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5593 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5594 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005595 }
5596 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005597 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005598 } else {
5599 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005600 }
5601 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005602 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005603 setverdict(pass);
5604}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005605function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005606 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005607
5608 f_init(1, true);
5609 f_sleep(1.0);
5610
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005611 f_ctrs_bsc_and_bts_init();
5612
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005613 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5614 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005615
5616 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5617 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005618
5619 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5620 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5621 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5622 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5623 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005624}
5625
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005626testcase TC_ho_into_this_bsc() runs on test_CT {
5627 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5628 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005629 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005630}
5631
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005632function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5633 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5634 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5635 f_tc_ho_into_this_bsc_main(pars);
5636 f_shutdown_helper();
5637}
5638
5639testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5640 f_tc_ho_into_this_bsc_a5('01'O);
5641}
5642
5643testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5644 f_tc_ho_into_this_bsc_a5('02'O);
5645}
5646
5647testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5648 f_tc_ho_into_this_bsc_a5('08'O);
5649}
5650
5651testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5652 f_tc_ho_into_this_bsc_a5('10'O);
5653}
5654
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005655testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5656 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5657 pars.host_aoip_tla := "::6";
5658 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005659 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005660}
5661
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005662/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005663 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005664 channel is later released (RR CHannel Release), should trigger inclusion of
5665 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5666 neighbors. */
5667testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5668 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5669 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005670 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005671 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005672
5673 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5674 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5675 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005676 f_shutdown_helper();
5677}
5678
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005679/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5680 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5681 list when the channel is released. */
5682testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5683 f_init_vty();
5684 f_vty_allow_srvcc_fast_return(true, 0)
5685
5686 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5687 pars.last_used_eutran_plmn := '323454'O;
5688 pars.exp_fast_return := false;
5689 f_tc_ho_into_this_bsc_main(pars);
5690 f_vty_allow_srvcc_fast_return(false, 0);
5691 f_shutdown_helper();
5692}
5693
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005694private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5695 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5696 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5697 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5698 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5699 setverdict(pass);
5700}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005701
5702private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5703 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005704 var MSC_ConnHdlr vc_conn;
5705 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5706
5707 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005708 if (disable_fast_return) {
5709 f_vty_allow_srvcc_fast_return(true, 0);
5710 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005711 f_sleep(1.0);
5712
5713 f_ctrs_bsc_and_bts_init();
5714
5715 pars.last_used_eutran_plmn := '323454'O;
5716 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5717 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5718
5719 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5720 vc_conn.done;
5721
5722 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5723 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5724 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5725 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5726 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5727 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005728
5729 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5730 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005731 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005732
5733 if (disable_fast_return) {
5734 f_vty_allow_srvcc_fast_return(false, 0);
5735 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005736 f_shutdown_helper();
5737}
5738
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005739/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5740 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5741 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5742 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5743testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5744 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5745}
5746/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5747 * independently of fast-reture allowed/forbidden in local BTS */
5748testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5749 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5750}
5751
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005752private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5753 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5754 f_rslem_register(0, new_chan_nr);
5755 g_chan_nr := new_chan_nr;
5756 f_sleep(1.0);
5757
5758 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5759 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5760 activate(as_Media());
5761
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005762 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005763 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005764 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005765
5766 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5767
5768 var PDU_BSSAP rx_bssap;
5769 var octetstring ho_command_str;
5770
5771 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5772
5773 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5774 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5775 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5776 log("L3 Info in HO Request Ack is ", ho_command);
5777
5778 var GsmArfcn arfcn;
5779 var RslChannelNr actual_new_chan_nr;
5780 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5781 actual_new_chan_nr, arfcn);
5782
5783 if (actual_new_chan_nr != new_chan_nr) {
5784 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5785 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5786 setverdict(fail);
5787 return;
5788 }
5789 log("Handover Command chan_nr is", actual_new_chan_nr);
5790
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005791 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5792 f_sleep(1.0);
5793
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005794 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5795 * tells the MS to handover to the new lchan. In this case, the MS
5796 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5797 * Handover Failure to the MSC. The procedure according to 3GPP TS
5798 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5799 * BSSMAP Clear Command: */
5800
5801 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5802 var BssmapCause cause := enum2int(cause_val);
5803 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5804
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005805 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005806 BSSAP.receive(tr_BSSMAP_ClearComplete);
5807
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005808 setverdict(pass);
5809 f_sleep(1.0);
5810
5811 setverdict(pass);
5812}
5813testcase TC_ho_in_fail_msc_clears() runs on test_CT {
5814 var MSC_ConnHdlr vc_conn;
5815 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5816
5817 f_init(1, true);
5818 f_sleep(1.0);
5819
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005820 f_ctrs_bsc_and_bts_init();
5821
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005822 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5823 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005824
5825 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
5826 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005827
5828 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5829 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5830 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5831 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5832 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005833 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005834}
5835
5836private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
5837 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5838 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5839 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5840 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5841 * before we get started. */
5842 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5843 f_rslem_register(0, new_chan_nr);
5844 g_chan_nr := new_chan_nr;
5845 f_sleep(1.0);
5846
5847 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5848 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5849 activate(as_Media());
5850
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005851 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005852 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005853 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005854
5855 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5856
5857 var PDU_BSSAP rx_bssap;
5858 var octetstring ho_command_str;
5859
5860 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5861
5862 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5863 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5864 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5865 log("L3 Info in HO Request Ack is ", ho_command);
5866
5867 var GsmArfcn arfcn;
5868 var RslChannelNr actual_new_chan_nr;
5869 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5870 actual_new_chan_nr, arfcn);
5871
5872 if (actual_new_chan_nr != new_chan_nr) {
5873 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5874 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5875 setverdict(fail);
5876 return;
5877 }
5878 log("Handover Command chan_nr is", actual_new_chan_nr);
5879
5880 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5881 * tells the MS to handover to the new lchan. Here comes the new MS on
5882 * the new lchan with a Handover RACH: */
5883
5884 /* send handover detect */
5885
5886 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5887
5888 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5889
5890 /* The MSC chooses to clear the connection now, maybe we got the
5891 * Handover RACH on the new cell but the MS still signaled Handover
5892 * Failure to the old BSS? */
5893
5894 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5895 var BssmapCause cause := enum2int(cause_val);
5896 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5897
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005898 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005899 BSSAP.receive(tr_BSSMAP_ClearComplete);
5900
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005901 f_sleep(1.0);
5902}
5903testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
5904 var MSC_ConnHdlr vc_conn;
5905 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5906
5907 f_init(1, true);
5908 f_sleep(1.0);
5909
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005910 f_ctrs_bsc_and_bts_init();
5911
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005912 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5913 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005914
5915 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
5916 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005917
5918 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5919 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5920 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5921 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5922 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005923 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005924}
5925
5926/* The new BSS's lchan times out before the MSC decides that handover failed. */
5927private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
5928 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5929 f_rslem_register(0, new_chan_nr);
5930 g_chan_nr := new_chan_nr;
5931 f_sleep(1.0);
5932
5933 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5934 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5935 activate(as_Media());
5936
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005937 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005938 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005939 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005940
5941 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5942
5943 var PDU_BSSAP rx_bssap;
5944 var octetstring ho_command_str;
5945
5946 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5947
5948 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5949 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5950 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5951 log("L3 Info in HO Request Ack is ", ho_command);
5952
5953 var GsmArfcn arfcn;
5954 var RslChannelNr actual_new_chan_nr;
5955 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5956 actual_new_chan_nr, arfcn);
5957
5958 if (actual_new_chan_nr != new_chan_nr) {
5959 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5960 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5961 setverdict(fail);
5962 return;
5963 }
5964 log("Handover Command chan_nr is", actual_new_chan_nr);
5965
5966 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5967 * tells the MS to handover to the new lchan. But the MS never shows up
5968 * on the new lchan. */
5969
5970 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5971
5972 /* Did osmo-bsc also send a Clear Request? */
5973 timer T := 0.5;
5974 T.start;
5975 alt {
5976 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
5977 [] T.timeout { }
5978 }
5979
5980 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
5981 * asked for it, this is a Handover Failure after all). */
5982
5983 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5984 var BssmapCause cause := enum2int(cause_val);
5985 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5986
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005987 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005988 BSSAP.receive(tr_BSSMAP_ClearComplete);
5989
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005990 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005991}
5992testcase TC_ho_in_fail_no_detect() runs on test_CT {
5993 var MSC_ConnHdlr vc_conn;
5994 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5995
5996 f_init(1, true);
5997 f_sleep(1.0);
5998
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005999 f_ctrs_bsc_and_bts_init();
6000
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006001 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6002 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006003
6004 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6005 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006006
6007 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6008 f_ctrs_bsc_and_bts_add(0, "handover:error");
6009 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6010 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6011 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006012 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006013}
6014
6015/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6016private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6017 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6018 f_rslem_register(0, new_chan_nr);
6019 g_chan_nr := new_chan_nr;
6020 f_sleep(1.0);
6021
6022 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6023 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6024 activate(as_Media());
6025
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006026 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006027 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006028 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006029
6030 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6031
6032 var PDU_BSSAP rx_bssap;
6033 var octetstring ho_command_str;
6034
6035 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6036
6037 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6038 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6039 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6040 log("L3 Info in HO Request Ack is ", ho_command);
6041
6042 var GsmArfcn arfcn;
6043 var RslChannelNr actual_new_chan_nr;
6044 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6045 actual_new_chan_nr, arfcn);
6046
6047 if (actual_new_chan_nr != new_chan_nr) {
6048 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6049 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6050 setverdict(fail);
6051 return;
6052 }
6053 log("Handover Command chan_nr is", actual_new_chan_nr);
6054
6055 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6056 * tells the MS to handover to the new lchan. But the MS never shows up
6057 * on the new lchan. */
6058
6059 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6060
6061 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006062 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006063
6064 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006065 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6066 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6067 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006068 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006069 BSSAP.receive(tr_BSSMAP_ClearComplete);
6070
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006071 f_sleep(1.0);
6072}
6073testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6074 var MSC_ConnHdlr vc_conn;
6075 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6076
6077 f_init(1, true);
6078 f_sleep(1.0);
6079
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006080 f_ctrs_bsc_and_bts_init();
6081
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006082 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6083 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006084
6085 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6086 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006087
6088 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6089 f_ctrs_bsc_and_bts_add(0, "handover:error");
6090 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6091 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6092 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006093 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006094}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006095
Neels Hofmeyr91401012019-07-11 00:42:35 +02006096type record of charstring Commands;
6097
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006098private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006099{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006100 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006101 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006102 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006103 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006104 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006105}
6106
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006107private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6108{
6109 f_vty_enter_cfg_cs7_inst(pt, 0);
6110 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6111 f_vty_transceive(pt, cmds[i]);
6112 }
6113 f_vty_transceive(pt, "end");
6114}
6115
Neels Hofmeyr91401012019-07-11 00:42:35 +02006116private function f_probe_for_handover(charstring log_label,
6117 charstring log_descr,
6118 charstring handover_vty_cmd,
6119 boolean expect_handover,
6120 boolean is_inter_bsc_handover := false)
6121runs on MSC_ConnHdlr
6122{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006123 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6124 * lchans to be established on bts 1 or bts 2. */
6125 f_rslem_suspend(RSL1_PROC);
6126 f_rslem_suspend(RSL2_PROC);
6127
Neels Hofmeyr91401012019-07-11 00:42:35 +02006128 var RSL_Message rsl;
6129
6130 var charstring log_msg := " (expecting handover)"
6131 if (not expect_handover) {
6132 log_msg := " (expecting NO handover)";
6133 }
6134 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6135 f_vty_transceive(BSCVTY, handover_vty_cmd);
6136
Neels Hofmeyr91401012019-07-11 00:42:35 +02006137 timer T := 2.0;
6138 T.start;
6139
6140 alt {
6141 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6142 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6143 log("Rx L3 from net: ", l3);
6144 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6145 var RslChannelNr new_chan_nr;
6146 var GsmArfcn arfcn;
6147 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6148 new_chan_nr, arfcn);
6149 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6150 log(l3.msgs.rrm.handoverCommand);
6151
6152 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6153 * matter on which BTS it really is, we're not going to follow through an entire handover
6154 * anyway. */
6155 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6156 f_rslem_resume(RSL1_PROC);
6157 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6158 f_rslem_resume(RSL2_PROC);
6159
6160 if (expect_handover and not is_inter_bsc_handover) {
6161 setverdict(pass);
6162 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6163 } else {
6164 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6165 & log_label & ": " & log_descr);
6166 }
6167
6168 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6169 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6170 * Handover Failure. */
6171 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6172
6173 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6174 f_sleep(0.5);
6175 RSL1.clear;
6176 RSL2.clear;
6177 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6178 break;
6179 } else {
6180 repeat;
6181 }
6182 }
6183 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6184 if (expect_handover and is_inter_bsc_handover) {
6185 setverdict(pass);
6186 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6187 } else {
6188 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6189 & log_label & ": " & log_descr);
6190 }
6191
6192 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6193
6194 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6195 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6196 * setting a short timeout and waiting is the only way. */
6197 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6198 f_sleep(1.5);
6199 log("f_probe_for_handover(" & log_label & "): ...done");
6200
6201 break;
6202 }
6203 [] T.timeout {
6204 if (expect_handover) {
6205 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6206 & log_label & ": " & log_descr);
6207 } else {
6208 setverdict(pass);
6209 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6210 }
6211 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6212 break;
6213 }
6214 }
6215
6216 f_rslem_resume(RSL1_PROC);
6217 f_rslem_resume(RSL2_PROC);
6218 f_sleep(3.0);
6219 RSL.clear;
6220
6221 log("f_probe_for_handover(" & log_label & "): done clearing");
6222}
6223
6224/* Test the effect of various neighbor configuration scenarios:
6225 *
6226 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6227 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6228 */
6229private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6230 g_pars := f_gen_test_hdlr_pars();
6231 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6232 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006233
6234 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6235 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6236
6237 /* Establish lchan at bts 0 */
6238 f_establish_fully(ass_cmd, exp_compl);
6239
6240 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6241 f_vty_enter_cfg_network(BSCVTY);
6242 f_vty_transceive(BSCVTY, "timer T7 1");
6243 f_vty_transceive(BSCVTY, "end");
6244}
6245
6246private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6247 f_tc_ho_neighbor_config_start();
6248
6249 /*
6250 * bts 0 ARFCN 871 BSIC 10
6251 * bts 1 ARFCN 871 BSIC 11
6252 * bts 2 ARFCN 871 BSIC 12
6253 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6254 */
6255
6256 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006257 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006258 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6259 "handover any to arfcn 871 bsic 11",
6260 true);
6261
6262 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6263 "handover any to arfcn 13 bsic 39",
6264 false);
6265
6266 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6267 "handover any to arfcn 871 bsic 12",
6268 false);
6269
6270 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6271 "handover any to arfcn 871 bsic 11",
6272 true);
6273}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006274testcase TC_ho_neighbor_config_1() runs on test_CT {
6275 var MSC_ConnHdlr vc_conn;
6276 f_init(3, true, guard_timeout := 60.0);
6277 f_sleep(1.0);
6278 f_ctrs_bsc_and_bts_init();
6279 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6280 vc_conn.done;
6281
6282 /* f_tc_ho_neighbor_config_start() */
6283 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6284 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6285
6286 /* 1.a */
6287 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6288 * handover quickly by sending a Handover Failure message. */
6289 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6290 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6291 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6292 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6293
6294 /* 1.b */
6295 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6296 f_ctrs_bsc_and_bts_add(0, "handover:error");
6297
6298 /* 1.c */
6299 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6300 f_ctrs_bsc_and_bts_add(0, "handover:error");
6301
6302 /* 1.d */
6303 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6304 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6305 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6306 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6307
6308 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006309 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006310}
6311
Neels Hofmeyr91401012019-07-11 00:42:35 +02006312private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6313 f_tc_ho_neighbor_config_start();
6314
6315 /*
6316 * bts 0 ARFCN 871 BSIC 10
6317 * bts 1 ARFCN 871 BSIC 11
6318 * bts 2 ARFCN 871 BSIC 12
6319 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6320 */
6321
6322 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006323 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006324 f_sleep(0.5);
6325
6326 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6327 "handover any to arfcn 871 bsic 11",
6328 true);
6329
6330 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6331 "handover any to arfcn 871 bsic 12",
6332 false);
6333}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006334testcase TC_ho_neighbor_config_2() runs on test_CT {
6335 var MSC_ConnHdlr vc_conn;
6336 f_init(3, true, guard_timeout := 50.0);
6337 f_sleep(1.0);
6338 f_ctrs_bsc_and_bts_init();
6339 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6340 vc_conn.done;
6341
6342 /* f_tc_ho_neighbor_config_start() */
6343 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6344 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6345
6346 /* 2.a */
6347 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6348 * handover quickly by sending a Handover Failure message. */
6349 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6350 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6351 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6352 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6353
6354 /* 2.b */
6355 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6356 f_ctrs_bsc_and_bts_add(0, "handover:error");
6357
6358 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006359 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006360}
6361
Neels Hofmeyr91401012019-07-11 00:42:35 +02006362private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6363 f_tc_ho_neighbor_config_start();
6364
6365 /*
6366 * bts 0 ARFCN 871 BSIC 10
6367 * bts 1 ARFCN 871 BSIC 11
6368 * bts 2 ARFCN 871 BSIC 12
6369 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6370 */
6371
6372 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006373 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006374 f_sleep(0.5);
6375
6376 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6377 "handover any to arfcn 871 bsic 11",
6378 false);
6379 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",
6380 "handover any to arfcn 871 bsic 12",
6381 true);
6382}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006383testcase TC_ho_neighbor_config_3() runs on test_CT {
6384 var MSC_ConnHdlr vc_conn;
6385 f_init(3, true, guard_timeout := 50.0);
6386 f_sleep(1.0);
6387 f_ctrs_bsc_and_bts_init();
6388 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6389 vc_conn.done;
6390
6391 /* f_tc_ho_neighbor_config_start() */
6392 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6393 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6394
6395 /* 3.a */
6396 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6397 f_ctrs_bsc_and_bts_add(0, "handover:error");
6398
6399 /* 3.b */
6400 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6401 * handover quickly by sending a Handover Failure message. */
6402 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6403 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6404 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6405 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6406
6407 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006408 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006409}
6410
Neels Hofmeyr91401012019-07-11 00:42:35 +02006411private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6412 f_tc_ho_neighbor_config_start();
6413
6414 /*
6415 * bts 0 ARFCN 871 BSIC 10
6416 * bts 1 ARFCN 871 BSIC 11
6417 * bts 2 ARFCN 871 BSIC 12
6418 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6419 */
6420
6421 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006422 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006423 f_sleep(0.5);
6424
6425 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6426 "handover any to arfcn 871 bsic 11",
6427 false);
6428 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6429 "handover any to arfcn 871 bsic 12",
6430 false);
6431 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6432 "handover any to arfcn 123 bsic 45",
6433 true, true);
6434}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006435testcase TC_ho_neighbor_config_4() runs on test_CT {
6436 var MSC_ConnHdlr vc_conn;
6437 f_init(3, true, guard_timeout := 50.0);
6438 f_sleep(1.0);
6439 f_ctrs_bsc_and_bts_init();
6440 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6441 vc_conn.done;
6442
6443 /* f_tc_ho_neighbor_config_start() */
6444 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6445 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6446
6447 /* 4.a */
6448 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6449 f_ctrs_bsc_and_bts_add(0, "handover:error");
6450
6451 /* 4.b */
6452 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6453 f_ctrs_bsc_and_bts_add(0, "handover:error");
6454
6455 /* 4.c */
6456 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6457 * handover quickly by timing out after the Handover Required message */
6458 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6459 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6460 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6461 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6462
6463 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006464 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006465}
6466
Neels Hofmeyr91401012019-07-11 00:42:35 +02006467private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6468 f_tc_ho_neighbor_config_start();
6469
6470 /*
6471 * bts 0 ARFCN 871 BSIC 10
6472 * bts 1 ARFCN 871 BSIC 11
6473 * bts 2 ARFCN 871 BSIC 12
6474 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6475 */
6476
6477 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 +02006478 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006479 f_sleep(0.5);
6480
6481 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6482 "handover any to arfcn 871 bsic 12",
6483 true, true);
6484}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006485testcase TC_ho_neighbor_config_5() runs on test_CT {
6486 var MSC_ConnHdlr vc_conn;
6487 f_init(3, true);
6488 f_sleep(1.0);
6489 f_ctrs_bsc_and_bts_init();
6490 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6491 vc_conn.done;
6492
6493 /* f_tc_ho_neighbor_config_start() */
6494 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6495 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6496
6497 /* 5 */
6498 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6499 * handover quickly by timing out after the Handover Required message */
6500 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6501 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6502 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6503 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6504
6505 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006506 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006507}
6508
Neels Hofmeyr91401012019-07-11 00:42:35 +02006509private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6510 f_tc_ho_neighbor_config_start();
6511
6512 /*
6513 * bts 0 ARFCN 871 BSIC 10
6514 * bts 1 ARFCN 871 BSIC 11
6515 * bts 2 ARFCN 871 BSIC 12
6516 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6517 */
6518
6519 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6520 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006521 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006522 f_sleep(0.5);
6523
6524 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6525 "handover any to arfcn 871 bsic 12",
6526 false);
6527}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006528testcase TC_ho_neighbor_config_6() runs on test_CT {
6529 var MSC_ConnHdlr vc_conn;
6530 f_init(3, true);
6531 f_sleep(1.0);
6532 f_ctrs_bsc_and_bts_init();
6533 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6534 vc_conn.done;
6535
6536 /* f_tc_ho_neighbor_config_start() */
6537 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6538 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6539
6540 /* 6.a */
6541 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6542 * handover quickly by timing out after the Handover Required message */
6543 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6544 f_ctrs_bsc_and_bts_add(0, "handover:error");
6545
6546 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006547 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006548}
6549
Neels Hofmeyr91401012019-07-11 00:42:35 +02006550private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6551 f_tc_ho_neighbor_config_start();
6552
6553 /*
6554 * bts 0 ARFCN 871 BSIC 10
6555 * bts 1 ARFCN 871 BSIC 11
6556 * bts 2 ARFCN 871 BSIC 12
6557 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6558 */
6559
6560 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6561 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006562 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006563 f_sleep(0.5);
6564
6565 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6566 "handover any to arfcn 871 bsic 12",
6567 true);
6568 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6569 "handover any to arfcn 123 bsic 45",
6570 true, true);
6571}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006572testcase TC_ho_neighbor_config_7() runs on test_CT {
6573 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006574 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006575 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006576 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006577 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6578 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006579
6580 /* f_tc_ho_neighbor_config_start() */
6581 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6582 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6583
6584 /* 7.a */
6585 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6586 * handover quickly by sending a Handover Failure message. */
6587 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6588 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6589 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6590 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6591
6592 /* 7.b */
6593 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6594 * handover quickly by timing out after the Handover Required message */
6595 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6596 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6597 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6598 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6599
6600 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006601 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006602}
6603
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006604/* OS#3041: Open and close N connections in a normal fashion, and expect no
6605 * BSSMAP Reset just because of that. */
6606testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6607 var default d;
6608 var integer i;
6609 var DchanTuple dt;
6610
6611 f_init();
6612
6613 /* Wait for initial BSSMAP Reset to pass */
6614 f_sleep(4.0);
6615
6616 d := activate(no_bssmap_reset());
6617
6618 /* Setup up a number of connections and RLSD them again from the MSC
6619 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6620 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006621 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006622 /* Since we're doing a lot of runs, give each one a fresh
6623 * T_guard from the top. */
6624 T_guard.start;
6625
6626 /* Setup a BSSAP connection and clear it right away. This is
6627 * the MSC telling the BSC about a planned release, it's not an
6628 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006629 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006630
6631 /* MSC disconnects (RLSD). */
6632 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6633 }
6634
6635 /* In the buggy behavior, a timeout of 2 seconds happens between above
6636 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6637 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6638 f_sleep(4.0);
6639
6640 deactivate(d);
6641 f_shutdown_helper();
6642}
Harald Welte552620d2017-12-16 23:21:36 +01006643
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006644/* OS#3041: Open and close N connections in a normal fashion, and expect no
6645 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6646 * the MSC. */
6647testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6648 var default d;
6649 var integer i;
6650 var DchanTuple dt;
6651 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006652 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6653 var BssmapCause cause := enum2int(cause_val);
6654
6655 f_init();
6656
6657 /* Wait for initial BSSMAP Reset to pass */
6658 f_sleep(4.0);
6659
6660 d := activate(no_bssmap_reset());
6661
6662 /* Setup up a number of connections and RLSD them again from the MSC
6663 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6664 * Let's do it some more times for good measure. */
6665 for (i := 0; i < 8; i := i+1) {
6666 /* Since we're doing a lot of runs, give each one a fresh
6667 * T_guard from the top. */
6668 T_guard.start;
6669
6670 /* Setup a BSSAP connection and clear it right away. This is
6671 * the MSC telling the BSC about a planned release, it's not an
6672 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006673 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006674
6675 /* Instruct BSC to clear channel */
6676 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6677
6678 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006679 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006680 }
6681
6682 /* In the buggy behavior, a timeout of 2 seconds happens between above
6683 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6684 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6685 f_sleep(4.0);
6686
6687 deactivate(d);
6688 f_shutdown_helper();
6689}
6690
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006691/* OS#3041: Open and close N connections in a normal fashion, and expect no
6692 * BSSMAP Reset just because of that. Close connections from the MS side with a
6693 * Release Ind on RSL. */
6694testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6695 var default d;
6696 var integer i;
6697 var DchanTuple dt;
6698 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006699 var integer j;
6700
6701 f_init();
6702
6703 /* Wait for initial BSSMAP Reset to pass */
6704 f_sleep(4.0);
6705
6706 d := activate(no_bssmap_reset());
6707
6708 /* Setup up a number of connections and RLSD them again from the MSC
6709 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6710 * Let's do it some more times for good measure. */
6711 for (i := 0; i < 8; i := i+1) {
6712 /* Since we're doing a lot of runs, give each one a fresh
6713 * T_guard from the top. */
6714 T_guard.start;
6715
6716 /* Setup a BSSAP connection and clear it right away. This is
6717 * the MSC telling the BSC about a planned release, it's not an
6718 * erratic loss of a connection. */
6719 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6720
6721 /* simulate RLL REL IND */
6722 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6723
6724 /* expect Clear Request on MSC side */
6725 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6726
6727 /* Instruct BSC to clear channel */
6728 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6729 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6730
6731 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006732 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006733 }
6734
6735 /* In the buggy behavior, a timeout of 2 seconds happens between above
6736 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6737 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6738 f_sleep(4.0);
6739
6740 deactivate(d);
6741 f_shutdown_helper();
6742}
6743
Harald Welte94e0c342018-04-07 11:33:23 +02006744/***********************************************************************
6745 * IPA style dynamic PDCH
6746 ***********************************************************************/
6747
6748private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6749 template (omit) RSL_Cause nack := omit)
6750runs on test_CT {
6751 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6752 var RSL_Message rsl_unused;
6753 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6754 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6755 /* expect the BSC to issue the related RSL command */
6756 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6757 if (istemplatekind(nack, "omit")) {
6758 /* respond with a related acknowledgement */
6759 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6760 } else {
6761 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6762 }
6763}
6764
6765private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6766 template (omit) RSL_Cause nack := omit)
6767runs on test_CT {
6768 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6769 var RSL_Message rsl_unused;
6770 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6771 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6772 /* expect the BSC to issue the related RSL command */
6773 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6774 if (istemplatekind(nack, "omit")) {
6775 /* respond with a related acknowledgement */
6776 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6777 } else {
6778 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6779 }
6780}
6781
6782private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6783runs on test_CT return charstring {
6784 var charstring cmd, resp;
6785 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006786 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006787}
6788
6789private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6790 template charstring exp)
6791runs on test_CT {
6792 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
6793 if (not match(mode, exp)) {
6794 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02006795 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02006796 }
6797}
6798
6799private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
6800runs on test_CT {
6801 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
6802 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
6803 f_vty_transceive(BSCVTY, "end");
6804}
6805
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02006806
6807private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
6808 var integer i;
6809 for (i := 0; i < 8; i := i + 1) {
6810 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
6811 }
6812}
6813
Harald Welte94e0c342018-04-07 11:33:23 +02006814private const charstring TCHF_MODE := "TCH/F mode";
6815private const charstring TCHH_MODE := "TCH/H mode";
6816private const charstring PDCH_MODE := "PDCH mode";
6817private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02006818private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02006819
6820/* Test IPA PDCH activation / deactivation triggered by VTY */
6821testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
6822 var RSL_Message rsl_unused;
6823
6824 /* change Timeslot 6 before f_init() starts RSL */
6825 f_init_vty();
6826 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6827 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6828
6829 f_init(1, false);
6830 f_sleep(1.0);
6831
6832 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6833
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006834 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006835 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6836 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6837 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6838 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6839 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006840 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006841 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6842
6843 /* De-activate it via VTY */
6844 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6845 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006846 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006847 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6848
6849 /* re-activate it via VTY */
6850 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
6851 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006852 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006853 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6854
6855 /* and finally de-activate it again */
6856 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6857 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006858 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006859 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6860
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006861 /* clean up config */
6862 f_ts_set_chcomb(0, 0, 6, "PDCH");
6863
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006864 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006865}
6866
6867/* Test IPA PDCH activation NACK */
6868testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
6869 var RSL_Message rsl_unused;
6870
6871 /* change Timeslot 6 before f_init() starts RSL */
6872 f_init_vty();
6873 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6874 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6875
6876 f_init(1, false);
6877 f_sleep(1.0);
6878
6879 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6880
6881 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6882 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6883 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6884 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6885 f_sleep(1.0);
6886 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6887
6888 /* De-activate it via VTY */
6889 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6890 f_sleep(1.0);
6891 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6892
6893 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
6894 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
6895 f_sleep(1.0);
6896 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6897
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006898 /* clean up config */
6899 f_ts_set_chcomb(0, 0, 6, "PDCH");
6900
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006901 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006902}
6903
6904
6905/***********************************************************************
6906 * Osmocom style dynamic PDCH
6907 ***********************************************************************/
6908
6909private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6910 template (omit) RSL_Cause nack := omit)
6911runs on test_CT {
6912 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6913 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02006914 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02006915 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6916 /* expect the BSC to issue the related RSL command */
6917 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
6918 if (istemplatekind(nack, "omit")) {
6919 /* respond with a related acknowledgement */
6920 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
6921 } else {
6922 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
6923 }
6924}
6925
6926private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6927 template (omit) RSL_Cause nack := omit)
6928runs on test_CT {
6929 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6930 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02006931 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02006932 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6933 /* expect the BSC to issue the related RSL command */
6934 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
6935 if (istemplatekind(nack, "omit")) {
6936 /* respond with a related acknowledgement */
6937 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
6938 } else {
6939 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
6940 }
6941}
6942
6943/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
6944testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
6945 var RSL_Message rsl_unused;
6946
6947 /* change Timeslot 6 before f_init() starts RSL */
6948 f_init_vty();
6949 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
6950 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6951
6952 f_init(1, false);
6953 f_sleep(1.0);
6954
6955 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
6956
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006957 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006958 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6959 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6960 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
6961
6962 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
6963 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006964 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 +02006965 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6966
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006967 /* clean up config */
6968 f_ts_set_chcomb(0, 0, 6, "PDCH");
6969
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006970 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006971}
6972
6973/* Test Osmocom dyn PDCH activation NACK behavior */
6974testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
6975 var RSL_Message rsl_unused;
6976
6977 /* change Timeslot 6 before f_init() starts RSL */
6978 f_init_vty();
6979 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
6980 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6981
6982 f_init(1, false);
6983 f_sleep(1.0);
6984
6985 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
6986
6987 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6988 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6989 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
6990
6991 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
6992 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
6993 f_sleep(1.0);
6994 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6995
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006996 /* clean up config */
6997 f_ts_set_chcomb(0, 0, 6, "PDCH");
6998
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006999 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007000}
7001
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007002/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7003testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7004 var RSL_Message rsl_unused, rsl_msg;
7005 var DchanTuple dt;
7006 var BSSAP_N_CONNECT_ind rx_c_ind;
7007
7008 /* change Timeslot 6 before f_init() starts RSL */
7009 f_init_vty();
7010 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7011 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7012
7013 f_init(1, false);
7014 f_sleep(1.0);
7015
7016 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7017
7018 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7019 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7020 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7021 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7022
7023 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7024 f_sleep(1.0);
7025 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7026 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7027
7028 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7029 * on CCCH+SDCCH4+CBCH) */
7030 var integer i;
7031 for (i := 0; i < 3; i := i + 1) {
7032 dt := f_est_dchan('23'O, i, '00010203040506'O);
7033 }
7034
7035 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7036 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7037 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7038 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7039
7040 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7041 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7042
7043 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7044 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7045 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7046 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7047
7048 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7049 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7050 dt.sccp_conn_id := rx_c_ind.connectionId;
7051 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7052
7053 /* Instruct BSC to clear channel */
7054 var BssmapCause cause := 0;
7055 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7056 f_exp_chan_rel_and_clear(dt, 0);
7057
7058 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7059 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7060 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7061 f_sleep(1.0);
7062 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7063
7064 /* clean up config */
7065 f_ts_set_chcomb(0, 0, 6, "PDCH");
7066
7067 f_shutdown_helper();
7068}
7069
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007070/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7071 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7072 it as TCH directly instead. SYS#5309. */
7073testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7074 var RSL_Message rsl_unused, rsl_msg;
7075 var DchanTuple dt;
7076 var BSSAP_N_CONNECT_ind rx_c_ind;
7077 var integer i;
7078
7079 /* change Timeslot 6 before f_init() starts RSL */
7080 f_init_vty();
7081 for (i := 1; i < 8; i := i + 1) {
7082 if (i == 6) {
7083 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7084 } else {
7085 f_ts_set_chcomb(0, 0, i, "PDCH");
7086 }
7087 }
7088 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7089
7090 f_init(1, false);
7091 f_sleep(1.0);
7092
7093 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7094
7095 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7096 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7097 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7098 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7099
7100 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7101 f_sleep(1.0);
7102 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7103 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7104
7105 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7106 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007107 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007108 for (i := 0; i < 3; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007109 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007110 }
7111
7112 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007113 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007114 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7115 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7116
7117 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7118 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7119
7120 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7121 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7122 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7123 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7124
7125 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7126 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7127 dt.sccp_conn_id := rx_c_ind.connectionId;
7128 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7129
7130 /* Instruct BSC to clear channel */
7131 var BssmapCause cause := 0;
7132 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7133 f_exp_chan_rel_and_clear(dt, 0);
7134
7135 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7136 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7137 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7138 f_sleep(1.0);
7139 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7140
7141 /* clean up config */
7142 f_ts_reset_chcomb(0);
7143 /* TODO: clean up other channels? */
7144
7145 f_shutdown_helper();
7146}
7147
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007148/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7149testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7150 var RSL_Message rsl_unused, rsl_msg;
7151 var DchanTuple dt;
7152 var BSSAP_N_CONNECT_ind rx_c_ind;
7153 var GsmRrMessage rr;
7154
7155 /* change Timeslot 6 before f_init() starts RSL */
7156 f_init_vty();
7157 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7158 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7159
7160 f_init(1, false);
7161 f_sleep(1.0);
7162
7163 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7164
7165 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7166 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7167 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7168 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7169
7170 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7171 f_sleep(1.0);
7172 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7173 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7174
7175 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7176 * on CCCH+SDCCH4+CBCH) */
7177 var integer i;
7178 for (i := 0; i < 3; i := i + 1) {
7179 dt := f_est_dchan('23'O, i, '00010203040506'O);
7180 }
7181
7182 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7183 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7184 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7185 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7186
7187 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7188 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7189
7190 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7191 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7192 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7193 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7194 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7195 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7196 }
7197
7198 /* FIXME? Currently the TS stays in state BORKEN: */
7199
7200 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7201 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7202 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7203 * f_sleep(1.0);
7204 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7205 */
7206
7207 /* clean up config */
7208 f_ts_set_chcomb(0, 0, 6, "PDCH");
7209
7210 f_shutdown_helper();
7211}
7212
Stefan Sperling0796a822018-10-05 13:01:39 +02007213testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007214 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007215 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7216 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7217 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007218 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007219}
7220
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007221testcase TC_chopped_ipa_payload() runs on test_CT {
7222 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7223 /* TODO: mp_bsc_ctrl_port does not work yet */};
7224 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7225 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7226 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007227 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007228}
7229
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007230/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7231 the BTS does autonomous MS power control loop */
7232testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7233 var MSC_ConnHdlr vc_conn;
7234 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7235 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7236 pars.exp_ms_power_params := true;
7237
7238 f_init(1, true);
7239 f_sleep(1.0);
7240 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7241 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007242 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007243}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007244
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007245/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7246testcase TC_c0_power_red_mode() runs on test_CT {
7247 f_init(1);
7248
7249 for (var integer red := 6; red >= 0; red := red - 2) {
7250 /* Configure BCCH carrier power reduction mode via the VTY */
7251 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7252
7253 /* Expect Osmocom specific BS Power Control message on the RSL */
7254 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7255 chan_nr := t_RslChanNr_BCCH(0),
7256 bs_power := tr_RSL_IE_BS_Power(red / 2));
7257 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7258 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7259
7260 /* Additionally verify the applied value over the CTRL interface */
7261 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7262 if (cred != int2str(red)) {
7263 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7264 cred, " (expected ", red, ")");
7265 }
7266 }
7267
7268 f_shutdown_helper();
7269}
7270
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007271/***********************************************************************
7272 * MSC Pooling
7273 ***********************************************************************/
7274
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007275template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007276 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 +02007277
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007278private function f_expect_lchan_rel(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt, template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007279runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007280 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007281 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007282 f_logp(BSCVTY, "Got RSL RR Release");
7283 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007284 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007285 f_logp(BSCVTY, "Got RSL Deact SACCH");
7286 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007287 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007288 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007289 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7290 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007291 break;
7292 }
7293 }
7294}
7295
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007296friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7297 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007298runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007299 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007300 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7301 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007302 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007303 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007304 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007305 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007306 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007307 }
7308 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007309 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007310 /* Also drop the SCCP connection */
7311 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7312 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007313 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007314 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007315 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7316 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007317 }
7318 }
7319}
7320
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007321private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7322 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007323runs on MSC_ConnHdlr {
7324 timer T := 10.0;
7325 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7326
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007327 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007328 f_create_bssmap_exp(l3_enc);
7329
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007330 /* RSL_Emulation.f_chan_est() on rsl_pt:
7331 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007332 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7333 */
7334 var RSL_Message rx_rsl;
7335 var GsmRrMessage rr;
7336
7337 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007338 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007339 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007340 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007341 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7342 */
7343 timer Tt := 10.0;
7344
7345 /* request a channel to be established */
7346 Tt.start;
7347 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007348 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007349 Tt.stop;
7350 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007351 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007352 setverdict(fail, "Unexpected RSL message on DCHAN");
7353 mtc.stop;
7354 }
7355 [] Tt.timeout {
7356 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7357 mtc.stop;
7358 }
7359 }
7360 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7361 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007362 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007363
7364
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007365 if (expect_bssmap_l3) {
7366 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7367 var template PDU_BSSAP exp_l3_compl;
7368 exp_l3_compl := tr_BSSMAP_ComplL3()
7369 if (g_pars.aoip == false) {
7370 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7371 } else {
7372 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7373 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007374
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007375 var PDU_BSSAP bssap;
7376 T.start;
7377 alt {
7378 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7379 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7380 log("rx exp_l3_compl = ", bssap);
7381 }
7382 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7383 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7384 }
7385 [] T.timeout {
7386 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7387 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007388 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007389
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007390 /* start ciphering, if requested */
7391 if (ispresent(g_pars.encr)) {
7392 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007393 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007394 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007395 }
7396
7397 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007398 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007399 }
7400 setverdict(pass);
7401 f_sleep(1.0);
7402}
7403
7404private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7405 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7406 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007407 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007408 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007409 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007410 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007411 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007412 }
7413}
7414
7415/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7416private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7417 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007418 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7419 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7420 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7421 f_perform_compl_l3(RSL, RSL_PROC, ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_IMSI_LV('001010000000004'H))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007422}
7423testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7424
7425 f_init(1, true);
7426 f_sleep(1.0);
7427 var MSC_ConnHdlr vc_conn;
7428 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007429
7430 f_ctrs_msc_init();
7431
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007432 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7433 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007434
7435 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
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 IMSI are round-robin'ed across two connected MSCs */
7440/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7441 * just as well using only RSL. */
7442testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7443
7444 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7445 f_sleep(1.0);
7446
7447 /* Control which MSC gets chosen next by the round-robin, otherwise
7448 * would be randomly affected by which other tests ran before this. */
7449 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7450
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007451 f_ctrs_msc_init();
7452
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007453 var MSC_ConnHdlr vc_conn1;
7454 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7455 pars1.mscpool.rsl_idx := 0;
7456 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7457 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7458 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007459 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007460
7461 var MSC_ConnHdlr vc_conn2;
7462 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7463 pars2.mscpool.rsl_idx := 1;
7464 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7465 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7466 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007467 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007468
7469 /* Test round-robin wrap to the first MSC */
7470 var MSC_ConnHdlr vc_conn3;
7471 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7472 pars3.mscpool.rsl_idx := 2;
7473 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7474 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7475 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007476 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007477 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007478}
7479
7480/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7481 * (configured in osmo-bsc.cfg). */
7482/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7483 * just as well using only RSL. */
7484testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7485
7486 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7487 f_sleep(1.0);
7488
7489 /* Control which MSC gets chosen next by the round-robin, otherwise
7490 * would be randomly affected by which other tests ran before this. */
7491 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7492
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007493 f_ctrs_msc_init();
7494
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007495 var MSC_ConnHdlr vc_conn1;
7496 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7497 pars1.mscpool.rsl_idx := 0;
7498 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7499 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7500 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007501 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007502
7503 var MSC_ConnHdlr vc_conn2;
7504 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7505 pars2.mscpool.rsl_idx := 1;
7506 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7507 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7508 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007509 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007510
7511 /* Test round-robin wrap to the first MSC */
7512 var MSC_ConnHdlr vc_conn3;
7513 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7514 pars3.mscpool.rsl_idx := 2;
7515 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7516 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7517 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007518 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007519 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007520}
7521
7522/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7523 * (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
7524 * NULL-NRI setting is stronger than that. */
7525/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7526 * just as well using only RSL. */
7527testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7528
7529 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7530 f_sleep(1.0);
7531
7532 /* Control which MSC gets chosen next by the round-robin, otherwise
7533 * would be randomly affected by which other tests ran before this. */
7534 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7535
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007536 f_ctrs_msc_init();
7537
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007538 var MSC_ConnHdlr vc_conn1;
7539 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7540 pars1.mscpool.rsl_idx := 0;
7541 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7542 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7543 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007544 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007545
7546 var MSC_ConnHdlr vc_conn2;
7547 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7548 pars2.mscpool.rsl_idx := 1;
7549 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7550 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7551 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007552 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007553
7554 /* Test round-robin wrap to the first MSC */
7555 var MSC_ConnHdlr vc_conn3;
7556 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7557 pars3.mscpool.rsl_idx := 2;
7558 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7559 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7560 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007561 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007562 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007563}
7564
7565/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7566 * assigned to any MSC (configured in osmo-bsc.cfg). */
7567/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7568 * just as well using only RSL. */
7569testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7570
7571 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7572 f_sleep(1.0);
7573
7574 /* Control which MSC gets chosen next by the round-robin, otherwise
7575 * would be randomly affected by which other tests ran before this. */
7576 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7577
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007578 f_ctrs_msc_init();
7579
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007580 var MSC_ConnHdlr vc_conn1;
7581 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7582 pars1.mscpool.rsl_idx := 0;
7583 /* An NRI that is not assigned to any MSC */
7584 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7585 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7586 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007587 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007588
7589 var MSC_ConnHdlr vc_conn2;
7590 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7591 pars2.mscpool.rsl_idx := 1;
7592 /* An NRI that is not assigned to any MSC */
7593 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7594 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7595 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007596 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007597
7598 /* Test round-robin wrap to the first MSC */
7599 var MSC_ConnHdlr vc_conn3;
7600 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7601 pars3.mscpool.rsl_idx := 2;
7602 /* An NRI that is not assigned to any MSC */
7603 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7604 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7605 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007606 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007607 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007608}
7609
7610/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7611 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7612/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7613 * just as well using only RSL. */
7614testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7615
7616 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7617 f_sleep(1.0);
7618
7619 /* Control which MSC gets chosen next by the round-robin, otherwise
7620 * would be randomly affected by which other tests ran before this. */
7621 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7622
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007623 f_ctrs_msc_init();
7624
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007625 var MSC_ConnHdlr vc_conn1;
7626 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7627 pars1.mscpool.rsl_idx := 0;
7628 /* An NRI that is assigned to an unconnected MSC */
7629 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7630 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7631 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007632 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7633 f_ctrs_msc_add(0, "mscpool:subscr:new");
7634 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007635
7636 var MSC_ConnHdlr vc_conn2;
7637 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7638 pars2.mscpool.rsl_idx := 1;
7639 /* An NRI that is assigned to an unconnected MSC */
7640 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7641 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7642 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007643 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7644 f_ctrs_msc_add(1, "mscpool:subscr:new");
7645 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007646
7647 /* Test round-robin wrap to the first MSC */
7648 var MSC_ConnHdlr vc_conn3;
7649 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7650 pars3.mscpool.rsl_idx := 2;
7651 /* An NRI that is assigned to an unconnected MSC */
7652 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7653 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7654 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007655 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7656 f_ctrs_msc_add(0, "mscpool:subscr:new");
7657 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007658 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007659}
7660
7661/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7662 * osmo-bsc.cfg). */
7663/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7664 * just as well using only RSL. */
7665testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7666
7667 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7668 f_sleep(1.0);
7669
7670 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7671 * this is not using round-robin. */
7672 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7673
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007674 f_ctrs_msc_init();
7675
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007676 var MSC_ConnHdlr vc_conn1;
7677 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7678 pars1.mscpool.rsl_idx := 0;
7679 /* An NRI of the second MSC's range (256-511) */
7680 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7681 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7682 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007683 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007684
7685 var MSC_ConnHdlr vc_conn2;
7686 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7687 pars2.mscpool.rsl_idx := 1;
7688 /* An NRI of the second MSC's range (256-511) */
7689 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7690 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7691 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007692 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007693
7694 var MSC_ConnHdlr vc_conn3;
7695 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7696 pars3.mscpool.rsl_idx := 2;
7697 /* An NRI of the second MSC's range (256-511) */
7698 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7699 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7700 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007701 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007702 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007703}
7704
7705/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7706 * while a round-robin remains unaffected by that. */
7707/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7708 * just as well using only RSL. */
7709testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7710
7711 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7712 f_sleep(1.0);
7713
7714 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7715 * this is not using round-robin. */
7716 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7717
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007718 f_ctrs_msc_init();
7719
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007720 var MSC_ConnHdlr vc_conn1;
7721 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7722 pars1.mscpool.rsl_idx := 0;
7723 /* An NRI of the third MSC's range (512-767) */
7724 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7725 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7726 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007727 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007728
7729 var MSC_ConnHdlr vc_conn2;
7730 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7731 pars2.mscpool.rsl_idx := 1;
7732 /* An NRI of the third MSC's range (512-767) */
7733 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7734 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7735 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007736 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007737
7738 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7739 var MSC_ConnHdlr vc_conn3;
7740 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7741 pars3.mscpool.rsl_idx := 2;
7742 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7743 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7744 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007745 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007746 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007747}
7748
7749/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
7750/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7751 * just as well using only RSL. */
7752testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
7753
7754 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7755 f_sleep(1.0);
7756
7757 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
7758 * instead, and hits msc 0. */
7759 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7760
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007761 f_ctrs_msc_init();
7762
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007763 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
7764 var MSC_ConnHdlr vc_conn1;
7765 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7766 pars1.mscpool.rsl_idx := 0;
7767 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
7768 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7769 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007770 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007771
7772 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
7773 var MSC_ConnHdlr vc_conn2;
7774 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7775 pars2.mscpool.rsl_idx := 1;
7776 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
7777 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7778 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007779 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007780 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007781}
7782
7783/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
7784 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7785private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
7786 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7787 //cid_list := { cIl_allInBSS := ''O };
7788 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7789 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7790 var BSSAP_N_UNITDATA_req paging;
7791 var hexstring imsi := '001010000000123'H;
7792
7793 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7794
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007795 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007796 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
7797 BSSAP.send(paging);
7798
7799 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7800 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7801 * channel number is picked here. */
7802 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7803 f_rslem_register(0, new_chan_nr);
7804 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
7805 f_rslem_unregister(0, new_chan_nr);
7806
7807 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
7808 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007809 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007810 f_sleep(1.0);
7811}
7812testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
7813 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7814 f_sleep(1.0);
7815
7816 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7817 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7818 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7819
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007820 f_ctrs_msc_init();
7821
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007822 var MSC_ConnHdlr vc_conn1;
7823 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7824 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007825 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7826 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007827 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
7828 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007829 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007830 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007831}
7832
7833/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
7834 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7835private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
7836 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7837 //cid_list := { cIl_allInBSS := ''O };
7838 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7839 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7840 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01007841 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007842 var BSSAP_N_UNITDATA_req paging;
7843
7844 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7845
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007846 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007847 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
7848 BSSAP.send(paging);
7849
7850 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7851 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7852 * channel number is picked here. */
7853 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7854 f_rslem_register(0, new_chan_nr);
7855 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
7856 f_rslem_unregister(0, new_chan_nr);
7857
7858 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
7859 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
7860 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007861 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(nri_v))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007862 f_sleep(1.0);
7863}
7864testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
7865 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7866 f_sleep(1.0);
7867
7868 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7869 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7870 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
7871
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007872 f_ctrs_msc_init();
7873
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007874 var MSC_ConnHdlr vc_conn1;
7875 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7876 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007877 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7878 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007879 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
7880 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007881 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007882 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007883}
7884
7885/* For round-robin, skip an MSC that has 'no allow-attach' set. */
7886/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7887 * just as well using only RSL. */
7888testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
7889
7890 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7891 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007892 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7893 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007894
7895 /* Control which MSC gets chosen next by the round-robin, otherwise
7896 * would be randomly affected by which other tests ran before this. */
7897 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7898
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007899 f_ctrs_msc_init();
7900
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007901 var MSC_ConnHdlr vc_conn1;
7902 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7903 pars1.mscpool.rsl_idx := 0;
7904 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7905 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7906 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007907 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007908
7909 var MSC_ConnHdlr vc_conn2;
7910 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7911 pars2.mscpool.rsl_idx := 1;
7912 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7913 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7914 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007915 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007916
7917 var MSC_ConnHdlr vc_conn3;
7918 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7919 pars3.mscpool.rsl_idx := 2;
7920 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7921 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7922 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007923 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007924 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007925}
7926
7927/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
7928 * TMSI NRI. */
7929testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
7930
7931 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7932 f_sleep(1.0);
7933
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007934 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7935 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
7936
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007937 /* Control which MSC gets chosen next by the round-robin, otherwise
7938 * would be randomly affected by which other tests ran before this. */
7939 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7940
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007941 f_ctrs_msc_init();
7942
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007943 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
7944 var MSC_ConnHdlr vc_conn1;
7945 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7946 pars1.mscpool.rsl_idx := 0;
7947 /* An NRI of the second MSC's range (256-511) */
7948 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
7949 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7950 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007951 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007952
7953 var MSC_ConnHdlr vc_conn2;
7954 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
7955 pars2.mscpool.rsl_idx := 1;
7956 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7957 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7958 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007959 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007960
7961 var MSC_ConnHdlr vc_conn3;
7962 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
7963 pars3.mscpool.rsl_idx := 2;
7964 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
7965 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7966 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007967 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007968 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007969}
7970
Philipp Maier783681c2020-07-16 16:47:06 +02007971/* Allow/Deny emergency calls globally via VTY */
7972private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
7973 f_vty_enter_cfg_msc(BSCVTY, 0);
7974 if (allow) {
7975 f_vty_transceive(BSCVTY, "allow-emergency allow");
7976 } else {
7977 f_vty_transceive(BSCVTY, "allow-emergency deny");
7978 }
7979 f_vty_transceive(BSCVTY, "exit");
7980 f_vty_transceive(BSCVTY, "exit");
7981}
7982
7983/* Allow/Deny emergency calls per BTS via VTY */
7984private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
7985 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
7986 if (allow) {
7987 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
7988 } else {
7989 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
7990 }
7991 f_vty_transceive(BSCVTY, "exit");
7992 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00007993 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02007994}
7995
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02007996/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
7997private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
7998 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
7999 if (allow) {
8000 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8001 } else {
8002 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8003 }
8004 f_vty_transceive(BSCVTY, "exit");
8005 f_vty_transceive(BSCVTY, "exit");
8006 f_vty_transceive(BSCVTY, "exit");
8007}
8008
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008009/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8010private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8011 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8012 if (allow) {
8013 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8014 } else {
8015 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8016 }
8017 f_vty_transceive(BSCVTY, "exit");
8018 f_vty_transceive(BSCVTY, "exit");
8019 f_vty_transceive(BSCVTY, "exit");
8020}
8021
Philipp Maier783681c2020-07-16 16:47:06 +02008022/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8023private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8024 var PDU_ML3_MS_NW emerg_setup;
8025 var octetstring emerg_setup_enc;
8026 var RSL_Message emerg_setup_data_ind;
8027
8028 f_establish_fully(omit, omit);
8029
8030 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8031 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8032 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8033
8034 RSL.send(emerg_setup_data_ind);
8035}
8036
8037/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8038 * CALLS are permitted by the BSC config. */
8039private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8040 var PDU_BSSAP emerg_setup_data_ind_bssap;
8041 var PDU_ML3_MS_NW emerg_setup;
8042 timer T := 3.0;
8043
8044 f_assignment_emerg_setup()
8045
8046 T.start;
8047 alt {
8048 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8049 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8050 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8051 setverdict(fail, "no emergency setup");
8052 }
8053 }
8054 [] BSSAP.receive {
8055 setverdict(fail, "unexpected BSSAP message!");
8056 }
8057 [] T.timeout {
8058 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8059 }
8060 }
8061
8062 setverdict(pass);
8063}
8064
8065/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8066 * forbidden by the BSC config. */
8067private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8068 var PDU_BSSAP emerg_setup_data_ind_bssap;
8069 timer T := 3.0;
8070
8071 f_assignment_emerg_setup()
8072
8073 T.start;
8074 alt {
8075 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8076 setverdict(pass);
8077 }
8078 [] RSL.receive {
8079 setverdict(fail, "unexpected RSL message!");
8080 }
8081 [] T.timeout {
8082 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8083 }
8084 }
8085}
8086
8087/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8088testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8089 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8090 var MSC_ConnHdlr vc_conn;
8091
8092 f_init(1, true);
8093 f_sleep(1.0);
8094
8095 f_vty_allow_emerg_msc(true);
8096 f_vty_allow_emerg_bts(true, 0);
8097 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8098 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008099 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008100}
8101
8102/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8103testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8104 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8105 var MSC_ConnHdlr vc_conn;
8106
8107 f_init(1, true);
8108 f_sleep(1.0);
8109
8110 f_vty_allow_emerg_msc(false);
8111 f_vty_allow_emerg_bts(true, 0);
8112 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8113 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008114 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008115}
8116
8117/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8118testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8119 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8120 var MSC_ConnHdlr vc_conn;
8121
8122 /* Note: This simulates a spec violation by the MS, correct MS
8123 * implementations would not try to establish an emergency call because
8124 * the system information tells in advance that emergency calls are
8125 * not forbidden */
8126
8127 f_init(1, true);
8128 f_sleep(1.0);
8129
8130 f_vty_allow_emerg_msc(true);
8131 f_vty_allow_emerg_bts(false, 0);
8132 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8133 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008134 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008135}
8136
Philipp Maier82812002020-08-13 18:48:27 +02008137/* Test what happens when an emergency call arrives while all TCH channels are
8138 * busy, the BSC is expected to terminate one call in favor of the incoming
8139 * emergency call */
8140testcase TC_emerg_premption() runs on test_CT {
8141 var ASP_RSL_Unitdata rsl_ud;
8142 var integer i;
8143 var integer chreq_total, chreq_nochan;
8144 var RSL_Message rx_rsl;
8145 var RslChannelNr chan_nr;
8146
8147 f_init(1);
8148 f_sleep(1.0);
8149
8150 f_vty_allow_emerg_msc(true);
8151 f_vty_allow_emerg_bts(true, 0);
8152
8153 /* Fill up all channels on the BTS */
8154 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8155 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8156 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8157 chan_nr := f_chreq_act_ack('33'O, i);
8158 }
8159 IPA_RSL[0].clear;
8160 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8161 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8162
8163 /* Send Channel request for emegergency call */
8164 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8165
8166 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8167 chan_nr := valueof(t_RslChanNr_Bm(1));
8168 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8169
8170 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8171 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8172 chan_nr := rx_rsl.ies[0].body.chan_nr;
8173 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8174 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008175
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008176 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008177}
8178
8179/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008180private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008181private type record FHParamsTs {
8182 boolean enabled,
8183 uint6_t hsn,
8184 uint6_t maio,
8185 ArfcnList ma
8186};
8187
8188/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008189private type record FHParamsTrx {
8190 GsmArfcn arfcn,
8191 FHParamsTs ts[8]
8192};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008193
8194/* Randomly generate the hopping parameters for the given timeslot numbers */
8195private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8196runs on test_CT return FHParamsTrx {
8197 var FHParamsTrx fhp;
8198
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008199 /* Generate a random ARFCN, including ARFCN 0 */
8200 fhp.arfcn := f_rnd_int(3);
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008201
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008202 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8203 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008204 fhp.ts[tn].enabled := false;
8205 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008206 continue;
8207 }
8208
8209 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008210 fhp.ts[tn].hsn := f_rnd_int(64);
8211 fhp.ts[tn].maio := f_rnd_int(64);
8212 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008213
8214 /* Random Mobile Allocation (hopping channels) */
8215 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8216 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8217 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008218 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008219 }
8220
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008221 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008222 }
8223
8224 log("f_TC_fh_params_gen(): ", fhp);
8225 return fhp;
8226}
8227
8228/* Make sure that the given Channel Description IE matches the hopping configuration */
8229private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8230{
8231 var template (present) ChannelDescription tr_cd;
8232 var template (present) MaioHsn tr_maio_hsn;
8233 var uint3_t tn := cd.chan_nr.tn;
8234
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008235 if (fhp.ts[tn].enabled) {
8236 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008237 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8238 } else {
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008239 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008240 }
8241
8242 if (not match(cd, tr_cd)) {
8243 setverdict(fail, "Channel Description IE does not match: ",
8244 cd, " vs expected ", tr_cd);
8245 }
8246}
8247
8248/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8249private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8250 in MobileAllocationLV ma)
8251{
8252 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8253
8254 if (not match(ma, tr_ma)) {
8255 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8256 tn, "): ", ma, " vs expected: ", tr_ma);
8257 } else {
8258 setverdict(pass);
8259 }
8260}
8261
8262private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8263 in MobileAllocationLV ma)
8264return template MobileAllocationLV {
8265 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008266 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008267 return { len := 0, ma := ''B };
8268 }
8269
8270 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8271 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8272 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008273
8274 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008275 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8276 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8277 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008278 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008279 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008280 }
8281 }
8282
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008283 /* Take ARFCN of the TRX itself into account */
8284 full_mask[fhp.arfcn] := '1'B;
8285
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008286 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008287 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8288 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008289 }
8290
8291 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008292 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008293 if (full_mask[i] != '1'B)
8294 { continue; }
8295
8296 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8297 if (slot_mask[i] == '1'B) {
8298 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008299 } else {
8300 ma_mask := ma_mask & '0'B;
8301 }
8302 }
8303
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008304 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8305 if (full_mask[0] == '1'B) {
8306 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8307 if (slot_mask[0] == '1'B) {
8308 ma_mask := ma_mask & '1'B;
8309 } else {
8310 ma_mask := ma_mask & '0'B;
8311 }
8312 }
8313
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008314 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008315 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008316 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8317
8318 return { len := ma_mask_len, ma := ma_mask };
8319}
8320
8321/* Configure the hopping parameters in accordance with the given record */
8322private function f_TC_fh_params_set(in FHParamsTrx fhp,
8323 uint8_t bts_nr := 0,
8324 uint8_t trx_nr := 0)
8325runs on test_CT {
8326 /* Enter the configuration node for the given BTS/TRX numbers */
8327 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8328
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008329 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn));
8330
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008331 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008332 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8333
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008334 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008335 f_vty_transceive(BSCVTY, "hopping enabled 0");
8336 f_vty_transceive(BSCVTY, "exit"); /* go back */
8337 continue;
8338 }
8339
8340 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008341 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8342 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008343
8344 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008345 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8346 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008347 }
8348
8349 f_vty_transceive(BSCVTY, "hopping enabled 1");
8350 f_vty_transceive(BSCVTY, "exit"); /* go back */
8351 }
8352
8353 f_vty_transceive(BSCVTY, "end");
8354}
8355
8356/* Disable frequency hopping on all timeslots */
8357private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8358 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008359 uint8_t trx_nr := 0,
8360 GsmArfcn arfcn := 871)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008361runs on test_CT {
8362 /* Enter the configuration node for the given BTS/TRX numbers */
8363 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8364
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008365 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn));
8366
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008367 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008368 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8369
8370 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008371 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8372 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008373 }
8374
8375 f_vty_transceive(BSCVTY, "hopping enabled 0");
8376 f_vty_transceive(BSCVTY, "exit"); /* go back */
8377 }
8378
8379 f_vty_transceive(BSCVTY, "end");
8380 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8381}
8382
8383/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8384 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8385testcase TC_fh_params_chan_activ() runs on test_CT {
8386 var FHParamsTrx fhp := f_TC_fh_params_gen();
8387 var RSL_Message rsl_msg;
8388 var RSL_IE_Body ie;
8389
8390 f_init_vty();
8391
8392 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8393 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8394
8395 f_init(1);
8396
8397 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8398 for (var integer i := 0; i < 9; i := i + 1) {
8399 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8400 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8401
8402 /* Make sure that Channel Identification IE is present */
8403 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8404 setverdict(fail, "RSL Channel Identification IE is absent");
8405 continue;
8406 }
8407
8408 /* Make sure that hopping parameters (HSN/MAIO) match */
8409 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8410
8411 /* "Mobile Allocation shall be included but empty" - let's check this */
8412 if (ie.chan_ident.ma.v.len != 0) {
8413 setverdict(fail, "Mobile Allocation IE is not empty: ",
8414 ie.chan_ident.ma, ", despite it shall be");
8415 continue;
8416 }
8417 }
8418
8419 /* Disable frequency hopping */
8420 f_TC_fh_params_unset(fhp);
8421
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008422 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008423}
8424
8425/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8426testcase TC_fh_params_imm_ass() runs on test_CT {
8427 var FHParamsTrx fhp := f_TC_fh_params_gen();
8428 var RSL_Message rsl_msg;
8429 var RSL_IE_Body ie;
8430
8431 f_init_vty();
8432
8433 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8434 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8435
8436 f_init(1);
8437
8438 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8439 for (var integer i := 0; i < 9; i := i + 1) {
8440 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8441 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8442
8443 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8444 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8445
8446 /* Make sure that Full Immediate Assign Info IE is present */
8447 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8448 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8449 continue;
8450 }
8451
8452 /* Decode the actual Immediate Assignment message */
8453 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8454 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8455 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8456 continue;
8457 }
8458
8459 /* Make sure that hopping parameters (HSN/MAIO) match */
8460 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8461
8462 /* Make sure that the Mobile Allocation IE matches */
8463 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8464 rr_msg.payload.imm_ass.mobile_allocation);
8465 }
8466
8467 /* Disable frequency hopping */
8468 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008469
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008470 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008471}
8472
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008473/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8474testcase TC_fh_params_assignment_cmd() runs on test_CT {
8475 var FHParamsTrx fhp := f_TC_fh_params_gen();
8476 var RSL_Message rsl_msg;
8477 var RSL_IE_Body ie;
8478
8479 f_init_vty();
8480
8481 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8482 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8483
8484 f_init(1);
8485
8486 /* HACK: work around "Couldn't find Expect for CRCX" */
8487 vc_MGCP.stop;
8488
8489 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8490 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8491
8492 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8493 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8494 for (var integer i := 0; i < 3; i := i + 1) {
8495 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8496 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8497
8498 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8499 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8500 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8501
8502 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8503 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8504 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8505
8506 /* Make sure that L3 Information IE is present */
8507 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8508 setverdict(fail, "RSL L3 Information IE is absent");
8509 continue;
8510 }
8511
8512 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8513 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8514 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8515 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8516 continue;
8517 }
8518
8519 /* Make sure that hopping parameters (HSN/MAIO) match */
8520 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8521 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8522
8523 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8524 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008525 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008526 continue;
8527 }
8528
8529 /* Make sure that the Mobile Allocation IE matches (if present) */
8530 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8531 if (chan_desc.h and ma_present) {
8532 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8533 l3_msg.payload.ass_cmd.mobile_allocation.v);
8534 } else if (chan_desc.h and not ma_present) {
8535 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8536 continue;
8537 } else if (not chan_desc.h and ma_present) {
8538 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8539 continue;
8540 }
8541 }
8542
8543 /* Give the IUT some time to release all channels */
8544 f_sleep(3.0);
8545
8546 /* Disable frequency hopping */
8547 f_TC_fh_params_unset(fhp);
8548
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008549 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008550}
8551
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008552/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8553private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8554runs on test_CT {
8555 var RSL_Message rsl_msg;
8556 var RSL_IE_Body ie;
8557 var DchanTuple dt;
8558
8559 /* Establish a dedicated channel, so we can trigger handover */
8560 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8561
8562 /* Trigger handover from BTS0 to BTS1 */
8563 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8564 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8565
8566 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8567 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8568
8569 /* ACKnowledge channel activation and expect (RR) Handover Command */
8570 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8571 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8572
8573 /* Make sure that L3 Information IE is present */
8574 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8575 setverdict(fail, "RSL L3 Information IE is absent");
8576 return;
8577 }
8578
8579 /* Decode the L3 message and make sure it is (RR) Handover Command */
8580 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8581 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8582 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8583 return;
8584 }
8585
8586 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8587 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8588 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8589 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8590 return;
8591 }
8592
8593 /* Make sure that hopping parameters (HSN/MAIO) match */
8594 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8595
8596 /* Make sure that Cell Channel Description IE is present */
8597 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8598 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8599 return;
8600 }
8601
8602 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8603 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8604 if (ma_present) {
8605 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8606 l3_msg.payload.ho_cmd.mobile_allocation.v);
8607 } else {
8608 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8609 return;
8610 }
8611}
8612testcase TC_fh_params_handover_cmd() runs on test_CT {
8613 var FHParamsTrx fhp := f_TC_fh_params_gen();
8614
8615 f_init_vty();
8616
8617 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8618 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8619
8620 f_vty_transceive(BSCVTY, "timeslot 0");
8621 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8622 f_vty_transceive(BSCVTY, "exit"); /* go back */
8623
8624 f_vty_transceive(BSCVTY, "timeslot 1");
8625 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8626 f_vty_transceive(BSCVTY, "end"); /* we're done */
8627
8628 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8629 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8630
8631 f_init(2);
8632
8633 f_TC_fh_params_handover_cmd(fhp);
8634
8635 /* Disable frequency hopping on BTS1 */
8636 f_TC_fh_params_unset(fhp, 1);
8637
8638 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8639 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8640
8641 f_vty_transceive(BSCVTY, "timeslot 0");
8642 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8643 f_vty_transceive(BSCVTY, "exit"); /* go back */
8644
8645 f_vty_transceive(BSCVTY, "timeslot 1");
8646 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8647 f_vty_transceive(BSCVTY, "end"); /* we're done */
8648
8649 f_shutdown_helper();
8650}
8651
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008652/* Verify the hopping parameters in System Information Type 4 */
8653testcase TC_fh_params_si4_cbch() runs on test_CT {
8654 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8655 var ASP_RSL_Unitdata rx_rsl_ud;
8656 timer T := 5.0;
8657
8658 f_init_vty();
8659
8660 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
8661 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8662
8663 f_vty_transceive(BSCVTY, "timeslot 0");
8664 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8665 f_vty_transceive(BSCVTY, "exit"); /* go back */
8666
8667 f_vty_transceive(BSCVTY, "timeslot 1");
8668 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
8669 f_vty_transceive(BSCVTY, "end"); /* we're done */
8670
8671 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8672 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8673
8674 f_init(1);
8675
8676 T.start;
8677 alt {
8678 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
8679 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
8680 var SystemInformation si := dec_SystemInformation(ie.other.payload);
8681
8682 /* Make sure that what we decoded is System Information Type 4 */
8683 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
8684 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
8685 repeat;
8686 }
8687
8688 /* Make sure that CBCH Channel Description IE is present */
8689 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
8690 setverdict(fail, "CBCH Channel Description IE is absent");
8691 break;
8692 }
8693
8694 /* Finally, check the hopping parameters (HSN, MAIO) */
8695 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
8696 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8697
8698 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
8699 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
8700 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
8701 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8702 break;
8703 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
8704 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8705 si.payload.si4.cbch_mobile_alloc.v);
8706 }
8707 }
8708 [] IPA_RSL[0].receive { repeat; }
8709 [] T.timeout {
8710 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
8711 }
8712 }
8713
8714 /* Disable frequency hopping */
8715 f_TC_fh_params_unset(fhp);
8716
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008717 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008718 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8719
8720 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008721 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008722 f_vty_transceive(BSCVTY, "exit"); /* go back */
8723
8724 f_vty_transceive(BSCVTY, "timeslot 1");
8725 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8726 f_vty_transceive(BSCVTY, "end"); /* we're done */
8727
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008728 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008729}
8730
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008731template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
8732 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
8733
8734private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
8735 template (present) BSSLAP_PDU expect_bsslap)
8736{
8737 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
8738 if (not match(bsslap, expect_bsslap)) {
8739 log("EXPECTING BSSLAP: ", expect_bsslap);
8740 log("GOT BSSLAP: ", bsslap);
8741 setverdict(fail, "BSSLAP is not as expected");
8742 mtc.stop;
8743 }
8744 setverdict(pass);
8745}
8746
8747/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
8748const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
8749
8750private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
8751 var PDU_BSSAP_LE rx_bsslap;
8752 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
8753 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
8754}
8755
8756/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8757 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
8758private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
8759 f_sleep(1.0);
8760
8761 f_establish_fully(omit, omit);
8762 f_bssap_le_register_imsi(g_pars.imsi, omit);
8763
8764 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8765 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8766
8767 var PDU_BSSAP_LE plr;
8768 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8769
8770 if (not do_ta_request) {
8771 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
8772 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
8773 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
8774 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
8775 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
8776 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
8777 mtc.stop;
8778 }
8779 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
8780 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
8781 if (not match(bsslap, expect_ta_layer3)) {
8782 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
8783 log("GOT BSSLAP: ", bsslap);
8784 setverdict(fail, "BSSLAP is not as expected");
8785 mtc.stop;
8786 }
8787 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
8788 * has no need to request the TA from the BSC and directly responds. */
8789 } else {
8790 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8791 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8792 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8793 }
8794
8795 /* SMLC got the TA from the BSC, now responds with geo information data. */
8796 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8797 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8798 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8799
8800 /* The LCS was using an active A-interface conn. It should still remain active after this. */
8801 f_mo_l3_transceive();
8802
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008803 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008804
8805 f_sleep(2.0);
8806 setverdict(pass);
8807}
8808
8809/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8810 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
8811private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
8812 f_lcs_loc_req_for_active_ms(false);
8813}
8814testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
8815 var MSC_ConnHdlr vc_conn;
8816 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8817
8818 f_init(1, true);
8819 f_sleep(1.0);
8820 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
8821 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008822 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008823}
8824
8825/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8826 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
8827private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
8828 f_lcs_loc_req_for_active_ms(true);
8829}
8830testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
8831 var MSC_ConnHdlr vc_conn;
8832 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8833
8834 f_init(1, true);
8835 f_sleep(1.0);
8836 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
8837 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008838 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008839}
8840
8841/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
8842 * conn without an active lchan. */
8843private function f_clear_A_conn() runs on MSC_ConnHdlr
8844{
8845 var BssmapCause cause := 0;
8846 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
8847 BSSAP.receive(tr_BSSMAP_ClearComplete);
8848 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8849
8850 timer no_more_bssap := 5.0;
8851 no_more_bssap.start;
8852 alt {
8853 [] no_more_bssap.timeout { break; }
8854 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
8855 setverdict(fail, "Expected no more BSSAP after Clear Complete");
8856 mtc.stop;
8857 }
8858 }
8859 setverdict(pass);
8860}
8861
8862/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
8863 * for LCS, for cases where there is only an A conn without an active lchan. */
8864private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
8865{
8866 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
8867
8868 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
8869 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
8870 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
8871 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8872 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8873 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
8874
8875 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
8876 f_clear_A_conn();
8877 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
8878 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8879}
8880
8881/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8882 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
8883 */
8884private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
8885 f_sleep(1.0);
8886
8887 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8888 f_bssap_le_register_imsi(g_pars.imsi, omit);
8889
8890 /* Register to receive the Paging Command */
8891 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8892 g_chan_nr := new_chan_nr;
8893 f_rslem_register(0, g_chan_nr);
8894
8895 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8896 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8897 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8898 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8899
8900 var PDU_BSSAP_LE plr;
8901 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8902
8903 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8904 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8905
8906 /* OsmoBSC needs to Page */
8907 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
8908 f_logp(BSCVTY, "got Paging Command");
8909
8910 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
8911 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008912 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(g_pars.imsi))), do_clear := false, expect_bssmap_l3 := false);
8913 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008914
8915 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
8916
8917 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8918
8919 /* SMLC got the TA from the BSC, now responds with geo information data. */
8920 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8921 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8922
8923 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8924
8925 /* The lchan is gone, the A-interface conn was created for the LCS only.
8926 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
8927 f_verify_active_A_conn_and_clear();
8928
8929 f_sleep(2.0);
8930 setverdict(pass);
8931}
8932testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
8933 var MSC_ConnHdlr vc_conn;
8934 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8935
8936 f_init(1, true);
8937 f_sleep(1.0);
8938
8939 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8940 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8941
8942 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
8943 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008944 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008945}
8946
8947/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
8948 */
8949private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
8950 f_sleep(1.0);
8951
8952 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8953 f_bssap_le_register_imsi(g_pars.imsi, omit);
8954
8955 /* provoke an abort by omitting both IMSI and IMEI */
8956 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8957 valueof(ts_BSSMAP_Perform_Location_Request(omit,
8958 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
8959 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8960
8961 /* BSC tells MSC about failure */
8962 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
8963 locationEstimate := omit, positioningData := omit,
8964 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
8965
8966 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
8967 f_verify_active_A_conn_and_clear();
8968
8969 f_sleep(2.0);
8970 setverdict(pass);
8971}
8972testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
8973 var MSC_ConnHdlr vc_conn;
8974 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8975
8976 f_init(1, true);
8977 f_sleep(1.0);
8978
8979 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8980 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8981
8982 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
8983 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008984 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008985}
8986
8987/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
8988 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
8989private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
8990 f_sleep(1.0);
8991
8992 f_establish_fully(omit, omit);
8993 f_bssap_le_register_imsi(g_pars.imsi, omit);
8994
8995 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8996 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8997
8998 var PDU_BSSAP_LE plr;
8999 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9000
9001 if (do_ta) {
9002 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9003 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9004 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9005 }
9006
9007 /* SMLC fails to respond, BSC runs into timeout */
9008 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9009 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9010
9011 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9012 locationEstimate := omit, positioningData := omit,
9013 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9014
9015 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9016 f_verify_active_A_conn_and_clear();
9017
9018 f_sleep(2.0);
9019 setverdict(pass);
9020}
9021
9022/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9023 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9024private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9025 f_lcs_loc_req_for_active_ms_le_timeout(false);
9026}
9027
9028testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9029 var MSC_ConnHdlr vc_conn;
9030 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9031
9032 f_init(1, true);
9033 f_sleep(1.0);
9034 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9035 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009036 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009037}
9038
9039/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9040 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9041private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9042 f_lcs_loc_req_for_active_ms_le_timeout(true);
9043}
9044
9045testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9046 var MSC_ConnHdlr vc_conn;
9047 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9048
9049 f_init(1, true);
9050 f_sleep(1.0);
9051 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9052 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009053 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009054}
9055
9056/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9057private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9058 f_sleep(1.0);
9059
9060 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9061 f_bssap_le_register_imsi(g_pars.imsi, omit);
9062
9063 /* Register to receive the Paging Command */
9064 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9065 g_chan_nr := new_chan_nr;
9066 f_rslem_register(0, g_chan_nr);
9067
9068 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9069 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9070 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9071 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9072
9073 var PDU_BSSAP_LE plr;
9074 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9075
9076 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9077 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9078
9079 /* OsmoBSC needs to Page */
9080 var PDU_BSSAP_LE rx_bsslap;
9081 alt {
9082 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9083 f_logp(BSCVTY, "got Paging Command");
9084 repeat;
9085 }
9086 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9087 /* MS does not respond to Paging, TA Req runs into timeout. */
9088 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9089 }
9090 }
9091
9092 /* SMLC responds with failure */
9093 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9094 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9095
9096 /* BSC tells MSC about failure */
9097 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9098 locationEstimate := omit, positioningData := omit,
9099 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9100
9101 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9102 f_verify_active_A_conn_and_clear();
9103
9104 f_sleep(2.0);
9105 setverdict(pass);
9106}
9107testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9108 var MSC_ConnHdlr vc_conn;
9109 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9110
9111 f_init(1, true);
9112 f_sleep(1.0);
9113
9114 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9115 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9116
9117 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9118 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009119 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009120}
9121
9122/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9123 * over. */
9124private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9125 f_sleep(1.0);
9126
9127 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9128 f_bssap_le_register_imsi(g_pars.imsi, omit);
9129
9130 /* Register to receive the Paging Command */
9131 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9132 g_chan_nr := new_chan_nr;
9133 f_rslem_register(0, g_chan_nr);
9134
9135 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9136 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9137 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9138 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9139
9140 var PDU_BSSAP_LE plr;
9141 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9142
9143 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9144 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009145 f_perform_compl_l3(RSL, RSL_PROC, valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV(g_pars.imsi)))),
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009146 do_clear := false, expect_bssmap_l3 := true);
9147
9148 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9149 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9150
9151 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9152 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9153
9154 /* SMLC got the TA from the BSC, now responds with geo information data. */
9155 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9156 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9157 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9158
9159 /* The lchan should still exist, it was from a CM Service Request. */
9160 f_mo_l3_transceive();
9161
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009162 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009163
9164 f_sleep(2.0);
9165 setverdict(pass);
9166}
9167testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9168 var MSC_ConnHdlr vc_conn;
9169 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9170
9171 f_init(1, true);
9172 f_sleep(1.0);
9173
9174 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9175 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9176
9177 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9178 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009179 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009180}
9181
9182/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9183 * the new lchan after handover. */
9184private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9185 f_sleep(1.0);
9186
9187 f_establish_fully(omit, omit);
9188 f_bssap_le_register_imsi(g_pars.imsi, omit);
9189
9190 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9191 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9192
9193 var PDU_BSSAP_LE plr;
9194 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9195
9196 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9197 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9198
9199 var HandoverState hs := {
9200 rr_ho_cmpl_seen := false,
9201 handover_done := false,
9202 old_chan_nr := -
9203 };
9204 /* issue hand-over command on VTY */
9205 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9206 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9207 f_rslem_suspend(RSL1_PROC);
9208
9209 /* From the MGW perspective, a handover is is characterized by
9210 * performing one MDCX operation with the MGW. So we expect to see
9211 * one more MDCX during handover. */
9212 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9213
9214 alt {
9215 [] as_handover(hs);
9216 }
9217
9218 var PDU_BSSAP_LE rx_bsslap;
9219
9220 interleave {
9221 /* Expect the BSC to inform the MSC about the handover */
9222 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9223
9224 /* Expect the BSC to inform the SMLC about the handover */
9225 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9226 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9227 }
9228 }
9229
9230 /* SMLC now responds with geo information data. */
9231 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9232 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9233 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9234
9235 /* lchan still active */
9236 f_mo_l3_transceive(RSL1);
9237
9238 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009239 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009240
9241 f_sleep(2.0);
9242 setverdict(pass);
9243}
9244testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9245 var MSC_ConnHdlr vc_conn;
9246 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9247
9248 f_init(2, true);
9249 f_sleep(1.0);
9250 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9251 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009252 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009253}
9254
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009255/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9256private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9257 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9258
9259 /* Also disable attach for the single connected MSC */
9260 f_vty_msc_allow_attach(BSCVTY, { false });
9261
9262 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) ));
9263 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9264
9265 /* No MSC is found, expecting a proper release on RSL */
9266 interleave {
9267 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9268 f_logp(BSCVTY, "Got RSL RR Release");
9269 }
9270 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9271 f_logp(BSCVTY, "Got RSL Deact SACCH");
9272 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009273 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009274 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9275 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009276 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009277 }
9278 }
9279 setverdict(pass);
9280}
9281testcase TC_no_msc() runs on test_CT {
9282
9283 f_init(1, true);
9284 f_sleep(1.0);
9285 var MSC_ConnHdlr vc_conn;
9286 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9287
9288 f_ctrs_bsc_init(counternames_bsc_mscpool);
9289
9290 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9291 vc_conn.done;
9292
9293 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9294 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009295 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009296}
9297
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009298/* Dyn PDCH todo:
9299 * activate OSMO as TCH/F
9300 * activate OSMO as TCH/H
9301 * does the BSC-located PCU socket get the updated INFO?
9302 * what if no PCU is connected at the time?
9303 * is the info correct on delayed PCU (re)connect?
9304 */
Harald Welte94e0c342018-04-07 11:33:23 +02009305
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009306private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9307 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9308 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9309
9310 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9311 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9312 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9313 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9314 g_pars.ass_codec_list.codecElements[0];
9315 if (isvalue(g_pars.expect_mr_s0_s7)) {
9316 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9317 g_pars.expect_mr_s0_s7;
9318 }
9319 }
9320 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9321 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9322 log("expecting ASS COMPL like this: ", exp_compl);
9323
9324 f_establish_fully(ass_cmd, exp_compl);
9325
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009326 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 +00009327
9328 var RSL_Message rsl;
9329
9330 timer T := 5.0;
9331 T.start;
9332 alt {
9333 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9334 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9335 log("Rx L3 from net: ", l3);
9336 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9337 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9338 mtc.stop;
9339 }
9340 }
9341 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9342 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9343 mtc.stop;
9344 }
9345 [] T.timeout {
9346 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9347 setverdict(pass);
9348 }
9349 }
9350 T.stop;
9351}
9352
9353/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9354 * osmo-bsc. */
9355testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9356 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9357 var MSC_ConnHdlr vc_conn;
9358
9359 f_init(1, true);
9360 f_sleep(1.0);
9361
9362 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9363 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9364 vc_conn.done;
9365 f_shutdown_helper();
9366}
9367
9368/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9369 */
9370testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9371 f_init_vty();
9372
9373 f_init(1, false);
9374 f_sleep(1.0);
9375
9376 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9377
9378 var ASP_RSL_Unitdata rx_rsl_ud;
9379 timer T := 5.0;
9380
9381 T.start;
9382 alt {
9383 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9384 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9385 T.stop;
9386 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9387 mtc.stop;
9388 }
9389 repeat;
9390 }
9391 [] T.timeout {
9392 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9393 setverdict(pass);
9394 }
9395 }
9396}
9397
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009398private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9399 /* First fully set up a speech lchan */
9400 f_TC_assignment_codec(id);
9401
9402 /* Trigger re-assignment to another lchan */
9403 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9404
9405 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9406 * one MDCX on MGCP. */
9407 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9408
9409 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9410 * as the old lchan used. */
9411 g_media.bts.ipa_crcx_seen := false;
9412 g_media.bts.ipa_mdcx_seen := false;
9413
9414 /* Send different BTS side RTP port number for the new lchan */
9415 g_media.bts.bts.port_nr := 4223;
9416
9417 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9418
9419 /* Trigger re-assignment. */
9420 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9421
9422 timer T := 5.0;
9423 T.start;
9424 alt {
9425 [] as_assignment(assignment_st);
9426 [] as_Media();
9427 [] T.timeout {
9428 break;
9429 }
9430 }
9431
9432 if (not assignment_st.assignment_done) {
9433 setverdict(fail, "Assignment did not complete");
9434 mtc.stop;
9435 }
9436
9437 f_check_mgcp_expectations()
9438 setverdict(pass);
9439
9440 f_sleep(2.0);
9441 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9442
9443 /* Instruct BSC to clear channel */
9444 var BssmapCause cause := 0;
9445 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9446 interleave {
9447 [] MGCP.receive(tr_DLCX) {}
9448 [] MGCP.receive(tr_DLCX) {}
9449 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9450 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009451 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009452 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009453 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009454 }
9455 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9456 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9457 }
9458 }
9459
9460 f_sleep(0.5);
9461}
9462
9463testcase TC_reassignment_fr() runs on test_CT {
9464 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9465 var MSC_ConnHdlr vc_conn;
9466
9467 f_init(1, true);
9468 f_sleep(1.0);
9469
9470 f_ctrs_bsc_and_bts_init();
9471
9472 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9473 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9474 vc_conn.done;
9475
9476 /* from f_establish_fully() */
9477 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9478 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9479 /* from re-assignment */
9480 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9481 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9482 f_ctrs_bsc_and_bts_verify();
9483 f_shutdown_helper();
9484}
9485
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009486const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9487const charstring REEST_CLEAR := "REEST_CLEAR";
9488const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9489
9490/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9491 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9492 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9493 * the MSC as the CM Re-Establishment is handled.
9494 *
9495 * MS bts0 bts1 bsc msc test-component
9496 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9497 * | | _1 wait a bit, to settle down
9498 * |<-x x--| | _1 "lose connection"
9499 * | | REEST_LOST_CONNECTION
9500 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9501 * | | REEST_CLEAR
9502 * | |<-0---| _1 Clear Command on first A-conn
9503 * | |--0-->| _1 Clear Complete
9504 * | |<----------------->| | _1 Release first channel
9505 * | | REEST_CLEAR_DONE
9506 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9507 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9508 *
9509 */
9510private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9511 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9512 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9513
9514 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9515 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9516
9517 f_establish_fully(ass_cmd, exp_compl);
9518
9519 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9520 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9521 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9522 f_sleep(2.0);
9523 COORD.send(REEST_LOST_CONNECTION);
9524
9525 alt {
9526 [] COORD.receive(REEST_CLEAR);
9527 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9528 setverdict(fail, "Unexpected channel release");
9529 mtc.stop;
9530 }
9531 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9532 setverdict(fail, "Unexpected channel release");
9533 mtc.stop;
9534 }
9535 }
9536 f_perform_clear()
9537 f_expect_dlcx_conns();
9538 COORD.send(REEST_CLEAR_DONE);
9539}
9540
9541private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9542 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9543
9544 /* The MS lost the connection on the first channel, now establishes another one */
9545 COORD.receive(REEST_LOST_CONNECTION);
9546
9547 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9548 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9549 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9550
9551 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009552 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009553 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9554
9555 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9556 COORD.send(REEST_CLEAR);
9557 COORD.receive(REEST_CLEAR_DONE);
9558
9559 f_sleep(2.0);
9560
9561 /* Answer the CM Re-Establishment with an Assignment Command. */
9562 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9563 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9564 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9565 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9566
9567 var AssignmentState st := valueof(ts_AssignmentStateInit);
9568 st.voice_call := true;
9569 st.is_assignment := true;
9570
9571 var ExpectCriteria mgcpcrit := {
9572 connid := omit,
9573 endpoint := omit,
9574 transid := omit
9575 };
9576 f_create_mgcp_expect(mgcpcrit);
9577
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009578 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009579
9580 BSSAP.send(ass_cmd);
9581
9582 var PDU_BSSAP bssap;
9583
9584 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009585 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9586 [] as_Media_ipacc(RSL1, RSL2);
9587 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009588 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9589 break;
9590 }
9591 }
9592
9593 f_sleep(3.0);
9594
9595 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009596 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009597 f_expect_dlcx_conns();
9598}
9599
9600testcase TC_cm_reestablishment() runs on test_CT {
9601 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9602 var MSC_ConnHdlr vc_conn1;
9603
9604 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9605 var MSC_ConnHdlr vc_conn2;
9606 pars2.imsi := pars1.imsi;
9607 pars2.media_nr := 2;
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009608 /* f_tc_cm_reestablishment_2 uses 'bts 1'.
9609 * BTS 1 has BSIC 11 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 3 */
9610 pars2.expect_tsc := 3;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009611
9612 f_init(2, true, guard_timeout := 40.0);
9613 f_sleep(1.0);
9614
9615 vc_conn1 := f_start_handler_create(pars1);
9616 vc_conn2 := f_start_handler_create(pars2);
9617 connect(vc_conn1:COORD, vc_conn2:COORD);
9618 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9619 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9620 vc_conn1.done;
9621 vc_conn2.done;
9622
9623 f_shutdown_helper();
9624}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009625
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009626function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9627 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9628runs on test_CT return template (omit) RSL_Message {
9629 var ASP_RSL_Unitdata rx_rsl_ud;
9630 timer T := t_secs;
9631
9632 T.start;
9633 alt {
9634 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9635 T.stop;
9636 }
9637 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9638 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9639 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9640 T.stop;
9641 return omit;
9642 }
9643 [] T.timeout {
9644 return omit;
9645 }
9646 }
9647 return rx_rsl_ud.rsl;
9648}
9649
9650private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9651 f_vty_enter_cfg_bts(pt, bts_nr);
9652 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9653 f_vty_transceive(pt, "exit");
9654 f_vty_transceive(pt, "exit");
9655 f_vty_transceive(pt, "exit");
9656}
9657
9658private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009659 template RslChannelNr chan_nr := ?,
9660 template (present) uint12_t arfcn := ?,
9661 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009662{
9663 var RSL_IE_Body full_imm_ass_info;
9664 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
9665 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9666 mtc.stop;
9667 }
9668
9669 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
9670 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
9671 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009672 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009673 page_mode := ?);
9674 if (not match(rr_imm_ass, expect_imm_ass)) {
9675 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
9676 setverdict(fail, "Failed to match Immediate Assignment");
9677 mtc.stop;
9678 }
9679}
9680
9681testcase TC_imm_ass_post_chan_ack() runs on test_CT {
9682 var RSL_Message chan_act;
9683 var RSL_Message imm_ass;
9684
9685 f_init(1, false);
9686 f_sleep(1.0);
9687
9688 /* (should be the default anyway, just to make things clear) */
9689 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
9690
9691 /* RA containing reason=LU */
9692 var GsmFrameNumber fn := 2342;
9693 var uint8_t ra := 2;
9694 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9695
9696 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9697
9698 /* First send the Chan Act ACK */
9699 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009700 var RSL_IE_Body chan_ident_ie;
9701 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9702 setverdict(fail, "RSL Channel Identification IE is absent");
9703 mtc.stop;
9704 }
9705
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009706 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
9707
9708 /* Then expect the Immediate Assignment, after we ACKed the chan act */
9709 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9710
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009711 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9712 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009713
9714 /* Check that the lchan is working */
9715 var octetstring l3 := '00010203040506'O;
9716 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9717
9718 var BSSAP_N_CONNECT_ind rx_c_ind;
9719 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9720 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9721
9722 f_sleep(1.0);
9723 f_shutdown_helper();
9724}
9725
9726testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
9727 var RSL_Message chan_act;
9728 var RSL_Message imm_ass;
9729
9730 f_init(1, false);
9731 f_sleep(1.0);
9732
9733 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9734
9735 /* RA containing reason=LU */
9736 var GsmFrameNumber fn := 2342;
9737 var uint8_t ra := 2;
9738 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9739
9740 /* (set bts 0 cfg back to default) */
9741 f_vty_set_imm_ass(BSCVTY);
9742
9743 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9744 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009745 var RSL_IE_Body chan_ident_ie;
9746 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9747 setverdict(fail, "RSL Channel Identification IE is absent");
9748 mtc.stop;
9749 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009750
9751 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9752 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009753 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9754 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009755
9756 /* Only now send the Chan Act ACK */
9757 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9758
9759 /* Check that the lchan is working */
9760 var octetstring l3 := '00010203040506'O;
9761 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9762
9763 var BSSAP_N_CONNECT_ind rx_c_ind;
9764 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9765 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9766
9767 f_sleep(1.0);
9768 f_shutdown_helper();
9769}
9770
Neels Hofmeyr23158742021-09-07 19:08:07 +02009771testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
9772 var RSL_Message chan_act;
9773 var RSL_Message imm_ass;
9774
9775 f_init(1, false);
9776 f_sleep(1.0);
9777
9778 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
9779
9780 /* RA containing reason=LU */
9781 var GsmFrameNumber fn := 2342;
9782 var uint8_t ra := 2;
9783 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9784
9785 /* (set bts 0 cfg back to default) */
9786 f_vty_set_imm_ass(BSCVTY);
9787
9788 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9789 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
9790 var RSL_IE_Body chan_ident_ie;
9791 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9792 setverdict(fail, "RSL Channel Identification IE is absent");
9793 mtc.stop;
9794 }
9795
9796 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9797 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9798 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9799 chan_ident_ie.chan_ident.ch_desc.v.tsc);
9800
9801 /* Only now send the Chan Act ACK */
9802 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9803
9804 /* Check that the lchan is working */
9805 var octetstring l3 := '00010203040506'O;
9806 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9807
9808 var BSSAP_N_CONNECT_ind rx_c_ind;
9809 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9810 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9811
9812 f_sleep(1.0);
9813 f_shutdown_helper();
9814}
9815
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009816testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
9817 /* change Timeslot 6 before f_init() starts RSL */
9818 f_init_vty();
9819 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
9820 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9821
9822 f_init(1, false);
9823 f_sleep(1.0);
9824
9825 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
9826 /* The BSC will activate the dynamic PDCH by default, so confirm that */
9827 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
9828 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
9829
9830 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
9831 f_ts_set_chcomb(0, 0, 6, "PDCH");
9832
9833 /* block all static timeslots so that the dyn TS will be used */
9834 f_disable_all_tch_f();
9835 f_disable_all_tch_h();
9836 f_disable_all_sdcch();
9837
9838 var RSL_Message chan_act;
9839 var RSL_Message imm_ass;
9840
9841 f_init(1, false);
9842 f_sleep(1.0);
9843
9844 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9845
9846 /* RA containing reason=LU */
9847 var GsmFrameNumber fn := 2342;
9848 var uint8_t ra := 2;
9849 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9850
9851 /* (set bts 0 cfg back to default) */
9852 f_vty_set_imm_ass(BSCVTY);
9853
9854 /* Expect the dyn TS to deactivate PDCH first */
9855 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
9856 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
9857
9858 /* Now activation as SDCCH8 */
9859 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
9860
9861 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009862 var RSL_IE_Body chan_ident_ie;
9863 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9864 setverdict(fail, "RSL Channel Identification IE is absent");
9865 mtc.stop;
9866 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009867
9868 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9869 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009870 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9871 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009872
9873 /* Only now send the Chan Act ACK */
9874 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9875
9876 /* Check that the lchan is working */
9877 var octetstring l3 := '00010203040506'O;
9878 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9879
9880 var BSSAP_N_CONNECT_ind rx_c_ind;
9881 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9882 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9883
9884 f_sleep(1.0);
9885 f_shutdown_helper();
9886}
9887
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +02009888testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
9889 /* change Timeslot 6 before f_init() starts RSL */
9890 f_init_vty();
9891 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
9892 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9893
9894 f_init(1, false);
9895 f_sleep(1.0);
9896
9897 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
9898 /* The BSC will activate the dynamic PDCH by default, so confirm that */
9899 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
9900 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
9901
9902 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
9903 f_ts_set_chcomb(0, 0, 6, "PDCH");
9904
9905 /* block all static timeslots so that the dyn TS will be used */
9906 f_disable_all_tch_f();
9907 f_disable_all_tch_h();
9908 f_disable_all_sdcch();
9909
9910 var RSL_Message chan_act;
9911 var RSL_Message imm_ass;
9912
9913 f_init(1, false);
9914 f_sleep(1.0);
9915
9916 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
9917
9918 /* RA containing reason=LU */
9919 var GsmFrameNumber fn := 2342;
9920 var uint8_t ra := 2;
9921 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9922
9923 /* (set bts 0 cfg back to default) */
9924 f_vty_set_imm_ass(BSCVTY);
9925
9926 /* Expect the dyn TS to deactivate PDCH first */
9927 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
9928
9929 /* And already the Immediate Assignment even before the PDCH Deact ACK */
9930 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9931
9932 /* continue the Osmo style PDCH Deact (usual chan rel) */
9933 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
9934
9935 /* Now activation as SDCCH8 */
9936 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
9937
9938 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009939 var RSL_IE_Body chan_ident_ie;
9940 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9941 setverdict(fail, "RSL Channel Identification IE is absent");
9942 mtc.stop;
9943 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +02009944 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9945
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009946 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9947 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +02009948
9949 /* Check that the lchan is working */
9950 var octetstring l3 := '00010203040506'O;
9951 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9952
9953 var BSSAP_N_CONNECT_ind rx_c_ind;
9954 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9955 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9956
9957 f_sleep(1.0);
9958 f_shutdown_helper();
9959}
9960
Harald Welte28d943e2017-11-25 15:00:50 +01009961control {
Harald Welte898113b2018-01-31 18:32:21 +01009962 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +01009963 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01009964 execute( TC_ctrl_msc0_connection_status() );
Harald Welte96c94412017-12-09 03:12:45 +01009965 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +02009966 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02009967 execute( TC_ctrl_location() );
9968 }
Harald Welte898113b2018-01-31 18:32:21 +01009969
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02009970 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02009971 execute( TC_si2quater_2_earfcns() );
9972 execute( TC_si2quater_3_earfcns() );
9973 execute( TC_si2quater_4_earfcns() );
9974 execute( TC_si2quater_5_earfcns() );
9975 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +02009976 execute( TC_si2quater_12_earfcns() );
9977 execute( TC_si2quater_23_earfcns() );
9978 execute( TC_si2quater_32_earfcns() );
9979 execute( TC_si2quater_33_earfcns() );
9980 execute( TC_si2quater_42_earfcns() );
9981 execute( TC_si2quater_48_earfcns() );
9982 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02009983 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +02009984 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02009985
Harald Welte898113b2018-01-31 18:32:21 +01009986 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +01009987 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +01009988 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +01009989 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +02009990 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +02009991 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +01009992 execute( TC_chan_act_ack_est_ind_noreply() );
9993 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +01009994 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +01009995 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07009996 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +01009997 execute( TC_chan_rel_rll_rel_ind() );
9998 execute( TC_chan_rel_conn_fail() );
9999 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010000 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10001 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010002 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010003 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010004 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010005 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010006 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010007 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010008
Harald Weltecfe2c962017-12-15 12:09:32 +010010009 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010010
10011 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010012 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010013 execute( TC_assignment_csd() );
10014 execute( TC_assignment_ctm() );
10015 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010016 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10017 execute( TC_assignment_aoip_tla_v6() );
10018 }
Harald Welte235ebf12017-12-15 14:18:16 +010010019 execute( TC_assignment_fr_a5_0() );
10020 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010021 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010022 execute( TC_assignment_fr_a5_1_codec_missing() );
10023 }
Harald Welte235ebf12017-12-15 14:18:16 +010010024 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010025 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010026 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010027 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010028 execute( TC_ciph_mode_a5_0() );
10029 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010030 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010031 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010032 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010033 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010034
Harald Welte60aa5762018-03-21 19:33:13 +010010035 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010036 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010037 execute( TC_assignment_codec_hr() );
10038 execute( TC_assignment_codec_efr() );
10039 execute( TC_assignment_codec_amr_f() );
10040 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010041
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010042 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010043 execute( TC_assignment_codec_amr_f_S1() );
10044 execute( TC_assignment_codec_amr_h_S1() );
10045 execute( TC_assignment_codec_amr_f_S124() );
10046 execute( TC_assignment_codec_amr_h_S124() );
10047 execute( TC_assignment_codec_amr_f_S0() );
10048 execute( TC_assignment_codec_amr_f_S02() );
10049 execute( TC_assignment_codec_amr_f_S024() );
10050 execute( TC_assignment_codec_amr_f_S0247() );
10051 execute( TC_assignment_codec_amr_h_S0() );
10052 execute( TC_assignment_codec_amr_h_S02() );
10053 execute( TC_assignment_codec_amr_h_S024() );
10054 execute( TC_assignment_codec_amr_h_S0247() );
10055 execute( TC_assignment_codec_amr_f_S01234567() );
10056 execute( TC_assignment_codec_amr_f_S0234567() );
10057 execute( TC_assignment_codec_amr_f_zero() );
10058 execute( TC_assignment_codec_amr_f_unsupp() );
10059 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010060 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10061 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010062 execute( TC_assignment_codec_amr_f_start_mode_4() );
10063 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010064 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010065 }
Harald Welte60aa5762018-03-21 19:33:13 +010010066
Philipp Maierac09bfc2019-01-08 13:41:39 +010010067 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10068 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10069 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10070 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10071 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10072 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10073 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10074 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10075 execute( TC_assignment_codec_req_hr_fr() );
10076 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010077 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10078 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10079 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010080
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010081 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010082
Harald Welte898113b2018-01-31 18:32:21 +010010083 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010084 execute( TC_rll_est_ind_inact_lchan() );
10085 execute( TC_rll_est_ind_inval_sapi1() );
10086 execute( TC_rll_est_ind_inval_sapi3() );
10087 execute( TC_rll_est_ind_inval_sacch() );
10088
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010089 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10090 execute( TC_tch_dlci_link_id_sapi() );
10091
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010092 /* SAPI N Reject triggered by RLL establishment failures */
10093 execute( TC_rll_rel_ind_sapi_n_reject() );
10094 execute( TC_rll_err_ind_sapi_n_reject() );
10095 execute( TC_rll_timeout_sapi_n_reject() );
10096
Harald Welte898113b2018-01-31 18:32:21 +010010097 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010098 execute( TC_paging_imsi_nochan() );
10099 execute( TC_paging_tmsi_nochan() );
10100 execute( TC_paging_tmsi_any() );
10101 execute( TC_paging_tmsi_sdcch() );
10102 execute( TC_paging_tmsi_tch_f() );
10103 execute( TC_paging_tmsi_tch_hf() );
10104 execute( TC_paging_imsi_nochan_cgi() );
10105 execute( TC_paging_imsi_nochan_lac_ci() );
10106 execute( TC_paging_imsi_nochan_ci() );
10107 execute( TC_paging_imsi_nochan_lai() );
10108 execute( TC_paging_imsi_nochan_lac() );
10109 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010110 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10111 execute( TC_paging_imsi_nochan_rnc() );
10112 execute( TC_paging_imsi_nochan_lac_rnc() );
10113 execute( TC_paging_imsi_nochan_lacs() );
10114 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010115 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010116 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010117 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010118 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010119 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010120
10121 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010122 execute( TC_rsl_unknown_unit_id() );
10123
10124 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010125
10126 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010127 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010128 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010129 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010130 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010131 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010132 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010133
Harald Welte261af4b2018-02-12 21:20:39 +010010134 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010135 execute( TC_ho_int_a5_0() );
10136 execute( TC_ho_int_a5_1() );
10137 execute( TC_ho_int_a5_3() );
10138 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010139 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010140
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010141 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010142 execute( TC_ho_out_fail_no_msc_response() );
10143 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010144 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010145
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010146 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010147 execute( TC_ho_into_this_bsc_a5_0() );
10148 execute( TC_ho_into_this_bsc_a5_1() );
10149 execute( TC_ho_into_this_bsc_a5_3() );
10150 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010151 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10152 execute( TC_ho_into_this_bsc_tla_v6() );
10153 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010154 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010155 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010156 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10157 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010158 execute( TC_ho_in_fail_msc_clears() );
10159 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10160 execute( TC_ho_in_fail_no_detect() );
10161 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010162
Neels Hofmeyr91401012019-07-11 00:42:35 +020010163 execute( TC_ho_neighbor_config_1() );
10164 execute( TC_ho_neighbor_config_2() );
10165 execute( TC_ho_neighbor_config_3() );
10166 execute( TC_ho_neighbor_config_4() );
10167 execute( TC_ho_neighbor_config_5() );
10168 execute( TC_ho_neighbor_config_6() );
10169 execute( TC_ho_neighbor_config_7() );
10170
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010171 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010172 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010173 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010174
10175 execute( TC_dyn_pdch_ipa_act_deact() );
10176 execute( TC_dyn_pdch_ipa_act_nack() );
10177 execute( TC_dyn_pdch_osmo_act_deact() );
10178 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010179 if (mp_enable_dyn_sdcch8_test) {
10180 execute( TC_dyn_ts_sdcch8_act_deact() );
10181 execute (TC_dyn_ts_sdcch8_tch_call_act_deact() );
10182 execute( TC_dyn_ts_sdcch8_act_nack() );
10183 }
Harald Welte99f3ca02018-06-14 13:40:29 +020010184
Stefan Sperling0796a822018-10-05 13:01:39 +020010185 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010186 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010187
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010188 /* Power control related */
10189 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010190 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010191
10192 /* MSC pooling */
10193 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10194 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10195 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10196 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10197 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10198 execute( TC_mscpool_L3Compl_on_1_msc() );
10199 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10200 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10201 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10202 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10203 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10204 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10205 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10206 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10207 execute( TC_mscpool_paging_and_response_imsi() );
10208 execute( TC_mscpool_paging_and_response_tmsi() );
10209 execute( TC_mscpool_no_allow_attach_round_robin() );
10210 execute( TC_mscpool_no_allow_attach_valid_nri() );
10211 }
10212
Harald Welte99f3ca02018-06-14 13:40:29 +020010213 execute( TC_early_conn_fail() );
10214 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010215 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010216
Philipp Maier783681c2020-07-16 16:47:06 +020010217 /* Emergency call handling (deny / allow) */
10218 execute( TC_assignment_emerg_setup_allow() );
10219 execute( TC_assignment_emerg_setup_deny_msc() );
10220 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010221 execute( TC_emerg_premption() );
10222
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010223 /* Frequency hopping parameters handling */
10224 execute( TC_fh_params_chan_activ() );
10225 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010226 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010227 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010228 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010229
10230 if (mp_enable_lcs_tests) {
10231 execute( TC_lcs_loc_req_for_active_ms() );
10232 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10233 execute( TC_lcs_loc_req_for_idle_ms() );
10234 execute( TC_lcs_loc_req_no_subscriber() );
10235 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10236 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10237 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10238 execute( TC_cm_service_during_lcs_loc_req() );
10239 execute( TC_ho_during_lcs_loc_req() );
10240 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010241
10242 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010243
10244 execute( TC_refuse_chan_act_to_vamos() );
10245 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010246
10247 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010248
10249 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010250
10251 execute( TC_imm_ass_post_chan_ack() );
10252 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010253 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010254 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010255 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Harald Welte28d943e2017-11-25 15:00:50 +010010256}
10257
10258}