diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn index 42de6be50..c82441514 100644 --- a/bsc/BSC_Tests.ttcn +++ b/bsc/BSC_Tests.ttcn @@ -12,6 +12,7 @@ import from BSSMAP_Templates all; import from IPA_Emulation all; import from IPA_Types all; import from RSL_Types all; +import from RSL_Emulation all; import from Osmocom_CTRL_Functions all; import from Osmocom_CTRL_Types all; @@ -75,10 +76,13 @@ modulepar { type record IPA_Client { IPA_Emulation_CT vc_IPA, IPA_CCM_Parameters ccm_pars, - charstring id + charstring id, + + RSL_Emulation_CT vc_RSL optional } -function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i) +function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i, + boolean handler_mode := false) runs on test_CT { timer T := 10.0; @@ -87,11 +91,22 @@ runs on test_CT { clnt.ccm_pars := c_IPA_default_ccm_pars; clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator"; clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0"; + if (handler_mode) { + clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL"); + } map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT); - connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]); + if (handler_mode) { + connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT); + } else { + connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]); + } clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars)); + if (handler_mode) { + clnt.vc_RSL.start(RSL_Emulation.main()); + return; + } /* wait for IPA RSL link to connect and send ID ACK */ T.start; @@ -170,7 +185,7 @@ altstep as_Tguard() runs on test_CT { } } -function f_init() runs on test_CT { +function f_init(boolean handler_mode := false) runs on test_CT { var integer i; if (g_initialized) { @@ -180,14 +195,14 @@ function f_init() runs on test_CT { /* Call a function of our 'parent component' BSSAP_Adapter_CT to start the * MSC-side BSSAP emulation */ - f_bssap_init("VirtMSC"); + f_bssap_init("VirtMSC", handler_mode); f_ipa_ctrl_start(ctrl, mp_bsc_ip, mp_bsc_ctrl_port, 0); for (i := 0; i < NUM_BTS; i := i+1) { /* wait until osmo-bts-omldummy has respawned */ f_wait_oml(i, "degraded", 5.0); /* start RSL connection */ - f_ipa_rsl_start(bts[i].rsl, mp_bsc_ip, mp_bsc_rsl_port, i); + f_ipa_rsl_start(bts[i].rsl, mp_bsc_ip, mp_bsc_rsl_port, i, handler_mode); /* wait until BSC tells us "connected" */ f_wait_oml(i, "connected", 5.0); } diff --git a/bsc/BSSAP_Adapter.ttcn b/bsc/BSSAP_Adapter.ttcn index 60c71037d..f1ff5b6b9 100644 --- a/bsc/BSSAP_Adapter.ttcn +++ b/bsc/BSSAP_Adapter.ttcn @@ -22,6 +22,9 @@ import from SCTPasp_PortType all; import from BSSAP_CodecPort all; import from BSSMAP_Templates all; +import from BSSMAP_Emulation all; + +import from MSC_ConnectionHandler all; type component BSSAP_Adapter_CT { /* component references */ @@ -33,6 +36,9 @@ type component BSSAP_Adapter_CT { var octetstring g_sio; var MSC_SCCP_MTP3_parameters g_sccp_pars; var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer; + + /* handler mode */ + var BSSMAP_Emulation_CT vc_BSSMAP; } modulepar { @@ -79,24 +85,33 @@ private function init_pars() runs on BSSAP_Adapter_CT { } -function f_bssap_init(charstring id) runs on BSSAP_Adapter_CT +function f_bssap_init(charstring id, boolean handler_mode := false) runs on BSSAP_Adapter_CT { init_pars(); /* create components */ vc_M3UA := M3UA_CT.create(id & "-M3UA"); vc_SCCP := SCCP_CT.create(id & "-SCCP"); + if (handler_mode) { + vc_BSSMAP := BSSMAP_Emulation_CT.create(id & "-BSSMAP"); + } map(vc_M3UA:SCTP_PORT, system:sctp); /* connect MTP3 service provider (M3UA) to lower side of SCCP */ connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT); - - /* connect BSSNAP dispatcher to upper side of SCCP */ - connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT); + if (handler_mode) { + connect(vc_BSSMAP:BSSAP, vc_SCCP:SCCP_SP_PORT); + } else { + /* connect BSSNAP dispatcher to upper side of SCCP */ + connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT); + } vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr)); vc_SCCP.start(SCCPStart(g_sccp_pars)); + if (handler_mode) { + vc_BSSMAP.start(BSSMAP_Emulation.main(MSC_BssmapOps, "")); + } } private altstep as_reset_ack() runs on BSSAP_Adapter_CT { diff --git a/bsc/gen_links.sh b/bsc/gen_links.sh index e46bee1ab..5d8555a8d 100755 --- a/bsc/gen_links.sh +++ b/bsc/gen_links.sh @@ -76,5 +76,5 @@ FILES="RTP_EncDec.cc RTP_Types.ttcn" gen_links $DIR $FILES DIR=../library -FILES="General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcn L3_Templates.ttcn BSSMAP_Templates.ttcn BSSMAP_Emulation.ttcn RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn BSSAP_CodecPort.ttcn Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn" +FILES="General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcn L3_Templates.ttcn BSSMAP_Templates.ttcn BSSMAP_Emulation.ttcn RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc BSSAP_CodecPort.ttcn Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn" gen_links $DIR $FILES diff --git a/bsc/regen_makefile.sh b/bsc/regen_makefile.sh index 8b8fa435c..d93748284 100755 --- a/bsc/regen_makefile.sh +++ b/bsc/regen_makefile.sh @@ -2,6 +2,6 @@ MAIN=BSC_Tests.ttcn -FILES="*.ttcn IPA_CodecPort_CtrlFunctDef.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc SCTPasp_PT.cc RTP_EncDec.cc SDP_EncDec.cc *.c" +FILES="*.ttcn IPA_CodecPort_CtrlFunctDef.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc SCTPasp_PT.cc RTP_EncDec.cc SDP_EncDec.cc RTP_CodecPort_CtrlFunctDef.cc MGCP_CodecPort_CtrlFunctDef.cc *.c" ../regen-makefile.sh $MAIN $FILES diff --git a/library/BSSMAP_Emulation.ttcn b/library/BSSMAP_Emulation.ttcn index 14bf238b8..ba7e27c3e 100644 --- a/library/BSSMAP_Emulation.ttcn +++ b/library/BSSMAP_Emulation.ttcn @@ -58,6 +58,11 @@ type component BSSMAP_Emulation_CT { /* use 16 as this is also the number of SCCP connections that SCCP_Emulation can handle */ var ConnectionData ConnectionTable[16]; + /* pending expected incoming connections */ + var ExpectData ExpectTable[8]; + /* procedure based port to register for incoming connections */ + port BSSMAPEM_PROC_PT PROC; + var charstring g_bssmap_id; var integer g_next_e1_ts := 1; }; @@ -274,6 +279,8 @@ function main(BssmapOps ops, charstring id) runs on BSSMAP_Emulation_CT { var PDU_BSSAP bssap; var MgcpCommand mgcp_req; var MgcpResponse mgcp_resp; + var BSSAP_ConnHdlr vc_hdlr; + var octetstring l3_info; alt { /* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */ @@ -401,6 +408,12 @@ function main(BssmapOps ops, charstring id) runs on BSSMAP_Emulation_CT { CLIENT.send(mgcp_resp) to vc_conn; } + + [] PROC.getcall(BSSMAPEM_register:{?,?}) -> param(l3_info, vc_hdlr) { + f_create_expect(l3_info, vc_hdlr); + PROC.reply(BSSMAPEM_register:{l3_info, vc_hdlr}); + } + } } } @@ -411,4 +424,69 @@ private function f_mgcp_ep_extract_cic(charstring inp) return integer { } +/*********************************************************************** + * "Expect" Handling (mapping for expected incoming SCCP connections) + ***********************************************************************/ + +/* data about an expected future incoming connection */ +type record ExpectData { + /* L3 payload based on which we can match it */ + octetstring l3_payload optional, + /* component reference for this connection */ + BSSAP_ConnHdlr vc_conn +} + +/* procedure based port to register for incoming connections */ +signature BSSMAPEM_register(in octetstring l3, in BSSAP_ConnHdlr hdlr); + +type port BSSMAPEM_PROC_PT procedure { + inout BSSMAPEM_register; +} with { extension "internal" }; + +/* CreateCallback that can be used as create_cb and will use the expectation table */ +function ExpectedCreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id) +runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr { + var BSSAP_ConnHdlr ret := null; + var octetstring l3_info; + var integer i; + + if (not ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) { + setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3"); + return ret; + } + l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info; + + for (i := 0; i < sizeof(ExpectTable); i:= i+1) { + if (not ispresent(ExpectTable[i].l3_payload)) { + continue; + } + if (l3_info == ExpectTable[i].l3_payload) { + ret := ExpectTable[i].vc_conn; + /* release this entry to be used again */ + ExpectTable[i].l3_payload := omit; + ExpectTable[i].vc_conn := null; + log("Found Expect[", i, "] for ", l3_info, " handled at ", ret); + /* return the component reference */ + return ret; + } + } + setverdict(fail, "Couldn't find Expect for incoming connection ", conn_ind); + return ret; +} + +private function f_create_expect(octetstring l3, BSSAP_ConnHdlr hdlr) +runs on BSSMAP_Emulation_CT { + var integer i; + for (i := 0; i < sizeof(ExpectTable); i := i+1) { + if (not ispresent(ExpectTable[i].l3_payload)) { + ExpectTable[i].l3_payload := l3; + ExpectTable[i].vc_conn := hdlr; + log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr); + return; + } + } + setverdict(fail, "No space left in ExpectTable"); +} + + } diff --git a/library/RSL_Emulation.ttcn b/library/RSL_Emulation.ttcn index d558412cd..a42ca1eae 100644 --- a/library/RSL_Emulation.ttcn +++ b/library/RSL_Emulation.ttcn @@ -199,6 +199,8 @@ function main() runs on RSL_Emulation_CT { while (true) { alt { + [] IPA_PT.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) { + } [] IPA_PT.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_ID_ACK}) { IPA_PT.send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_PAGING_LOAD_IND(23))); }