| module BSCNAT_Tests { |
| |
| /* osmo-bsc_nat test suite in TTCN-3 |
| * (C) 2018-2019 sysmocom - s.f.m.c. GmbH |
| * Author: Daniel Willmann |
| * 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 |
| */ |
| |
| import from Osmocom_Types all; |
| |
| import from IPL4asp_Types all; |
| |
| import from IPA_Emulation all; |
| import from RAN_Emulation all; |
| |
| import from MTP3asp_Types all; |
| |
| import from Osmocom_CTRL_Functions all; |
| import from Osmocom_CTRL_Types all; |
| import from Osmocom_CTRL_Adapter all; |
| |
| import from SCCP_Types all; |
| import from SCCPasp_Types all; |
| import from SCCP_Emulation all; |
| |
| import from MSC_Simulation all; |
| import from MSC_ConnectionHandler all; |
| import from BSC_MS_Simulation all; |
| import from BSC_MS_ConnectionHandler all; |
| |
| import from Osmocom_VTY_Functions all; |
| import from TELNETasp_PortType all; |
| |
| const integer NUM_MSC := 1; |
| const integer NUM_BSC := 1; |
| |
| type record BscState { |
| BSC_CT BSC, |
| MSC_SCCP_MTP3_parameters sccp_pars, |
| SCCP_PAR_Address sccp_addr_own, |
| SCCP_PAR_Address sccp_addr_peer |
| } |
| |
| type record MscState { |
| MSC_CT MSC, |
| MSC_SCCP_MTP3_parameters sccp_pars, |
| SCCP_PAR_Address sccp_addr_own |
| } |
| |
| type component test_CT extends CTRL_Adapter_CT { |
| var MscState msc[NUM_MSC]; |
| var BscState bsc[NUM_BSC]; |
| |
| port TELNETasp_PT BSCNATVTY; |
| |
| var boolean g_initialized := false; |
| var octetstring g_sio := '83'O; |
| } |
| |
| modulepar { |
| PortNumber mp_bsc_port := 49999; |
| charstring mp_bsc_ip := "127.0.0.1"; |
| |
| PortNumber mp_msc_port := 5000; |
| charstring mp_msc_ip := "127.0.0.1"; |
| |
| /* port number to which to establish the IPA CTRL connection */ |
| integer mp_nat_ctrl_port := 4250; |
| /* port number to which to establish the SCCPLite connection */ |
| PortNumber mp_nat_port := 5000; |
| charstring mp_nat_ip := "127.0.0.1"; |
| |
| charstring mp_sccp_service_type := "mtp3_itu"; |
| |
| integer mp_bsc_pc := 196; |
| integer mp_bsc_ssn := 254; |
| |
| integer mp_msc_pc := 185; /* 0.23.1 */ |
| integer mp_msc_ssn := 254; |
| } |
| |
| /* construct a SCCP_PAR_Address with just PC + SSN and no GT */ |
| template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := { |
| addressIndicator := { |
| pointCodeIndic := '1'B, |
| ssnIndicator := '1'B, |
| globalTitleIndic := '0000'B, |
| routingIndicator := '1'B |
| }, |
| signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O), |
| //signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio), |
| subsystemNumber := ssn, |
| globalTitle := omit |
| } |
| |
| template MTP3_Field_sio ts_sio(octetstring sio_in) := { |
| ni := substr(oct2bit(sio_in),0,2), |
| prio := substr(oct2bit(sio_in),2,2), |
| si := substr(oct2bit(sio_in),4,4) |
| } |
| |
| template MSC_SCCP_MTP3_parameters ts_SCCP_Pars(octetstring sio, integer opc, integer dpc, |
| integer local_ssn) := { |
| sio := ts_sio(sio), |
| opc := opc, |
| dpc := dpc, |
| sls := 0, |
| sccp_serviceType := mp_sccp_service_type, |
| ssn := local_ssn |
| }; |
| |
| function f_init_BscState(inout BscState bsc_st, integer opc, integer dpc, integer local_ssn, integer remote_ssn) |
| runs on test_CT { |
| bsc_st.sccp_pars := valueof(ts_SCCP_Pars(g_sio, opc, dpc, local_ssn)); |
| bsc_st.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(opc, local_ssn)); |
| bsc_st.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(dpc, remote_ssn)); |
| } |
| |
| function f_init_MscState(inout MscState msc_st, integer opc, integer dpc, integer local_ssn, integer remote_ssn) |
| runs on test_CT { |
| msc_st.sccp_pars := valueof(ts_SCCP_Pars(g_sio, opc, dpc, local_ssn)); |
| msc_st.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(opc, local_ssn)); |
| } |
| |
| function f_vty_allow_osmux(boolean allow) runs on test_CT { |
| if (allow) { |
| f_vty_config(BSCNATVTY, "mgcp", "osmux on"); |
| } else { |
| f_vty_config(BSCNATVTY, "mgcp", "osmux off"); |
| } |
| } |
| |
| function f_init_vty(charstring id := "foo") runs on test_CT { |
| if (BSCNATVTY.checkstate("Mapped")) { |
| /* skip initialization if already executed once */ |
| return; |
| } |
| map(self:BSCNATVTY, system:BSCNATVTY); |
| f_vty_set_prompts(BSCNATVTY); |
| f_vty_transceive(BSCNATVTY, "enable"); |
| } |
| |
| function f_init(void_fn_bsc_ms fn_bsc_ms, void_fn_bsc fn_bsc, BssmapCreateCallback cb_msc, boolean use_osmux) runs on test_CT { |
| var integer i; |
| var charstring id; |
| |
| f_init_vty("VirtBSCNAT"); |
| f_vty_allow_osmux(use_osmux); |
| f_ipa_ctrl_start_client(mp_nat_ip, mp_nat_ctrl_port); |
| |
| for (i := 0; i < NUM_MSC; i := i+1) { |
| f_init_MscState(msc[i], mp_msc_pc +i, mp_bsc_pc, mp_msc_ssn, mp_bsc_ssn); |
| id := "MSC" & int2str(i); |
| msc[i].MSC := MSC_CT.create(id); |
| msc[i].MSC.start(MSC_Simulation.main(mp_msc_ip, mp_msc_port + i, |
| msc[i].sccp_pars, msc[i].sccp_addr_own, |
| cb_msc, id)); |
| } |
| |
| /* Wait for bsc_nat to attach to MSC. Before that all BSC connections will be dropped */ |
| f_sleep(5.0); |
| |
| for (i := 0; i < NUM_BSC; i := i+1) { |
| f_init_BscState(bsc[i], mp_bsc_pc +i, mp_msc_pc, mp_bsc_ssn, mp_msc_ssn); |
| id := "BSC" & int2str(i); |
| bsc[i].BSC := BSC_CT.create(id); |
| var BSC_MS_TestHdlrParams pars; |
| pars.sccp_addr_own := bsc[i].sccp_addr_own; |
| pars.sccp_addr_remote := bsc[i].sccp_addr_peer; |
| pars.use_osmux := use_osmux; |
| bsc[i].BSC.start(BSC_MS_Simulation.main(mp_nat_ip, mp_nat_port, mp_bsc_ip, mp_bsc_port+i, |
| bsc[i].sccp_pars, pars, fn_bsc_ms, fn_bsc, id)); |
| } |
| |
| } |
| |
| function f_wait_finish(timer T) runs on test_CT { |
| var integer i; |
| alt { |
| /* wait for BSC to stop. The idea is that the BSC components terminate first */ |
| [] bsc[0].BSC.done { } |
| [] T.timeout { setverdict(fail); } |
| } |
| |
| all component.stop; |
| /* terminate the MSCs */ |
| for (i := 0; i < NUM_MSC; i := i+1) { |
| msc[i].MSC.stop; |
| } |
| setverdict(pass); |
| } |
| |
| |
| function f_TC_recv_dump(boolean use_osmux := false) runs on test_CT { |
| timer T := 30.0; |
| T.start; |
| |
| f_init(refers(bsc_ms_establish_fully), |
| refers(bsc_do_nothing), |
| refers(CreateCallback_establish_fully), |
| use_osmux); |
| |
| f_wait_finish(T); |
| } |
| |
| testcase TC_recv_dump() runs on test_CT { |
| f_TC_recv_dump(); |
| } |
| |
| testcase TC_recv_dump_osmux() runs on test_CT { |
| f_TC_recv_dump(true); |
| } |
| |
| testcase TC_ctrl_location() runs on test_CT { |
| timer T := 30.0; |
| T.start; |
| |
| f_init(refers(bsc_ms_do_nothing), |
| refers(bsc_ctrl_location), |
| refers(CreateCallback_establish_fully), |
| false); |
| |
| f_ctrl_exp_trap(IPA_CTRL, "net.0.bsc.0.bts.0.location-state", |
| "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01", |
| 10.0); |
| f_ctrl_set(IPA_CTRL, "net.0.bsc.0.rf_locked", "1"); |
| |
| f_wait_finish(T); |
| } |
| |
| control { |
| execute( TC_recv_dump() ); |
| execute( TC_recv_dump_osmux() ); |
| execute( TC_ctrl_location() ); |
| } |
| |
| } |