Expand IPA emulaitpn code + example to include CCM and SCCP binding

This commit is contained in:
Harald Welte 2017-11-22 00:45:07 +01:00
parent 00566f55f0
commit d86cdc6811
5 changed files with 327 additions and 17 deletions

View File

@ -1,12 +1,24 @@
module IPA_Test {
import from IPA_CodecPort all;
import from IPA_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
type component ipa_CT {
port IPA_CODEC_PT IPA;
import from IPA_Emulation all;
import from SCCP_Types all;
import from SCCPasp_Types all;
import from SCCP_Emulation all;
type component test_CT {
/* component references */
var IPA_Emulation_CT vc_IPA;
var SCCP_CT vc_SCCP;
/* test port to SCCP emulation */
port SCCPasp_PT SCCP;
var boolean g_initialized := false;
var octetstring g_sio;
var MSC_SCCP_MTP3_parameters g_sccp_pars;
var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer;
var ConnectionId g_ipa_conn_id := -1;
}
@ -16,27 +28,82 @@ module IPA_Test {
charstring mp_local_ip := "127.0.0.1";
PortNumber mp_remote_port := 3002;
charstring mp_remote_ip := "127.0.0.1";
charstring mp_sccp_service_type := "mtp3_itu";
integer mp_own_pc := 196;
integer mp_own_ssn := 254;
integer mp_peer_pc := 185; /* 0.23.1 */
integer mp_peer_ssn := 254;
}
private function f_init() runs on ipa_CT {
/* 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
}
function init_pars() runs on test_CT {
g_sio := '83'O;
g_sccp_pars := {
sio := {
ni := substr(oct2bit(g_sio),0,2),
prio := substr(oct2bit(g_sio),2,2),
si := substr(oct2bit(g_sio),4,4)
},
opc := mp_own_pc,
dpc := mp_peer_pc,
sls := 0,
sccp_serviceType := mp_sccp_service_type,
ssn := mp_own_ssn
};
g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn));
g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn));
}
private function f_init() runs on test_CT {
var Result res;
if (g_initialized == true) {
return;
}
g_initialized := true;
map(self:IPA, system:IPA_CODEC_PT);
res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA, mp_remote_ip, mp_remote_port,
mp_local_ip, mp_local_port, 0, { tcp:={} });
g_ipa_conn_id := res.connId;
init_pars();
/* create components */
vc_IPA := IPA_Emulation_CT.create;
vc_SCCP := SCCP_CT.create;
map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
/* connect MTP3 service provider (IPA) to lower side of SCCP */
connect(vc_IPA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);
/* connect us to upper side of SCCP */
connect(self:SCCP, vc_SCCP:SCCP_SP_PORT);
vc_IPA.start(IPA_Emulation.ScanEvents());
vc_SCCP.start(SCCPStart(g_sccp_pars));
//IPA_Emulation.f_connect(mp_remote_ip, mp_remote_port, mp_local_ip, mp_local_port);
}
testcase TC_recv_dump() runs on ipa_CT {
testcase TC_recv_dump() runs on test_CT {
f_init();
while (true) {
IPA.receive;
SCCP.receive;
}
}

View File

@ -27,6 +27,17 @@ DIR=$BASEDIR/titan.TestPorts.IPL4asp/src
FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh"
gen_links $DIR $FILES
DIR=../library
FILES="Osmocom_Types.ttcn IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc"
# required by SCCP Emulation
DIR=../MTP3asp_CNL113337/src
FILES="MTP3asp_PortType.ttcn MTP3asp_Types.ttcn"
gen_links $DIR $FILES
DIR=../SCCP_CNL113341/src
FILES="SCCP_Emulation.ttcn SCCP_EncDec.cc SCCP_Mapping.ttcnpp SCCP_Types.ttcn SCCPasp_Types.ttcn"
gen_links $DIR $FILES
ln -s SCCP_Mapping.ttcnpp SCCP_Mapping.ttcn
DIR=../library
FILES="General_Types.ttcn Osmocom_Types.ttcn IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc"
gen_links $DIR $FILES

View File

@ -2,7 +2,7 @@
MAIN=IPA_Test.ttcn
FILES="*.ttcn IPA_CodecPort_CtrlFunctDef.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc"
FILES="*.ttcn SCCP_EncDec.cc IPA_CodecPort_CtrlFunctDef.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc"
ttcn3_makefilegen -l -f $MAIN $FILES
sed -i -e 's/# TTCN3_DIR = /TTCN3_DIR = \/usr/' Makefile

158
library/IPA_Emulation.ttcn Normal file
View File

@ -0,0 +1,158 @@
module IPA_Emulation {
import from IPA_Types all;
import from IPA_CodecPort all;
import from IPA_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
import from MTP3asp_Types all;
import from MTP3asp_PortType all;
/*
modulepar {
}
*/
type component IPA_Emulation_CT {
/* down-facing port to IPA codec port */
port IPA_CODEC_PT IPA_PORT;
/* up-facing port to SCCP */
port MTP3asp_SP_PT MTP3_SP_PORT;
var boolean g_initialized := false;
var ConnectionId g_ipa_conn_id := -1;
}
function f_connect(charstring remote_host, PortNumber remote_port,
charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
var Result res;
res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
local_host, local_port, 0, { tcp:={} });
g_ipa_conn_id := res.connId;
}
template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
sio := { '10'B, '00'B, '0011'B },
opc := opc,
dpc := 0,
sls := 0,
data := data
}
private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
len := 0, /* overwritten by codec */
tag := tag,
data := payload
}
/* build IPA CCM ID RESP response from IPA CCM GET */
private function f_ccm_make_id_resp(PDU_IPA_CCM get) return PDU_IPA_CCM {
var integer i;
var PDU_IPA_CCM resp := {
msg_type := IPAC_MSGT_ID_RESP,
u := {
resp := {}
}
}
for (i := 0; i < sizeof(get.u.get); i := i + 1) {
var IpaCcmIdTag tag := get.u.get[i].tag;
var charstring foo;
select (tag) {
case (IPAC_IDTAG_UNIT) {
foo := "0/1/2";
}
case (IPAC_IDTAG_UNITNAME) {
foo := "mahlzeit";
}
case else {
foo := "foo";
}
}
resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
}
return resp;
}
/* transmit IPA CCM message */
private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
var IPA_Send ipa_tx := {
connId := g_ipa_conn_id,
streamId := IPAC_PROTO_CCM,
msg := enc_PDU_IPA_CCM(ccm)
}
log("CCM Tx:", ccm);
IPA_PORT.send(ipa_tx);
}
template PDU_IPA_CCM ts_IPA_PONG := {
msg_type := IPAC_MSGT_PONG,
u := omit
}
template PDU_IPA_CCM ts_IPA_ACK := {
msg_type := IPAC_MSGT_ID_ACK,
u := omit
}
/* receive IPA CCM message */
private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
select (ccm.msg_type) {
case (IPAC_MSGT_PING) {
f_ccm_tx(valueof(ts_IPA_PONG));
}
case (IPAC_MSGT_ID_ACK) {
f_ccm_tx(valueof(ts_IPA_ACK));
}
case (IPAC_MSGT_ID_GET) {
f_ccm_tx(f_ccm_make_id_resp(ccm));
}
case else {
log("Unknown/unsupported IPA CCM message type", ccm);
}
}
}
function ScanEvents() runs on IPA_Emulation_CT {
var IPA_RecvFrom ipa_rx;
var ASP_MTP3_TRANSFERreq mtp_req;
f_connect("127.0.0.1", 5000, "127.0.0.1", 49999);
while (true) {
alt {
/* Received IPA -> up into SCCP stack */
[] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
select (ipa_rx.streamId) {
case (IPAC_PROTO_CCM) {
var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
log("CCM Rx:", ccm);
f_ccm_rx(ccm);
}
case (IPAC_PROTO_SCCP) {
var ASP_MTP3_TRANSFERind mtp;
mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
MTP3_SP_PORT.send(mtp);
}
case else {
log("Unknown/unsupported IPA Stream ID", ipa_rx);
}
}
}
/* Received SCCP -> down into IPA */
[] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
var IPA_Send ipa_tx := {
connId := g_ipa_conn_id,
streamId := IPAC_PROTO_SCCP,
msg := mtp_req.data
}
IPA_PORT.send(ipa_tx);
}
}
}
}
}

View File

@ -4,7 +4,24 @@ module IPA_Types {
import from Osmocom_Types all;
type uint8_t IpaStreamId;
type enumerated IpaStreamId {
IPAC_PROTO_RSL (0),
IPAC_PROTO_OSMO (238),
IPAC_PROTO_MGCP_OLD (252),
IPAC_PROTO_SCCP (253),
IPAC_PROTO_CCM (254),
IPAC_PROTO_OML (255)
} with { variant "FIELDLENGTH(8)" }
type enumerated IpaExtStreamId {
IPAC_PROTO_EXT_CTRL ('00'H),
IPAC_PROTO_EXT_MGCP ('01'H),
IPAC_PROTO_EXT_LAC ('02'H),
IPAC_PROTO_EXT_SMSC ('03'H),
IPAC_PROTO_EXT_ORC ('04'H),
IPAC_PROTO_EXT_GSUP ('05'H),
IPAC_PROTO_EXT_OAP ('06'H)
} with { variant "FIELDLENGTH(8)" }
external function enc_PDU_IPA(in PDU_IPA pdu) return octetstring
with { extension "prototype(convert)"
@ -22,10 +39,67 @@ type record PDU_IPA
IpaStreamId streamId,
octetstring payloadData
} with {
variant (lengthInd) "LENGTHTO(lengthInd,streamId,payloadData)";
variant (lengthInd) "LENGTHTO(payloadData)";
variant (lengthInd) "FIELDLENGTH(16)";
variant (lengthInd) "BYTEORDER(last)";
encode "RAW";
}
type enumerated IpaCcmMsgtype {
IPAC_MSGT_PING ('00'H),
IPAC_MSGT_PONG ('01'H),
IPAC_MSGT_ID_GET ('04'H),
IPAC_MSGT_ID_RESP ('05'H),
IPAC_MSGT_ID_ACK ('06'H)
} with { variant "FIELDLENGTH(8)" }
type enumerated IpaCcmIdTag {
IPAC_IDTAG_SERNR ('00'H),
IPAC_IDTAG_UNITNAME ('01'H),
IPAC_IDTAG_LOCATION1 ('02'H),
IPAC_IDTAG_LOCATION2 ('03'H),
IPAC_IDTAG_EQUIPVERS ('04'H),
IPAC_IDTAG_SWVERSION ('05'H),
IPAC_IDTAG_IPADDR ('06'H),
IPAC_IDTAG_MACADDR ('07'H),
IPAC_IDTAG_UNIT ('08'H)
} with { variant "FIELDLENGTH(8)" }
type record IpaCcmGetPart {
uint8_t one,
IpaCcmIdTag tag
}
type set of IpaCcmGetPart IpaCcmIdGet;
type record IpaCcmRespPart {
uint16_t len,
IpaCcmIdTag tag,
charstring data
} with { variant (len) "LENGTHTO(data,tag)" }
type set of IpaCcmRespPart IpaCcmIdResp;
type union IpaCcmUnion {
IpaCcmIdGet get,
IpaCcmIdResp resp,
octetstring other
}
type record PDU_IPA_CCM {
IpaCcmMsgtype msg_type,
IpaCcmUnion u optional
} with { variant "" };
external function enc_PDU_IPA_CCM(in PDU_IPA_CCM pdu) return octetstring
with { extension "prototype(convert)"
extension "encode(RAW)"
}
external function dec_PDU_IPA_CCM(in octetstring stream) return PDU_IPA_CCM
with { extension "prototype(convert)"
extension "decode(RAW)"
}
} with { encode "RAW" }