RAN_Emulation: Modularize protocol support
The RAN_Emulation currently unconditionally provides BSSAP and MGCP support. Let's re-structure the code so that support for those protocols is now possible to enable/disable at compile time. This patch is in preparation of introducing RANAP support in RAN_Emulation. Change-Id: Id53ba3ff05f9946230e0e4a759245de14a0f9fbd Related: OS#2856
This commit is contained in:
parent
8a397ae7ba
commit
2fce7887f4
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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 <laforge@gnumonks.org>
|
||||
* (C) 2017-2019 by Harald Welte <laforge@gnumonks.org>
|
||||
* 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)
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue