diff --git a/bsc-nat/BSC_MS_ConnectionHandler.ttcn b/bsc-nat/BSC_MS_ConnectionHandler.ttcn index 63d0451c5..e52b678fd 100644 --- a/bsc-nat/BSC_MS_ConnectionHandler.ttcn +++ b/bsc-nat/BSC_MS_ConnectionHandler.ttcn @@ -53,6 +53,7 @@ const RanOps BSC_MS_RanOps := { unitdata_cb := refers(UnitdataCallback), decode_dtap := false, role_ms := true, + protocol := RAN_PROTOCOL_BSSAP, sccp_addr_local := omit, sccp_addr_peer := omit } diff --git a/bsc-nat/MSC_ConnectionHandler.ttcn b/bsc-nat/MSC_ConnectionHandler.ttcn index 383b67b12..8635a2969 100644 --- a/bsc-nat/MSC_ConnectionHandler.ttcn +++ b/bsc-nat/MSC_ConnectionHandler.ttcn @@ -59,6 +59,7 @@ const RanOps MSC_RanOps := { unitdata_cb := refers(UnitdataCallback), decode_dtap := false, role_ms := false, + protocol := RAN_PROTOCOL_BSSAP, sccp_addr_local := omit, sccp_addr_peer := omit } diff --git a/bsc-nat/gen_links.sh b/bsc-nat/gen_links.sh index e54eec483..16e32b78f 100755 --- a/bsc-nat/gen_links.sh +++ b/bsc-nat/gen_links.sh @@ -47,7 +47,7 @@ FILES="RTP_EncDec.cc RTP_Types.ttcn" gen_links $DIR $FILES DIR=../library -FILES="Misc_Helpers.ttcn 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.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn RAN_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn BSSAP_CodecPort.ttcn" +FILES="Misc_Helpers.ttcn 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.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn RAN_Emulation.ttcnpp MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn BSSAP_CodecPort.ttcn" gen_links $DIR $FILES ignore_pp_results diff --git a/bsc-nat/regen_makefile.sh b/bsc-nat/regen_makefile.sh index c5fe64c41..f49df7e2e 100755 --- a/bsc-nat/regen_makefile.sh +++ b/bsc-nat/regen_makefile.sh @@ -4,6 +4,6 @@ MAIN=BSCNAT_Tests.ttcn FILES="*.ttcn *.ttcnpp SCCP_EncDec.cc IPA_CodecPort_CtrlFunctDef.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc RTP_EncDec.cc SDP_EncDec.cc *.c MGCP_CodecPort_CtrlFunctDef.cc" -export CPPFLAGS_TTCN3="-DIPA_EMULATION_SCCP -DIPA_EMULATION_MGCP -DUSE_MTP3_DISTRIBUTOR" +export CPPFLAGS_TTCN3="-DIPA_EMULATION_SCCP -DIPA_EMULATION_MGCP -DRAN_EMULATION_BSSAP -DRAN_EMULATION_MGCP -DUSE_MTP3_DISTRIBUTOR" ../regen-makefile.sh $MAIN $FILES diff --git a/bsc/MSC_ConnectionHandler.ttcn b/bsc/MSC_ConnectionHandler.ttcn index 36e554df6..520cc3eac 100644 --- a/bsc/MSC_ConnectionHandler.ttcn +++ b/bsc/MSC_ConnectionHandler.ttcn @@ -376,6 +376,7 @@ const RanOps MSC_RanOps := { unitdata_cb := refers(UnitdataCallback), decode_dtap := false, role_ms := false, + protocol := RAN_PROTOCOL_BSSAP, sccp_addr_local := omit, sccp_addr_peer := omit } diff --git a/bsc/gen_links.sh b/bsc/gen_links.sh index d8393c325..a4f09f4d6 100755 --- a/bsc/gen_links.sh +++ b/bsc/gen_links.sh @@ -67,7 +67,7 @@ FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn" gen_links $DIR $FILES DIR=../library -FILES="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn RAN_Emulation.ttcn RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc BSSAP_CodecPort.ttcn RAN_Adapter.ttcn Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn SCCP_Templates.ttcn IPA_Testing.ttcn" +FILES="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn RAN_Emulation.ttcnpp RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc BSSAP_CodecPort.ttcn RAN_Adapter.ttcnpp Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn SCCP_Templates.ttcn IPA_Testing.ttcn" gen_links $DIR $FILES ignore_pp_results diff --git a/bsc/regen_makefile.sh b/bsc/regen_makefile.sh index 08629d209..06fa81216 100755 --- a/bsc/regen_makefile.sh +++ b/bsc/regen_makefile.sh @@ -4,6 +4,6 @@ MAIN=BSC_Tests.ttcn FILES="*.ttcn *.ttcnpp 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 IuUP_EncDec.cc Native_FunctionDefs.cc TELNETasp_PT.cc *.c" -export CPPFLAGS_TTCN3="-DIPA_EMULATION_RSL -DIPA_EMULATION_MGCP -DIPA_EMULATION_SCCP -DUSE_MTP3_DISTRIBUTOR" +export CPPFLAGS_TTCN3="-DIPA_EMULATION_RSL -DIPA_EMULATION_MGCP -DIPA_EMULATION_SCCP -DRAN_EMULATION_BSSAP -DRAN_EMULATION_MGCP -DUSE_MTP3_DISTRIBUTOR" ../regen-makefile.sh $MAIN $FILES diff --git a/library/RAN_Adapter.ttcn b/library/RAN_Adapter.ttcnpp similarity index 98% rename from library/RAN_Adapter.ttcn rename to library/RAN_Adapter.ttcnpp index 294f747bb..43b4988a6 100644 --- a/library/RAN_Adapter.ttcn +++ b/library/RAN_Adapter.ttcnpp @@ -88,6 +88,7 @@ function f_bssap_init(inout RAN_Adapter ba, in RAN_Configuration cfg, charstring ba.vc_RAN := RAN_Emulation_CT.create(id & "-RAN"); } select (cfg.transport) { +#ifdef RAN_EMULATION_BSSAP case (BSSAP_TRANSPORT_AoIP) { ba.vc_M3UA := M3UA_CT.create(id & "-M3UA"); map(ba.vc_M3UA:SCTP_PORT, system:sctp); @@ -128,6 +129,7 @@ function f_bssap_init(inout RAN_Adapter ba, in RAN_Configuration cfg, charstring ba.vc_WAIT.done; disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT); } +#endif case else { setverdict(fail, "Unsuppored RAN_Transport"); mtc.stop; @@ -139,8 +141,10 @@ function f_bssap_init(inout RAN_Adapter ba, in RAN_Configuration cfg, charstring T.start; //T.timeout; log("Connecting BSSMAP Emulation to SCCP_SP_PORT and starting emulation"); +#if RAN_EMULATION_BSSAP /* connect BSSNAP component to upper side of SCCP */ connect(ba.vc_RAN:BSSAP, ba.vc_SCCP:SCCP_SP_PORT); +#endif if (cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER or cfg.transport == BSSAP_TRANSPORT_SCCPlite_CLIENT) { /* connect IPA MGCP port with BSSMAP MGCP port */ diff --git a/library/RAN_Emulation.ttcn b/library/RAN_Emulation.ttcnpp similarity index 92% rename from library/RAN_Emulation.ttcn rename to library/RAN_Emulation.ttcnpp index 72e2733fc..e0911331e 100644 --- a/library/RAN_Emulation.ttcn +++ b/library/RAN_Emulation.ttcnpp @@ -22,7 +22,7 @@ module RAN_Emulation { * Inbound Unit Data messages (such as are dispatched to the RanOps.unitdata_cb() callback, * which is registered with an argument to the main() function below. * - * (C) 2017-2018 by Harald Welte + * (C) 2017-2019 by Harald Welte * All rights reserved. * * Released under the terms of GNU General Public License, Version 2 or @@ -34,13 +34,19 @@ import from General_Types all; import from Osmocom_Types all; import from SCCP_Emulation all; import from SCCPasp_Types all; +import from IPA_Emulation all; +import from MobileL3_Types all; + +#ifdef RAN_EMULATION_BSSAP import from BSSAP_Types all; import from BSSAP_CodecPort all; import from BSSMAP_Templates all; +#endif + +#ifdef RAN_EMULATION_MGCP import from MGCP_Types all; import from MGCP_Templates all; -import from IPA_Emulation all; -import from MobileL3_Types all; +#endif /* General "base class" component definition, of which specific implementations * derive themselves by means of the "extends" feature */ @@ -61,12 +67,6 @@ type enumerated RAN_Conn_Prim { MSC_CONN_PRIM_CONF_IND } -type record BSSAP_Conn_Req { - SCCP_PAR_Address addr_peer, - SCCP_PAR_Address addr_own, - PDU_BSSAP bssap -} - /* similar to PDU_BSSAP with DTAP, but DTAP is already decoded! */ type record PDU_DTAP_MO { OCT1 dlci optional, @@ -102,23 +102,22 @@ template PDU_DTAP_MO tr_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 d dtap := dtap } -template BSSAP_Conn_Req ts_BSSAP_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, PDU_BSSAP bssap) := { - addr_peer := peer, - addr_own := own, - bssap := bssap -}; - - /* port between individual per-connection components and this dispatcher */ type port RAN_Conn_PT message { - /* BSSAP or direct DTAP messages from/to clients */ - inout PDU_BSSAP, PDU_DTAP_MO, PDU_DTAP_MT, - /* misc indications / requests between SCCP and client */ - RAN_Conn_Prim, + inout +#ifdef RAN_EMULATION_BSSAP + PDU_BSSAP, /* Client requests us to create SCCP Connection */ BSSAP_Conn_Req, +#endif +#ifdef RAN_EMULATION_MGCP /* MGCP, only used for IPA SCCPlite (MGCP in IPA mux) */ - MgcpCommand, MgcpResponse; + MgcpCommand, MgcpResponse, +#endif + /* direct DTAP messages from/to clients */ + PDU_DTAP_MO, PDU_DTAP_MT, + /* misc indications / requests between SCCP and client */ + RAN_Conn_Prim; } with { extension "internal" }; @@ -127,8 +126,10 @@ type record ConnectionData { /* reference to the instance of the per-connection component */ RAN_ConnHdlr comp_ref, integer sccp_conn_id, +#ifdef RAN_EMULATION_MGCP /* most recent MGCP transaction ID (Used on MSC side) */ MgcpTransId mgcp_trans_id optional, +#endif /* CIC that has been used for voice of this channel (BSC side) */ integer cic optional, /* array of N(SD) values for MO DTAP messages, indexed by discriminator */ @@ -142,12 +143,16 @@ type record ImsiMapping { } type component RAN_Emulation_CT { - /* SCCP port on the bottom side, using ASP primitives */ + /* SCCP ports on the bottom side, using ASP primitives */ +#ifdef RAN_EMULATION_BSSAP port BSSAP_CODEC_PT BSSAP; +#endif /* BSSAP port to the per-connection clients */ port RAN_Conn_PT CLIENT; +#ifdef RAN_EMULATION_MGCP /* MGCP port */ port IPA_MGCP_PT MGCP; +#endif /* use 16 as this is also the number of SCCP connections that SCCP_Emulation can handle */ var ConnectionData ConnectionTable[16]; @@ -212,6 +217,8 @@ runs on RAN_Emulation_CT return RAN_ConnHdlr { mtc.stop; } + +#ifdef RAN_EMULATION_MGCP /* resolve component reference by CIC */ private function f_comp_by_mgcp_tid(MgcpTransId tid) runs on RAN_Emulation_CT return RAN_ConnHdlr { @@ -237,6 +244,7 @@ runs on RAN_Emulation_CT { setverdict(fail, "RAN Connection table not found by component ", client); mtc.stop; } +#endif private function f_comp_by_cic(integer cic) runs on RAN_Emulation_CT return RAN_ConnHdlr { @@ -303,7 +311,9 @@ runs on RAN_Emulation_CT { for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) { ConnectionTable[i].comp_ref := null; ConnectionTable[i].sccp_conn_id := -1; +#ifdef RAN_EMULATION_MGCP ConnectionTable[i].mgcp_trans_id := omit; +#endif ConnectionTable[i].cic := omit; ConnectionTable[i].n_sd := { 0, 0, 0, 0 }; } @@ -354,6 +364,18 @@ runs on RAN_Emulation_CT return RAN_ConnHdlr { return null; } +#ifdef RAN_EMULATION_BSSAP +type record BSSAP_Conn_Req { + SCCP_PAR_Address addr_peer, + SCCP_PAR_Address addr_own, + PDU_BSSAP bssap +} +template BSSAP_Conn_Req ts_BSSAP_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, PDU_BSSAP bssap) := { + addr_peer := peer, + addr_own := own, + bssap := bssap +}; + /* handle (optional) userData portion of various primitives and dispatch it to the client */ private function f_handle_userData(RAN_ConnHdlr client, PDU_BSSAP bssap) runs on RAN_Emulation_CT { @@ -420,69 +442,6 @@ runs on RAN_Emulation_CT return template PDU_BSSAP { return g_ran_ops.unitdata_cb.apply(bssap); } -type record RanOps { - BssmapCreateCallback create_cb, - BssmapUnitdataCallback unitdata_cb, - boolean decode_dtap, - boolean role_ms, - /* needed for performing BSSMAP RESET */ - SCCP_PAR_Address sccp_addr_local optional, - SCCP_PAR_Address sccp_addr_peer optional -} - -template BIT4 t_ML3_DISC_CC_MM_SS := ('0011'B, '0101'B, '1011'B); - -/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */ -function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) { - var uint2_t seq_nr; - if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) { - seq_nr := cd.n_sd[0]; - cd.n_sd[0] := (cd.n_sd[0] + 1) mod 4; - } else if (ischosen(dtap.msgs.gcc)) { - seq_nr := cd.n_sd[1]; - cd.n_sd[1] := (cd.n_sd[1] + 1) mod 2; - } else if (ischosen(dtap.msgs.bcc)) { - seq_nr := cd.n_sd[2]; - cd.n_sd[2] := (cd.n_sd[2] + 1) mod 2; - } else if (ischosen(dtap.msgs.loc)) { - seq_nr := cd.n_sd[3]; - cd.n_sd[3] := (cd.n_sd[3] + 1) mod 2; - } else { - /* no sequence number to patch */ - return; - } - log("patching N(SD)=", seq_nr, " into dtap ", enc_l3); - enc_l3[1] := (enc_l3[1] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6); - log("patched enc_l3: ", enc_l3); -} - -private function f_bssap_l3_is_rr(PDU_BSSAP bssap) return boolean { - var template octetstring l3 := f_bssap_extract_l3(bssap); - if (not isvalue(l3)) { - return false; - } - var octetstring l3v := valueof(l3); - if (lengthof(l3v) < 1) { - return false; - } - /* lower 4 bits of first octet are protocol discriminator */ - if ((oct2bit(l3v[0]) and4b '00001111'B) == '00000110'B) { - return true; - } - return false; -} - -private altstep as_reset_ack() runs on RAN_Emulation_CT { - var BSSAP_N_UNITDATA_ind ud_ind; - [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { - log("Respoding to inbound RESET with RESET-ACK"); - BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, - ts_BSSMAP_ResetAck)); - repeat; - } -} - - private function f_bssap_wait_for_reset() runs on RAN_Emulation_CT { var BSSAP_N_UNITDATA_ind ud_ind; timer T := 20.0; @@ -522,37 +481,98 @@ function f_bssap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on RAN_ } } -function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { +private function f_bssap_l3_is_rr(PDU_BSSAP bssap) return boolean { + var template octetstring l3 := f_bssap_extract_l3(bssap); + return f_L3_is_rr(l3); +} +#endif - g_ran_id := id; - g_ran_ops := ops; - f_conn_table_init(); - f_expect_table_init(); - if (isvalue(ops.sccp_addr_peer) and isvalue(ops.sccp_addr_local)) { - f_sleep(1.0); /* HACK to wait for M3UA/ASP to be ACTIVE */ - f_bssap_reset(ops.sccp_addr_peer, ops.sccp_addr_local); + +type enumerated RanProtocol { + RAN_PROTOCOL_BSSAP +} + +type record RanOps { +#ifdef RAN_EMULATION_BSSAP + BssmapCreateCallback create_cb optional, + BssmapUnitdataCallback unitdata_cb optional, +#endif + boolean decode_dtap, + boolean role_ms, + RanProtocol protocol, + /* needed for performing BSSMAP RESET */ + SCCP_PAR_Address sccp_addr_local optional, + SCCP_PAR_Address sccp_addr_peer optional +} + +template BIT4 t_ML3_DISC_CC_MM_SS := ('0011'B, '0101'B, '1011'B); + +private function f_L3_is_rr(template octetstring l3) return boolean { + if (not isvalue(l3)) { + return false; } + var octetstring l3v := valueof(l3); + if (lengthof(l3v) < 1) { + return false; + } + /* lower 4 bits of first octet are protocol discriminator */ + if ((oct2bit(l3v[0]) and4b '00001111'B) == '00000110'B) { + return true; + } + return false; +} - while (true) { +/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */ +function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) { + var uint2_t seq_nr; + if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) { + seq_nr := cd.n_sd[0]; + cd.n_sd[0] := (cd.n_sd[0] + 1) mod 4; + } else if (ischosen(dtap.msgs.gcc)) { + seq_nr := cd.n_sd[1]; + cd.n_sd[1] := (cd.n_sd[1] + 1) mod 2; + } else if (ischosen(dtap.msgs.bcc)) { + seq_nr := cd.n_sd[2]; + cd.n_sd[2] := (cd.n_sd[2] + 1) mod 2; + } else if (ischosen(dtap.msgs.loc)) { + seq_nr := cd.n_sd[3]; + cd.n_sd[3] := (cd.n_sd[3] + 1) mod 2; + } else { + /* no sequence number to patch */ + return; + } + log("patching N(SD)=", seq_nr, " into dtap ", enc_l3); + enc_l3[1] := (enc_l3[1] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6); + log("patched enc_l3: ", enc_l3); +} + +private altstep as_reset_ack() runs on RAN_Emulation_CT { +#ifdef RAN_EMULATION_BSSAP + var BSSAP_N_UNITDATA_ind ud_ind; +#endif +#ifdef RAN_EMULATION_BSSAP + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { + log("Respoding to inbound RESET with RESET-ACK"); + BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, + ts_BSSMAP_ResetAck)); + repeat; + } +#endif +} + + +private altstep as_main_bssap() runs on RAN_Emulation_CT { +#ifdef RAN_EMULATION_BSSAP var BSSAP_N_UNITDATA_ind ud_ind; var BSSAP_N_CONNECT_ind conn_ind; var BSSAP_N_CONNECT_cfm conn_cfm; var BSSAP_N_DATA_ind data_ind; var BSSAP_N_DISCONNECT_ind disc_ind; var BSSAP_Conn_Req creq; - var RAN_ConnHdlr vc_conn; var PDU_BSSAP bssap; - var PDU_DTAP_MO dtap_mo; - var PDU_DTAP_MT dtap_mt; - var MgcpCommand mgcp_req; - var MgcpResponse mgcp_resp; - var RAN_ConnHdlr vc_hdlr; - var octetstring l3_info; - var hexstring imsi; - var OCT4 tmsi; + var RAN_ConnHdlr vc_conn; - alt { /* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */ [] BSSAP.receive(BSSAP_N_UNITDATA_ind:?) -> value ud_ind { /* Connectionless Procedures like RESET */ @@ -563,10 +583,9 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { ud_ind.calledAddress, resp)); } } - /* SCCP -> Client: new connection from BSC */ [] BSSAP.receive(BSSAP_N_CONNECT_ind:?) -> value conn_ind { - vc_conn := ops.create_cb.apply(conn_ind, id); + vc_conn := g_ran_ops.create_cb.apply(conn_ind, g_ran_id); /* store mapping between client components and SCCP connectionId */ f_conn_table_add(vc_conn, conn_ind.connectionId); /* handle user payload */ @@ -574,7 +593,6 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { /* confirm connection establishment */ BSSAP.send(ts_BSSAP_CONNECT_res(conn_ind.connectionId, omit)); } - /* SCCP -> Client: connection-oriented data in existing connection */ [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value data_ind { vc_conn := f_comp_by_conn_id(data_ind.connectionId); @@ -582,7 +600,6 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { f_handle_userData(vc_conn, data_ind.userData); } } - /* SCCP -> Client: disconnect of an existing connection */ [] BSSAP.receive(BSSAP_N_DISCONNECT_ind:?) -> value disc_ind { vc_conn := f_comp_by_conn_id(disc_ind.connectionId); @@ -595,7 +612,6 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { f_conn_table_del(disc_ind.connectionId); /* TOOD: return confirm to other side? */ } - /* SCCP -> Client: connection confirm for outbound connection */ [] BSSAP.receive(BSSAP_N_CONNECT_cfm:?) -> value conn_cfm { vc_conn := f_comp_by_conn_id(conn_cfm.connectionId); @@ -606,6 +622,11 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { f_handle_userData(vc_conn, conn_cfm.userData); } } + [] CLIENT.receive(PDU_BSSAP:?) -> value bssap sender vc_conn { + var integer conn_id := f_conn_id_by_comp(vc_conn); + /* send it to dispatcher */ + BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap)); + } /* Disconnect request client -> SCCP */ [] CLIENT.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ) -> sender vc_conn { @@ -644,33 +665,16 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { } } +#else + [false] CLIENT.receive(false) {} +#endif +} - [] CLIENT.receive(PDU_BSSAP:?) -> value bssap sender vc_conn { - var integer conn_id := f_conn_id_by_comp(vc_conn); - /* send it to dispatcher */ - BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap)); - } - - [g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MO:?) -> value dtap_mo sender vc_conn { - var integer idx := f_idx_by_comp(vc_conn); - /* convert from decoded DTAP to encoded DTAP */ - var octetstring l3_enc := enc_PDU_ML3_MS_NW(dtap_mo.dtap); - /* patch correct L3 send sequence number N(SD) into l3_enc */ - if (dtap_mo.skip_seq_patching == false) { - f_ML3_patch_seq(ConnectionTable[idx], dtap_mo.dtap, l3_enc); - } - bssap := valueof(ts_BSSAP_DTAP(l3_enc, dtap_mo.dlci)); - BSSAP.send(ts_BSSAP_DATA_req(ConnectionTable[idx].sccp_conn_id, bssap)); - } - - [not g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MT:?) -> value dtap_mt sender vc_conn { - var integer conn_id := f_conn_id_by_comp(vc_conn); - /* convert from decoded DTAP to encoded DTAP */ - var octetstring l3_enc := enc_PDU_ML3_NW_MS(dtap_mt.dtap); - bssap := valueof(ts_BSSAP_DTAP(l3_enc, dtap_mo.dlci)); - BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap)); - } - +private altstep as_main_mgcp() runs on RAN_Emulation_CT { +#ifdef RAN_EMULATION_MGCP + var MgcpCommand mgcp_req; + var MgcpResponse mgcp_resp; + var RAN_ConnHdlr vc_conn; /* Handling of MGCP in IPA SCCPLite case. This predates 3GPP AoIP * and uses a MGCP session in parallel to BSSAP. BSSAP uses CIC @@ -710,7 +714,68 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { vc_conn := f_comp_by_mgcp_tid(mgcp_resp.line.trans_id); CLIENT.send(mgcp_resp) to vc_conn; } +#else + [false] CLIENT.receive {} +#endif +} +/* send a raw (encoded) L3 message over given SCCP connection */ +private function f_xmit_raw_l3(integer sccp_conn_id, OCT1 dlci, octetstring l3_enc) runs on RAN_Emulation_CT +{ + select (g_ran_ops.protocol) { +#ifdef RAN_EMULATION_BSSAP + case (RAN_PROTOCOL_BSSAP) { + var PDU_BSSAP bssap; + bssap := valueof(ts_BSSAP_DTAP(l3_enc, dlci)); + BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, bssap)); + } +#endif + } +} + +function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { + + g_ran_id := id; + g_ran_ops := ops; + f_conn_table_init(); + f_expect_table_init(); + + if (isvalue(ops.sccp_addr_peer) and isvalue(ops.sccp_addr_local)) { + f_sleep(1.0); /* HACK to wait for M3UA/ASP to be ACTIVE */ + f_bssap_reset(ops.sccp_addr_peer, ops.sccp_addr_local); + } + + while (true) { + var RAN_ConnHdlr vc_conn; + var PDU_DTAP_MO dtap_mo; + var PDU_DTAP_MT dtap_mt; + var RAN_ConnHdlr vc_hdlr; + var octetstring l3_info; + var hexstring imsi; + var OCT4 tmsi; + + alt { + [g_ran_ops.protocol == RAN_PROTOCOL_BSSAP] as_main_bssap(); + + [g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MO:?) -> value dtap_mo sender vc_conn { + var integer idx := f_idx_by_comp(vc_conn); + /* convert from decoded DTAP to encoded DTAP */ + var octetstring l3_enc := enc_PDU_ML3_MS_NW(dtap_mo.dtap); + /* patch correct L3 send sequence number N(SD) into l3_enc */ + if (dtap_mo.skip_seq_patching == false) { + f_ML3_patch_seq(ConnectionTable[idx], dtap_mo.dtap, l3_enc); + } + f_xmit_raw_l3(ConnectionTable[idx].sccp_conn_id, dtap_mo.dlci, l3_enc); + } + + [not g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MT:?) -> value dtap_mt sender vc_conn { + var integer idx := f_idx_by_comp(vc_conn); + /* convert from decoded DTAP to encoded DTAP */ + var octetstring l3_enc := enc_PDU_ML3_NW_MS(dtap_mt.dtap); + f_xmit_raw_l3(ConnectionTable[idx].sccp_conn_id, dtap_mt.dlci, l3_enc); + } + + [] as_main_mgcp(); [] PROC.getcall(RAN_register:{?,?}) -> param(l3_info, vc_hdlr) { f_create_expect(l3_info, vc_hdlr); @@ -727,11 +792,13 @@ function main(RanOps ops, charstring id) runs on RAN_Emulation_CT { } } +#ifdef RAN_EMULATION_MGCP private function f_mgcp_ep_extract_cic(charstring inp) return integer { var charstring local_part := regexp(inp, "(*)@*", 0); return hex2int(str2hex(local_part)); } +#endif /*********************************************************************** * "Expect" Handling (mapping for expected incoming SCCP connections) diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn index e408f8298..11baf2ab7 100644 --- a/msc/BSC_ConnectionHandler.ttcn +++ b/msc/BSC_ConnectionHandler.ttcn @@ -180,6 +180,7 @@ const RanOps BSC_RanOps := { unitdata_cb := refers(BscUnitdataCallback), decode_dtap := true, role_ms := true, + protocol := RAN_PROTOCOL_BSSAP, sccp_addr_local := omit, sccp_addr_peer := omit } diff --git a/msc/gen_links.sh b/msc/gen_links.sh index a29118a87..e4e142bac 100755 --- a/msc/gen_links.sh +++ b/msc/gen_links.sh @@ -89,7 +89,7 @@ DIR=../library FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn MNCC_Types.ttcn MNCC_EncDec.cc MNCC_CodecPort.ttcn mncc.h MNCC_Emulation.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc " FILES+="IPA_Types.ttcn IPA_Emulation.ttcnpp IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc GSUP_Types.ttcn GSUP_Emulation.ttcn " FILES+="Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn L3_Templates.ttcn L3_Common.ttcn " -FILES+="RAN_Emulation.ttcn BSSAP_CodecPort.ttcn BSSMAP_Templates.ttcn RAN_Adapter.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_Emulation.ttcn " +FILES+="RAN_Emulation.ttcnpp BSSAP_CodecPort.ttcn BSSMAP_Templates.ttcn RAN_Adapter.ttcnpp MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_Emulation.ttcn " FILES+="RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunctDef.cc " FILES+="MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunctDef.cc " FILES+="SMPP_CodecPort.ttcn SMPP_CodecPort_CtrlFunct.ttcn SMPP_CodecPort_CtrlFunctDef.cc SMPP_Emulation.ttcn SMPP_Templates.ttcn " diff --git a/msc/regen_makefile.sh b/msc/regen_makefile.sh index 5645fdde3..091faf822 100755 --- a/msc/regen_makefile.sh +++ b/msc/regen_makefile.sh @@ -2,6 +2,6 @@ FILES="*.ttcn *.ttcnpp SCCP_EncDec.cc SCTPasp_PT.cc TCCConversion.cc TCCInterface.cc UD_PT.cc MNCC_EncDec.cc IPL4asp_PT.cc IPL4asp_discovery.cc SDP_EncDec.cc RTP_EncDec.cc IPA_CodecPort_CtrlFunctDef.cc RTP_CodecPort_CtrlFunctDef.cc MGCP_CodecPort_CtrlFunctDef.cc TELNETasp_PT.cc Native_FunctionDefs.cc SMPP_EncDec.cc SMPP_CodecPort_CtrlFunctDef.cc MAP_EncDec.cc SS_EncDec.cc TCCEncoding.cc SGsAP_CodecPort_CtrlFunctDef.cc *.c *.asn" -export CPPFLAGS_TTCN3="-DIPA_EMULATION_MGCP -DIPA_EMULATION_GSUP -DIPA_EMULATION_SCCP -DUSE_MTP3_DISTRIBUTOR" +export CPPFLAGS_TTCN3="-DIPA_EMULATION_MGCP -DIPA_EMULATION_GSUP -DIPA_EMULATION_SCCP -DRAN_EMULATION_BSSAP -DRAN_EMULATION_MGCP -DUSE_MTP3_DISTRIBUTOR" ../regen-makefile.sh MSC_Tests.ttcn $FILES