blob: cb28a20bc6d8d771e1f6b17d02d59c009c45adc5 [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
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002775/* Verify correct stats on the number of configured and connected MSCs */
2776private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2777 g_pars := f_gen_test_hdlr_pars();
2778 var StatsDExpects expect := {
2779 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2780 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2781 };
2782 f_statsd_expect(expect);
2783}
2784
2785private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2786{
2787 var MSC_ConnHdlr vc_conn;
2788
2789 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2790 f_sleep(1.0);
2791 vc_conn := f_start_handler(tc_fn);
2792 vc_conn.done;
2793
2794 /* Also verify stat exposed on CTRL interface */
2795 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2796 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2797
2798 f_shutdown_helper();
2799}
2800
2801/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2802private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2803 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2804}
2805testcase TC_stat_num_msc_connected_1() runs on test_CT {
2806 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2807}
2808
2809/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2810private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2811 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2812}
2813testcase TC_stat_num_msc_connected_2() runs on test_CT {
2814 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2815}
2816
2817/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2818private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2819 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2820}
2821testcase TC_stat_num_msc_connected_3() runs on test_CT {
2822 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2823}
2824
Harald Welte4003d112017-12-09 22:35:39 +01002825testcase TC_ctrl() runs on test_CT {
2826 var charstring ctrl_resp;
2827
Harald Welte89d42e82017-12-17 16:42:41 +01002828 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002829
2830 /* all below values must match the osmo-bsc.cfg config file used */
2831
Harald Welte6a129692018-03-17 17:30:14 +01002832 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2833 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002834 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002835
2836 var integer bts_nr := 0;
2837 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2838 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2839 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2840 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2841 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2842 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2843 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2844
2845 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2846 f_sleep(2.0);
2847 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2848 setverdict(fail, "oml-uptime not incrementing as expected");
2849 }
2850 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2851
2852 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2853
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002854 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002855}
2856
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002857/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2858 "location-state" over the SCCPlite IPA conn */
2859testcase TC_ctrl_location() runs on test_CT {
2860 var MSC_ConnHdlr vc_conn;
2861 var integer bts_nr := 0;
2862
2863 f_init(1, true);
2864 f_sleep(1.0);
2865
2866 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2867 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2868 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2869
2870 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2871 f_sleep(2.0);
2872
2873 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2874 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2875 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
2876
2877 /* should match the one from config */
2878 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
2879
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002880 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002881}
2882
Harald Welte6f521d82017-12-11 19:52:02 +01002883
2884/***********************************************************************
2885 * Paging Testing
2886 ***********************************************************************/
2887
2888type record Cell_Identity {
2889 GsmMcc mcc,
2890 GsmMnc mnc,
2891 GsmLac lac,
2892 GsmCellId ci
2893};
Harald Welte24135bd2018-03-17 19:27:53 +01002894private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01002895private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01002896
Harald Welte5d1a2202017-12-13 19:51:29 +01002897type set of integer BtsIdList;
2898
2899private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
2900 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
2901 if (bts_id == bts_ids[j]) {
2902 return true;
2903 }
2904 }
2905 return false;
2906}
Harald Welte6f521d82017-12-11 19:52:02 +01002907
2908/* core paging test helper function; used by most paging test cases */
2909private function f_pageing_helper(hexstring imsi,
2910 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01002911 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01002912 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002913 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01002914{
2915 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002916 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01002917 var RSL_Message rx_rsl;
2918 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01002919 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01002920
2921 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01002922
2923 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01002924 for (i := 0; i < NUM_BTS; i := i + 1) {
2925 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01002926 }
Harald Welte6f521d82017-12-11 19:52:02 +01002927
2928 if (isvalue(rsl_chneed)) {
2929 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
2930 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
2931 } else {
2932 bssmap_chneed := omit;
2933 }
2934
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002935 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
2936 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01002937
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002938 if (not istemplatekind(tmsi, "omit")) {
2939 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002940 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002941 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002942 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002943
Harald Welte5d1a2202017-12-13 19:51:29 +01002944 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002945 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01002946 /* check channel type, paging group */
2947 if (rx_rsl.ies[1].body.paging_group != paging_group) {
2948 setverdict(fail, "Paging for wrong paging group");
2949 }
2950 if (ispresent(rsl_chneed) and
2951 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
2952 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
2953 }
Harald Welte6f521d82017-12-11 19:52:02 +01002954 }
Harald Welte2fccd982018-01-31 15:48:19 +01002955 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01002956 /* do a quick check on all not-included BTSs if they received paging */
2957 for (i := 0; i < NUM_BTS; i := i + 1) {
2958 timer T := 0.1;
2959 if (f_bts_in_list(i, bts_ids)) {
2960 continue;
2961 }
2962 T.start;
2963 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002964 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01002965 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
2966 }
2967 [] IPA_RSL[i].receive { repeat; }
2968 [] T.timeout { }
2969 }
Harald Welte6f521d82017-12-11 19:52:02 +01002970 }
2971
2972 setverdict(pass);
2973}
2974
Harald Welte5d1a2202017-12-13 19:51:29 +01002975const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01002976const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01002977const BtsIdList c_BtsId_LAC1 := { 0, 1 };
2978const BtsIdList c_BtsId_LAC2 := { 2 };
2979
Harald Welte6f521d82017-12-11 19:52:02 +01002980/* PAGING by IMSI + TMSI */
2981testcase TC_paging_imsi_nochan() runs on test_CT {
2982 var BSSMAP_FIELD_CellIdentificationList cid_list;
2983 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01002984 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002985 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002986}
2987
2988/* PAGING by IMSI + TMSI */
2989testcase TC_paging_tmsi_nochan() runs on test_CT {
2990 var BSSMAP_FIELD_CellIdentificationList cid_list;
2991 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002992 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002993 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002994}
2995
2996/* Paging with different "channel needed' values */
2997testcase TC_paging_tmsi_any() runs on test_CT {
2998 var BSSMAP_FIELD_CellIdentificationList cid_list;
2999 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003000 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003001 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003002}
3003testcase TC_paging_tmsi_sdcch() runs on test_CT {
3004 var BSSMAP_FIELD_CellIdentificationList cid_list;
3005 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003006 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003007 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003008}
3009testcase TC_paging_tmsi_tch_f() runs on test_CT {
3010 var BSSMAP_FIELD_CellIdentificationList cid_list;
3011 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003012 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003013 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003014}
3015testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3016 var BSSMAP_FIELD_CellIdentificationList cid_list;
3017 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003018 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003019 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003020}
3021
3022/* Paging by CGI */
3023testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3024 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3025 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003026 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003027 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003028}
3029
3030/* Paging by LAC+CI */
3031testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3032 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3033 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003034 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003035 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003036}
3037
3038/* Paging by CI */
3039testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3040 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3041 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003042 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003043 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003044}
3045
3046/* Paging by LAI */
3047testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3048 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3049 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003050 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003051 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003052}
3053
3054/* Paging by LAC */
3055testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3056 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3057 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003058 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003059 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003060}
3061
3062/* Paging by "all in BSS" */
3063testcase TC_paging_imsi_nochan_all() runs on test_CT {
3064 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3065 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003066 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003067 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003068}
3069
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003070/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003071testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3072 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3073 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 +01003074 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003075 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003076}
Harald Welte6f521d82017-12-11 19:52:02 +01003077
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003078/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003079testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3080 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3081 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003082 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003083 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003084}
3085
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003086/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003087testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3088 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3089 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003090 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003091 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003092}
3093
Harald Welte6f521d82017-12-11 19:52:02 +01003094/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003095testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3096 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3097 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3098 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003099 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003100}
3101
3102/* Paging on empty list: Verify none of them page */
3103testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3104 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3105 cid_list := { cIl_LAC := { } };
3106 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003107 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003108}
3109
Stefan Sperling049a86e2018-03-20 15:51:00 +01003110/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3111testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3112 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3113 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3114 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3115 f_shutdown_helper();
3116}
3117
Harald Welte6f521d82017-12-11 19:52:02 +01003118/* Verify paging retransmission interval + count */
3119/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003120/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003121
Harald Weltee65d40e2017-12-13 00:09:06 +01003122/* Verify PCH load */
3123testcase TC_paging_imsi_load() runs on test_CT {
3124 var BSSMAP_FIELD_CellIdentificationList cid_list;
3125 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003126 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003127 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003128 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003129
3130 /* tell BSC there is no paging space anymore */
3131 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003132 f_sleep(0.2);
3133 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003134
3135 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3136 * there would be 8 retransmissions during 4 seconds */
3137 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003138 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003139 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003140 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003141 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003142 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003143 }
Harald Welte2caa1062018-03-17 18:19:05 +01003144 [] T_retrans.timeout {
3145 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3146 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3147 T_retrans.start;
3148 repeat;
3149 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003150 [] T.timeout {
3151 setverdict(pass);
3152 }
3153 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003154
3155 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003156}
3157
Harald Welte235ebf12017-12-15 14:18:16 +01003158/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003159testcase TC_paging_counter() runs on test_CT {
3160 var BSSMAP_FIELD_CellIdentificationList cid_list;
3161 timer T := 4.0;
3162 var integer i;
3163 var integer paging_attempted_bsc;
3164 var integer paging_attempted_bts[NUM_BTS];
3165 var integer paging_expired_bts[NUM_BTS];
3166 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3167
3168 f_init();
3169
3170 /* read counters before paging */
3171 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3172 for (i := 0; i < NUM_BTS; i := i+1) {
3173 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3174 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3175 }
3176
3177 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3178
3179 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3180 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3181 for (i := 0; i < NUM_BTS; i := i+1) {
3182 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3183 paging_attempted_bts[i]+1);
3184 }
3185
3186 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3187 f_sleep(12.0);
3188 for (i := 0; i < NUM_BTS; i := i+1) {
3189 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3190 paging_expired_bts[i]+1);
3191 }
Harald Welte1ff69992017-12-14 12:31:17 +01003192
Philipp Maier282ca4b2018-02-27 17:17:00 +01003193 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003194}
3195
3196
Harald Welte10985002017-12-12 09:29:15 +01003197/* Verify paging stops after A-RESET */
3198testcase TC_paging_imsi_a_reset() runs on test_CT {
3199 var BSSMAP_FIELD_CellIdentificationList cid_list;
3200 timer T := 3.0;
3201 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003202 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003203
3204 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003205 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 +01003206 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003207 [] 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 +01003208 [] BSSAP.receive { repeat; }
3209 }
3210
Daniel Willmanncbef3982018-07-30 09:22:40 +02003211 /* Wait to avoid a possible race condition if a paging message is
3212 * received right before the reset ACK. */
3213 f_sleep(0.2);
3214
Harald Welte10985002017-12-12 09:29:15 +01003215 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003216 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3217 IPA_RSL[i].clear;
3218 }
Harald Welte10985002017-12-12 09:29:15 +01003219
3220 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3221 T.start;
3222 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003223 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003224 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003225 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003226 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003227 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003228 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003229 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003230 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003231 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003232 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003233 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003234 }
Harald Welte10985002017-12-12 09:29:15 +01003235 [] T.timeout {
3236 setverdict(pass);
3237 }
3238 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003239
3240 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003241}
Harald Welteae026692017-12-09 01:03:01 +01003242
Philipp Maierf45824a2019-08-14 14:44:10 +02003243/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3244 * paging response we can not know which MSC is in charge, so we will blindly
3245 * pick the first configured MSC. This behavior is required in order to make
3246 * MT-CSFB calls working because in those cases the BSC can not know that the
3247 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3248 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003249 */
3250testcase TC_paging_resp_unsol() runs on test_CT {
3251
3252 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003253 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003254
3255 var BSSAP_N_CONNECT_ind rx_c_ind;
3256 var DchanTuple dt;
3257 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003258 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003259
3260 /* Send CHAN RQD and wait for allocation; acknowledge it */
3261 dt.rsl_chan_nr := f_chreq_act_ack();
3262
3263 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3264 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3265
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003266
Philipp Maierf45824a2019-08-14 14:44:10 +02003267 /* Expevct a CR with a matching Paging response on the A-Interface */
3268 T.start;
3269 alt {
3270 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3271 setverdict(pass);
3272 }
3273 [] BSSAP.receive {
3274 setverdict(fail, "Received unexpected message on A-Interface!");
3275 }
3276 [] T.timeout {
3277 setverdict(fail, "Received nothing on A-Interface!");
3278 }
3279 }
3280
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003281 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003282}
3283
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003284/* Test RSL link drop causes counter increment */
3285testcase TC_rsl_drop_counter() runs on test_CT {
3286 var integer rsl_fail;
3287
Harald Welte89d42e82017-12-17 16:42:41 +01003288 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003289
3290 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3291
3292 bts[0].rsl.vc_IPA.stop;
3293
3294 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3295
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003296 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003297}
3298
3299/* TODO: Test OML link drop causes counter increment */
3300
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003301/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3302function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3303 timer T := 10.0;
3304
3305 bts[0].rsl.id := "IPA-0-RSL";
3306 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3307 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3308 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003309 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003310
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003311 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003312
3313 f_init_mgcp("VirtMSC");
3314
3315 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3316 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3317 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3318 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3319
3320 /* wait for IPA OML link to connect and then disconnect */
3321 T.start;
3322 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003323 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003324 T.stop;
3325 return true;
3326 }
3327 [] IPA_RSL[0].receive { repeat }
3328 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003329 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003330 }
3331 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003332 return false;
3333}
3334
3335/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3336testcase TC_rsl_unknown_unit_id() runs on test_CT {
3337 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3338 setverdict(pass);
3339 } else {
3340 setverdict(fail, "Timeout RSL waiting for connection to close");
3341 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003342 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003343}
3344
3345
3346/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3347testcase TC_oml_unknown_unit_id() runs on test_CT {
3348 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3349 setverdict(pass);
3350 } else {
3351 setverdict(fail, "Timeout OML waiting for connection to close");
3352 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003353 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003354}
3355
3356
Harald Weltec1a2fff2017-12-17 11:06:19 +01003357/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003358 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003359 ***********************************************************************/
3360
Harald Welte6811d102019-04-14 22:23:14 +02003361import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003362import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003363import from RSL_Emulation all;
3364import from MSC_ConnectionHandler all;
3365
3366type function void_fn(charstring id) runs on MSC_ConnHdlr;
3367
Harald Welte336820c2018-05-31 20:34:52 +02003368/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003369private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3370 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003371 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003372 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003373 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003374 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003375 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3376 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3377 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003378 if (isvalue(bts[2])) {
3379 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3380 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3381 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003382 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003383 if (mp_enable_lcs_tests) {
3384 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3385 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3386 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003387 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003388 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003389 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003390}
3391
Neels Hofmeyrda436782021-07-20 22:09:06 +02003392function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003393runs on test_CT return MSC_ConnHdlr {
3394 var charstring id := testcasename();
3395 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003396 var integer bssap_idx := 0;
3397 if (isvalue(pars)) {
3398 bssap_idx := valueof(pars).mscpool.bssap_idx;
3399 }
Harald Welte336820c2018-05-31 20:34:52 +02003400 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003401 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003402 return vc_conn;
3403}
3404
3405function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3406runs on test_CT return MSC_ConnHdlr {
3407 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003408 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003409 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003410 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003411 return vc_conn;
3412}
3413
Neels Hofmeyrda436782021-07-20 22:09:06 +02003414function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3415runs on test_CT return MSC_ConnHdlr {
3416 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3417}
3418
Harald Weltea0630032018-03-20 21:09:55 +01003419/* first function inside ConnHdlr component; sets g_pars + starts function */
3420private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3421runs on MSC_ConnHdlr {
3422 if (isvalue(pars)) {
3423 g_pars := valueof(pars);
3424 }
3425 fn.apply(id);
3426}
3427
Oliver Smith26a3db72021-07-09 13:51:29 +02003428private function f_vty_encryption_a5(charstring options) runs on test_CT {
3429 f_vty_transceive(BSCVTY, "configure terminal");
3430 f_vty_transceive(BSCVTY, "network");
3431 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3432 f_vty_transceive(BSCVTY, "exit");
3433 f_vty_transceive(BSCVTY, "exit");
3434}
3435
3436private function f_vty_encryption_a5_reset() runs on test_CT {
3437 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3438 f_vty_encryption_a5("0 1 3");
3439}
3440
Harald Welte3c86ea02018-05-10 22:28:05 +02003441/* Establish signalling channel (non-assignment case) followed by cipher mode */
3442private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003443 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3444 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003445 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003446 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3447 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3448 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3449 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003450
Philipp Maier23000732018-05-18 11:25:37 +02003451 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003452}
3453testcase TC_ciph_mode_a5_0() runs on test_CT {
3454 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003455 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003456 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3457
3458 f_init(1, true);
3459 f_sleep(1.0);
3460 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3461 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003462 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003463}
3464testcase TC_ciph_mode_a5_1() runs on test_CT {
3465 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003466 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003467 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3468
3469 f_init(1, true);
3470 f_sleep(1.0);
3471 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3472 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003473 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003474}
Oliver Smith50b98122021-07-09 15:00:28 +02003475/* OS#4975: verify that A5/2 is preferred over A5/0 */
3476testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3477 var MSC_ConnHdlr vc_conn;
3478 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3479
3480 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3481 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3482
3483 f_init(1, true);
3484 f_vty_encryption_a5("0 1 2 3");
3485 f_sleep(1.0);
3486 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3487 vc_conn.done;
3488 f_vty_encryption_a5_reset();
3489 f_shutdown_helper();
3490}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003491/* OS#4975: verify that A5/1 is preferred over A5/2 */
3492testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3493 var MSC_ConnHdlr vc_conn;
3494 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3495
3496 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3497 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3498
3499 f_init(1, true);
3500 f_vty_encryption_a5("1 2");
3501 f_sleep(1.0);
3502 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3503 vc_conn.done;
3504 f_vty_encryption_a5_reset();
3505 f_shutdown_helper();
3506}
Harald Welte3c86ea02018-05-10 22:28:05 +02003507testcase TC_ciph_mode_a5_3() runs on test_CT {
3508 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003509 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003510 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3511
3512 f_init(1, true);
3513 f_sleep(1.0);
3514 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3515 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003516 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003517}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003518/* Establish a Signalling channel with A5/4 encryption. */
3519testcase TC_ciph_mode_a5_4() runs on test_CT {
3520 var MSC_ConnHdlr vc_conn;
3521 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3522 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003523
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003524 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003525 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003526 f_sleep(1.0);
3527 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3528 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003529 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003530 f_shutdown_helper();
3531}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003532/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3533private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3534 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3535 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3536 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3537 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3538
3539 f_establish_fully(ass_cmd, exp_compl);
3540}
3541testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3542 var MSC_ConnHdlr vc_conn;
3543 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3544
3545 f_init(1, true);
3546 f_sleep(1.0);
3547 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3548 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003549 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003550}
3551
Harald Welte3c86ea02018-05-10 22:28:05 +02003552
3553/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003554private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003555 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3556 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003557
Harald Welte552620d2017-12-16 23:21:36 +01003558 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3559 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003560
Harald Weltea0630032018-03-20 21:09:55 +01003561 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003562}
Harald Welte552620d2017-12-16 23:21:36 +01003563testcase TC_assignment_fr_a5_0() runs on test_CT {
3564 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003565 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003566 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003567
Harald Welte89d42e82017-12-17 16:42:41 +01003568 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003569 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003570 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003571 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003572 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003573}
Harald Welte552620d2017-12-16 23:21:36 +01003574testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003575 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003576 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003577 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003578
Harald Welte89d42e82017-12-17 16:42:41 +01003579 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003580 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003581 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3582 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003583 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003584}
3585testcase TC_assignment_fr_a5_3() runs on test_CT {
3586 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003587 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003588 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003589
Harald Welte651fcdc2018-05-10 20:23:16 +02003590 f_init(1, true);
3591 f_sleep(1.0);
3592 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003593 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003594 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003595}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003596/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3597testcase TC_assignment_fr_a5_4() runs on test_CT {
3598 var MSC_ConnHdlr vc_conn;
3599 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3600 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3601
3602 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003603 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003604 f_sleep(1.0);
3605 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3606 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003607 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003608 f_shutdown_helper();
3609}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003610
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003611/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3612testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3613 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3614 var MSC_ConnHdlr vc_conn;
3615
3616 f_init(1, true);
3617 f_sleep(1.0);
3618
3619 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3620 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3621 vc_conn.done;
3622 f_shutdown_helper();
3623}
3624
Harald Welte552620d2017-12-16 23:21:36 +01003625/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3626private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003627 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003628 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003629 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003630
3631 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003632 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3633
Harald Weltea0630032018-03-20 21:09:55 +01003634 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003635}
Harald Welte552620d2017-12-16 23:21:36 +01003636testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3637 var MSC_ConnHdlr vc_conn;
3638
Harald Welte89d42e82017-12-17 16:42:41 +01003639 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003640 f_sleep(1.0);
3641
Harald Welte8863fa12018-05-10 20:15:27 +02003642 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003643 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003644 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003645}
3646
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003647private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3648 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3649 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003650
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003651 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3652 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3653
3654 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3655
3656 var BSSMAP_FIELD_CodecType codecType;
3657 timer T := 10.0;
3658
3659 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3660 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3661
3662 f_create_chan_and_exp();
3663 /* we should now have a COMPL_L3 at the MSC */
3664
3665 var template PDU_BSSAP exp_l3_compl;
3666 exp_l3_compl := tr_BSSMAP_ComplL3()
3667 if (g_pars.aoip == false) {
3668 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3669 } else {
3670 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3671 }
3672 T.start;
3673 alt {
3674 [] BSSAP.receive(exp_l3_compl);
3675 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3676 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3677 }
3678 [] T.timeout {
3679 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3680 }
3681 }
3682
3683 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003684 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003685}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003686testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3687 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003688 var MSC_ConnHdlr vc_conn;
3689
Harald Welte89d42e82017-12-17 16:42:41 +01003690 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003691 f_sleep(1.0);
3692
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003693 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003694 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003695 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003696 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003697}
3698
3699
Harald Welte4532e0a2017-12-23 02:05:44 +01003700private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003701 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003702 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003703 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003704 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003705
3706 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003707 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003708
3709 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003710 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3711 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003712 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3713 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3714 };
3715 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003716}
3717
3718testcase TC_assignment_sign() runs on test_CT {
3719 var MSC_ConnHdlr vc_conn;
3720
3721 f_init(1, true);
3722 f_sleep(1.0);
3723
Harald Welte8863fa12018-05-10 20:15:27 +02003724 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003725 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003726 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003727}
3728
Harald Welte60aa5762018-03-21 19:33:13 +01003729/***********************************************************************
3730 * Codec (list) testing
3731 ***********************************************************************/
3732
3733/* check if the given rsl_mode is compatible with the a_elem */
3734private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3735return boolean {
3736 select (a_elem.codecType) {
3737 case (GSM_FR) {
3738 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3739 return true;
3740 }
3741 }
3742 case (GSM_HR) {
3743 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3744 return true;
3745 }
3746 }
3747 case (GSM_EFR) {
3748 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3749 return true;
3750 }
3751 }
3752 case (FR_AMR) {
3753 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3754 return true;
3755 }
3756 }
3757 case (HR_AMR) {
3758 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3759 return true;
3760 }
3761 }
3762 case else { }
3763 }
3764 return false;
3765}
3766
3767/* check if the given rsl_mode is compatible with the a_list */
3768private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3769return boolean {
3770 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3771 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3772 return true;
3773 }
3774 }
3775 return false;
3776}
3777
3778/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003779function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003780return BSSMAP_IE_ChannelType {
3781 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3782 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3783 select (a_elem.codecType) {
3784 case (GSM_FR) {
3785 ret.channelRateAndType := ChRate_TCHF;
3786 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3787 }
3788 case (GSM_HR) {
3789 ret.channelRateAndType := ChRate_TCHH;
3790 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3791 }
3792 case (GSM_EFR) {
3793 ret.channelRateAndType := ChRate_TCHF;
3794 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3795 }
3796 case (FR_AMR) {
3797 ret.channelRateAndType := ChRate_TCHF;
3798 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3799 }
3800 case (HR_AMR) {
3801 ret.channelRateAndType := ChRate_TCHH;
3802 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3803 }
3804 case else {
3805 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003806 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003807 }
3808 }
3809 return ret;
3810}
3811
Harald Weltea63b9102018-03-22 20:36:16 +01003812private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3813return template RSL_IE_Body {
3814 var template RSL_IE_Body mode_ie := {
3815 chan_mode := {
3816 len := ?,
3817 reserved := ?,
3818 dtx_d := ?,
3819 dtx_u := ?,
3820 spd_ind := RSL_SPDI_SPEECH,
3821 ch_rate_type := -,
3822 coding_alg_rate := -
3823 }
3824 }
3825
3826 select (a_elem.codecType) {
3827 case (GSM_FR) {
3828 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3829 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3830 }
3831 case (GSM_HR) {
3832 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3833 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3834 }
3835 case (GSM_EFR) {
3836 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3837 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3838 }
3839 case (FR_AMR) {
3840 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3841 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3842 }
3843 case (HR_AMR) {
3844 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3845 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3846 }
3847 }
3848 return mode_ie;
3849}
3850
Harald Welte60aa5762018-03-21 19:33:13 +01003851type record CodecListTest {
3852 BSSMAP_IE_SpeechCodecList codec_list,
3853 charstring id
3854}
3855type record of CodecListTest CodecListTests
3856
3857private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003858 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3859 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003860
3861 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003862 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003863 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3864 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3865 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003866 if (isvalue(g_pars.expect_mr_s0_s7)) {
3867 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3868 g_pars.expect_mr_s0_s7;
3869 }
Harald Welte79f3f542018-05-25 20:02:37 +02003870 }
Harald Welte60aa5762018-03-21 19:33:13 +01003871 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3872 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003873 log("expecting ASS COMPL like this: ", exp_compl);
3874
3875 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01003876
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003877 if (not g_pars.expect_channel_mode_modify) {
3878 /* Verify that the RSL-side activation actually matches our expectations */
3879 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01003880
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003881 var RSL_IE_Body mode_ie;
3882 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
3883 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02003884 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003885 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003886 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
3887 if (not match(mode_ie, t_mode_ie)) {
3888 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
3889 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003890 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003891
3892 var RSL_IE_Body mr_conf;
3893 if (g_pars.expect_mr_conf_ie != omit) {
3894 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
3895 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
3896 mtc.stop;
3897 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003898 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003899
3900 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
3901 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
3902 g_pars.expect_mr_conf_ie);
3903 }
3904 } else {
3905 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
3906 log("found RSL MR CONFIG IE: ", mr_conf);
3907 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
3908 mtc.stop;
3909 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003910 }
3911 }
Harald Welte60aa5762018-03-21 19:33:13 +01003912}
3913
Philipp Maierd0e64b02019-03-13 14:15:23 +01003914private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
3915
3916 var PDU_BSSAP ass_cmd := f_gen_ass_req();
3917 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
3918
3919 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003920 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01003921 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3922 }
3923 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3924 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
3925 log("expecting ASS FAIL like this: ", exp_fail);
3926
3927 f_establish_fully(ass_cmd, exp_fail);
3928}
3929
Harald Welte60aa5762018-03-21 19:33:13 +01003930testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003931 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003932 var MSC_ConnHdlr vc_conn;
3933
3934 f_init(1, true);
3935 f_sleep(1.0);
3936
3937 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003938 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003939 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003940 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003941}
3942
3943testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003944 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003945 var MSC_ConnHdlr vc_conn;
3946
3947 f_init(1, true);
3948 f_sleep(1.0);
3949
3950 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003951 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003952 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003953 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003954}
3955
3956testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003957 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003958 var MSC_ConnHdlr vc_conn;
3959
3960 f_init(1, true);
3961 f_sleep(1.0);
3962
3963 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003964 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003965 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003966 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003967}
3968
Philipp Maierd0e64b02019-03-13 14:15:23 +01003969/* Allow 5,90k only (current default config) */
3970private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003971 f_vty_cfg_msc(BSCVTY, 0, {
3972 "amr-config 12_2k forbidden",
3973 "amr-config 10_2k forbidden",
3974 "amr-config 7_95k forbidden",
3975 "amr-config 7_40k forbidden",
3976 "amr-config 6_70k forbidden",
3977 "amr-config 5_90k allowed",
3978 "amr-config 5_15k forbidden",
3979 "amr-config 4_75k forbidden"
3980 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003981}
3982
3983/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
3984 * ("Config-NB-Code = 1") */
3985private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003986 f_vty_cfg_msc(BSCVTY, 0, {
3987 "amr-config 12_2k allowed",
3988 "amr-config 10_2k forbidden",
3989 "amr-config 7_95k forbidden",
3990 "amr-config 7_40k allowed",
3991 "amr-config 6_70k forbidden",
3992 "amr-config 5_90k allowed",
3993 "amr-config 5_15k forbidden",
3994 "amr-config 4_75k allowed"
3995 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003996}
3997
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003998private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
3999 var charstring tch;
4000 if (fr) {
4001 tch := "tch-f";
4002 } else {
4003 tch := "tch-h";
4004 }
4005 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4006}
4007
4008/* Set the AMR start-mode for this TCH back to the default configuration. */
4009private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4010 f_vty_amr_start_mode_set(fr, "auto");
4011}
4012
Harald Welte60aa5762018-03-21 19:33:13 +01004013testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004014 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004015 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004016
4017 /* Note: This setups the codec configuration. The parameter payload in
4018 * mr_conf must be consistant with the parameter codecElements in pars
4019 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004020 var RSL_IE_Body mr_conf := {
4021 other := {
4022 len := 2,
4023 payload := '2804'O
4024 }
4025 };
Harald Welte60aa5762018-03-21 19:33:13 +01004026
Philipp Maier7695a0d2018-09-27 17:52:14 +02004027 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004028 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004029 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4030 pars.expect_mr_conf_ie := mr_conf;
4031
Harald Welte60aa5762018-03-21 19:33:13 +01004032 f_init(1, true);
4033 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004034 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004035
Harald Welte8863fa12018-05-10 20:15:27 +02004036 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004037 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004038
4039 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004040 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004041}
4042
4043testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004044 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004045 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004046
4047 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004048 var RSL_IE_Body mr_conf := {
4049 other := {
4050 len := 2,
4051 payload := '2804'O
4052 }
4053 };
Harald Welte60aa5762018-03-21 19:33:13 +01004054
Philipp Maier7695a0d2018-09-27 17:52:14 +02004055 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004056 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004057 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4058 pars.expect_mr_conf_ie := mr_conf;
4059
Harald Welte60aa5762018-03-21 19:33:13 +01004060 f_init(1, true);
4061 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004062 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004063
Harald Welte8863fa12018-05-10 20:15:27 +02004064 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004065 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004066
4067 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004068 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004069}
4070
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004071/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4072testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4073 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4074 var MSC_ConnHdlr vc_conn;
4075
4076 f_init(1, true);
4077 f_sleep(1.0);
4078
4079 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4080 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4081 * expecting a Channel Mode Modify if the channel type is compatible. */
4082 f_disable_all_sdcch();
4083 f_disable_all_tch_h();
4084
4085 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4086 pars.expect_channel_mode_modify := true;
4087 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4088 vc_conn.done;
4089
4090 f_enable_all_sdcch();
4091 f_enable_all_tch();
4092 f_shutdown_helper();
4093}
4094
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004095/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4096testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4097 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4098 var MSC_ConnHdlr vc_conn;
4099
4100 var RSL_IE_Body mr_conf := {
4101 other := {
4102 len := 2,
4103 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4104 }
4105 };
4106
4107 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4108 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4109 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4110 pars.expect_mr_conf_ie := mr_conf;
4111
4112 f_init(1, true);
4113 f_sleep(1.0);
4114
4115 /* First set nonzero start mode bits */
4116 f_vty_amr_start_mode_set(true, "4");
4117 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4118 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4119 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4120 f_vty_amr_start_mode_set(true, "auto");
4121
4122 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4123 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004124
4125 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4126 f_vty_amr_start_mode_set(true, "1");
4127 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004128 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004129}
4130
Neels Hofmeyr21863562020-11-26 00:34:33 +00004131function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4132 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004133runs on test_CT {
4134
4135 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4136 var MSC_ConnHdlr vc_conn;
4137
4138 /* See note above */
4139 var RSL_IE_Body mr_conf := {
4140 other := {
4141 len := lengthof(mrconf),
4142 payload := mrconf
4143 }
4144 };
4145
4146 if (fr) {
4147 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4148 } else {
4149 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4150 }
4151 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4152 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4153 pars.expect_mr_conf_ie := mr_conf;
4154 pars.expect_mr_s0_s7 := exp_s8_s0;
4155
4156 f_init(1, true);
4157 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004158 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004159 f_sleep(1.0);
4160
4161 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4162 vc_conn.done;
4163 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004164 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004165}
4166
4167function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4168runs on test_CT {
4169
4170 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4171 var MSC_ConnHdlr vc_conn;
4172
4173 if (fr) {
4174 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4175 } else {
4176 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4177 }
4178 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4179 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4180
4181 f_init(1, true);
4182 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004183 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004184 f_sleep(1.0);
4185
4186 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4187 vc_conn.done;
4188 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004189 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004190}
4191
4192
4193/* Set S1, we expect an AMR multirate configuration IE with all four rates
4194 * set. */
4195testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004196 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004197 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004198}
4199
4200/* Set S1, we expect an AMR multirate configuration IE with the lower three
4201 * rates set. */
4202testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004203 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004204 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004205}
4206
4207/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4208 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4209testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004210 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004211 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004212}
4213
4214/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4215 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4216testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004217 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004218 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004219}
4220
4221/* The following block of tests selects more and more rates until all four
4222 * possible rates are in the active set (full rate) */
4223testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004224 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004225 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004226}
4227
4228testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004229 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004230 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004231}
4232
4233testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004234 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004235 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004236}
4237
4238testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004239 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004240 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004241}
4242
4243/* The following block of tests selects more and more rates until all three
4244 * possible rates are in the active set (half rate) */
4245testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004246 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004247 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004248}
4249
4250testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004251 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004252 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004253}
4254
4255testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004256 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004257 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004258}
4259
4260/* The following block tests what happens when the MSC does offer rate
4261 * configurations that are not supported by the BSC. Normally such situations
4262 * should not happen because the MSC gets informed by the BSC in advance via
4263 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4264 * to offer rates that are not applicable anyway. */
4265
4266testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004267 /* Try to include 12,2k in into the active set even though the channel
4268 * is half rate only. The BSC is expected to remove the 12,0k */
4269 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004270 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004271}
4272
4273testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004274 /* See what happens when all rates are selected at once. Since then
4275 * Also S1 is selected, this setting will be prefered and we should
4276 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4277 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004278 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004279}
4280
4281testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004282 /* Same as above, but with S1 missing, the MSC is then expected to
4283 * select the currently supported rates, which are also 12.2k, 7,40k,
4284 * 5,90k, and 4,75k, into the active set. */
4285 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004286 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004287}
4288
4289testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004290 /* Try to select no rates at all */
4291 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004292 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004293}
4294
4295testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004296 /* Try to select only unsupported rates */
4297 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004298 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004299}
4300
4301testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004302 /* Try to select 12,2k for half rate */
4303 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004304 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004305}
4306
Neels Hofmeyr21863562020-11-26 00:34:33 +00004307testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4308 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4309 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004310 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004311}
4312
4313testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4314 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4315 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004316 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004317}
4318
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004319testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004320 /* "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 +00004321 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4322 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004323 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004324}
4325
4326testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004327 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4328 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004329 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004330 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004331}
4332
Philipp Maierac09bfc2019-01-08 13:41:39 +01004333private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004334 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4335 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4336 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4337 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004338}
4339
4340private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004341 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4342 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004343}
4344
4345private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004346 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4347 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4348 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4349 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4350 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4351 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004352}
4353
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004354private function f_disable_all_sdcch() runs on test_CT {
4355 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4356 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4357 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4358 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4359}
4360
4361private function f_enable_all_sdcch() runs on test_CT {
4362 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4363 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4364 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4365 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4366}
4367
Philipp Maierac09bfc2019-01-08 13:41:39 +01004368/* Allow HR only */
4369private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4370 g_pars := f_gen_test_hdlr_pars();
4371 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4372 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4373 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4374 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4375 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4376 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4377 f_establish_fully(ass_cmd, exp_compl);
4378}
4379
4380/* Allow FR only */
4381private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4382 g_pars := f_gen_test_hdlr_pars();
4383 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4384 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4385 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4386 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4387 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4388 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4389 f_establish_fully(ass_cmd, exp_compl);
4390}
4391
4392/* Allow HR only (expect assignment failure) */
4393private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(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_fail := tr_BSSMAP_AssignmentFail;
4397 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4398 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4399 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4400 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4401 f_establish_fully(ass_cmd, exp_fail);
4402}
4403
4404/* Allow FR only (expect assignment failure) */
4405private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4406 g_pars := f_gen_test_hdlr_pars();
4407 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4408 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4409 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4410 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4411 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4412 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4413 f_establish_fully(ass_cmd, exp_fail);
4414}
4415
4416/* Allow FR and HR, but prefer FR */
4417private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4418 g_pars := f_gen_test_hdlr_pars();
4419 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4420 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4421 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4422 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4423 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4424 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4425 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4426 f_establish_fully(ass_cmd, exp_compl);
4427}
4428
4429/* Allow FR and HR, but prefer HR */
4430private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4431 g_pars := f_gen_test_hdlr_pars();
4432 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4433 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4434 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4435 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4436 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4437 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4438 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4439 f_establish_fully(ass_cmd, exp_compl);
4440}
4441
4442/* Allow FR and HR, but prefer FR */
4443private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4444 g_pars := f_gen_test_hdlr_pars();
4445 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4446 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4447 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4448 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4449 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4450 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4451 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4452 f_establish_fully(ass_cmd, exp_compl);
4453}
4454
4455/* Allow FR and HR, but prefer HR */
4456private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4457 g_pars := f_gen_test_hdlr_pars();
4458 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4459 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4460 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4461 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4462 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4463 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4464 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4465 f_establish_fully(ass_cmd, exp_compl);
4466}
4467
4468/* Request a HR channel while all FR channels are exhausted, this is expected
4469 * to work without conflicts */
4470testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4471 var MSC_ConnHdlr vc_conn;
4472 f_init(1, true);
4473 f_sleep(1.0);
4474 f_enable_all_tch();
4475 f_disable_all_tch_f();
4476 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4477 vc_conn.done;
4478 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004479 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004480}
4481
4482/* Request a FR channel while all FR channels are exhausted, this is expected
4483 * to fail. */
4484testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4485 var MSC_ConnHdlr vc_conn;
4486 f_init(1, true);
4487 f_sleep(1.0);
4488 f_enable_all_tch();
4489 f_disable_all_tch_f();
4490 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4491 vc_conn.done;
4492 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004493 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004494}
4495
4496/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4497 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4498testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4499 var MSC_ConnHdlr vc_conn;
4500 f_init(1, true);
4501 f_sleep(1.0);
4502 f_enable_all_tch();
4503 f_disable_all_tch_f();
4504 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4505 vc_conn.done;
4506 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004507 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004508}
4509
4510/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4511 * are exhausted, this is expected to work without conflicts. */
4512testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4513 var MSC_ConnHdlr vc_conn;
4514 f_init(1, true);
4515 f_sleep(1.0);
4516 f_enable_all_tch();
4517 f_disable_all_tch_f();
4518 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4519 vc_conn.done;
4520 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004521 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004522}
4523
4524/* Request a FR channel while all HR channels are exhausted, this is expected
4525 * to work without conflicts */
4526testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4527 var MSC_ConnHdlr vc_conn;
4528 f_init(1, true);
4529 f_sleep(1.0);
4530 f_enable_all_tch();
4531 f_disable_all_tch_h();
4532 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4533 vc_conn.done;
4534 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004535 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004536}
4537
4538/* Request a HR channel while all HR channels are exhausted, this is expected
4539 * to fail. */
4540testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4541 var MSC_ConnHdlr vc_conn;
4542 f_init(1, true);
4543 f_sleep(1.0);
4544 f_enable_all_tch();
4545 f_disable_all_tch_h();
4546 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4547 vc_conn.done;
4548 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004549 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004550}
4551
4552/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4553 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4554testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4555 var MSC_ConnHdlr vc_conn;
4556 f_init(1, true);
4557 f_sleep(1.0);
4558 f_enable_all_tch();
4559 f_disable_all_tch_h();
4560 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4561 vc_conn.done;
4562 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004563 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004564}
4565
4566/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4567 * are exhausted, this is expected to work without conflicts. */
4568testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4569 var MSC_ConnHdlr vc_conn;
4570 f_init(1, true);
4571 f_sleep(1.0);
4572 f_enable_all_tch();
4573 f_disable_all_tch_h();
4574 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4575 vc_conn.done;
4576 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004577 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004578}
4579
4580/* Allow FR and HR, but prefer HR */
4581private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4582 g_pars := f_gen_test_hdlr_pars();
4583 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4584 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4585 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4586 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4587 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4588 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4589 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4590 f_establish_fully(ass_cmd, exp_compl);
4591}
4592
4593/* Allow FR and HR, but prefer FR */
4594private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4595 g_pars := f_gen_test_hdlr_pars();
4596 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4597 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4598 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4599 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4600 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4601 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4602 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4603 f_establish_fully(ass_cmd, exp_compl);
4604}
4605
4606/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4607 * HR, which is the prefered type, is selected. */
4608testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4609 var MSC_ConnHdlr vc_conn;
4610 f_init(1, true);
4611 f_sleep(1.0);
4612 f_enable_all_tch();
4613 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4614 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004615 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004616}
4617
4618/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4619 * FR, which is the prefered type, is selected. */
4620testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4621 var MSC_ConnHdlr vc_conn;
4622 f_init(1, true);
4623 f_sleep(1.0);
4624 f_enable_all_tch();
4625 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4626 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004627 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004628}
4629
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004630/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4631private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4632 g_pars := f_gen_test_hdlr_pars();
4633 g_pars.ra := '02'O; /* RA containing reason=LU */
4634
4635 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4636 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4637 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4638 var template uint3_t tsc := ?;
4639
4640 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4641 f_create_bssmap_exp(l3_enc);
4642 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4643 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4644
4645 /* we should now have a COMPL_L3 at the MSC */
4646 timer T := 10.0;
4647 T.start;
4648 alt {
4649 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4650 [] T.timeout {
4651 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4652 }
4653 }
4654}
4655testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4656 var MSC_ConnHdlr vc_conn;
4657 f_init(1, true);
4658 f_sleep(1.0);
4659 f_disable_all_sdcch();
4660 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4661 vc_conn.done;
4662 f_enable_all_sdcch();
4663 f_shutdown_helper();
4664}
4665
4666/* Request a signalling channel with all SDCCH exhausted, it is
4667 expected that no TCH will be selected for signalling and assigment will fail
4668 because it's dictated by VTY config */
4669testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4670 var RSL_Message rsl_unused, rsl_msg;
4671 var GsmRrMessage rr;
4672 f_init(1, false);
4673 f_sleep(1.0);
4674 f_vty_allow_tch_for_signalling(false, 0);
4675 f_disable_all_sdcch();
4676
4677 /* RA containing reason=LU */
4678 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4679 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4680 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4681 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4682 setverdict(fail, "Expected reject");
4683 }
4684
4685 f_vty_allow_tch_for_signalling(true, 0);
4686 f_enable_all_sdcch();
4687 f_shutdown_helper();
4688}
4689
4690/* Request a voice channel with all SDCCH exhausted, it is
4691 * expected that TCH channel will be allocated since the VTY option is only
4692 * aimed at signalling requests */
4693private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4694 g_pars := f_gen_test_hdlr_pars();
4695 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4696
4697 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4698 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4699 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4700 var template uint3_t tsc := ?;
4701
4702 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4703 f_create_bssmap_exp(l3_enc);
4704 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4705 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4706
4707 /* we should now have a COMPL_L3 at the MSC */
4708 timer T := 10.0;
4709 T.start;
4710 alt {
4711 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4712 [] T.timeout {
4713 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4714 }
4715 }
4716}
4717testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4718 var MSC_ConnHdlr vc_conn;
4719 f_init(1, true);
4720 f_sleep(1.0);
4721 f_vty_allow_tch_for_signalling(false, 0);
4722 f_disable_all_sdcch();
4723
4724 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4725 vc_conn.done;
4726
4727 f_vty_allow_tch_for_signalling(true, 0);
4728 f_enable_all_sdcch();
4729 f_shutdown_helper();
4730}
4731
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004732testcase TC_assignment_osmux() runs on test_CT {
4733 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4734 var MSC_ConnHdlr vc_conn;
4735
4736 /* See note above */
4737 var RSL_IE_Body mr_conf := {
4738 other := {
4739 len := 2,
4740 payload := '2804'O
4741 }
4742 };
4743
4744 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4745 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4746 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4747 pars.expect_mr_conf_ie := mr_conf;
4748 pars.use_osmux := true;
4749
4750 f_init(1, true, true);
4751 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004752 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004753
4754 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4755 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004756
4757 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004758 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004759}
4760
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004761/* test the procedure of the MSC requesting a Classmark Update:
4762 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4763 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004764private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004765 g_pars := f_gen_test_hdlr_pars();
4766
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
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004771 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4772 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4773
Harald Welte898113b2018-01-31 18:32:21 +01004774 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4775 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4776 setverdict(pass);
4777}
4778testcase TC_classmark() runs on test_CT {
4779 var MSC_ConnHdlr vc_conn;
4780 f_init(1, true);
4781 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004782 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004783 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004784 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004785}
4786
Harald Welteeddf0e92020-06-21 19:42:15 +02004787/* Send a CommonID from the simulated MSC and verify that the information is used to
4788 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4789private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4790 g_pars := f_gen_test_hdlr_pars();
4791 f_MscConnHdlr_init_vty();
4792
4793 f_create_chan_and_exp();
4794 /* we should now have a COMPL_L3 at the MSC */
4795 BSSAP.receive(tr_BSSMAP_ComplL3);
4796
4797 /* Send CommonID */
4798 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4799
4800 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4801 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4802 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4803
4804 setverdict(pass);
4805}
4806testcase TC_common_id() runs on test_CT {
4807 var MSC_ConnHdlr vc_conn;
4808 f_init(1, true);
4809 f_sleep(1.0);
4810 vc_conn := f_start_handler(refers(f_tc_common_id));
4811 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004812 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004813}
4814
Harald Weltee3bd6582018-01-31 22:51:25 +01004815private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004816 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004817 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004818 /* we should now have a COMPL_L3 at the MSC */
4819 BSSAP.receive(tr_BSSMAP_ComplL3);
4820
Harald Weltee3bd6582018-01-31 22:51:25 +01004821 /* send the single message we want to send */
4822 f_rsl_send_l3(l3);
4823}
4824
4825private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4826 timer T := sec;
4827 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004828 T.start;
4829 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004830 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4831 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004832 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004833 }
4834 [] T.timeout {
4835 setverdict(pass);
4836 }
4837 }
4838}
4839
Harald Weltee3bd6582018-01-31 22:51:25 +01004840/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4841private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4842 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4843 f_bssap_expect_nothing();
4844}
Harald Welte898113b2018-01-31 18:32:21 +01004845testcase TC_unsol_ass_fail() runs on test_CT {
4846 var MSC_ConnHdlr vc_conn;
4847 f_init(1, true);
4848 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004849 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004850 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004851 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004852}
Harald Welte552620d2017-12-16 23:21:36 +01004853
Harald Welteea99a002018-01-31 20:46:43 +01004854
4855/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4856private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004857 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4858 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004859}
4860testcase TC_unsol_ass_compl() runs on test_CT {
4861 var MSC_ConnHdlr vc_conn;
4862 f_init(1, true);
4863 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004864 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004865 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004866 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004867}
4868
4869
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004870/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4871private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004872 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4873 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004874}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004875testcase TC_unsol_ho_fail() runs on test_CT {
4876 var MSC_ConnHdlr vc_conn;
4877 f_init(1, true);
4878 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004879 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004880 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004881 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004882}
4883
4884
Harald Weltee3bd6582018-01-31 22:51:25 +01004885/* short message from MS should be ignored */
4886private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004887 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004888 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01004889 /* we should now have a COMPL_L3 at the MSC */
4890 BSSAP.receive(tr_BSSMAP_ComplL3);
4891
4892 /* send short message */
4893 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
4894 f_bssap_expect_nothing();
4895}
4896testcase TC_err_82_short_msg() runs on test_CT {
4897 var MSC_ConnHdlr vc_conn;
4898 f_init(1, true);
4899 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004900 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01004901 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004902 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01004903}
4904
4905
Harald Weltee9e02e42018-01-31 23:36:25 +01004906/* 24.008 8.4 Unknown message must trigger RR STATUS */
4907private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
4908 f_est_single_l3(ts_RRM_UL_REL('00'O));
4909 timer T := 3.0
4910 alt {
4911 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
4912 setverdict(pass);
4913 }
4914 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01004915 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01004916 }
4917}
4918testcase TC_err_84_unknown_msg() runs on test_CT {
4919 var MSC_ConnHdlr vc_conn;
4920 f_init(1, true);
4921 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004922 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01004923 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004924 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01004925}
4926
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004927/***********************************************************************
4928 * Handover
4929 ***********************************************************************/
4930
Harald Welte94e0c342018-04-07 11:33:23 +02004931/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
4932private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
4933runs on test_CT {
4934 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4935 " timeslot "&int2str(ts_nr)&" ";
4936 f_vty_transceive(BSCVTY, cmd & suffix);
4937}
4938
Harald Welte261af4b2018-02-12 21:20:39 +01004939/* 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 +07004940private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
4941 uint8_t bts_nr, uint8_t trx_nr,
4942 in RslChannelNr chan_nr)
4943{
Harald Welte261af4b2018-02-12 21:20:39 +01004944 /* FIXME: resolve those from component-global state */
4945 var integer ts_nr := chan_nr.tn;
4946 var integer ss_nr;
4947 if (ischosen(chan_nr.u.ch0)) {
4948 ss_nr := 0;
4949 } else if (ischosen(chan_nr.u.lm)) {
4950 ss_nr := chan_nr.u.lm.sub_chan;
4951 } else if (ischosen(chan_nr.u.sdcch4)) {
4952 ss_nr := chan_nr.u.sdcch4.sub_chan;
4953 } else if (ischosen(chan_nr.u.sdcch8)) {
4954 ss_nr := chan_nr.u.sdcch8.sub_chan;
4955 } else {
4956 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02004957 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01004958 }
4959
4960 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4961 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004962 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01004963}
4964
Neels Hofmeyr91401012019-07-11 00:42:35 +02004965/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
4966 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
4967 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
4968 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
4969 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004970private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
4971 in RslChannelNr chan_nr, uint8_t new_bts_nr)
4972{
4973 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01004974}
4975
4976/* intra-BSC hand-over between BTS0 and BTS1 */
4977private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004978 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4979 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01004980
4981 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4982 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4983
Harald Weltea0630032018-03-20 21:09:55 +01004984 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02004985 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01004986
4987 var HandoverState hs := {
4988 rr_ho_cmpl_seen := false,
4989 handover_done := false,
4990 old_chan_nr := -
4991 };
4992 /* issue hand-over command on VTY */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004993 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01004994 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
4995 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004996
4997 /* From the MGW perspective, a handover is is characterized by
4998 * performing one MDCX operation with the MGW. So we expect to see
4999 * one more MDCX during handover. */
5000 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5001
Harald Welte261af4b2018-02-12 21:20:39 +01005002 alt {
5003 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005004 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005005
Philipp Maier4dae0652018-11-12 12:03:26 +01005006 /* Since this is an internal handover we expect the BSC to inform the
5007 * MSC about the event */
5008 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5009
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005010 /* Check the amount of MGCP transactions is still consistant with the
5011 * test expectation */
5012 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005013
5014 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5015 * g_chan_nr to the new lchan that was handed over to. It lives in bts 1, so look it up at RSL1_PROC. */
5016 f_verify_encr_info(f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr));
5017
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005018 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005019}
5020
5021testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005022 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005023 var MSC_ConnHdlr vc_conn;
5024 f_init(2, true);
5025 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005026
5027 f_ctrs_bsc_and_bts_init();
5028
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005029 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005030 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005031
5032 /* from f_establish_fully() */
5033 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5034 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5035 /* from handover */
5036 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5037 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5038 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5039 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5040 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005041 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005042}
Harald Weltee9e02e42018-01-31 23:36:25 +01005043
Oliver Smith7eabd312021-07-12 14:18:56 +02005044function 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 +02005045 var MSC_ConnHdlr vc_conn;
5046 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5047 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5048
5049 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005050 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005051 f_sleep(1.0);
5052
5053 f_ctrs_bsc_and_bts_init();
5054
5055 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5056 vc_conn.done;
5057
5058 /* from f_establish_fully() */
5059 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5060 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5061 /* from handover */
5062 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5063 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5064 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5065 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5066 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005067 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005068 f_shutdown_helper();
5069}
5070
5071testcase TC_ho_int_a5_0() runs on test_CT {
5072 f_tc_ho_int_a5('01'O);
5073}
5074
5075testcase TC_ho_int_a5_1() runs on test_CT {
5076 f_tc_ho_int_a5('02'O);
5077}
5078
5079testcase TC_ho_int_a5_3() runs on test_CT {
5080 f_tc_ho_int_a5('08'O);
5081}
5082
5083testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005084 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005085}
5086
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005087/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5088private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5089 g_pars := f_gen_test_hdlr_pars();
5090 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5091 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005092
5093 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5094 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5095
5096 f_establish_fully(ass_cmd, exp_compl);
5097 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5098
5099 var HandoverState hs := {
5100 rr_ho_cmpl_seen := false,
5101 handover_done := false,
5102 old_chan_nr := -
5103 };
5104 /* issue hand-over command on VTY */
5105 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5106 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5107 f_rslem_suspend(RSL1_PROC);
5108
5109 /* From the MGW perspective, a handover is is characterized by
5110 * performing one MDCX operation with the MGW. So we expect to see
5111 * one more MDCX during handover. */
5112 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5113
5114 var RSL_Message rsl;
5115 var PDU_ML3_NW_MS l3;
5116 var RslChannelNr new_chan_nr;
5117 var GsmArfcn arfcn;
5118 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5119 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5120 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5121 setverdict(fail, "Expected handoverCommand");
5122 mtc.stop;
5123 }
5124 }
5125 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5126 new_chan_nr, arfcn);
5127
5128 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5129
5130 /* resume processing of RSL DChan messages, which was temporarily suspended
5131 * before performing a hand-over */
5132 f_rslem_resume(RSL1_PROC);
5133 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5134
5135 f_sleep(1.0);
5136
5137 /* Handover fails because no HANDO DET appears on the new lchan,
5138 * and the old lchan reports a Radio Link Failure. */
5139 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5140
5141 var PDU_BSSAP rx_clear_request;
5142 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5143 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5144 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5145
5146 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5147
5148 var MgcpCommand mgcp;
5149 interleave {
5150 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5151 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005152 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005153 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005154 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005155 }
5156 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005157 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005158 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005159 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005160 }
5161 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5162 }
5163
5164 f_sleep(0.5);
5165 setverdict(pass);
5166}
5167testcase TC_ho_int_radio_link_failure() runs on test_CT {
5168 var MSC_ConnHdlr vc_conn;
5169 f_init(2, true);
5170 f_sleep(1.0);
5171
5172 f_ctrs_bsc_and_bts_init();
5173
5174 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5175 vc_conn.done;
5176
5177 /* from f_establish_fully() */
5178 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5179 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5180 /* from handover */
5181 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5182 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5183 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5184 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
5185 f_ctrs_bsc_and_bts_verify();
5186 f_shutdown_helper();
5187}
5188
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005189/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005190private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005191 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005192 var template MgcpResponse mgcp_resp;
5193 var MGCP_RecvFrom mrf;
5194 var template MgcpMessage msg_resp;
5195 var template MgcpMessage msg_dlcx := {
5196 command := tr_DLCX()
5197 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005198
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005199 if (g_pars.aoip) {
5200 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005201 log("Got first DLCX: ", mgcp);
5202 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005203 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005204
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005205 MGCP.receive(tr_DLCX()) -> value mgcp {
5206 log("Got second DLCX: ", mgcp);
5207 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5208 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005209 } else {
5210 /* For SCCPLite, BSC doesn't handle the MSC-side */
5211 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5212 log("Got first DLCX: ", mrf.msg.command);
5213 msg_resp := {
5214 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5215 }
5216 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5217 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005218 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005219}
5220
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005221private 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 +01005222
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005223 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005224 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5225
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005226 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005227
5228 f_sleep(0.5);
5229 /* The MSC negotiates Handover Request and Handover Request Ack with
5230 * the other BSS and comes back with a BSSMAP Handover Command
5231 * containing an RR Handover Command coming from the target BSS... */
5232
5233 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5234 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5235 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5236 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5237 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5238
5239 /* expect the Handover Command to go out on RR */
5240 var RSL_Message rsl_ho_cmd
5241 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5242 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5243 var RSL_IE_Body rsl_ho_cmd_l3;
5244 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5245 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5246 setverdict(fail);
5247 } else {
5248 log("Found L3 Info: ", rsl_ho_cmd_l3);
5249 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5250 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5251 setverdict(fail);
5252 } else {
5253 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5254 setverdict(pass);
5255 }
5256 }
5257
5258 /* When the other BSS has reported a completed handover, this side is
5259 * torn down. */
5260
5261 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5262 var BssmapCause cause := enum2int(cause_val);
5263 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5264
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005265 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005266
5267 interleave {
5268 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5269 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5270 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005271 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005272 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005273 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005274}
5275
5276private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5277 g_pars := f_gen_test_hdlr_pars();
5278 var PDU_BSSAP ass_req := f_gen_ass_req();
5279 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5280 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5281 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5282 f_establish_fully(ass_req, exp_compl);
5283
5284 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005285}
5286testcase TC_ho_out_of_this_bsc() runs on test_CT {
5287 var MSC_ConnHdlr vc_conn;
5288
5289 f_init(1, true);
5290 f_sleep(1.0);
5291
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005292 f_ctrs_bsc_and_bts_init();
5293
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005294 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5295 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005296
5297 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5298 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5299 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5300 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5301 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5302 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5303 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005304 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005305}
5306
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005307private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5308 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005309 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005310 octetstring l3 := '0123456789'O)
5311runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005312 /* The old lchan and conn should still be active. See that arbitrary L3
5313 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005314 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005315 var template PDU_BSSAP exp_data := {
5316 discriminator := '1'B,
5317 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005318 dlci := dlci,
5319 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005320 pdu := {
5321 dtap := l3
5322 }
5323 };
5324 BSSAP.receive(exp_data);
5325 setverdict(pass);
5326}
5327
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005328private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5329 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005330 template (value) OCT1 dlci := '00'O,
5331 octetstring l3 := '0123456789'O)
5332runs on MSC_ConnHdlr {
5333 BSSAP.send(PDU_BSSAP:{
5334 discriminator := '1'B,
5335 spare := '0000000'B,
5336 dlci := dlci,
5337 lengthIndicator := lengthof(l3),
5338 pdu := {
5339 dtap := l3
5340 }
5341 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005342 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005343 setverdict(pass);
5344}
5345
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005346/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5347 * simply never sends a BSSMAP Handover Command. */
5348private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005349 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005350
5351 var PDU_BSSAP ass_req := f_gen_ass_req();
5352 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5353 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5354 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5355 f_establish_fully(ass_req, exp_compl);
5356
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005357 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005358 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5359
5360 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5361
5362 /* osmo-bsc should time out 10 seconds after the handover started.
5363 * Let's give it a bit extra. */
5364 f_sleep(15.0);
5365
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005366 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005367 f_sleep(1.0);
5368}
5369testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5370 var MSC_ConnHdlr vc_conn;
5371
5372 f_init(1, true);
5373 f_sleep(1.0);
5374
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005375 f_ctrs_bsc_and_bts_init();
5376
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005377 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5378 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005379
5380 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5381 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5382 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5383 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5384 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5385 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5386 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005387 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005388}
5389
5390/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5391 * RR Handover Failure. */
5392private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005393 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005394
5395 var PDU_BSSAP ass_req := f_gen_ass_req();
5396 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5397 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5398 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5399 f_establish_fully(ass_req, exp_compl);
5400
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005401 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005402 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5403
5404 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5405
5406 f_sleep(0.5);
5407 /* The MSC negotiates Handover Request and Handover Request Ack with
5408 * the other BSS and comes back with a BSSMAP Handover Command
5409 * containing an RR Handover Command coming from the target BSS... */
5410
5411 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5412 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5413 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5414 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5415 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5416
5417 /* expect the Handover Command to go out on RR */
5418 var RSL_Message rsl_ho_cmd
5419 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5420 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5421 var RSL_IE_Body rsl_ho_cmd_l3;
5422 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5423 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5424 setverdict(fail);
5425 } else {
5426 log("Found L3 Info: ", rsl_ho_cmd_l3);
5427 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5428 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5429 setverdict(fail);
5430 } else {
5431 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5432 setverdict(pass);
5433 }
5434 }
5435
5436 f_sleep(0.2);
5437 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5438
5439 /* Should tell the MSC about the failure */
5440 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5441
5442 f_sleep(1.0);
5443
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005444 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005445 f_sleep(1.0);
5446
5447 setverdict(pass);
5448 f_sleep(1.0);
5449}
5450testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5451 var MSC_ConnHdlr vc_conn;
5452
5453 f_init(1, true);
5454 f_sleep(1.0);
5455
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005456 f_ctrs_bsc_and_bts_init();
5457
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005458 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5459 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005460
5461 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5462 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5463 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5464 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5465 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5466 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5467 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005468 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005469}
5470
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005471/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5472 * (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 +02005473 * and the lchan is released. */
5474private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005475 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005476
5477 var PDU_BSSAP ass_req := f_gen_ass_req();
5478 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5479 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5480 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5481 f_establish_fully(ass_req, exp_compl);
5482
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005483 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005484 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5485
5486 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5487
5488 f_sleep(0.5);
5489 /* The MSC negotiates Handover Request and Handover Request Ack with
5490 * the other BSS and comes back with a BSSMAP Handover Command
5491 * containing an RR Handover Command coming from the target BSS... */
5492
5493 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5494 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5495 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5496 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5497 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5498
5499 /* expect the Handover Command to go out on RR */
5500 var RSL_Message rsl_ho_cmd
5501 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5502 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5503 var RSL_IE_Body rsl_ho_cmd_l3;
5504 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5505 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5506 setverdict(fail);
5507 } else {
5508 log("Found L3 Info: ", rsl_ho_cmd_l3);
5509 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5510 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5511 setverdict(fail);
5512 } else {
5513 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5514 setverdict(pass);
5515 }
5516 }
5517
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005518 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5519 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5520 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005521
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005522 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005523 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5524 log("Got BSSMAP Clear Request");
5525 /* Instruct BSC to clear channel */
5526 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5527 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5528
5529 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005530 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005531 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5532 log("Got Deact SACCH");
5533 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005534 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005535 log("Got RR Release");
5536 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005537 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005538 log("Got RF Chan Rel");
5539 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005540 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005541 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005542 }
5543
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005544 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005545 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005546
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005547 setverdict(pass);
5548 f_sleep(1.0);
5549}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005550testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005551 var MSC_ConnHdlr vc_conn;
5552
5553 f_init(1, true);
5554 f_sleep(1.0);
5555
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005556 f_ctrs_bsc_and_bts_init();
5557
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005558 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005559 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005560
5561 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5562 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5563 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5564 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5565 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5566 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5567 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005568 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005569}
5570
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005571private 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 +01005572 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5573 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5574 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5575 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5576 * before we get started. */
5577 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5578 f_rslem_register(0, new_chan_nr);
5579 g_chan_nr := new_chan_nr;
5580 f_sleep(1.0);
5581
5582 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5583 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5584 activate(as_Media());
5585
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005586 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005587 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005588 oldToNewBSSIEs := oldToNewBSSIEs,
5589 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005590 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005591
5592 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5593
5594 var PDU_BSSAP rx_bssap;
5595 var octetstring ho_command_str;
5596
5597 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005598
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005599 /* we're sure that the channel activation is done now, verify the encryption parameters in it */
5600 f_verify_encr_info(f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr));
5601
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005602 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5603 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5604 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5605 log("L3 Info in HO Request Ack is ", ho_command);
5606
5607 var GsmArfcn arfcn;
5608 var RslChannelNr actual_new_chan_nr;
5609 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5610 actual_new_chan_nr, arfcn);
5611
5612 if (actual_new_chan_nr != new_chan_nr) {
5613 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5614 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5615 setverdict(fail);
5616 return;
5617 }
5618 log("Handover Command chan_nr is", actual_new_chan_nr);
5619
5620 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5621 * tells the MS to handover to the new lchan. Here comes the new MS on
5622 * the new lchan with a Handover RACH: */
5623
5624 /* send handover detect */
5625
5626 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5627
5628 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5629
5630 /* send handover complete over the new channel */
5631
5632 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5633 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5634 enc_PDU_ML3_MS_NW(l3_tx)));
5635
5636 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005637 setverdict(pass);
5638}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005639
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005640private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005641 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005642 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5643 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5644 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005645 }
5646 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005647 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005648 } else {
5649 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005650 }
5651 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005652 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005653 setverdict(pass);
5654}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005655function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005656 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005657
5658 f_init(1, true);
5659 f_sleep(1.0);
5660
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005661 f_ctrs_bsc_and_bts_init();
5662
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005663 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5664 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005665
5666 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5667 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005668
5669 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5670 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5671 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5672 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5673 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005674}
5675
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005676testcase TC_ho_into_this_bsc() runs on test_CT {
5677 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5678 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005679 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005680}
5681
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005682function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5683 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5684 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5685 f_tc_ho_into_this_bsc_main(pars);
5686 f_shutdown_helper();
5687}
5688
5689testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5690 f_tc_ho_into_this_bsc_a5('01'O);
5691}
5692
5693testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5694 f_tc_ho_into_this_bsc_a5('02'O);
5695}
5696
5697testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5698 f_tc_ho_into_this_bsc_a5('08'O);
5699}
5700
5701testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5702 f_tc_ho_into_this_bsc_a5('10'O);
5703}
5704
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005705testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5706 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5707 pars.host_aoip_tla := "::6";
5708 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005709 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005710}
5711
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005712/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005713 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005714 channel is later released (RR CHannel Release), should trigger inclusion of
5715 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5716 neighbors. */
5717testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5718 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5719 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005720 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005721 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005722
5723 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5724 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5725 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005726 f_shutdown_helper();
5727}
5728
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005729/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5730 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5731 list when the channel is released. */
5732testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5733 f_init_vty();
5734 f_vty_allow_srvcc_fast_return(true, 0)
5735
5736 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5737 pars.last_used_eutran_plmn := '323454'O;
5738 pars.exp_fast_return := false;
5739 f_tc_ho_into_this_bsc_main(pars);
5740 f_vty_allow_srvcc_fast_return(false, 0);
5741 f_shutdown_helper();
5742}
5743
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005744private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5745 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5746 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5747 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5748 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5749 setverdict(pass);
5750}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005751
5752private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5753 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005754 var MSC_ConnHdlr vc_conn;
5755 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5756
5757 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005758 if (disable_fast_return) {
5759 f_vty_allow_srvcc_fast_return(true, 0);
5760 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005761 f_sleep(1.0);
5762
5763 f_ctrs_bsc_and_bts_init();
5764
5765 pars.last_used_eutran_plmn := '323454'O;
5766 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5767 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5768
5769 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5770 vc_conn.done;
5771
5772 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5773 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5774 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5775 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5776 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5777 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005778
5779 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5780 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005781 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005782
5783 if (disable_fast_return) {
5784 f_vty_allow_srvcc_fast_return(false, 0);
5785 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005786 f_shutdown_helper();
5787}
5788
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005789/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5790 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5791 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5792 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5793testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5794 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5795}
5796/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5797 * independently of fast-reture allowed/forbidden in local BTS */
5798testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5799 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5800}
5801
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005802private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5803 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5804 f_rslem_register(0, new_chan_nr);
5805 g_chan_nr := new_chan_nr;
5806 f_sleep(1.0);
5807
5808 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5809 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5810 activate(as_Media());
5811
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005812 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005813 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005814 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005815
5816 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5817
5818 var PDU_BSSAP rx_bssap;
5819 var octetstring ho_command_str;
5820
5821 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5822
5823 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5824 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5825 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5826 log("L3 Info in HO Request Ack is ", ho_command);
5827
5828 var GsmArfcn arfcn;
5829 var RslChannelNr actual_new_chan_nr;
5830 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5831 actual_new_chan_nr, arfcn);
5832
5833 if (actual_new_chan_nr != new_chan_nr) {
5834 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5835 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5836 setverdict(fail);
5837 return;
5838 }
5839 log("Handover Command chan_nr is", actual_new_chan_nr);
5840
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005841 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5842 f_sleep(1.0);
5843
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005844 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5845 * tells the MS to handover to the new lchan. In this case, the MS
5846 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5847 * Handover Failure to the MSC. The procedure according to 3GPP TS
5848 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5849 * BSSMAP Clear Command: */
5850
5851 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5852 var BssmapCause cause := enum2int(cause_val);
5853 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5854
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005855 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005856 BSSAP.receive(tr_BSSMAP_ClearComplete);
5857
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005858 setverdict(pass);
5859 f_sleep(1.0);
5860
5861 setverdict(pass);
5862}
5863testcase TC_ho_in_fail_msc_clears() runs on test_CT {
5864 var MSC_ConnHdlr vc_conn;
5865 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5866
5867 f_init(1, true);
5868 f_sleep(1.0);
5869
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005870 f_ctrs_bsc_and_bts_init();
5871
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005872 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5873 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005874
5875 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
5876 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005877
5878 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5879 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5880 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5881 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5882 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005883 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005884}
5885
5886private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
5887 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5888 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5889 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5890 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5891 * before we get started. */
5892 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5893 f_rslem_register(0, new_chan_nr);
5894 g_chan_nr := new_chan_nr;
5895 f_sleep(1.0);
5896
5897 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5898 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5899 activate(as_Media());
5900
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005901 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005902 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005903 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005904
5905 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5906
5907 var PDU_BSSAP rx_bssap;
5908 var octetstring ho_command_str;
5909
5910 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5911
5912 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5913 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5914 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5915 log("L3 Info in HO Request Ack is ", ho_command);
5916
5917 var GsmArfcn arfcn;
5918 var RslChannelNr actual_new_chan_nr;
5919 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5920 actual_new_chan_nr, arfcn);
5921
5922 if (actual_new_chan_nr != new_chan_nr) {
5923 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5924 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5925 setverdict(fail);
5926 return;
5927 }
5928 log("Handover Command chan_nr is", actual_new_chan_nr);
5929
5930 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5931 * tells the MS to handover to the new lchan. Here comes the new MS on
5932 * the new lchan with a Handover RACH: */
5933
5934 /* send handover detect */
5935
5936 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5937
5938 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5939
5940 /* The MSC chooses to clear the connection now, maybe we got the
5941 * Handover RACH on the new cell but the MS still signaled Handover
5942 * Failure to the old BSS? */
5943
5944 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5945 var BssmapCause cause := enum2int(cause_val);
5946 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5947
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005948 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005949 BSSAP.receive(tr_BSSMAP_ClearComplete);
5950
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005951 f_sleep(1.0);
5952}
5953testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
5954 var MSC_ConnHdlr vc_conn;
5955 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5956
5957 f_init(1, true);
5958 f_sleep(1.0);
5959
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005960 f_ctrs_bsc_and_bts_init();
5961
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005962 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5963 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005964
5965 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
5966 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005967
5968 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5969 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5970 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5971 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5972 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005973 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005974}
5975
5976/* The new BSS's lchan times out before the MSC decides that handover failed. */
5977private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
5978 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5979 f_rslem_register(0, new_chan_nr);
5980 g_chan_nr := new_chan_nr;
5981 f_sleep(1.0);
5982
5983 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5984 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5985 activate(as_Media());
5986
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005987 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005988 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005989 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005990
5991 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5992
5993 var PDU_BSSAP rx_bssap;
5994 var octetstring ho_command_str;
5995
5996 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5997
5998 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5999 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6000 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6001 log("L3 Info in HO Request Ack is ", ho_command);
6002
6003 var GsmArfcn arfcn;
6004 var RslChannelNr actual_new_chan_nr;
6005 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6006 actual_new_chan_nr, arfcn);
6007
6008 if (actual_new_chan_nr != new_chan_nr) {
6009 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6010 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6011 setverdict(fail);
6012 return;
6013 }
6014 log("Handover Command chan_nr is", actual_new_chan_nr);
6015
6016 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6017 * tells the MS to handover to the new lchan. But the MS never shows up
6018 * on the new lchan. */
6019
6020 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6021
6022 /* Did osmo-bsc also send a Clear Request? */
6023 timer T := 0.5;
6024 T.start;
6025 alt {
6026 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6027 [] T.timeout { }
6028 }
6029
6030 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6031 * asked for it, this is a Handover Failure after all). */
6032
6033 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6034 var BssmapCause cause := enum2int(cause_val);
6035 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6036
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006037 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006038 BSSAP.receive(tr_BSSMAP_ClearComplete);
6039
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006040 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006041}
6042testcase TC_ho_in_fail_no_detect() runs on test_CT {
6043 var MSC_ConnHdlr vc_conn;
6044 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6045
6046 f_init(1, true);
6047 f_sleep(1.0);
6048
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006049 f_ctrs_bsc_and_bts_init();
6050
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006051 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6052 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006053
6054 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6055 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006056
6057 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6058 f_ctrs_bsc_and_bts_add(0, "handover:error");
6059 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6060 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6061 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006062 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006063}
6064
6065/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6066private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6067 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6068 f_rslem_register(0, new_chan_nr);
6069 g_chan_nr := new_chan_nr;
6070 f_sleep(1.0);
6071
6072 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6073 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6074 activate(as_Media());
6075
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006076 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006077 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006078 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006079
6080 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6081
6082 var PDU_BSSAP rx_bssap;
6083 var octetstring ho_command_str;
6084
6085 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6086
6087 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6088 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6089 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6090 log("L3 Info in HO Request Ack is ", ho_command);
6091
6092 var GsmArfcn arfcn;
6093 var RslChannelNr actual_new_chan_nr;
6094 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6095 actual_new_chan_nr, arfcn);
6096
6097 if (actual_new_chan_nr != new_chan_nr) {
6098 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6099 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6100 setverdict(fail);
6101 return;
6102 }
6103 log("Handover Command chan_nr is", actual_new_chan_nr);
6104
6105 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6106 * tells the MS to handover to the new lchan. But the MS never shows up
6107 * on the new lchan. */
6108
6109 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6110
6111 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006112 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006113
6114 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006115 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6116 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6117 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006118 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006119 BSSAP.receive(tr_BSSMAP_ClearComplete);
6120
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006121 f_sleep(1.0);
6122}
6123testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6124 var MSC_ConnHdlr vc_conn;
6125 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6126
6127 f_init(1, true);
6128 f_sleep(1.0);
6129
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006130 f_ctrs_bsc_and_bts_init();
6131
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006132 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6133 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006134
6135 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6136 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006137
6138 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6139 f_ctrs_bsc_and_bts_add(0, "handover:error");
6140 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6141 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6142 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006143 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006144}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006145
Neels Hofmeyr91401012019-07-11 00:42:35 +02006146type record of charstring Commands;
6147
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006148private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006149{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006150 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006151 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006152 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006153 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006154 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006155}
6156
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006157private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6158{
6159 f_vty_enter_cfg_cs7_inst(pt, 0);
6160 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6161 f_vty_transceive(pt, cmds[i]);
6162 }
6163 f_vty_transceive(pt, "end");
6164}
6165
Neels Hofmeyr91401012019-07-11 00:42:35 +02006166private function f_probe_for_handover(charstring log_label,
6167 charstring log_descr,
6168 charstring handover_vty_cmd,
6169 boolean expect_handover,
6170 boolean is_inter_bsc_handover := false)
6171runs on MSC_ConnHdlr
6172{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006173 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6174 * lchans to be established on bts 1 or bts 2. */
6175 f_rslem_suspend(RSL1_PROC);
6176 f_rslem_suspend(RSL2_PROC);
6177
Neels Hofmeyr91401012019-07-11 00:42:35 +02006178 var RSL_Message rsl;
6179
6180 var charstring log_msg := " (expecting handover)"
6181 if (not expect_handover) {
6182 log_msg := " (expecting NO handover)";
6183 }
6184 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6185 f_vty_transceive(BSCVTY, handover_vty_cmd);
6186
Neels Hofmeyr91401012019-07-11 00:42:35 +02006187 timer T := 2.0;
6188 T.start;
6189
6190 alt {
6191 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6192 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6193 log("Rx L3 from net: ", l3);
6194 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6195 var RslChannelNr new_chan_nr;
6196 var GsmArfcn arfcn;
6197 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6198 new_chan_nr, arfcn);
6199 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6200 log(l3.msgs.rrm.handoverCommand);
6201
6202 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6203 * matter on which BTS it really is, we're not going to follow through an entire handover
6204 * anyway. */
6205 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6206 f_rslem_resume(RSL1_PROC);
6207 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6208 f_rslem_resume(RSL2_PROC);
6209
6210 if (expect_handover and not is_inter_bsc_handover) {
6211 setverdict(pass);
6212 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6213 } else {
6214 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6215 & log_label & ": " & log_descr);
6216 }
6217
6218 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6219 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6220 * Handover Failure. */
6221 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6222
6223 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6224 f_sleep(0.5);
6225 RSL1.clear;
6226 RSL2.clear;
6227 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6228 break;
6229 } else {
6230 repeat;
6231 }
6232 }
6233 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6234 if (expect_handover and is_inter_bsc_handover) {
6235 setverdict(pass);
6236 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6237 } else {
6238 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6239 & log_label & ": " & log_descr);
6240 }
6241
6242 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6243
6244 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6245 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6246 * setting a short timeout and waiting is the only way. */
6247 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6248 f_sleep(1.5);
6249 log("f_probe_for_handover(" & log_label & "): ...done");
6250
6251 break;
6252 }
6253 [] T.timeout {
6254 if (expect_handover) {
6255 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6256 & log_label & ": " & log_descr);
6257 } else {
6258 setverdict(pass);
6259 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6260 }
6261 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6262 break;
6263 }
6264 }
6265
6266 f_rslem_resume(RSL1_PROC);
6267 f_rslem_resume(RSL2_PROC);
6268 f_sleep(3.0);
6269 RSL.clear;
6270
6271 log("f_probe_for_handover(" & log_label & "): done clearing");
6272}
6273
6274/* Test the effect of various neighbor configuration scenarios:
6275 *
6276 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6277 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6278 */
6279private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6280 g_pars := f_gen_test_hdlr_pars();
6281 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6282 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006283
6284 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6285 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6286
6287 /* Establish lchan at bts 0 */
6288 f_establish_fully(ass_cmd, exp_compl);
6289
6290 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6291 f_vty_enter_cfg_network(BSCVTY);
6292 f_vty_transceive(BSCVTY, "timer T7 1");
6293 f_vty_transceive(BSCVTY, "end");
6294}
6295
6296private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6297 f_tc_ho_neighbor_config_start();
6298
6299 /*
6300 * bts 0 ARFCN 871 BSIC 10
6301 * bts 1 ARFCN 871 BSIC 11
6302 * bts 2 ARFCN 871 BSIC 12
6303 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6304 */
6305
6306 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006307 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006308 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6309 "handover any to arfcn 871 bsic 11",
6310 true);
6311
6312 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6313 "handover any to arfcn 13 bsic 39",
6314 false);
6315
6316 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6317 "handover any to arfcn 871 bsic 12",
6318 false);
6319
6320 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6321 "handover any to arfcn 871 bsic 11",
6322 true);
6323}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006324testcase TC_ho_neighbor_config_1() runs on test_CT {
6325 var MSC_ConnHdlr vc_conn;
6326 f_init(3, true, guard_timeout := 60.0);
6327 f_sleep(1.0);
6328 f_ctrs_bsc_and_bts_init();
6329 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6330 vc_conn.done;
6331
6332 /* f_tc_ho_neighbor_config_start() */
6333 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6334 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6335
6336 /* 1.a */
6337 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6338 * handover quickly by sending a Handover Failure message. */
6339 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6340 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6341 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6342 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6343
6344 /* 1.b */
6345 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6346 f_ctrs_bsc_and_bts_add(0, "handover:error");
6347
6348 /* 1.c */
6349 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6350 f_ctrs_bsc_and_bts_add(0, "handover:error");
6351
6352 /* 1.d */
6353 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6354 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6355 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6356 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
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_2(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: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006373 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006374 f_sleep(0.5);
6375
6376 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6377 "handover any to arfcn 871 bsic 11",
6378 true);
6379
6380 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6381 "handover any to arfcn 871 bsic 12",
6382 false);
6383}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006384testcase TC_ho_neighbor_config_2() runs on test_CT {
6385 var MSC_ConnHdlr vc_conn;
6386 f_init(3, true, guard_timeout := 50.0);
6387 f_sleep(1.0);
6388 f_ctrs_bsc_and_bts_init();
6389 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6390 vc_conn.done;
6391
6392 /* f_tc_ho_neighbor_config_start() */
6393 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6394 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6395
6396 /* 2.a */
6397 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6398 * handover quickly by sending a Handover Failure message. */
6399 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6400 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6401 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6402 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6403
6404 /* 2.b */
6405 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6406 f_ctrs_bsc_and_bts_add(0, "handover:error");
6407
6408 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006409 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006410}
6411
Neels Hofmeyr91401012019-07-11 00:42:35 +02006412private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6413 f_tc_ho_neighbor_config_start();
6414
6415 /*
6416 * bts 0 ARFCN 871 BSIC 10
6417 * bts 1 ARFCN 871 BSIC 11
6418 * bts 2 ARFCN 871 BSIC 12
6419 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6420 */
6421
6422 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006423 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006424 f_sleep(0.5);
6425
6426 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6427 "handover any to arfcn 871 bsic 11",
6428 false);
6429 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",
6430 "handover any to arfcn 871 bsic 12",
6431 true);
6432}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006433testcase TC_ho_neighbor_config_3() runs on test_CT {
6434 var MSC_ConnHdlr vc_conn;
6435 f_init(3, true, guard_timeout := 50.0);
6436 f_sleep(1.0);
6437 f_ctrs_bsc_and_bts_init();
6438 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6439 vc_conn.done;
6440
6441 /* f_tc_ho_neighbor_config_start() */
6442 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6443 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6444
6445 /* 3.a */
6446 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6447 f_ctrs_bsc_and_bts_add(0, "handover:error");
6448
6449 /* 3.b */
6450 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6451 * handover quickly by sending a Handover Failure message. */
6452 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6453 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6454 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6455 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6456
6457 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006458 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006459}
6460
Neels Hofmeyr91401012019-07-11 00:42:35 +02006461private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6462 f_tc_ho_neighbor_config_start();
6463
6464 /*
6465 * bts 0 ARFCN 871 BSIC 10
6466 * bts 1 ARFCN 871 BSIC 11
6467 * bts 2 ARFCN 871 BSIC 12
6468 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6469 */
6470
6471 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006472 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006473 f_sleep(0.5);
6474
6475 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6476 "handover any to arfcn 871 bsic 11",
6477 false);
6478 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6479 "handover any to arfcn 871 bsic 12",
6480 false);
6481 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6482 "handover any to arfcn 123 bsic 45",
6483 true, true);
6484}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006485testcase TC_ho_neighbor_config_4() runs on test_CT {
6486 var MSC_ConnHdlr vc_conn;
6487 f_init(3, true, guard_timeout := 50.0);
6488 f_sleep(1.0);
6489 f_ctrs_bsc_and_bts_init();
6490 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
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 /* 4.a */
6498 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6499 f_ctrs_bsc_and_bts_add(0, "handover:error");
6500
6501 /* 4.b */
6502 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6503 f_ctrs_bsc_and_bts_add(0, "handover:error");
6504
6505 /* 4.c */
6506 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6507 * handover quickly by timing out after the Handover Required message */
6508 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6509 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6510 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6511 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6512
6513 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006514 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006515}
6516
Neels Hofmeyr91401012019-07-11 00:42:35 +02006517private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6518 f_tc_ho_neighbor_config_start();
6519
6520 /*
6521 * bts 0 ARFCN 871 BSIC 10
6522 * bts 1 ARFCN 871 BSIC 11
6523 * bts 2 ARFCN 871 BSIC 12
6524 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6525 */
6526
6527 log("f_tc_ho_neighbor_config: 5. explicit remote neighbor re-using ARFCN+BSIC: 'neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006528 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006529 f_sleep(0.5);
6530
6531 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6532 "handover any to arfcn 871 bsic 12",
6533 true, true);
6534}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006535testcase TC_ho_neighbor_config_5() runs on test_CT {
6536 var MSC_ConnHdlr vc_conn;
6537 f_init(3, true);
6538 f_sleep(1.0);
6539 f_ctrs_bsc_and_bts_init();
6540 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6541 vc_conn.done;
6542
6543 /* f_tc_ho_neighbor_config_start() */
6544 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6545 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6546
6547 /* 5 */
6548 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6549 * handover quickly by timing out after the Handover Required message */
6550 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6551 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6552 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6553 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6554
6555 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006556 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006557}
6558
Neels Hofmeyr91401012019-07-11 00:42:35 +02006559private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6560 f_tc_ho_neighbor_config_start();
6561
6562 /*
6563 * bts 0 ARFCN 871 BSIC 10
6564 * bts 1 ARFCN 871 BSIC 11
6565 * bts 2 ARFCN 871 BSIC 12
6566 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6567 */
6568
6569 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6570 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006571 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006572 f_sleep(0.5);
6573
6574 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6575 "handover any to arfcn 871 bsic 12",
6576 false);
6577}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006578testcase TC_ho_neighbor_config_6() runs on test_CT {
6579 var MSC_ConnHdlr vc_conn;
6580 f_init(3, true);
6581 f_sleep(1.0);
6582 f_ctrs_bsc_and_bts_init();
6583 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6584 vc_conn.done;
6585
6586 /* f_tc_ho_neighbor_config_start() */
6587 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6588 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6589
6590 /* 6.a */
6591 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6592 * handover quickly by timing out after the Handover Required message */
6593 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6594 f_ctrs_bsc_and_bts_add(0, "handover:error");
6595
6596 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006597 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006598}
6599
Neels Hofmeyr91401012019-07-11 00:42:35 +02006600private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6601 f_tc_ho_neighbor_config_start();
6602
6603 /*
6604 * bts 0 ARFCN 871 BSIC 10
6605 * bts 1 ARFCN 871 BSIC 11
6606 * bts 2 ARFCN 871 BSIC 12
6607 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6608 */
6609
6610 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6611 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006612 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006613 f_sleep(0.5);
6614
6615 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6616 "handover any to arfcn 871 bsic 12",
6617 true);
6618 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6619 "handover any to arfcn 123 bsic 45",
6620 true, true);
6621}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006622testcase TC_ho_neighbor_config_7() runs on test_CT {
6623 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006624 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006625 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006626 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006627 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6628 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006629
6630 /* f_tc_ho_neighbor_config_start() */
6631 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6632 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6633
6634 /* 7.a */
6635 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6636 * handover quickly by sending a Handover Failure message. */
6637 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6638 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6639 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6640 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6641
6642 /* 7.b */
6643 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6644 * handover quickly by timing out after the Handover Required message */
6645 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6646 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6647 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6648 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6649
6650 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006651 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006652}
6653
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006654/* OS#3041: Open and close N connections in a normal fashion, and expect no
6655 * BSSMAP Reset just because of that. */
6656testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6657 var default d;
6658 var integer i;
6659 var DchanTuple dt;
6660
6661 f_init();
6662
6663 /* Wait for initial BSSMAP Reset to pass */
6664 f_sleep(4.0);
6665
6666 d := activate(no_bssmap_reset());
6667
6668 /* Setup up a number of connections and RLSD them again from the MSC
6669 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6670 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006671 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006672 /* Since we're doing a lot of runs, give each one a fresh
6673 * T_guard from the top. */
6674 T_guard.start;
6675
6676 /* Setup a BSSAP connection and clear it right away. This is
6677 * the MSC telling the BSC about a planned release, it's not an
6678 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006679 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006680
6681 /* MSC disconnects (RLSD). */
6682 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6683 }
6684
6685 /* In the buggy behavior, a timeout of 2 seconds happens between above
6686 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6687 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6688 f_sleep(4.0);
6689
6690 deactivate(d);
6691 f_shutdown_helper();
6692}
Harald Welte552620d2017-12-16 23:21:36 +01006693
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006694/* OS#3041: Open and close N connections in a normal fashion, and expect no
6695 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6696 * the MSC. */
6697testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6698 var default d;
6699 var integer i;
6700 var DchanTuple dt;
6701 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006702 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6703 var BssmapCause cause := enum2int(cause_val);
6704
6705 f_init();
6706
6707 /* Wait for initial BSSMAP Reset to pass */
6708 f_sleep(4.0);
6709
6710 d := activate(no_bssmap_reset());
6711
6712 /* Setup up a number of connections and RLSD them again from the MSC
6713 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6714 * Let's do it some more times for good measure. */
6715 for (i := 0; i < 8; i := i+1) {
6716 /* Since we're doing a lot of runs, give each one a fresh
6717 * T_guard from the top. */
6718 T_guard.start;
6719
6720 /* Setup a BSSAP connection and clear it right away. This is
6721 * the MSC telling the BSC about a planned release, it's not an
6722 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006723 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006724
6725 /* Instruct BSC to clear channel */
6726 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6727
6728 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006729 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006730 }
6731
6732 /* In the buggy behavior, a timeout of 2 seconds happens between above
6733 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6734 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6735 f_sleep(4.0);
6736
6737 deactivate(d);
6738 f_shutdown_helper();
6739}
6740
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006741/* OS#3041: Open and close N connections in a normal fashion, and expect no
6742 * BSSMAP Reset just because of that. Close connections from the MS side with a
6743 * Release Ind on RSL. */
6744testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6745 var default d;
6746 var integer i;
6747 var DchanTuple dt;
6748 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006749 var integer j;
6750
6751 f_init();
6752
6753 /* Wait for initial BSSMAP Reset to pass */
6754 f_sleep(4.0);
6755
6756 d := activate(no_bssmap_reset());
6757
6758 /* Setup up a number of connections and RLSD them again from the MSC
6759 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6760 * Let's do it some more times for good measure. */
6761 for (i := 0; i < 8; i := i+1) {
6762 /* Since we're doing a lot of runs, give each one a fresh
6763 * T_guard from the top. */
6764 T_guard.start;
6765
6766 /* Setup a BSSAP connection and clear it right away. This is
6767 * the MSC telling the BSC about a planned release, it's not an
6768 * erratic loss of a connection. */
6769 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6770
6771 /* simulate RLL REL IND */
6772 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6773
6774 /* expect Clear Request on MSC side */
6775 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6776
6777 /* Instruct BSC to clear channel */
6778 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6779 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6780
6781 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006782 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006783 }
6784
6785 /* In the buggy behavior, a timeout of 2 seconds happens between above
6786 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6787 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6788 f_sleep(4.0);
6789
6790 deactivate(d);
6791 f_shutdown_helper();
6792}
6793
Harald Welte94e0c342018-04-07 11:33:23 +02006794/***********************************************************************
6795 * IPA style dynamic PDCH
6796 ***********************************************************************/
6797
6798private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6799 template (omit) RSL_Cause nack := omit)
6800runs on test_CT {
6801 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6802 var RSL_Message rsl_unused;
6803 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6804 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6805 /* expect the BSC to issue the related RSL command */
6806 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6807 if (istemplatekind(nack, "omit")) {
6808 /* respond with a related acknowledgement */
6809 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6810 } else {
6811 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6812 }
6813}
6814
6815private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6816 template (omit) RSL_Cause nack := omit)
6817runs on test_CT {
6818 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6819 var RSL_Message rsl_unused;
6820 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6821 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6822 /* expect the BSC to issue the related RSL command */
6823 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6824 if (istemplatekind(nack, "omit")) {
6825 /* respond with a related acknowledgement */
6826 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6827 } else {
6828 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6829 }
6830}
6831
6832private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6833runs on test_CT return charstring {
6834 var charstring cmd, resp;
6835 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006836 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006837}
6838
6839private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6840 template charstring exp)
6841runs on test_CT {
6842 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
6843 if (not match(mode, exp)) {
6844 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02006845 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02006846 }
6847}
6848
6849private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
6850runs on test_CT {
6851 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
6852 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
6853 f_vty_transceive(BSCVTY, "end");
6854}
6855
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02006856
6857private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
6858 var integer i;
6859 for (i := 0; i < 8; i := i + 1) {
6860 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
6861 }
6862}
6863
Harald Welte94e0c342018-04-07 11:33:23 +02006864private const charstring TCHF_MODE := "TCH/F mode";
6865private const charstring TCHH_MODE := "TCH/H mode";
6866private const charstring PDCH_MODE := "PDCH mode";
6867private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02006868private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02006869
6870/* Test IPA PDCH activation / deactivation triggered by VTY */
6871testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
6872 var RSL_Message rsl_unused;
6873
6874 /* change Timeslot 6 before f_init() starts RSL */
6875 f_init_vty();
6876 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6877 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6878
6879 f_init(1, false);
6880 f_sleep(1.0);
6881
6882 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6883
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006884 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006885 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6886 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6887 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6888 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6889 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006890 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006891 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6892
6893 /* De-activate it via VTY */
6894 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6895 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006896 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006897 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6898
6899 /* re-activate it via VTY */
6900 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
6901 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006902 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006903 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6904
6905 /* and finally de-activate it again */
6906 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6907 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006908 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006909 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6910
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006911 /* clean up config */
6912 f_ts_set_chcomb(0, 0, 6, "PDCH");
6913
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006914 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006915}
6916
6917/* Test IPA PDCH activation NACK */
6918testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
6919 var RSL_Message rsl_unused;
6920
6921 /* change Timeslot 6 before f_init() starts RSL */
6922 f_init_vty();
6923 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6924 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6925
6926 f_init(1, false);
6927 f_sleep(1.0);
6928
6929 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6930
6931 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6932 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6933 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6934 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6935 f_sleep(1.0);
6936 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6937
6938 /* De-activate it via VTY */
6939 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6940 f_sleep(1.0);
6941 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6942
6943 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
6944 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
6945 f_sleep(1.0);
6946 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6947
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006948 /* clean up config */
6949 f_ts_set_chcomb(0, 0, 6, "PDCH");
6950
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006951 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006952}
6953
6954
6955/***********************************************************************
6956 * Osmocom style dynamic PDCH
6957 ***********************************************************************/
6958
6959private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6960 template (omit) RSL_Cause nack := omit)
6961runs on test_CT {
6962 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6963 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02006964 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02006965 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6966 /* expect the BSC to issue the related RSL command */
6967 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
6968 if (istemplatekind(nack, "omit")) {
6969 /* respond with a related acknowledgement */
6970 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
6971 } else {
6972 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
6973 }
6974}
6975
6976private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6977 template (omit) RSL_Cause nack := omit)
6978runs on test_CT {
6979 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6980 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02006981 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02006982 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6983 /* expect the BSC to issue the related RSL command */
6984 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
6985 if (istemplatekind(nack, "omit")) {
6986 /* respond with a related acknowledgement */
6987 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
6988 } else {
6989 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
6990 }
6991}
6992
6993/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
6994testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
6995 var RSL_Message rsl_unused;
6996
6997 /* change Timeslot 6 before f_init() starts RSL */
6998 f_init_vty();
6999 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7000 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7001
7002 f_init(1, false);
7003 f_sleep(1.0);
7004
7005 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7006
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007007 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007008 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7009 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7010 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7011
7012 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7013 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007014 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 +02007015 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7016
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007017 /* clean up config */
7018 f_ts_set_chcomb(0, 0, 6, "PDCH");
7019
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007020 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007021}
7022
7023/* Test Osmocom dyn PDCH activation NACK behavior */
7024testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7025 var RSL_Message rsl_unused;
7026
7027 /* change Timeslot 6 before f_init() starts RSL */
7028 f_init_vty();
7029 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7030 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7031
7032 f_init(1, false);
7033 f_sleep(1.0);
7034
7035 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7036
7037 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7038 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7039 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7040
7041 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7042 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7043 f_sleep(1.0);
7044 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7045
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007046 /* clean up config */
7047 f_ts_set_chcomb(0, 0, 6, "PDCH");
7048
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007049 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007050}
7051
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007052/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7053testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7054 var RSL_Message rsl_unused, rsl_msg;
7055 var DchanTuple dt;
7056 var BSSAP_N_CONNECT_ind rx_c_ind;
7057
7058 /* change Timeslot 6 before f_init() starts RSL */
7059 f_init_vty();
7060 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7061 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7062
7063 f_init(1, false);
7064 f_sleep(1.0);
7065
7066 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7067
7068 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7069 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7070 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7071 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7072
7073 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7074 f_sleep(1.0);
7075 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7076 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7077
7078 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7079 * on CCCH+SDCCH4+CBCH) */
7080 var integer i;
7081 for (i := 0; i < 3; i := i + 1) {
7082 dt := f_est_dchan('23'O, i, '00010203040506'O);
7083 }
7084
7085 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7086 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7087 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7088 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7089
7090 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7091 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7092
7093 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7094 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7095 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7096 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7097
7098 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7099 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7100 dt.sccp_conn_id := rx_c_ind.connectionId;
7101 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7102
7103 /* Instruct BSC to clear channel */
7104 var BssmapCause cause := 0;
7105 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7106 f_exp_chan_rel_and_clear(dt, 0);
7107
7108 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7109 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7110 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7111 f_sleep(1.0);
7112 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7113
7114 /* clean up config */
7115 f_ts_set_chcomb(0, 0, 6, "PDCH");
7116
7117 f_shutdown_helper();
7118}
7119
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007120/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7121 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7122 it as TCH directly instead. SYS#5309. */
7123testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7124 var RSL_Message rsl_unused, rsl_msg;
7125 var DchanTuple dt;
7126 var BSSAP_N_CONNECT_ind rx_c_ind;
7127 var integer i;
7128
7129 /* change Timeslot 6 before f_init() starts RSL */
7130 f_init_vty();
7131 for (i := 1; i < 8; i := i + 1) {
7132 if (i == 6) {
7133 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7134 } else {
7135 f_ts_set_chcomb(0, 0, i, "PDCH");
7136 }
7137 }
7138 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7139
7140 f_init(1, false);
7141 f_sleep(1.0);
7142
7143 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7144
7145 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7146 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7147 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7148 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7149
7150 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7151 f_sleep(1.0);
7152 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7153 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7154
7155 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7156 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007157 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007158 for (i := 0; i < 3; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007159 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007160 }
7161
7162 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007163 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007164 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7165 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7166
7167 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7168 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7169
7170 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7171 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7172 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7173 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7174
7175 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7176 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7177 dt.sccp_conn_id := rx_c_ind.connectionId;
7178 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7179
7180 /* Instruct BSC to clear channel */
7181 var BssmapCause cause := 0;
7182 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7183 f_exp_chan_rel_and_clear(dt, 0);
7184
7185 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7186 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7187 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7188 f_sleep(1.0);
7189 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7190
7191 /* clean up config */
7192 f_ts_reset_chcomb(0);
7193 /* TODO: clean up other channels? */
7194
7195 f_shutdown_helper();
7196}
7197
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007198/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7199testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7200 var RSL_Message rsl_unused, rsl_msg;
7201 var DchanTuple dt;
7202 var BSSAP_N_CONNECT_ind rx_c_ind;
7203 var GsmRrMessage rr;
7204
7205 /* change Timeslot 6 before f_init() starts RSL */
7206 f_init_vty();
7207 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7208 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7209
7210 f_init(1, false);
7211 f_sleep(1.0);
7212
7213 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7214
7215 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7216 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7217 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7218 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7219
7220 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7221 f_sleep(1.0);
7222 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7223 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7224
7225 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7226 * on CCCH+SDCCH4+CBCH) */
7227 var integer i;
7228 for (i := 0; i < 3; i := i + 1) {
7229 dt := f_est_dchan('23'O, i, '00010203040506'O);
7230 }
7231
7232 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7233 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7234 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7235 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7236
7237 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7238 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7239
7240 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7241 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7242 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7243 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7244 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7245 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7246 }
7247
7248 /* FIXME? Currently the TS stays in state BORKEN: */
7249
7250 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7251 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7252 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7253 * f_sleep(1.0);
7254 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7255 */
7256
7257 /* clean up config */
7258 f_ts_set_chcomb(0, 0, 6, "PDCH");
7259
7260 f_shutdown_helper();
7261}
7262
Stefan Sperling0796a822018-10-05 13:01:39 +02007263testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007264 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007265 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7266 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7267 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007268 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007269}
7270
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007271testcase TC_chopped_ipa_payload() runs on test_CT {
7272 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7273 /* TODO: mp_bsc_ctrl_port does not work yet */};
7274 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7275 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7276 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007277 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007278}
7279
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007280/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7281 the BTS does autonomous MS power control loop */
7282testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7283 var MSC_ConnHdlr vc_conn;
7284 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7285 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7286 pars.exp_ms_power_params := true;
7287
7288 f_init(1, true);
7289 f_sleep(1.0);
7290 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7291 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007292 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007293}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007294
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007295/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7296testcase TC_c0_power_red_mode() runs on test_CT {
7297 f_init(1);
7298
7299 for (var integer red := 6; red >= 0; red := red - 2) {
7300 /* Configure BCCH carrier power reduction mode via the VTY */
7301 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7302
7303 /* Expect Osmocom specific BS Power Control message on the RSL */
7304 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7305 chan_nr := t_RslChanNr_BCCH(0),
7306 bs_power := tr_RSL_IE_BS_Power(red / 2));
7307 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7308 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7309
7310 /* Additionally verify the applied value over the CTRL interface */
7311 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7312 if (cred != int2str(red)) {
7313 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7314 cred, " (expected ", red, ")");
7315 }
7316 }
7317
7318 f_shutdown_helper();
7319}
7320
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007321/***********************************************************************
7322 * MSC Pooling
7323 ***********************************************************************/
7324
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007325template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007326 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 +02007327
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007328private 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 +02007329runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007330 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007331 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007332 f_logp(BSCVTY, "Got RSL RR Release");
7333 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007334 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007335 f_logp(BSCVTY, "Got RSL Deact SACCH");
7336 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007337 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007338 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007339 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7340 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007341 break;
7342 }
7343 }
7344}
7345
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007346friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7347 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007348runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007349 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007350 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7351 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007352 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007353 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007354 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007355 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007356 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007357 }
7358 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007359 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007360 /* Also drop the SCCP connection */
7361 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7362 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007363 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007364 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007365 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7366 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007367 }
7368 }
7369}
7370
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007371private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7372 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007373runs on MSC_ConnHdlr {
7374 timer T := 10.0;
7375 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7376
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007377 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007378 f_create_bssmap_exp(l3_enc);
7379
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007380 /* RSL_Emulation.f_chan_est() on rsl_pt:
7381 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007382 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7383 */
7384 var RSL_Message rx_rsl;
7385 var GsmRrMessage rr;
7386
7387 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007388 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007389 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007390 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007391 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7392 */
7393 timer Tt := 10.0;
7394
7395 /* request a channel to be established */
7396 Tt.start;
7397 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007398 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007399 Tt.stop;
7400 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007401 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007402 setverdict(fail, "Unexpected RSL message on DCHAN");
7403 mtc.stop;
7404 }
7405 [] Tt.timeout {
7406 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7407 mtc.stop;
7408 }
7409 }
7410 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7411 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007412 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007413
7414
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007415 if (expect_bssmap_l3) {
7416 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7417 var template PDU_BSSAP exp_l3_compl;
7418 exp_l3_compl := tr_BSSMAP_ComplL3()
7419 if (g_pars.aoip == false) {
7420 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7421 } else {
7422 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7423 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007424
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007425 var PDU_BSSAP bssap;
7426 T.start;
7427 alt {
7428 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7429 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7430 log("rx exp_l3_compl = ", bssap);
7431 }
7432 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7433 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7434 }
7435 [] T.timeout {
7436 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7437 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007438 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007439
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007440 /* start ciphering, if requested */
7441 if (ispresent(g_pars.encr)) {
7442 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007443 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007444 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007445 }
7446
7447 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007448 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007449 }
7450 setverdict(pass);
7451 f_sleep(1.0);
7452}
7453
7454private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7455 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7456 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007457 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007458 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007459 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007460 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007461 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007462 }
7463}
7464
7465/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7466private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7467 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007468 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7469 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7470 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7471 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 +02007472}
7473testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7474
7475 f_init(1, true);
7476 f_sleep(1.0);
7477 var MSC_ConnHdlr vc_conn;
7478 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007479
7480 f_ctrs_msc_init();
7481
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007482 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7483 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007484
7485 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007486 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007487}
7488
7489/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7490/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7491 * just as well using only RSL. */
7492testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7493
7494 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7495 f_sleep(1.0);
7496
7497 /* Control which MSC gets chosen next by the round-robin, otherwise
7498 * would be randomly affected by which other tests ran before this. */
7499 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7500
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007501 f_ctrs_msc_init();
7502
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007503 var MSC_ConnHdlr vc_conn1;
7504 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7505 pars1.mscpool.rsl_idx := 0;
7506 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7507 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7508 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007509 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007510
7511 var MSC_ConnHdlr vc_conn2;
7512 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7513 pars2.mscpool.rsl_idx := 1;
7514 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7515 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7516 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007517 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007518
7519 /* Test round-robin wrap to the first MSC */
7520 var MSC_ConnHdlr vc_conn3;
7521 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7522 pars3.mscpool.rsl_idx := 2;
7523 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7524 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7525 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007526 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007527 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007528}
7529
7530/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7531 * (configured in osmo-bsc.cfg). */
7532/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7533 * just as well using only RSL. */
7534testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7535
7536 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7537 f_sleep(1.0);
7538
7539 /* Control which MSC gets chosen next by the round-robin, otherwise
7540 * would be randomly affected by which other tests ran before this. */
7541 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7542
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007543 f_ctrs_msc_init();
7544
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007545 var MSC_ConnHdlr vc_conn1;
7546 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7547 pars1.mscpool.rsl_idx := 0;
7548 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7549 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7550 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007551 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007552
7553 var MSC_ConnHdlr vc_conn2;
7554 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7555 pars2.mscpool.rsl_idx := 1;
7556 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7557 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7558 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007559 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007560
7561 /* Test round-robin wrap to the first MSC */
7562 var MSC_ConnHdlr vc_conn3;
7563 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7564 pars3.mscpool.rsl_idx := 2;
7565 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7566 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7567 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007568 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007569 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007570}
7571
7572/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7573 * (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
7574 * NULL-NRI setting is stronger than that. */
7575/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7576 * just as well using only RSL. */
7577testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7578
7579 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7580 f_sleep(1.0);
7581
7582 /* Control which MSC gets chosen next by the round-robin, otherwise
7583 * would be randomly affected by which other tests ran before this. */
7584 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7585
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007586 f_ctrs_msc_init();
7587
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007588 var MSC_ConnHdlr vc_conn1;
7589 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7590 pars1.mscpool.rsl_idx := 0;
7591 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7592 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7593 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007594 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007595
7596 var MSC_ConnHdlr vc_conn2;
7597 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7598 pars2.mscpool.rsl_idx := 1;
7599 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7600 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7601 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007602 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007603
7604 /* Test round-robin wrap to the first MSC */
7605 var MSC_ConnHdlr vc_conn3;
7606 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7607 pars3.mscpool.rsl_idx := 2;
7608 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7609 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7610 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007611 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007612 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007613}
7614
7615/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7616 * assigned to any MSC (configured in osmo-bsc.cfg). */
7617/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7618 * just as well using only RSL. */
7619testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7620
7621 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7622 f_sleep(1.0);
7623
7624 /* Control which MSC gets chosen next by the round-robin, otherwise
7625 * would be randomly affected by which other tests ran before this. */
7626 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7627
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007628 f_ctrs_msc_init();
7629
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007630 var MSC_ConnHdlr vc_conn1;
7631 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7632 pars1.mscpool.rsl_idx := 0;
7633 /* An NRI that is not assigned to any MSC */
7634 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7635 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7636 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007637 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007638
7639 var MSC_ConnHdlr vc_conn2;
7640 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7641 pars2.mscpool.rsl_idx := 1;
7642 /* An NRI that is not assigned to any MSC */
7643 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7644 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7645 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007646 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007647
7648 /* Test round-robin wrap to the first MSC */
7649 var MSC_ConnHdlr vc_conn3;
7650 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7651 pars3.mscpool.rsl_idx := 2;
7652 /* An NRI that is not assigned to any MSC */
7653 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7654 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7655 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007656 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007657 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007658}
7659
7660/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7661 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7662/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7663 * just as well using only RSL. */
7664testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7665
7666 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7667 f_sleep(1.0);
7668
7669 /* Control which MSC gets chosen next by the round-robin, otherwise
7670 * would be randomly affected by which other tests ran before this. */
7671 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7672
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007673 f_ctrs_msc_init();
7674
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007675 var MSC_ConnHdlr vc_conn1;
7676 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7677 pars1.mscpool.rsl_idx := 0;
7678 /* An NRI that is assigned to an unconnected MSC */
7679 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7680 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7681 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007682 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7683 f_ctrs_msc_add(0, "mscpool:subscr:new");
7684 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007685
7686 var MSC_ConnHdlr vc_conn2;
7687 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7688 pars2.mscpool.rsl_idx := 1;
7689 /* An NRI that is assigned to an unconnected MSC */
7690 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7691 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7692 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007693 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7694 f_ctrs_msc_add(1, "mscpool:subscr:new");
7695 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007696
7697 /* Test round-robin wrap to the first MSC */
7698 var MSC_ConnHdlr vc_conn3;
7699 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7700 pars3.mscpool.rsl_idx := 2;
7701 /* An NRI that is assigned to an unconnected MSC */
7702 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7703 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7704 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007705 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7706 f_ctrs_msc_add(0, "mscpool:subscr:new");
7707 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007708 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007709}
7710
7711/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7712 * osmo-bsc.cfg). */
7713/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7714 * just as well using only RSL. */
7715testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7716
7717 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7718 f_sleep(1.0);
7719
7720 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7721 * this is not using round-robin. */
7722 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7723
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007724 f_ctrs_msc_init();
7725
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007726 var MSC_ConnHdlr vc_conn1;
7727 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7728 pars1.mscpool.rsl_idx := 0;
7729 /* An NRI of the second MSC's range (256-511) */
7730 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7731 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7732 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007733 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007734
7735 var MSC_ConnHdlr vc_conn2;
7736 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7737 pars2.mscpool.rsl_idx := 1;
7738 /* An NRI of the second MSC's range (256-511) */
7739 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7740 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7741 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007742 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007743
7744 var MSC_ConnHdlr vc_conn3;
7745 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7746 pars3.mscpool.rsl_idx := 2;
7747 /* An NRI of the second MSC's range (256-511) */
7748 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7749 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7750 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007751 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007752 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007753}
7754
7755/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7756 * while a round-robin remains unaffected by that. */
7757/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7758 * just as well using only RSL. */
7759testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7760
7761 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7762 f_sleep(1.0);
7763
7764 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7765 * this is not using round-robin. */
7766 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7767
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007768 f_ctrs_msc_init();
7769
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007770 var MSC_ConnHdlr vc_conn1;
7771 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7772 pars1.mscpool.rsl_idx := 0;
7773 /* An NRI of the third MSC's range (512-767) */
7774 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7775 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7776 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007777 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007778
7779 var MSC_ConnHdlr vc_conn2;
7780 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7781 pars2.mscpool.rsl_idx := 1;
7782 /* An NRI of the third MSC's range (512-767) */
7783 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7784 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7785 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007786 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007787
7788 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7789 var MSC_ConnHdlr vc_conn3;
7790 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7791 pars3.mscpool.rsl_idx := 2;
7792 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7793 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7794 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007795 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007796 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007797}
7798
7799/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
7800/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7801 * just as well using only RSL. */
7802testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
7803
7804 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7805 f_sleep(1.0);
7806
7807 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
7808 * instead, and hits msc 0. */
7809 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7810
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007811 f_ctrs_msc_init();
7812
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007813 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
7814 var MSC_ConnHdlr vc_conn1;
7815 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7816 pars1.mscpool.rsl_idx := 0;
7817 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
7818 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7819 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007820 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007821
7822 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
7823 var MSC_ConnHdlr vc_conn2;
7824 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7825 pars2.mscpool.rsl_idx := 1;
7826 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
7827 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7828 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007829 f_ctrs_msc_expect(2, "mscpool:subscr:known");
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 IMSI, which would be
7834 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7835private function f_tc_mscpool_paging_imsi(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 BSSAP_N_UNITDATA_req paging;
7841 var hexstring imsi := '001010000000123'H;
7842
7843 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7844
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007845 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007846 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
7847 BSSAP.send(paging);
7848
7849 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7850 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7851 * channel number is picked here. */
7852 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7853 f_rslem_register(0, new_chan_nr);
7854 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
7855 f_rslem_unregister(0, new_chan_nr);
7856
7857 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
7858 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007859 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007860 f_sleep(1.0);
7861}
7862testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
7863 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7864 f_sleep(1.0);
7865
7866 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7867 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7868 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7869
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007870 f_ctrs_msc_init();
7871
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007872 var MSC_ConnHdlr vc_conn1;
7873 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7874 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007875 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7876 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007877 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
7878 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007879 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007880 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007881}
7882
7883/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
7884 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7885private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
7886 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7887 //cid_list := { cIl_allInBSS := ''O };
7888 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7889 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7890 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01007891 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007892 var BSSAP_N_UNITDATA_req paging;
7893
7894 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7895
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007896 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007897 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
7898 BSSAP.send(paging);
7899
7900 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7901 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7902 * channel number is picked here. */
7903 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7904 f_rslem_register(0, new_chan_nr);
7905 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
7906 f_rslem_unregister(0, new_chan_nr);
7907
7908 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
7909 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
7910 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007911 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 +02007912 f_sleep(1.0);
7913}
7914testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
7915 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7916 f_sleep(1.0);
7917
7918 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7919 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7920 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
7921
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007922 f_ctrs_msc_init();
7923
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007924 var MSC_ConnHdlr vc_conn1;
7925 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7926 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007927 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7928 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007929 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
7930 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007931 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007932 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007933}
7934
7935/* For round-robin, skip an MSC that has 'no allow-attach' set. */
7936/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7937 * just as well using only RSL. */
7938testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
7939
7940 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7941 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007942 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7943 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007944
7945 /* Control which MSC gets chosen next by the round-robin, otherwise
7946 * would be randomly affected by which other tests ran before this. */
7947 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7948
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007949 f_ctrs_msc_init();
7950
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007951 var MSC_ConnHdlr vc_conn1;
7952 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7953 pars1.mscpool.rsl_idx := 0;
7954 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7955 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7956 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007957 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007958
7959 var MSC_ConnHdlr vc_conn2;
7960 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7961 pars2.mscpool.rsl_idx := 1;
7962 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7963 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7964 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007965 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007966
7967 var MSC_ConnHdlr vc_conn3;
7968 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7969 pars3.mscpool.rsl_idx := 2;
7970 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7971 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7972 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007973 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007974 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007975}
7976
7977/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
7978 * TMSI NRI. */
7979testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
7980
7981 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7982 f_sleep(1.0);
7983
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007984 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7985 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
7986
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007987 /* Control which MSC gets chosen next by the round-robin, otherwise
7988 * would be randomly affected by which other tests ran before this. */
7989 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7990
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007991 f_ctrs_msc_init();
7992
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007993 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
7994 var MSC_ConnHdlr vc_conn1;
7995 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7996 pars1.mscpool.rsl_idx := 0;
7997 /* An NRI of the second MSC's range (256-511) */
7998 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
7999 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8000 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008001 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008002
8003 var MSC_ConnHdlr vc_conn2;
8004 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8005 pars2.mscpool.rsl_idx := 1;
8006 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8007 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8008 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008009 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008010
8011 var MSC_ConnHdlr vc_conn3;
8012 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8013 pars3.mscpool.rsl_idx := 2;
8014 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8015 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8016 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008017 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008018 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008019}
8020
Philipp Maier783681c2020-07-16 16:47:06 +02008021/* Allow/Deny emergency calls globally via VTY */
8022private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8023 f_vty_enter_cfg_msc(BSCVTY, 0);
8024 if (allow) {
8025 f_vty_transceive(BSCVTY, "allow-emergency allow");
8026 } else {
8027 f_vty_transceive(BSCVTY, "allow-emergency deny");
8028 }
8029 f_vty_transceive(BSCVTY, "exit");
8030 f_vty_transceive(BSCVTY, "exit");
8031}
8032
8033/* Allow/Deny emergency calls per BTS via VTY */
8034private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8035 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8036 if (allow) {
8037 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8038 } else {
8039 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8040 }
8041 f_vty_transceive(BSCVTY, "exit");
8042 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008043 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008044}
8045
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008046/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8047private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8048 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8049 if (allow) {
8050 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8051 } else {
8052 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8053 }
8054 f_vty_transceive(BSCVTY, "exit");
8055 f_vty_transceive(BSCVTY, "exit");
8056 f_vty_transceive(BSCVTY, "exit");
8057}
8058
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008059/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8060private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8061 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8062 if (allow) {
8063 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8064 } else {
8065 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8066 }
8067 f_vty_transceive(BSCVTY, "exit");
8068 f_vty_transceive(BSCVTY, "exit");
8069 f_vty_transceive(BSCVTY, "exit");
8070}
8071
Philipp Maier783681c2020-07-16 16:47:06 +02008072/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8073private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8074 var PDU_ML3_MS_NW emerg_setup;
8075 var octetstring emerg_setup_enc;
8076 var RSL_Message emerg_setup_data_ind;
8077
8078 f_establish_fully(omit, omit);
8079
8080 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8081 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8082 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8083
8084 RSL.send(emerg_setup_data_ind);
8085}
8086
8087/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8088 * CALLS are permitted by the BSC config. */
8089private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8090 var PDU_BSSAP emerg_setup_data_ind_bssap;
8091 var PDU_ML3_MS_NW emerg_setup;
8092 timer T := 3.0;
8093
8094 f_assignment_emerg_setup()
8095
8096 T.start;
8097 alt {
8098 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8099 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8100 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8101 setverdict(fail, "no emergency setup");
8102 }
8103 }
8104 [] BSSAP.receive {
8105 setverdict(fail, "unexpected BSSAP message!");
8106 }
8107 [] T.timeout {
8108 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8109 }
8110 }
8111
8112 setverdict(pass);
8113}
8114
8115/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8116 * forbidden by the BSC config. */
8117private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8118 var PDU_BSSAP emerg_setup_data_ind_bssap;
8119 timer T := 3.0;
8120
8121 f_assignment_emerg_setup()
8122
8123 T.start;
8124 alt {
8125 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8126 setverdict(pass);
8127 }
8128 [] RSL.receive {
8129 setverdict(fail, "unexpected RSL message!");
8130 }
8131 [] T.timeout {
8132 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8133 }
8134 }
8135}
8136
8137/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8138testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8139 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8140 var MSC_ConnHdlr vc_conn;
8141
8142 f_init(1, true);
8143 f_sleep(1.0);
8144
8145 f_vty_allow_emerg_msc(true);
8146 f_vty_allow_emerg_bts(true, 0);
8147 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8148 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008149 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008150}
8151
8152/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8153testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8154 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8155 var MSC_ConnHdlr vc_conn;
8156
8157 f_init(1, true);
8158 f_sleep(1.0);
8159
8160 f_vty_allow_emerg_msc(false);
8161 f_vty_allow_emerg_bts(true, 0);
8162 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8163 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008164 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008165}
8166
8167/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8168testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8169 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8170 var MSC_ConnHdlr vc_conn;
8171
8172 /* Note: This simulates a spec violation by the MS, correct MS
8173 * implementations would not try to establish an emergency call because
8174 * the system information tells in advance that emergency calls are
8175 * not forbidden */
8176
8177 f_init(1, true);
8178 f_sleep(1.0);
8179
8180 f_vty_allow_emerg_msc(true);
8181 f_vty_allow_emerg_bts(false, 0);
8182 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8183 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008184 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008185}
8186
Philipp Maier82812002020-08-13 18:48:27 +02008187/* Test what happens when an emergency call arrives while all TCH channels are
8188 * busy, the BSC is expected to terminate one call in favor of the incoming
8189 * emergency call */
8190testcase TC_emerg_premption() runs on test_CT {
8191 var ASP_RSL_Unitdata rsl_ud;
8192 var integer i;
8193 var integer chreq_total, chreq_nochan;
8194 var RSL_Message rx_rsl;
8195 var RslChannelNr chan_nr;
8196
8197 f_init(1);
8198 f_sleep(1.0);
8199
8200 f_vty_allow_emerg_msc(true);
8201 f_vty_allow_emerg_bts(true, 0);
8202
8203 /* Fill up all channels on the BTS */
8204 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8205 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8206 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8207 chan_nr := f_chreq_act_ack('33'O, i);
8208 }
8209 IPA_RSL[0].clear;
8210 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8211 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8212
8213 /* Send Channel request for emegergency call */
8214 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8215
8216 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8217 chan_nr := valueof(t_RslChanNr_Bm(1));
8218 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8219
8220 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8221 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8222 chan_nr := rx_rsl.ies[0].body.chan_nr;
8223 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8224 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008225
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008226 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008227}
8228
8229/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008230private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008231private type record FHParamsTs {
8232 boolean enabled,
8233 uint6_t hsn,
8234 uint6_t maio,
8235 ArfcnList ma
8236};
8237
8238/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008239private type record FHParamsTrx {
8240 GsmArfcn arfcn,
8241 FHParamsTs ts[8]
8242};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008243
8244/* Randomly generate the hopping parameters for the given timeslot numbers */
8245private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8246runs on test_CT return FHParamsTrx {
8247 var FHParamsTrx fhp;
8248
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008249 /* Generate a random ARFCN, including ARFCN 0 */
8250 fhp.arfcn := f_rnd_int(3);
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008251
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008252 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8253 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008254 fhp.ts[tn].enabled := false;
8255 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008256 continue;
8257 }
8258
8259 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008260 fhp.ts[tn].hsn := f_rnd_int(64);
8261 fhp.ts[tn].maio := f_rnd_int(64);
8262 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008263
8264 /* Random Mobile Allocation (hopping channels) */
8265 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8266 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8267 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008268 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008269 }
8270
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008271 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008272 }
8273
8274 log("f_TC_fh_params_gen(): ", fhp);
8275 return fhp;
8276}
8277
8278/* Make sure that the given Channel Description IE matches the hopping configuration */
8279private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8280{
8281 var template (present) ChannelDescription tr_cd;
8282 var template (present) MaioHsn tr_maio_hsn;
8283 var uint3_t tn := cd.chan_nr.tn;
8284
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008285 if (fhp.ts[tn].enabled) {
8286 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008287 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8288 } else {
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008289 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008290 }
8291
8292 if (not match(cd, tr_cd)) {
8293 setverdict(fail, "Channel Description IE does not match: ",
8294 cd, " vs expected ", tr_cd);
8295 }
8296}
8297
8298/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8299private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8300 in MobileAllocationLV ma)
8301{
8302 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8303
8304 if (not match(ma, tr_ma)) {
8305 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8306 tn, "): ", ma, " vs expected: ", tr_ma);
8307 } else {
8308 setverdict(pass);
8309 }
8310}
8311
8312private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8313 in MobileAllocationLV ma)
8314return template MobileAllocationLV {
8315 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008316 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008317 return { len := 0, ma := ''B };
8318 }
8319
8320 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8321 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8322 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008323
8324 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008325 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8326 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8327 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008328 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008329 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008330 }
8331 }
8332
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008333 /* Take ARFCN of the TRX itself into account */
8334 full_mask[fhp.arfcn] := '1'B;
8335
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008336 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008337 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8338 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008339 }
8340
8341 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008342 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008343 if (full_mask[i] != '1'B)
8344 { continue; }
8345
8346 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8347 if (slot_mask[i] == '1'B) {
8348 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008349 } else {
8350 ma_mask := ma_mask & '0'B;
8351 }
8352 }
8353
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008354 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8355 if (full_mask[0] == '1'B) {
8356 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8357 if (slot_mask[0] == '1'B) {
8358 ma_mask := ma_mask & '1'B;
8359 } else {
8360 ma_mask := ma_mask & '0'B;
8361 }
8362 }
8363
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008364 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008365 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008366 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8367
8368 return { len := ma_mask_len, ma := ma_mask };
8369}
8370
8371/* Configure the hopping parameters in accordance with the given record */
8372private function f_TC_fh_params_set(in FHParamsTrx fhp,
8373 uint8_t bts_nr := 0,
8374 uint8_t trx_nr := 0)
8375runs on test_CT {
8376 /* Enter the configuration node for the given BTS/TRX numbers */
8377 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8378
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008379 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn));
8380
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008381 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008382 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8383
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008384 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008385 f_vty_transceive(BSCVTY, "hopping enabled 0");
8386 f_vty_transceive(BSCVTY, "exit"); /* go back */
8387 continue;
8388 }
8389
8390 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008391 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8392 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008393
8394 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008395 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8396 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008397 }
8398
8399 f_vty_transceive(BSCVTY, "hopping enabled 1");
8400 f_vty_transceive(BSCVTY, "exit"); /* go back */
8401 }
8402
8403 f_vty_transceive(BSCVTY, "end");
8404}
8405
8406/* Disable frequency hopping on all timeslots */
8407private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8408 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008409 uint8_t trx_nr := 0,
8410 GsmArfcn arfcn := 871)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008411runs on test_CT {
8412 /* Enter the configuration node for the given BTS/TRX numbers */
8413 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8414
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008415 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn));
8416
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008417 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008418 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8419
8420 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008421 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8422 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008423 }
8424
8425 f_vty_transceive(BSCVTY, "hopping enabled 0");
8426 f_vty_transceive(BSCVTY, "exit"); /* go back */
8427 }
8428
8429 f_vty_transceive(BSCVTY, "end");
8430 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8431}
8432
8433/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8434 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8435testcase TC_fh_params_chan_activ() runs on test_CT {
8436 var FHParamsTrx fhp := f_TC_fh_params_gen();
8437 var RSL_Message rsl_msg;
8438 var RSL_IE_Body ie;
8439
8440 f_init_vty();
8441
8442 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8443 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8444
8445 f_init(1);
8446
8447 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8448 for (var integer i := 0; i < 9; i := i + 1) {
8449 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8450 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8451
8452 /* Make sure that Channel Identification IE is present */
8453 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8454 setverdict(fail, "RSL Channel Identification IE is absent");
8455 continue;
8456 }
8457
8458 /* Make sure that hopping parameters (HSN/MAIO) match */
8459 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8460
8461 /* "Mobile Allocation shall be included but empty" - let's check this */
8462 if (ie.chan_ident.ma.v.len != 0) {
8463 setverdict(fail, "Mobile Allocation IE is not empty: ",
8464 ie.chan_ident.ma, ", despite it shall be");
8465 continue;
8466 }
8467 }
8468
8469 /* Disable frequency hopping */
8470 f_TC_fh_params_unset(fhp);
8471
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008472 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008473}
8474
8475/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8476testcase TC_fh_params_imm_ass() runs on test_CT {
8477 var FHParamsTrx fhp := f_TC_fh_params_gen();
8478 var RSL_Message rsl_msg;
8479 var RSL_IE_Body ie;
8480
8481 f_init_vty();
8482
8483 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8484 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8485
8486 f_init(1);
8487
8488 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8489 for (var integer i := 0; i < 9; i := i + 1) {
8490 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8491 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8492
8493 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8494 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8495
8496 /* Make sure that Full Immediate Assign Info IE is present */
8497 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8498 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8499 continue;
8500 }
8501
8502 /* Decode the actual Immediate Assignment message */
8503 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8504 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8505 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8506 continue;
8507 }
8508
8509 /* Make sure that hopping parameters (HSN/MAIO) match */
8510 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8511
8512 /* Make sure that the Mobile Allocation IE matches */
8513 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8514 rr_msg.payload.imm_ass.mobile_allocation);
8515 }
8516
8517 /* Disable frequency hopping */
8518 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008519
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008520 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008521}
8522
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008523/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8524testcase TC_fh_params_assignment_cmd() runs on test_CT {
8525 var FHParamsTrx fhp := f_TC_fh_params_gen();
8526 var RSL_Message rsl_msg;
8527 var RSL_IE_Body ie;
8528
8529 f_init_vty();
8530
8531 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8532 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8533
8534 f_init(1);
8535
8536 /* HACK: work around "Couldn't find Expect for CRCX" */
8537 vc_MGCP.stop;
8538
8539 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8540 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8541
8542 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8543 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8544 for (var integer i := 0; i < 3; i := i + 1) {
8545 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8546 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8547
8548 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8549 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8550 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8551
8552 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8553 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8554 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8555
8556 /* Make sure that L3 Information IE is present */
8557 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8558 setverdict(fail, "RSL L3 Information IE is absent");
8559 continue;
8560 }
8561
8562 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8563 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8564 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8565 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8566 continue;
8567 }
8568
8569 /* Make sure that hopping parameters (HSN/MAIO) match */
8570 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8571 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8572
8573 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8574 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008575 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008576 continue;
8577 }
8578
8579 /* Make sure that the Mobile Allocation IE matches (if present) */
8580 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8581 if (chan_desc.h and ma_present) {
8582 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8583 l3_msg.payload.ass_cmd.mobile_allocation.v);
8584 } else if (chan_desc.h and not ma_present) {
8585 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8586 continue;
8587 } else if (not chan_desc.h and ma_present) {
8588 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8589 continue;
8590 }
8591 }
8592
8593 /* Give the IUT some time to release all channels */
8594 f_sleep(3.0);
8595
8596 /* Disable frequency hopping */
8597 f_TC_fh_params_unset(fhp);
8598
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008599 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008600}
8601
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008602/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8603private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8604runs on test_CT {
8605 var RSL_Message rsl_msg;
8606 var RSL_IE_Body ie;
8607 var DchanTuple dt;
8608
8609 /* Establish a dedicated channel, so we can trigger handover */
8610 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8611
8612 /* Trigger handover from BTS0 to BTS1 */
8613 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8614 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8615
8616 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8617 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8618
8619 /* ACKnowledge channel activation and expect (RR) Handover Command */
8620 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8621 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8622
8623 /* Make sure that L3 Information IE is present */
8624 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8625 setverdict(fail, "RSL L3 Information IE is absent");
8626 return;
8627 }
8628
8629 /* Decode the L3 message and make sure it is (RR) Handover Command */
8630 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8631 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8632 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8633 return;
8634 }
8635
8636 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8637 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8638 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8639 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8640 return;
8641 }
8642
8643 /* Make sure that hopping parameters (HSN/MAIO) match */
8644 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8645
8646 /* Make sure that Cell Channel Description IE is present */
8647 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8648 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8649 return;
8650 }
8651
8652 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8653 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8654 if (ma_present) {
8655 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8656 l3_msg.payload.ho_cmd.mobile_allocation.v);
8657 } else {
8658 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8659 return;
8660 }
8661}
8662testcase TC_fh_params_handover_cmd() runs on test_CT {
8663 var FHParamsTrx fhp := f_TC_fh_params_gen();
8664
8665 f_init_vty();
8666
8667 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8668 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8669
8670 f_vty_transceive(BSCVTY, "timeslot 0");
8671 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8672 f_vty_transceive(BSCVTY, "exit"); /* go back */
8673
8674 f_vty_transceive(BSCVTY, "timeslot 1");
8675 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8676 f_vty_transceive(BSCVTY, "end"); /* we're done */
8677
8678 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8679 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8680
8681 f_init(2);
8682
8683 f_TC_fh_params_handover_cmd(fhp);
8684
8685 /* Disable frequency hopping on BTS1 */
8686 f_TC_fh_params_unset(fhp, 1);
8687
8688 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8689 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8690
8691 f_vty_transceive(BSCVTY, "timeslot 0");
8692 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8693 f_vty_transceive(BSCVTY, "exit"); /* go back */
8694
8695 f_vty_transceive(BSCVTY, "timeslot 1");
8696 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8697 f_vty_transceive(BSCVTY, "end"); /* we're done */
8698
8699 f_shutdown_helper();
8700}
8701
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008702/* Verify the hopping parameters in System Information Type 4 */
8703testcase TC_fh_params_si4_cbch() runs on test_CT {
8704 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8705 var ASP_RSL_Unitdata rx_rsl_ud;
8706 timer T := 5.0;
8707
8708 f_init_vty();
8709
8710 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
8711 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8712
8713 f_vty_transceive(BSCVTY, "timeslot 0");
8714 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8715 f_vty_transceive(BSCVTY, "exit"); /* go back */
8716
8717 f_vty_transceive(BSCVTY, "timeslot 1");
8718 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
8719 f_vty_transceive(BSCVTY, "end"); /* we're done */
8720
8721 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8722 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8723
8724 f_init(1);
8725
8726 T.start;
8727 alt {
8728 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
8729 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
8730 var SystemInformation si := dec_SystemInformation(ie.other.payload);
8731
8732 /* Make sure that what we decoded is System Information Type 4 */
8733 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
8734 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
8735 repeat;
8736 }
8737
8738 /* Make sure that CBCH Channel Description IE is present */
8739 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
8740 setverdict(fail, "CBCH Channel Description IE is absent");
8741 break;
8742 }
8743
8744 /* Finally, check the hopping parameters (HSN, MAIO) */
8745 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
8746 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8747
8748 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
8749 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
8750 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
8751 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8752 break;
8753 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
8754 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8755 si.payload.si4.cbch_mobile_alloc.v);
8756 }
8757 }
8758 [] IPA_RSL[0].receive { repeat; }
8759 [] T.timeout {
8760 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
8761 }
8762 }
8763
8764 /* Disable frequency hopping */
8765 f_TC_fh_params_unset(fhp);
8766
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008767 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008768 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8769
8770 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008771 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008772 f_vty_transceive(BSCVTY, "exit"); /* go back */
8773
8774 f_vty_transceive(BSCVTY, "timeslot 1");
8775 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8776 f_vty_transceive(BSCVTY, "end"); /* we're done */
8777
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008778 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008779}
8780
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008781template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
8782 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
8783
8784private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
8785 template (present) BSSLAP_PDU expect_bsslap)
8786{
8787 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
8788 if (not match(bsslap, expect_bsslap)) {
8789 log("EXPECTING BSSLAP: ", expect_bsslap);
8790 log("GOT BSSLAP: ", bsslap);
8791 setverdict(fail, "BSSLAP is not as expected");
8792 mtc.stop;
8793 }
8794 setverdict(pass);
8795}
8796
8797/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
8798const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
8799
8800private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
8801 var PDU_BSSAP_LE rx_bsslap;
8802 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
8803 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
8804}
8805
8806/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8807 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
8808private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
8809 f_sleep(1.0);
8810
8811 f_establish_fully(omit, omit);
8812 f_bssap_le_register_imsi(g_pars.imsi, omit);
8813
8814 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8815 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8816
8817 var PDU_BSSAP_LE plr;
8818 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8819
8820 if (not do_ta_request) {
8821 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
8822 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
8823 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
8824 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
8825 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
8826 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
8827 mtc.stop;
8828 }
8829 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
8830 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
8831 if (not match(bsslap, expect_ta_layer3)) {
8832 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
8833 log("GOT BSSLAP: ", bsslap);
8834 setverdict(fail, "BSSLAP is not as expected");
8835 mtc.stop;
8836 }
8837 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
8838 * has no need to request the TA from the BSC and directly responds. */
8839 } else {
8840 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8841 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8842 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8843 }
8844
8845 /* SMLC got the TA from the BSC, now responds with geo information data. */
8846 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8847 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8848 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8849
8850 /* The LCS was using an active A-interface conn. It should still remain active after this. */
8851 f_mo_l3_transceive();
8852
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008853 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008854
8855 f_sleep(2.0);
8856 setverdict(pass);
8857}
8858
8859/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8860 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
8861private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
8862 f_lcs_loc_req_for_active_ms(false);
8863}
8864testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
8865 var MSC_ConnHdlr vc_conn;
8866 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8867
8868 f_init(1, true);
8869 f_sleep(1.0);
8870 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
8871 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008872 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008873}
8874
8875/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8876 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
8877private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
8878 f_lcs_loc_req_for_active_ms(true);
8879}
8880testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
8881 var MSC_ConnHdlr vc_conn;
8882 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8883
8884 f_init(1, true);
8885 f_sleep(1.0);
8886 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
8887 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008888 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008889}
8890
8891/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
8892 * conn without an active lchan. */
8893private function f_clear_A_conn() runs on MSC_ConnHdlr
8894{
8895 var BssmapCause cause := 0;
8896 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
8897 BSSAP.receive(tr_BSSMAP_ClearComplete);
8898 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8899
8900 timer no_more_bssap := 5.0;
8901 no_more_bssap.start;
8902 alt {
8903 [] no_more_bssap.timeout { break; }
8904 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
8905 setverdict(fail, "Expected no more BSSAP after Clear Complete");
8906 mtc.stop;
8907 }
8908 }
8909 setverdict(pass);
8910}
8911
8912/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
8913 * for LCS, for cases where there is only an A conn without an active lchan. */
8914private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
8915{
8916 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
8917
8918 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
8919 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
8920 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
8921 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8922 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8923 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
8924
8925 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
8926 f_clear_A_conn();
8927 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
8928 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8929}
8930
8931/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8932 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
8933 */
8934private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
8935 f_sleep(1.0);
8936
8937 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8938 f_bssap_le_register_imsi(g_pars.imsi, omit);
8939
8940 /* Register to receive the Paging Command */
8941 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8942 g_chan_nr := new_chan_nr;
8943 f_rslem_register(0, g_chan_nr);
8944
8945 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8946 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8947 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8948 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8949
8950 var PDU_BSSAP_LE plr;
8951 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8952
8953 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8954 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8955
8956 /* OsmoBSC needs to Page */
8957 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
8958 f_logp(BSCVTY, "got Paging Command");
8959
8960 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
8961 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008962 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);
8963 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008964
8965 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
8966
8967 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8968
8969 /* SMLC got the TA from the BSC, now responds with geo information data. */
8970 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8971 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8972
8973 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8974
8975 /* The lchan is gone, the A-interface conn was created for the LCS only.
8976 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
8977 f_verify_active_A_conn_and_clear();
8978
8979 f_sleep(2.0);
8980 setverdict(pass);
8981}
8982testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
8983 var MSC_ConnHdlr vc_conn;
8984 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8985
8986 f_init(1, true);
8987 f_sleep(1.0);
8988
8989 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8990 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8991
8992 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
8993 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008994 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008995}
8996
8997/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
8998 */
8999private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9000 f_sleep(1.0);
9001
9002 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9003 f_bssap_le_register_imsi(g_pars.imsi, omit);
9004
9005 /* provoke an abort by omitting both IMSI and IMEI */
9006 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9007 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9008 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9009 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9010
9011 /* BSC tells MSC about failure */
9012 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9013 locationEstimate := omit, positioningData := omit,
9014 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9015
9016 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9017 f_verify_active_A_conn_and_clear();
9018
9019 f_sleep(2.0);
9020 setverdict(pass);
9021}
9022testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9023 var MSC_ConnHdlr vc_conn;
9024 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9025
9026 f_init(1, true);
9027 f_sleep(1.0);
9028
9029 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9030 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9031
9032 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9033 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009034 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009035}
9036
9037/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9038 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9039private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9040 f_sleep(1.0);
9041
9042 f_establish_fully(omit, omit);
9043 f_bssap_le_register_imsi(g_pars.imsi, omit);
9044
9045 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9046 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9047
9048 var PDU_BSSAP_LE plr;
9049 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9050
9051 if (do_ta) {
9052 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9053 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9054 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9055 }
9056
9057 /* SMLC fails to respond, BSC runs into timeout */
9058 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9059 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9060
9061 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9062 locationEstimate := omit, positioningData := omit,
9063 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9064
9065 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9066 f_verify_active_A_conn_and_clear();
9067
9068 f_sleep(2.0);
9069 setverdict(pass);
9070}
9071
9072/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9073 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9074private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9075 f_lcs_loc_req_for_active_ms_le_timeout(false);
9076}
9077
9078testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9079 var MSC_ConnHdlr vc_conn;
9080 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9081
9082 f_init(1, true);
9083 f_sleep(1.0);
9084 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9085 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009086 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009087}
9088
9089/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9090 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9091private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9092 f_lcs_loc_req_for_active_ms_le_timeout(true);
9093}
9094
9095testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9096 var MSC_ConnHdlr vc_conn;
9097 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9098
9099 f_init(1, true);
9100 f_sleep(1.0);
9101 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9102 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009103 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009104}
9105
9106/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9107private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9108 f_sleep(1.0);
9109
9110 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9111 f_bssap_le_register_imsi(g_pars.imsi, omit);
9112
9113 /* Register to receive the Paging Command */
9114 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9115 g_chan_nr := new_chan_nr;
9116 f_rslem_register(0, g_chan_nr);
9117
9118 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9119 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9120 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9121 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9122
9123 var PDU_BSSAP_LE plr;
9124 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9125
9126 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9127 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9128
9129 /* OsmoBSC needs to Page */
9130 var PDU_BSSAP_LE rx_bsslap;
9131 alt {
9132 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9133 f_logp(BSCVTY, "got Paging Command");
9134 repeat;
9135 }
9136 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9137 /* MS does not respond to Paging, TA Req runs into timeout. */
9138 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9139 }
9140 }
9141
9142 /* SMLC responds with failure */
9143 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9144 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9145
9146 /* BSC tells MSC about failure */
9147 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9148 locationEstimate := omit, positioningData := omit,
9149 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9150
9151 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9152 f_verify_active_A_conn_and_clear();
9153
9154 f_sleep(2.0);
9155 setverdict(pass);
9156}
9157testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9158 var MSC_ConnHdlr vc_conn;
9159 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9160
9161 f_init(1, true);
9162 f_sleep(1.0);
9163
9164 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9165 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9166
9167 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9168 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009169 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009170}
9171
9172/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9173 * over. */
9174private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9175 f_sleep(1.0);
9176
9177 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9178 f_bssap_le_register_imsi(g_pars.imsi, omit);
9179
9180 /* Register to receive the Paging Command */
9181 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9182 g_chan_nr := new_chan_nr;
9183 f_rslem_register(0, g_chan_nr);
9184
9185 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9186 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9187 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9188 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9189
9190 var PDU_BSSAP_LE plr;
9191 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9192
9193 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9194 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009195 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 +02009196 do_clear := false, expect_bssmap_l3 := true);
9197
9198 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9199 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9200
9201 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9202 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9203
9204 /* SMLC got the TA from the BSC, now responds with geo information data. */
9205 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9206 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9207 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9208
9209 /* The lchan should still exist, it was from a CM Service Request. */
9210 f_mo_l3_transceive();
9211
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009212 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009213
9214 f_sleep(2.0);
9215 setverdict(pass);
9216}
9217testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9218 var MSC_ConnHdlr vc_conn;
9219 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9220
9221 f_init(1, true);
9222 f_sleep(1.0);
9223
9224 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9225 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9226
9227 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9228 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009229 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009230}
9231
9232/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9233 * the new lchan after handover. */
9234private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9235 f_sleep(1.0);
9236
9237 f_establish_fully(omit, omit);
9238 f_bssap_le_register_imsi(g_pars.imsi, omit);
9239
9240 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9241 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9242
9243 var PDU_BSSAP_LE plr;
9244 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9245
9246 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9247 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9248
9249 var HandoverState hs := {
9250 rr_ho_cmpl_seen := false,
9251 handover_done := false,
9252 old_chan_nr := -
9253 };
9254 /* issue hand-over command on VTY */
9255 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9256 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9257 f_rslem_suspend(RSL1_PROC);
9258
9259 /* From the MGW perspective, a handover is is characterized by
9260 * performing one MDCX operation with the MGW. So we expect to see
9261 * one more MDCX during handover. */
9262 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9263
9264 alt {
9265 [] as_handover(hs);
9266 }
9267
9268 var PDU_BSSAP_LE rx_bsslap;
9269
9270 interleave {
9271 /* Expect the BSC to inform the MSC about the handover */
9272 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9273
9274 /* Expect the BSC to inform the SMLC about the handover */
9275 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9276 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9277 }
9278 }
9279
9280 /* SMLC now responds with geo information data. */
9281 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9282 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9283 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9284
9285 /* lchan still active */
9286 f_mo_l3_transceive(RSL1);
9287
9288 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009289 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009290
9291 f_sleep(2.0);
9292 setverdict(pass);
9293}
9294testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9295 var MSC_ConnHdlr vc_conn;
9296 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9297
9298 f_init(2, true);
9299 f_sleep(1.0);
9300 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9301 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009302 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009303}
9304
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009305/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9306private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9307 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9308
9309 /* Also disable attach for the single connected MSC */
9310 f_vty_msc_allow_attach(BSCVTY, { false });
9311
9312 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) ));
9313 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9314
9315 /* No MSC is found, expecting a proper release on RSL */
9316 interleave {
9317 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9318 f_logp(BSCVTY, "Got RSL RR Release");
9319 }
9320 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9321 f_logp(BSCVTY, "Got RSL Deact SACCH");
9322 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009323 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009324 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9325 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009326 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009327 }
9328 }
9329 setverdict(pass);
9330}
9331testcase TC_no_msc() runs on test_CT {
9332
9333 f_init(1, true);
9334 f_sleep(1.0);
9335 var MSC_ConnHdlr vc_conn;
9336 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9337
9338 f_ctrs_bsc_init(counternames_bsc_mscpool);
9339
9340 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9341 vc_conn.done;
9342
9343 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9344 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009345 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009346}
9347
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009348/* Dyn PDCH todo:
9349 * activate OSMO as TCH/F
9350 * activate OSMO as TCH/H
9351 * does the BSC-located PCU socket get the updated INFO?
9352 * what if no PCU is connected at the time?
9353 * is the info correct on delayed PCU (re)connect?
9354 */
Harald Welte94e0c342018-04-07 11:33:23 +02009355
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009356private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9357 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9358 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9359
9360 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9361 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9362 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9363 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9364 g_pars.ass_codec_list.codecElements[0];
9365 if (isvalue(g_pars.expect_mr_s0_s7)) {
9366 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9367 g_pars.expect_mr_s0_s7;
9368 }
9369 }
9370 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9371 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9372 log("expecting ASS COMPL like this: ", exp_compl);
9373
9374 f_establish_fully(ass_cmd, exp_compl);
9375
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009376 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 +00009377
9378 var RSL_Message rsl;
9379
9380 timer T := 5.0;
9381 T.start;
9382 alt {
9383 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9384 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9385 log("Rx L3 from net: ", l3);
9386 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9387 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9388 mtc.stop;
9389 }
9390 }
9391 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9392 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9393 mtc.stop;
9394 }
9395 [] T.timeout {
9396 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9397 setverdict(pass);
9398 }
9399 }
9400 T.stop;
9401}
9402
9403/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9404 * osmo-bsc. */
9405testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9406 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9407 var MSC_ConnHdlr vc_conn;
9408
9409 f_init(1, true);
9410 f_sleep(1.0);
9411
9412 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9413 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9414 vc_conn.done;
9415 f_shutdown_helper();
9416}
9417
9418/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9419 */
9420testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9421 f_init_vty();
9422
9423 f_init(1, false);
9424 f_sleep(1.0);
9425
9426 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9427
9428 var ASP_RSL_Unitdata rx_rsl_ud;
9429 timer T := 5.0;
9430
9431 T.start;
9432 alt {
9433 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9434 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9435 T.stop;
9436 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9437 mtc.stop;
9438 }
9439 repeat;
9440 }
9441 [] T.timeout {
9442 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9443 setverdict(pass);
9444 }
9445 }
9446}
9447
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009448private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9449 /* First fully set up a speech lchan */
9450 f_TC_assignment_codec(id);
9451
9452 /* Trigger re-assignment to another lchan */
9453 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9454
9455 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9456 * one MDCX on MGCP. */
9457 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9458
9459 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9460 * as the old lchan used. */
9461 g_media.bts.ipa_crcx_seen := false;
9462 g_media.bts.ipa_mdcx_seen := false;
9463
9464 /* Send different BTS side RTP port number for the new lchan */
9465 g_media.bts.bts.port_nr := 4223;
9466
9467 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9468
9469 /* Trigger re-assignment. */
9470 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9471
9472 timer T := 5.0;
9473 T.start;
9474 alt {
9475 [] as_assignment(assignment_st);
9476 [] as_Media();
9477 [] T.timeout {
9478 break;
9479 }
9480 }
9481
9482 if (not assignment_st.assignment_done) {
9483 setverdict(fail, "Assignment did not complete");
9484 mtc.stop;
9485 }
9486
9487 f_check_mgcp_expectations()
9488 setverdict(pass);
9489
9490 f_sleep(2.0);
9491 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9492
9493 /* Instruct BSC to clear channel */
9494 var BssmapCause cause := 0;
9495 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9496 interleave {
9497 [] MGCP.receive(tr_DLCX) {}
9498 [] MGCP.receive(tr_DLCX) {}
9499 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9500 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009501 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009502 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009503 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009504 }
9505 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9506 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9507 }
9508 }
9509
9510 f_sleep(0.5);
9511}
9512
9513testcase TC_reassignment_fr() runs on test_CT {
9514 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9515 var MSC_ConnHdlr vc_conn;
9516
9517 f_init(1, true);
9518 f_sleep(1.0);
9519
9520 f_ctrs_bsc_and_bts_init();
9521
9522 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9523 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9524 vc_conn.done;
9525
9526 /* from f_establish_fully() */
9527 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9528 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9529 /* from re-assignment */
9530 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9531 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9532 f_ctrs_bsc_and_bts_verify();
9533 f_shutdown_helper();
9534}
9535
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009536const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9537const charstring REEST_CLEAR := "REEST_CLEAR";
9538const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9539
9540/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9541 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9542 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9543 * the MSC as the CM Re-Establishment is handled.
9544 *
9545 * MS bts0 bts1 bsc msc test-component
9546 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9547 * | | _1 wait a bit, to settle down
9548 * |<-x x--| | _1 "lose connection"
9549 * | | REEST_LOST_CONNECTION
9550 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9551 * | | REEST_CLEAR
9552 * | |<-0---| _1 Clear Command on first A-conn
9553 * | |--0-->| _1 Clear Complete
9554 * | |<----------------->| | _1 Release first channel
9555 * | | REEST_CLEAR_DONE
9556 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9557 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9558 *
9559 */
9560private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9561 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9562 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9563
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 f_establish_fully(ass_cmd, exp_compl);
9568
9569 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9570 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9571 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9572 f_sleep(2.0);
9573 COORD.send(REEST_LOST_CONNECTION);
9574
9575 alt {
9576 [] COORD.receive(REEST_CLEAR);
9577 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9578 setverdict(fail, "Unexpected channel release");
9579 mtc.stop;
9580 }
9581 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9582 setverdict(fail, "Unexpected channel release");
9583 mtc.stop;
9584 }
9585 }
9586 f_perform_clear()
9587 f_expect_dlcx_conns();
9588 COORD.send(REEST_CLEAR_DONE);
9589}
9590
9591private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9592 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9593
9594 /* The MS lost the connection on the first channel, now establishes another one */
9595 COORD.receive(REEST_LOST_CONNECTION);
9596
9597 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9598 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9599 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9600
9601 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009602 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 +02009603 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9604
9605 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9606 COORD.send(REEST_CLEAR);
9607 COORD.receive(REEST_CLEAR_DONE);
9608
9609 f_sleep(2.0);
9610
9611 /* Answer the CM Re-Establishment with an Assignment Command. */
9612 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9613 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9614 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9615 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9616
9617 var AssignmentState st := valueof(ts_AssignmentStateInit);
9618 st.voice_call := true;
9619 st.is_assignment := true;
9620
9621 var ExpectCriteria mgcpcrit := {
9622 connid := omit,
9623 endpoint := omit,
9624 transid := omit
9625 };
9626 f_create_mgcp_expect(mgcpcrit);
9627
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009628 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009629
9630 BSSAP.send(ass_cmd);
9631
9632 var PDU_BSSAP bssap;
9633
9634 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009635 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9636 [] as_Media_ipacc(RSL1, RSL2);
9637 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009638 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9639 break;
9640 }
9641 }
9642
9643 f_sleep(3.0);
9644
9645 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009646 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009647 f_expect_dlcx_conns();
9648}
9649
9650testcase TC_cm_reestablishment() runs on test_CT {
9651 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9652 var MSC_ConnHdlr vc_conn1;
9653
9654 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9655 var MSC_ConnHdlr vc_conn2;
9656 pars2.imsi := pars1.imsi;
9657 pars2.media_nr := 2;
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009658 /* f_tc_cm_reestablishment_2 uses 'bts 1'.
9659 * BTS 1 has BSIC 11 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 3 */
9660 pars2.expect_tsc := 3;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009661
9662 f_init(2, true, guard_timeout := 40.0);
9663 f_sleep(1.0);
9664
9665 vc_conn1 := f_start_handler_create(pars1);
9666 vc_conn2 := f_start_handler_create(pars2);
9667 connect(vc_conn1:COORD, vc_conn2:COORD);
9668 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9669 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9670 vc_conn1.done;
9671 vc_conn2.done;
9672
9673 f_shutdown_helper();
9674}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009675
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009676function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9677 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9678runs on test_CT return template (omit) RSL_Message {
9679 var ASP_RSL_Unitdata rx_rsl_ud;
9680 timer T := t_secs;
9681
9682 T.start;
9683 alt {
9684 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9685 T.stop;
9686 }
9687 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9688 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9689 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9690 T.stop;
9691 return omit;
9692 }
9693 [] T.timeout {
9694 return omit;
9695 }
9696 }
9697 return rx_rsl_ud.rsl;
9698}
9699
9700private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9701 f_vty_enter_cfg_bts(pt, bts_nr);
9702 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9703 f_vty_transceive(pt, "exit");
9704 f_vty_transceive(pt, "exit");
9705 f_vty_transceive(pt, "exit");
9706}
9707
9708private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009709 template RslChannelNr chan_nr := ?,
9710 template (present) uint12_t arfcn := ?,
9711 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009712{
9713 var RSL_IE_Body full_imm_ass_info;
9714 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
9715 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9716 mtc.stop;
9717 }
9718
9719 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
9720 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
9721 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009722 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009723 page_mode := ?);
9724 if (not match(rr_imm_ass, expect_imm_ass)) {
9725 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
9726 setverdict(fail, "Failed to match Immediate Assignment");
9727 mtc.stop;
9728 }
9729}
9730
9731testcase TC_imm_ass_post_chan_ack() runs on test_CT {
9732 var RSL_Message chan_act;
9733 var RSL_Message imm_ass;
9734
9735 f_init(1, false);
9736 f_sleep(1.0);
9737
9738 /* (should be the default anyway, just to make things clear) */
9739 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
9740
9741 /* RA containing reason=LU */
9742 var GsmFrameNumber fn := 2342;
9743 var uint8_t ra := 2;
9744 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9745
9746 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9747
9748 /* First send the Chan Act ACK */
9749 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009750 var RSL_IE_Body chan_ident_ie;
9751 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9752 setverdict(fail, "RSL Channel Identification IE is absent");
9753 mtc.stop;
9754 }
9755
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009756 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
9757
9758 /* Then expect the Immediate Assignment, after we ACKed the chan act */
9759 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9760
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009761 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9762 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009763
9764 /* Check that the lchan is working */
9765 var octetstring l3 := '00010203040506'O;
9766 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9767
9768 var BSSAP_N_CONNECT_ind rx_c_ind;
9769 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9770 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9771
9772 f_sleep(1.0);
9773 f_shutdown_helper();
9774}
9775
9776testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
9777 var RSL_Message chan_act;
9778 var RSL_Message imm_ass;
9779
9780 f_init(1, false);
9781 f_sleep(1.0);
9782
9783 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9784
9785 /* RA containing reason=LU */
9786 var GsmFrameNumber fn := 2342;
9787 var uint8_t ra := 2;
9788 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9789
9790 /* (set bts 0 cfg back to default) */
9791 f_vty_set_imm_ass(BSCVTY);
9792
9793 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9794 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009795 var RSL_IE_Body chan_ident_ie;
9796 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9797 setverdict(fail, "RSL Channel Identification IE is absent");
9798 mtc.stop;
9799 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009800
9801 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9802 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009803 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9804 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009805
9806 /* Only now send the Chan Act ACK */
9807 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9808
9809 /* Check that the lchan is working */
9810 var octetstring l3 := '00010203040506'O;
9811 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9812
9813 var BSSAP_N_CONNECT_ind rx_c_ind;
9814 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9815 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9816
9817 f_sleep(1.0);
9818 f_shutdown_helper();
9819}
9820
Neels Hofmeyr23158742021-09-07 19:08:07 +02009821testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
9822 var RSL_Message chan_act;
9823 var RSL_Message imm_ass;
9824
9825 f_init(1, false);
9826 f_sleep(1.0);
9827
9828 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
9829
9830 /* RA containing reason=LU */
9831 var GsmFrameNumber fn := 2342;
9832 var uint8_t ra := 2;
9833 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9834
9835 /* (set bts 0 cfg back to default) */
9836 f_vty_set_imm_ass(BSCVTY);
9837
9838 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9839 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
9840 var RSL_IE_Body chan_ident_ie;
9841 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9842 setverdict(fail, "RSL Channel Identification IE is absent");
9843 mtc.stop;
9844 }
9845
9846 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9847 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9848 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9849 chan_ident_ie.chan_ident.ch_desc.v.tsc);
9850
9851 /* Only now send the Chan Act ACK */
9852 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9853
9854 /* Check that the lchan is working */
9855 var octetstring l3 := '00010203040506'O;
9856 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9857
9858 var BSSAP_N_CONNECT_ind rx_c_ind;
9859 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9860 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9861
9862 f_sleep(1.0);
9863 f_shutdown_helper();
9864}
9865
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009866testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
9867 /* change Timeslot 6 before f_init() starts RSL */
9868 f_init_vty();
9869 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
9870 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9871
9872 f_init(1, false);
9873 f_sleep(1.0);
9874
9875 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
9876 /* The BSC will activate the dynamic PDCH by default, so confirm that */
9877 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
9878 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
9879
9880 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
9881 f_ts_set_chcomb(0, 0, 6, "PDCH");
9882
9883 /* block all static timeslots so that the dyn TS will be used */
9884 f_disable_all_tch_f();
9885 f_disable_all_tch_h();
9886 f_disable_all_sdcch();
9887
9888 var RSL_Message chan_act;
9889 var RSL_Message imm_ass;
9890
9891 f_init(1, false);
9892 f_sleep(1.0);
9893
9894 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9895
9896 /* RA containing reason=LU */
9897 var GsmFrameNumber fn := 2342;
9898 var uint8_t ra := 2;
9899 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9900
9901 /* (set bts 0 cfg back to default) */
9902 f_vty_set_imm_ass(BSCVTY);
9903
9904 /* Expect the dyn TS to deactivate PDCH first */
9905 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
9906 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
9907
9908 /* Now activation as SDCCH8 */
9909 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
9910
9911 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009912 var RSL_IE_Body chan_ident_ie;
9913 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9914 setverdict(fail, "RSL Channel Identification IE is absent");
9915 mtc.stop;
9916 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009917
9918 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9919 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009920 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9921 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009922
9923 /* Only now send the Chan Act ACK */
9924 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9925
9926 /* Check that the lchan is working */
9927 var octetstring l3 := '00010203040506'O;
9928 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9929
9930 var BSSAP_N_CONNECT_ind rx_c_ind;
9931 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9932 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9933
9934 f_sleep(1.0);
9935 f_shutdown_helper();
9936}
9937
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +02009938testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
9939 /* change Timeslot 6 before f_init() starts RSL */
9940 f_init_vty();
9941 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
9942 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9943
9944 f_init(1, false);
9945 f_sleep(1.0);
9946
9947 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
9948 /* The BSC will activate the dynamic PDCH by default, so confirm that */
9949 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
9950 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
9951
9952 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
9953 f_ts_set_chcomb(0, 0, 6, "PDCH");
9954
9955 /* block all static timeslots so that the dyn TS will be used */
9956 f_disable_all_tch_f();
9957 f_disable_all_tch_h();
9958 f_disable_all_sdcch();
9959
9960 var RSL_Message chan_act;
9961 var RSL_Message imm_ass;
9962
9963 f_init(1, false);
9964 f_sleep(1.0);
9965
9966 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
9967
9968 /* RA containing reason=LU */
9969 var GsmFrameNumber fn := 2342;
9970 var uint8_t ra := 2;
9971 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9972
9973 /* (set bts 0 cfg back to default) */
9974 f_vty_set_imm_ass(BSCVTY);
9975
9976 /* Expect the dyn TS to deactivate PDCH first */
9977 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
9978
9979 /* And already the Immediate Assignment even before the PDCH Deact ACK */
9980 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9981
9982 /* continue the Osmo style PDCH Deact (usual chan rel) */
9983 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
9984
9985 /* Now activation as SDCCH8 */
9986 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
9987
9988 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009989 var RSL_IE_Body chan_ident_ie;
9990 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9991 setverdict(fail, "RSL Channel Identification IE is absent");
9992 mtc.stop;
9993 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +02009994 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9995
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009996 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9997 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +02009998
9999 /* Check that the lchan is working */
10000 var octetstring l3 := '00010203040506'O;
10001 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10002
10003 var BSSAP_N_CONNECT_ind rx_c_ind;
10004 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10005 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10006
10007 f_sleep(1.0);
10008 f_shutdown_helper();
10009}
10010
Harald Welte28d943e2017-11-25 15:00:50 +010010011control {
Harald Welte898113b2018-01-31 18:32:21 +010010012 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010013 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010014 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +020010015 execute( TC_stat_num_msc_connected_1() );
10016 execute( TC_stat_num_msc_connected_2() );
10017 execute( TC_stat_num_msc_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010018 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010019 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010020 execute( TC_ctrl_location() );
10021 }
Harald Welte898113b2018-01-31 18:32:21 +010010022
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010023 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010024 execute( TC_si2quater_2_earfcns() );
10025 execute( TC_si2quater_3_earfcns() );
10026 execute( TC_si2quater_4_earfcns() );
10027 execute( TC_si2quater_5_earfcns() );
10028 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010029 execute( TC_si2quater_12_earfcns() );
10030 execute( TC_si2quater_23_earfcns() );
10031 execute( TC_si2quater_32_earfcns() );
10032 execute( TC_si2quater_33_earfcns() );
10033 execute( TC_si2quater_42_earfcns() );
10034 execute( TC_si2quater_48_earfcns() );
10035 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010036 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010037 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010038
Harald Welte898113b2018-01-31 18:32:21 +010010039 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010040 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010041 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010042 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010043 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010044 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010045 execute( TC_chan_act_ack_est_ind_noreply() );
10046 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010047 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010048 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010049 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010050 execute( TC_chan_rel_rll_rel_ind() );
10051 execute( TC_chan_rel_conn_fail() );
10052 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010053 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10054 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010055 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010056 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010057 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010058 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010059 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010060 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010061
Harald Weltecfe2c962017-12-15 12:09:32 +010010062 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010063
10064 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010065 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010066 execute( TC_assignment_csd() );
10067 execute( TC_assignment_ctm() );
10068 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010069 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10070 execute( TC_assignment_aoip_tla_v6() );
10071 }
Harald Welte235ebf12017-12-15 14:18:16 +010010072 execute( TC_assignment_fr_a5_0() );
10073 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010074 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010075 execute( TC_assignment_fr_a5_1_codec_missing() );
10076 }
Harald Welte235ebf12017-12-15 14:18:16 +010010077 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010078 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010079 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010080 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010081 execute( TC_ciph_mode_a5_0() );
10082 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010083 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010084 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010085 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010086 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010087
Harald Welte60aa5762018-03-21 19:33:13 +010010088 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010089 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010090 execute( TC_assignment_codec_hr() );
10091 execute( TC_assignment_codec_efr() );
10092 execute( TC_assignment_codec_amr_f() );
10093 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010094
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010095 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010096 execute( TC_assignment_codec_amr_f_S1() );
10097 execute( TC_assignment_codec_amr_h_S1() );
10098 execute( TC_assignment_codec_amr_f_S124() );
10099 execute( TC_assignment_codec_amr_h_S124() );
10100 execute( TC_assignment_codec_amr_f_S0() );
10101 execute( TC_assignment_codec_amr_f_S02() );
10102 execute( TC_assignment_codec_amr_f_S024() );
10103 execute( TC_assignment_codec_amr_f_S0247() );
10104 execute( TC_assignment_codec_amr_h_S0() );
10105 execute( TC_assignment_codec_amr_h_S02() );
10106 execute( TC_assignment_codec_amr_h_S024() );
10107 execute( TC_assignment_codec_amr_h_S0247() );
10108 execute( TC_assignment_codec_amr_f_S01234567() );
10109 execute( TC_assignment_codec_amr_f_S0234567() );
10110 execute( TC_assignment_codec_amr_f_zero() );
10111 execute( TC_assignment_codec_amr_f_unsupp() );
10112 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010113 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10114 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010115 execute( TC_assignment_codec_amr_f_start_mode_4() );
10116 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010117 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010118 }
Harald Welte60aa5762018-03-21 19:33:13 +010010119
Philipp Maierac09bfc2019-01-08 13:41:39 +010010120 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10121 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10122 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10123 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10124 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10125 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10126 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10127 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10128 execute( TC_assignment_codec_req_hr_fr() );
10129 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010130 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10131 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10132 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010133
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010134 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010135
Harald Welte898113b2018-01-31 18:32:21 +010010136 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010137 execute( TC_rll_est_ind_inact_lchan() );
10138 execute( TC_rll_est_ind_inval_sapi1() );
10139 execute( TC_rll_est_ind_inval_sapi3() );
10140 execute( TC_rll_est_ind_inval_sacch() );
10141
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010142 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10143 execute( TC_tch_dlci_link_id_sapi() );
10144
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010145 /* SAPI N Reject triggered by RLL establishment failures */
10146 execute( TC_rll_rel_ind_sapi_n_reject() );
10147 execute( TC_rll_err_ind_sapi_n_reject() );
10148 execute( TC_rll_timeout_sapi_n_reject() );
10149
Harald Welte898113b2018-01-31 18:32:21 +010010150 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010151 execute( TC_paging_imsi_nochan() );
10152 execute( TC_paging_tmsi_nochan() );
10153 execute( TC_paging_tmsi_any() );
10154 execute( TC_paging_tmsi_sdcch() );
10155 execute( TC_paging_tmsi_tch_f() );
10156 execute( TC_paging_tmsi_tch_hf() );
10157 execute( TC_paging_imsi_nochan_cgi() );
10158 execute( TC_paging_imsi_nochan_lac_ci() );
10159 execute( TC_paging_imsi_nochan_ci() );
10160 execute( TC_paging_imsi_nochan_lai() );
10161 execute( TC_paging_imsi_nochan_lac() );
10162 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010163 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10164 execute( TC_paging_imsi_nochan_rnc() );
10165 execute( TC_paging_imsi_nochan_lac_rnc() );
10166 execute( TC_paging_imsi_nochan_lacs() );
10167 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010168 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010169 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010170 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010171 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010172 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010173
10174 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010175 execute( TC_rsl_unknown_unit_id() );
10176
10177 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010178
10179 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010180 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010181 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010182 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010183 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010184 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010185 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010186
Harald Welte261af4b2018-02-12 21:20:39 +010010187 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010188 execute( TC_ho_int_a5_0() );
10189 execute( TC_ho_int_a5_1() );
10190 execute( TC_ho_int_a5_3() );
10191 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010192 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010193
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010194 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010195 execute( TC_ho_out_fail_no_msc_response() );
10196 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010197 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010198
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010199 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010200 execute( TC_ho_into_this_bsc_a5_0() );
10201 execute( TC_ho_into_this_bsc_a5_1() );
10202 execute( TC_ho_into_this_bsc_a5_3() );
10203 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010204 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10205 execute( TC_ho_into_this_bsc_tla_v6() );
10206 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010207 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010208 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010209 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10210 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010211 execute( TC_ho_in_fail_msc_clears() );
10212 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10213 execute( TC_ho_in_fail_no_detect() );
10214 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010215
Neels Hofmeyr91401012019-07-11 00:42:35 +020010216 execute( TC_ho_neighbor_config_1() );
10217 execute( TC_ho_neighbor_config_2() );
10218 execute( TC_ho_neighbor_config_3() );
10219 execute( TC_ho_neighbor_config_4() );
10220 execute( TC_ho_neighbor_config_5() );
10221 execute( TC_ho_neighbor_config_6() );
10222 execute( TC_ho_neighbor_config_7() );
10223
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010224 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010225 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010226 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010227
10228 execute( TC_dyn_pdch_ipa_act_deact() );
10229 execute( TC_dyn_pdch_ipa_act_nack() );
10230 execute( TC_dyn_pdch_osmo_act_deact() );
10231 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010232 if (mp_enable_dyn_sdcch8_test) {
10233 execute( TC_dyn_ts_sdcch8_act_deact() );
10234 execute (TC_dyn_ts_sdcch8_tch_call_act_deact() );
10235 execute( TC_dyn_ts_sdcch8_act_nack() );
10236 }
Harald Welte99f3ca02018-06-14 13:40:29 +020010237
Stefan Sperling0796a822018-10-05 13:01:39 +020010238 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010239 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010240
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010241 /* Power control related */
10242 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010243 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010244
10245 /* MSC pooling */
10246 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10247 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10248 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10249 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10250 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10251 execute( TC_mscpool_L3Compl_on_1_msc() );
10252 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10253 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10254 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10255 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10256 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10257 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10258 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10259 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10260 execute( TC_mscpool_paging_and_response_imsi() );
10261 execute( TC_mscpool_paging_and_response_tmsi() );
10262 execute( TC_mscpool_no_allow_attach_round_robin() );
10263 execute( TC_mscpool_no_allow_attach_valid_nri() );
10264 }
10265
Harald Welte99f3ca02018-06-14 13:40:29 +020010266 execute( TC_early_conn_fail() );
10267 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010268 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010269
Philipp Maier783681c2020-07-16 16:47:06 +020010270 /* Emergency call handling (deny / allow) */
10271 execute( TC_assignment_emerg_setup_allow() );
10272 execute( TC_assignment_emerg_setup_deny_msc() );
10273 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010274 execute( TC_emerg_premption() );
10275
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010276 /* Frequency hopping parameters handling */
10277 execute( TC_fh_params_chan_activ() );
10278 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010279 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010280 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010281 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010282
10283 if (mp_enable_lcs_tests) {
10284 execute( TC_lcs_loc_req_for_active_ms() );
10285 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10286 execute( TC_lcs_loc_req_for_idle_ms() );
10287 execute( TC_lcs_loc_req_no_subscriber() );
10288 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10289 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10290 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10291 execute( TC_cm_service_during_lcs_loc_req() );
10292 execute( TC_ho_during_lcs_loc_req() );
10293 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010294
10295 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010296
10297 execute( TC_refuse_chan_act_to_vamos() );
10298 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010299
10300 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010301
10302 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010303
10304 execute( TC_imm_ass_post_chan_ack() );
10305 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010306 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010307 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010308 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Harald Welte28d943e2017-11-25 15:00:50 +010010309}
10310
10311}