ipa: Further progress on the bsc-nat test suite
diff --git a/ipa/BSC_MS_Simulation.ttcn b/ipa/BSC_MS_Simulation.ttcn
index c33e848..24ac4bc 100644
--- a/ipa/BSC_MS_Simulation.ttcn
+++ b/ipa/BSC_MS_Simulation.ttcn
@@ -43,9 +43,12 @@
 	/* connect MTP3 service provider (IPA) to lower side of SCCP */
 	connect(vc_IPA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);
 
-	/* connect BSSNAP dispatcher to upper side of SCCP */
+	/* connect BSSMAP dispatcher to upper side of SCCP */
 	connect(vc_BSSMAP:SCCP, vc_SCCP:SCCP_SP_PORT);
 
+	/* connect BSSMAP dispatcher to IPA_Emulation MGCP */
+	connect(vc_BSSMAP:MGCP, vc_IPA:IPA_MGCP_PORT);
+
 	vc_IPA.start(IPA_Emulation.main_client(remote_ip, remote_port, local_ip, local_port));
 	vc_SCCP.start(SCCPStart(sccp_pars));
 	vc_BSSMAP.start(BSSMAP_Emulation.main(BSC_MS_BssmapOps));
diff --git a/ipa/MSC_ConnectionHandler.ttcn b/ipa/MSC_ConnectionHandler.ttcn
index 641a832..53123fe 100644
--- a/ipa/MSC_ConnectionHandler.ttcn
+++ b/ipa/MSC_ConnectionHandler.ttcn
@@ -7,6 +7,10 @@
 import from BSSMAP_Emulation all;
 import from BSSMAP_Templates all;
 
+import from MGCP_Types all;
+import from MGCP_Templates all;
+import from SDP_Types all;
+
 /* this component represents a single subscriber connection at the MSC.
  * There is a 1:1 mapping between SCCP connections and BSSAP_ConnHdlr components.
  * We inherit all component variables, ports, functions, ... from BSSAP_ConnHdlr */
@@ -15,6 +19,11 @@
 	var uint5_t g_e1_timeslot;
 	/* SCCP Connecction Identifier for the underlying SCCP connection */
 	var integer g_sccp_conn_id;
+
+	var MSC_State g_state := MSC_STATE_NONE;
+	var MgcpEndpoint g_ep_name;
+	var MgcpCallId g_call_id;
+	var MgcpConnectionId g_mgcp_conn_id;
 }
 
 /* Callback function from general BSSMAP_Emulation whenever a new incoming
@@ -49,30 +58,98 @@
 	unitdata_cb := refers(UnitdataCallback)
 }
 
+type enumerated MSC_State {
+	MSC_STATE_NONE,
+	MSC_STATE_WAIT_ASS_COMPL,
+	MSC_STATE_WAIT_CRCX_ACK,
+	MSC_STATE_WAIT_MDCX_ACK,
+	MSC_STATE_WAIT_CLEAR_COMPL,
+	MSC_STATE_WAIT_DLCX_ACK
+}
+
+private function f_mgcp_alloc_tid() return MgcpTransId {
+	return int2str(float2int(rnd()*2147483647.0));
+}
+
+private function f_mgcp_alloc_call_id() return MgcpCallId {
+	return int2hex(float2int(rnd()*2147483647.0), 8);
+}
+
+function extract_conn_id(MgcpResponse resp) return MgcpConnectionId {
+	var integer i;
+	for (i := 0; i < lengthof(resp.params); i := i + 1) {
+		var MgcpParameter par := resp.params[i];
+		if (par.code == "I") {
+			return str2hex(par.val);
+		}
+	}
+	setverdict(fail);
+	return '00000000'H;
+}
+
 /* main function processing various incoming events */
 function main(integer connection_id, integer timeslot) runs on MSC_ConnHdlr {
-	g_sccp_conn_id := connection_id;
+	var MgcpResponse mgcp_rsp;
+
 	g_e1_timeslot := 1; /* FIXME */
 
+	g_sccp_conn_id := connection_id;
+	g_call_id := f_mgcp_alloc_call_id();
+	g_ep_name := hex2str(int2hex(g_e1_timeslot, 1)) & "@mgw";
+
 	while (true) {
 		var PDU_BSSAP bssap;
 		alt {
 		/* new SCCP-level connection indication from BSC */
-		[] BSSAP.receive(tr_BSSMAP_ComplL3) -> value bssap {
+		[g_state == MSC_STATE_NONE] BSSAP.receive(tr_BSSMAP_ComplL3) -> value bssap {
 			/* respond with ASSIGNMENT CMD  */
+			g_state := MSC_STATE_WAIT_ASS_COMPL;
 			BSSAP.send(ts_BSSMAP_AssignmentReq(0, g_e1_timeslot));
-			/* FIXME: Send MGCP */
+			}
+		[g_state == MSC_STATE_WAIT_ASS_COMPL] BSSAP.receive(tr_BSSMAP_AssignmentComplete) {
+			/* FIXME: Send MGCP CRCX */
+			g_state := MSC_STATE_WAIT_CRCX_ACK;
+			var MgcpTransId trans_id := f_mgcp_alloc_tid();
+			//template SDP_Message sdp := omit;
+			BSSAP.send(ts_CRCX(trans_id, g_ep_name, "recvonly", g_call_id)); //, sdp));
 			}
 		/*
-		[] BSSAP.receive(tr_BSSMAP_AssignmentCompl) {
-		}
 		[] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
 		}
 		*/
+
+		/* receive CRCX ACK: transmit MDCX */
+		[g_state == MSC_STATE_WAIT_CRCX_ACK] BSSAP.receive(tr_CRCX_ACK) -> value mgcp_rsp {
+			/* extract connection ID */
+			g_mgcp_conn_id := extract_conn_id(mgcp_rsp);
+			g_state := MSC_STATE_WAIT_MDCX_ACK;
+			var MgcpTransId trans_id := f_mgcp_alloc_tid();
+			BSSAP.send(ts_MDCX(trans_id, g_ep_name, "sendrecv", g_call_id, g_mgcp_conn_id));
+			}
+
+		/* receive MDCX ACK: wait + transmit CLEAR COMMAND */
+		[g_state == MSC_STATE_WAIT_MDCX_ACK] BSSAP.receive(tr_CRCX_ACK) -> value mgcp_rsp {
+			g_state := MSC_STATE_WAIT_CLEAR_COMPL
+			BSSAP.send(ts_BSSMAP_ClearCommand(0));
+			}
+
+		/* CLEAR COMPLETE from BSS (response to CLEAR COMMAND) */
+		[g_state == MSC_STATE_WAIT_CLEAR_COMPL] BSSAP.receive(ts_BSSMAP_ClearComplete) {
+			/* send DLCX */
+			g_state := MSC_STATE_WAIT_DLCX_ACK;
+			var MgcpTransId trans_id := f_mgcp_alloc_tid();
+			BSSAP.send(ts_DLCX(trans_id, g_ep_name, g_call_id));
+			}
+
+		[g_state == MSC_STATE_WAIT_DLCX_ACK] BSSAP.receive(tr_DLCX_ACK) {
+			setverdict(pass);
+			self.stop;
+			}
+
 		/* TODO: CLEAR REQUEST from BSS */
-		/* TODO: CLEAR COMPLETE from BSS (response to CLEAR COMMAND) */
 
 		[] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
+			setverdict(fail);
 			self.stop;
 			}
 
diff --git a/ipa/MSC_Simulation.ttcn b/ipa/MSC_Simulation.ttcn
index 8c94188..0198350 100755
--- a/ipa/MSC_Simulation.ttcn
+++ b/ipa/MSC_Simulation.ttcn
@@ -46,6 +46,9 @@
 	/* connect BSSNAP dispatcher to upper side of SCCP */
 	connect(vc_BSSMAP:SCCP, vc_SCCP:SCCP_SP_PORT);
 
+	/* connect BSSMAP dispatcher to IPA_Emulation MGCP */
+	connect(vc_BSSMAP:MGCP, vc_IPA:IPA_MGCP_PORT);
+
 	vc_IPA.start(IPA_Emulation.main_server(local_ip, local_port));
 	vc_SCCP.start(SCCPStart(sccp_pars));
 	vc_BSSMAP.start(BSSMAP_Emulation.main(MSC_BssmapOps));
diff --git a/ipa/gen_links.sh b/ipa/gen_links.sh
index be11ec0..7dd5ed2 100755
--- a/ipa/gen_links.sh
+++ b/ipa/gen_links.sh
@@ -16,7 +16,7 @@
 #gen_links $DIR $FILES
 
 DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
-FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCConversion.hh TCCInterface.cc TCCInterface_ip.h"
+FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCConversion.hh TCCInterface.cc TCCInterface_ip.h SDP_EncDec.cc"
 gen_links $DIR $FILES
 
 DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
@@ -35,7 +35,7 @@
 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
+ln -sf SCCP_Mapping.ttcnpp SCCP_Mapping.ttcn
 
 DIR=$BASEDIR/titan.ProtocolModules.BSSMAP_v11.2.0/src
 FILES="BSSAP_Types.ttcn"
@@ -45,7 +45,15 @@
 FILES="MobileL3_CC_Types.ttcn MobileL3_CommonIE_Types.ttcn MobileL3_GMM_SM_Types.ttcn MobileL3_MM_Types.ttcn MobileL3_RRM_Types.ttcn MobileL3_SMS_Types.ttcn MobileL3_SS_Types.ttcn MobileL3_Types.ttcn"
 gen_links $DIR $FILES
 
+DIR=$BASEDIR/titan.ProtocolModules.SDP/src
+FILES="SDP_EncDec.cc SDP_Types.ttcn SDP_parse_.tab.c SDP_parse_.tab.h SDP_parse_parser.h SDP_parser.l
+SDP_parser.y lex.SDP_parse_.c"
+gen_links $DIR $FILES
+
+DIR=$BASEDIR/titan.ProtocolModules.RTP/src
+FILES="RTP_EncDec.cc RTP_Types.ttcn"
+gen_links $DIR $FILES
 
 DIR=../library
-FILES="General_Types.ttcn Osmocom_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"
+FILES="General_Types.ttcn Osmocom_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 MGCP_Types.ttcn MGCP_Templates.ttcn"
 gen_links $DIR $FILES
diff --git a/ipa/regen_makefile.sh b/ipa/regen_makefile.sh
index 1acda32..be79a35 100755
--- a/ipa/regen_makefile.sh
+++ b/ipa/regen_makefile.sh
@@ -2,7 +2,7 @@
 
 MAIN=IPA_Test.ttcn
 
-FILES="*.ttcn SCCP_EncDec.cc 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 RTP_EncDec.cc SDP_EncDec *.c"
 
 ttcn3_makefilegen -l -f $MAIN $FILES
 sed -i -e 's/# TTCN3_DIR = /TTCN3_DIR = \/usr/' Makefile