module BTS_Tests_VAMOS { /* Integration Tests for OsmoBTS * * (C) 2021 by sysmocom - s.m.f.c. GmbH * Author: Vadim Yanitskiy * * All rights reserved. * * Released under the terms of GNU General Public License, Version 2 or * (at your option) any later version. * * SPDX-License-Identifier: GPL-2.0-or-later * * This module contains VAMOS specific test cases. */ import from Misc_Helpers all; import from General_Types all; import from Osmocom_Types all; import from GSM_Types all; import from L1CTL_PortType all; import from L1CTL_Types all; import from LAPDm_Types all; import from IPA_Emulation all; import from GSM_RR_Types all; import from L3_Templates all; import from RSL_Emulation all; import from RSL_Types all; import from BTS_Tests all; private type record of ChanNrModeSet ChanNrModeTest; private type record of ChanNrMode ChanNrModeSet; private type record ChanNrMode { RslChannelNr chan_nr, RSL_IE_ChannelMode chan_mode }; /* VFF: V0(TCH/F) & V1(TCH/F), 2 channels total */ private template (value) ChanNrModeTest ChanNrModeTestVFF(uint3_t tn) := { { { ts_RslChanNr_Bm(tn), /* V0(TCH/F), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_F_VAMOS) }, { ts_RslChanNr_Osmo_VAMOS_Bm(tn), /* V1(TCH/F), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_F_VAMOS) } }, { { ts_RslChanNr_Bm(tn), /* V0(TCH/F), FR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_F_VAMOS, RSL_CMOD_SP_GSM1) }, { ts_RslChanNr_Osmo_VAMOS_Bm(tn), /* V1(TCH/F), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_F_VAMOS) } }, { { ts_RslChanNr_Bm(tn), /* V0(TCH/F), EFR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_F_VAMOS, RSL_CMOD_SP_GSM2) }, { ts_RslChanNr_Osmo_VAMOS_Bm(tn), /* V1(TCH/F), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_F_VAMOS, RSL_CMOD_SP_GSM3) } }, { { ts_RslChanNr_Bm(tn), /* V0(TCH/F), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_F_VAMOS, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Osmo_VAMOS_Bm(tn), /* V1(TCH/F), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_F_VAMOS, RSL_CMOD_SP_GSM3) } } }; /* VHH: V0(TCH/H0) & V1(TCH/H0) + V0(TCH/H1) & V1(TCH/H1), 4 channels total */ private template (value) ChanNrModeTest ChanNrModeTestVHH(uint3_t tn) := { { { ts_RslChanNr_Lm(tn, 0), /* V0(TCH/H0), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 0), /* V1(TCH/H0), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) } }, { { ts_RslChanNr_Lm(tn, 0), /* V0(TCH/H0), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), HR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM1) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 0), /* V1(TCH/H0), HR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM1) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) } }, { { ts_RslChanNr_Lm(tn, 0), /* V0(TCH/H0), HR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM1) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 0), /* V1(TCH/H0), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) } }, { { ts_RslChanNr_Lm(tn, 0), /* V0(TCH/H0), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 0), /* V1(TCH/H0), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) } } }; /* HVHH: TCH/H0 + V0(TCH/H1) & V1(TCH/H1), 3 channels total (mixed) */ private template (value) ChanNrModeTest ChanNrModeTestHVHH(uint3_t tn) := { { { ts_RslChanNr_Lm(tn, 0), /* TCH/H0, signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_TCH_H) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_OSMO_TCH_H_VAMOS) } }, { { ts_RslChanNr_Lm(tn, 0), /* TCH/H0, signalling */ ts_RSL_ChanMode_SIGN(RSL_CHRT_TCH_H) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) } }, { { ts_RslChanNr_Lm(tn, 0), /* TCH/H0, HR codec */ ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), HR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM1) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) } }, { { ts_RslChanNr_Lm(tn, 0), /* TCH/H0, AMR codec */ ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Lm(tn, 1), /* V0(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) }, { ts_RslChanNr_Osmo_VAMOS_Lm(tn, 1), /* V1(TCH/H1), AMR codec */ ts_RSL_ChanMode(RSL_CHRT_OSMO_TCH_H_VAMOS, RSL_CMOD_SP_GSM3) } } }; private template (value) RSL_IE ts_RSL_IE_OsmoTSC := { iei := RSL_IE_OSMO_TRAINING_SEQUENCE, body := { osmo_training_sequence := { len := 0, /* overridden */ tsc_set := f_rnd_int(4), tsc := f_rnd_int(8) } } } private function f_TC_vamos_exec_async(in ChanNrModeTest test, void_fn handler) runs on test_CT { /* Up to 4 simultenious lchans */ var ConnHdlrPars pars[4]; var ConnHdlr vc_conn[4]; f_init(); for (var integer i := 0; i < lengthof(test); i := i + 1) { /* Start a ConnHdlr component for each logical channel */ for (var integer ch := 0; ch < lengthof(test[i]); ch := ch + 1) { pars[ch] := valueof(t_Pars(test[i][ch].chan_nr, test[i][ch].chan_mode)); vc_conn[ch] := f_start_handler(handler, pars[ch], l1ctl := false); } /* Wait for all ConnHdlr components to finish */ for (var integer ch := 0; ch < lengthof(test[i]); ch := ch + 1) { vc_conn[ch].done; } } Misc_Helpers.f_shutdown(__BFILE__, __LINE__); } private function f_TC_vamos_chan_act(charstring id) runs on ConnHdlr { var RSL_IE tsc_ie := valueof(ts_RSL_IE_OsmoTSC); /* CHANnel ACTIVation with Osmocom specific TSC IE */ f_rsl_chan_act(g_pars.chan_mode, more_ies := { tsc_ie }); /* Hold the channel for a while */ f_sleep(0.3); /* DEACTivate the channel */ f_rsl_chan_deact(); f_rslem_unregister(0, g_chan_nr); } /* VFF: V0(TCH/F) & V1(TCH/F), 2 channels total */ testcase TC_vamos_chan_act_vff() runs on test_CT { /* TCH/F on TS1 */ var ChanNrModeTest test := valueof(ChanNrModeTestVFF(1)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_act)); } testcase TC_vamos_chan_act_dyn_ipa_vff() runs on test_CT { /* TCH/F+PDCH on TS3 */ var ChanNrModeTest test := valueof(ChanNrModeTestVFF(3)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_act)); } testcase TC_vamos_chan_act_dyn_osmo_vff() runs on test_CT { /* TCH/F+TCH/H+PDCH on TS4 */ var ChanNrModeTest test := valueof(ChanNrModeTestVFF(4)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_act)); } /* VHH: V0(TCH/H0) & V1(TCH/H0) + V0(TCH/H1) & V1(TCH/H1), 4 channels total */ testcase TC_vamos_chan_act_vhh() runs on test_CT { var ChanNrModeTest test := valueof(ChanNrModeTestVHH(5)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_act)); /* TCH/H on TS5 */ } testcase TC_vamos_chan_act_dyn_osmo_vhh() runs on test_CT { /* TCH/F+TCH/H+PDCH on TS4 */ var ChanNrModeTest test := valueof(ChanNrModeTestVHH(4)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_act)); } /* HVHH: TCH/H0 + V0(TCH/H1) & V1(TCH/H1), 3 channels total (mixed) */ testcase TC_vamos_chan_act_hvhh() runs on test_CT { var ChanNrModeTest test := valueof(ChanNrModeTestHVHH(5)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_act)); /* TCH/H on TS5 */ } testcase TC_vamos_chan_act_dyn_osmo_hvhh() runs on test_CT { /* TCH/F+TCH/H+PDCH on TS4 */ var ChanNrModeTest test := valueof(ChanNrModeTestHVHH(4)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_act)); } private function f_TC_vamos_chan_mode_modify(charstring id) runs on ConnHdlr { var RSL_IE tsc_ie := valueof(ts_RSL_IE_OsmoTSC); /* CHANnel ACTIVation with Osmocom specific IEs */ f_rsl_chan_act(g_pars.chan_mode, more_ies := { tsc_ie }); /* If we're in signalling mode, modify to speech */ if (g_pars.chan_mode.spd_ind == RSL_SPDI_SIGN) { g_pars.chan_mode.spd_ind := RSL_SPDI_SPEECH; g_pars.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1; } else { /* ... or vice versa */ g_pars.chan_mode.spd_ind := RSL_SPDI_SIGN; g_pars.chan_mode.coding_alg_rate := RSL_CMOD_NO_RESOURCE; } var RSL_Message rsl := valueof(ts_RSL_MODE_MODIFY_REQ(g_chan_nr, g_pars.chan_mode)); rsl.ies := rsl.ies & { tsc_ie }; RSL.send(rsl); timer T := 1.0; T.start; alt { [] RSL.receive(tr_RSL_MODE_MODIFY_ACK(g_chan_nr)) { setverdict(pass); } [] RSL.receive(tr_RSL_MODE_MODIFY_NACK(g_chan_nr, ?)) { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx MODE MODIFY NACK"); } [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for MODE MODIFY (N)ACK"); } } /* DEACTivate the channel */ f_rsl_chan_deact(); f_rslem_unregister(0, g_chan_nr); } /* VFF: V0(TCH/F) & V1(TCH/F), 2 channels total */ testcase TC_vamos_chan_mode_modify_vff() runs on test_CT { /* TCH/F on TS1 */ var ChanNrModeTest test := valueof(ChanNrModeTestVFF(1)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_mode_modify)); } testcase TC_vamos_chan_mode_modify_dyn_ipa_vff() runs on test_CT { /* TCH/F+PDCH on TS3 */ var ChanNrModeTest test := valueof(ChanNrModeTestVFF(3)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_mode_modify)); } testcase TC_vamos_chan_mode_modify_dyn_osmo_vff() runs on test_CT { /* TCH/F+TCH/H+PDCH on TS4 */ var ChanNrModeTest test := valueof(ChanNrModeTestVFF(4)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_mode_modify)); } /* VHH: V0(TCH/H0) & V1(TCH/H0) + V0(TCH/H1) & V1(TCH/H1), 4 channels total */ testcase TC_vamos_chan_mode_modify_vhh() runs on test_CT { var ChanNrModeTest test := valueof(ChanNrModeTestVHH(5)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_mode_modify)); /* TCH/H on TS5 */ } testcase TC_vamos_chan_mode_modify_dyn_osmo_vhh() runs on test_CT { /* TCH/F+TCH/H+PDCH on TS4 */ var ChanNrModeTest test := valueof(ChanNrModeTestVHH(4)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_mode_modify)); } /* HVHH: TCH/H0 + V0(TCH/H1) & V1(TCH/H1), 3 channels total (mixed) */ testcase TC_vamos_chan_mode_modify_hvhh() runs on test_CT { var ChanNrModeTest test := valueof(ChanNrModeTestHVHH(5)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_mode_modify)); /* TCH/H on TS5 */ } testcase TC_vamos_chan_mode_modify_dyn_osmo_hvhh() runs on test_CT { /* TCH/F+TCH/H+PDCH on TS4 */ var ChanNrModeTest test := valueof(ChanNrModeTestHVHH(4)); f_TC_vamos_exec_async(test, refers(f_TC_vamos_chan_mode_modify)); } control { /* CHANnel ACTIVation tests */ execute( TC_vamos_chan_act_vff() ); execute( TC_vamos_chan_act_vhh() ); execute( TC_vamos_chan_act_hvhh() ); execute( TC_vamos_chan_act_dyn_ipa_vff() ); execute( TC_vamos_chan_act_dyn_osmo_vff() ); execute( TC_vamos_chan_act_dyn_osmo_vhh() ); execute( TC_vamos_chan_act_dyn_osmo_hvhh() ); /* MODE MODIFY tests */ execute( TC_vamos_chan_mode_modify_vff() ); execute( TC_vamos_chan_mode_modify_vhh() ); execute( TC_vamos_chan_mode_modify_hvhh() ); execute( TC_vamos_chan_mode_modify_dyn_ipa_vff() ); execute( TC_vamos_chan_mode_modify_dyn_osmo_vff() ); execute( TC_vamos_chan_mode_modify_dyn_osmo_vhh() ); execute( TC_vamos_chan_mode_modify_dyn_osmo_hvhh() ); } }