Change in osmo-ttcn3-hacks[master]: msc: overhaul voice call testing

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Sat Nov 23 07:59:08 UTC 2019


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/15938 )

Change subject: msc: overhaul voice call testing
......................................................................

msc: overhaul voice call testing

* Semantic:

We don't really know which side the MSC first creates a CRCX for. Instead of
assuming that the RAN side is always CRCX'd first, simply handle a "first" and
a "second" CRCX, not making any assumptions which is for which side.
Notably, there still are quite a few places assuming which CRCX corresponds to
the RAN/CN side, but the changes are sufficient to still pass the tests when
osmo-msc swaps the CRCX order; sometimes for slightly obscure reasons, for
example because it doesn't matter that the wrong port number is returned during
a subsequent MDCX... Cleaning up the rest is still todo for later.

Remove code dup from call establishing code, particularly for MGCP.

Use f_mo_call_establish() and f_mt_call() where ever possible, to make all of
the call establishing tests handle upcoming changes in osmo-msc's order of
messages, without re-implementing the changes for each test individually.

The X-Osmux parameter was so far expected to appear in the first CRCX received,
assuming that this first CRCX is for the RAN.  Instead, detect whether X-Osmux
is contained in a CRCX, and reply with an Osmux CID if so, regardless of it
being the first or second CRCX.  Count the number of X-Osmux parameters
received in CRCX messages, and compare after call setup to verify X-Osmux
presence.

Since f_mo_call_establish() can't handle RANAP assignment, a few Iu tests that
worked with the older code dup will break by this patch. This is fixed by a
subsequent patch, see I0ead36333ab665147b8d222070ea5cf8afc555ec.

* Details, per patch chunk:

Change ts_BSSMAP_IE_AoIP_TLA4 to a non-value template, so that we can use a
wildcard for the assigned port number from MGCP (depending on RAN or CN CRCX
first, the RAN port number can be one or the other).

In CallParameters, move MGCP handling instructions into a separate record
"CrcxResponse", and have two of them for handling the first and the second
CRCX, replacing mgw_rtp_{ip,port}_{bss,mss} and mgcp_connection_id_{bss,mss}.

In CallParameters, add some flags for early-exiting call establishment with a
particular desired behavior, for specialized tests.

In CallParameters, use common default values and don't repeat them in each and
every call establishing test.

Set cpars.mo_call := {true,false} implicitly when f_{mo,mt}_call_establish()
are invoked.

Remove CRCX comments implying RAN or CN side, instead just talk of the "first"
and the "second" CRCX.

Implement one common f_handle_crcx() function, which is used by
f_mo_call_establish(), f_mt_call_complete(), as_optional_mgcp_crcx(), and
implicitly uses the first/second CRCX handling.

For Assigment, use a wildcard RTP port so that we don't have to assume which
CRCX was for the RAN side.

In f_mo_call_establish(), insert special case conditions to make it enact
errors at specific times, for individual tests. That saves re-implementing the
entire call establishment (code dup).

For error cases, add expectation of a CC Release message in the call
establishment. This should not apply for normal successful operation, but
because interleave does not support conditionals, add flags
got_mncc_setup_compl_ind and got_cc_connect to break the interleave when
establishing is complete, so that the CC Release is skipped.
A CC Release always breaks the interleave, at whatever time it arrives.

Tests adopting f_{mo,mt}_call instead of code dup:
  f_tc_mo_setup_and_nothing()
  f_tc_mo_crcx_ran_timeout()
  f_tc_mo_crcx_ran_reject()
  f_tc_mo_release_timeout()
  f_tc_mo_cc_bssmap_clear()

Change-Id: I8b82476f55a98f7a94d5c4f1cd80eac427b2d20f
---
M library/BSSMAP_Templates.ttcn
M msc/BSC_ConnectionHandler.ttcn
M msc/MSC_Tests.ttcn
3 files changed, 292 insertions(+), 335 deletions(-)

Approvals:
  laforge: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/library/BSSMAP_Templates.ttcn b/library/BSSMAP_Templates.ttcn
index 41755db..406dfc5 100644
--- a/library/BSSMAP_Templates.ttcn
+++ b/library/BSSMAP_Templates.ttcn
@@ -420,6 +420,19 @@
 template (value) BSSMAP_IE_AoIP_TransportLayerAddress ts_BSSMAP_IE_AoIP_TLA6(OCT16 ip, uint16_t pt) :=
 							ts_BSSMAP_IE_AoIP_TLA({ipv6:=ip}, pt, 18);
 
+template BSSMAP_IE_AoIP_TransportLayerAddress tr_BSSMAP_IE_AoIP_TLA(template BSSMAP_FIELD_IPAddress addr,
+								    template uint16_t udp_port,
+								    template integer len := ?) := {
+	elementIdentifier := '7C'O,
+	lengthIndicator := len,
+	ipAddress := addr,
+	uDPPortValue := udp_port
+}
+template BSSMAP_IE_AoIP_TransportLayerAddress tr_BSSMAP_IE_AoIP_TLA4(template OCT4 ip, template uint16_t pt) :=
+	tr_BSSMAP_IE_AoIP_TLA({ipv4:=ip}, pt, 6);
+template BSSMAP_IE_AoIP_TransportLayerAddress tr_BSSMAP_IE_AoIP_TLA6(template OCT16 ip, template uint16_t pt) :=
+	tr_BSSMAP_IE_AoIP_TLA({ipv6:=ip}, pt, 18);
+
 template (value) BSSMAP_IE_KC128 ts_BSSMAP_IE_Kc128(OCT16 kc128) := {
 	elementIdentifier := '83'O,
 	kC128_Value := kc128
diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn
index 7a94d85..4330b53 100644
--- a/msc/BSC_ConnectionHandler.ttcn
+++ b/msc/BSC_ConnectionHandler.ttcn
@@ -676,6 +676,13 @@
 	/* re-configure MSC behaviour via VTY */
 }
 
+type record CrcxResponse {
+	integer resp,	/* 1 = reply with OK, 0 = do not reply, -1 = reply with error */
+	HostName mgw_rtp_ip,
+	PortNumber mgw_rtp_port,
+	MgcpConnectionId mgcp_connection_id	/* MGCP Connection ID BSS Side */
+}
+
 /* parameters related to a (MO?) voice call */
 type record CallParameters {
 	/* CC related parameters */
@@ -695,24 +702,24 @@
 	PortNumber bss_rtp_port optional,		/* BSS Side RTP Port */
 	HostName mss_rtp_ip optional,			/* MSS Side RTP IP */
 	PortNumber mss_rtp_port optional,		/* MSS Side RTP Port */
-	HostName mgw_rtp_ip_bss,			/* BSS-facing MGW RTP IP */
-	PortNumber mgw_rtp_port_bss,			/* BSS-facing MGW RTP Port */
-	HostName mgw_rtp_ip_mss,			/* MSS-facing MGW RTP IP */
-	PortNumber mgw_rtp_port_mss,			/* MSS-facing MGW RTP Port */
+	integer got_crcx_count,
+	CrcxResponse mgw_conn_1,
+	CrcxResponse mgw_conn_2,
 	uint7_t rtp_payload_type,			/* dynamic RTP payload type */
 	charstring rtp_sdp_format,			/* AMR/8000 or the like */
 	boolean mgw_drop_dlcx optional,			/* Provoke errors by not responding to DLCX
 							   (f_mt_call and f_mt_call) */
+	boolean stop_after_cc_setup,			/* Special case: stop call establish after CC Setup */
+	boolean ran_clear_when_alerting,		/* Special case: send Clear upon CC Alerting */
 
 	MgcpCallId mgcp_call_id optional,		/* MGCP Call ID; CallAgent allocated */
 	MgcpEndpoint mgcp_ep optional			/* MGCP Endpoint, CallAgent or MGW allocated */,
-	MgcpConnectionId mgcp_connection_id_bss,	/* MGCP Connection ID BSS Side */
-	MgcpConnectionId mgcp_connection_id_mss,	/* MGCP Connection ID MSS Side */
 
-	boolean use_osmux				/* MSC is expected to use Osmux for this call */
+	boolean use_osmux,				/* MSC is expected to use Osmux for this call */
+	integer got_osmux_count
 }
 
-template (value) CallParameters t_CallParams(hexstring called, integer tid) := {
+template (value) CallParameters t_CallParams(hexstring called := '12345'H, integer tid := 0) := {
 	called_party := called,
 	transaction_id := tid,
 	mo_call := false,
@@ -724,32 +731,43 @@
 	bss_rtp_port := 9000,
 	mss_rtp_ip := omit,
 	mss_rtp_port := omit,
-	mgw_rtp_ip_bss := "1.1.1.1",
-	mgw_rtp_port_bss := 10000,
-	mgw_rtp_ip_mss := "1.1.1.1",
-	mgw_rtp_port_mss := 11000,
+	got_crcx_count := 0,
+	mgw_conn_1 := {
+		resp := 1,
+		mgw_rtp_ip := "1.1.1.1",
+		mgw_rtp_port := 10000,
+		mgcp_connection_id := '11111'H
+	},
+	mgw_conn_2 := {
+		resp := 1,
+		mgw_rtp_ip := "1.1.1.1",
+		mgw_rtp_port := 11000,
+		mgcp_connection_id := '22222'H
+	},
 	rtp_payload_type := 98,
 	rtp_sdp_format := "AMR/8000",
 	mgw_drop_dlcx := false,
+	stop_after_cc_setup := false,
+	ran_clear_when_alerting := false,
 	mgcp_call_id := omit,
-	mgcp_ep := omit,
-	mgcp_connection_id_bss := '0'H,//
-	mgcp_connection_id_mss := '0'H,//
-	use_osmux := false
+	mgcp_ep := "rtpbridge/1 at mgw",
+	use_osmux := false,
+	got_osmux_count := 0
 };
 
 /* Allocate a call reference and send SETUP via MNCC to MSC */
 function f_mt_call_initate(inout CallParameters cpars)
 runs on BSC_ConnHdlr {
+	cpars.mo_call := false;
 	cpars.mncc_callref := f_rnd_int(2147483648);
 	MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
 					hex2str(cpars.called_party), hex2str(g_pars.imsi)));
 }
 
 private template (value) SDP_Message ts_SDP_CRCX_CN(CallParameters cpars) :=
-	ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+	ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
 		hex2str(cpars.mgcp_call_id), "42",
-		cpars.mgw_rtp_port_mss,
+		cpars.mgw_conn_2.mgw_rtp_port,
 		{ int2str(cpars.rtp_payload_type) },
 		{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
 		  cpars.rtp_sdp_format)),
@@ -770,6 +788,8 @@
 
 	log("f_mt_call_complete 1");
 
+	cpars.got_osmux_count := 0;
+
 	/* MS <- MSC: Expect CC SETUP */
 	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
 
@@ -783,53 +803,26 @@
 	/* Ask MSC via MNCC to create the RTP socket on the MSC/MGW side */
 	MNCC.send(ts_MNCC_RTP_CREATE(cpars.mncc_callref));
 
-	/* First MGCP CRCX (for BSS/RAN side) */
+	/* First MGCP CRCX */
 	MGCP.receive(tr_CRCX) -> value mgcp_cmd {
 		log("f_mt_call_complete 3");
-		cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
-
-		/* When the endpoint contains a wildcard we keep the endpoint
-		 * identifier we have set up in cpars. Otherwise we use the
-		 * endpoint name that the call agent has supplied */
-		if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
-			cpars.mgcp_ep := mgcp_cmd.line.ep;
+		if (not f_handle_crcx(cpars, mgcp_cmd)) {
+			return;
 		}
-
-		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_bss, cpars.mgw_rtp_ip_bss,
-							hex2str(cpars.mgcp_call_id), "42",
-							cpars.mgw_rtp_port_bss,
-							{ int2str(cpars.rtp_payload_type) },
-							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
-										cpars.rtp_sdp_format)),
-							  valueof(ts_SDP_ptime(20)) }));
-
-		if (cpars.use_osmux) {
-			osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
-			if (osmux_cid != -1) { /* we expect MSC to use wildcard here */
-				setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
-				mtc.stop;
-			}
-			osmux_cid := 0;
-			mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
-		} else {
-			mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, sdp);
-		}
-
-		f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(cpars.mgcp_ep));
-		MGCP.send(mgcp_resp);
 		}
 
 
 	if (g_pars.ran_is_geran) {
-		var BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
-			valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_rtp_ip_bss),cpars.mgw_rtp_port_bss));
+		var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
+			tr_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_conn_1.mgw_rtp_ip), ?);
 
 		interleave {
 		/* Second MGCP CRCX (this time for MSS/CN side) */
 		[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
 			log("f_mt_call_complete 4");
-			var SDP_Message sdp := valueof(ts_SDP_CRCX_CN(cpars));
-			MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+			if (not f_handle_crcx(cpars, mgcp_cmd)) {
+				break;
+			}
 			}
 
 		/* MSC acknowledges the MNCC_CREATE to the MNCC handler */
@@ -839,7 +832,7 @@
 
 		/* expect the MSC to trigger a BSSMAP ASSIGNMENT */
 		[] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) -> value bssap {
-			var BSSMAP_IE_AoIP_TransportLayerAddress tla;
+			var template BSSMAP_IE_AoIP_TransportLayerAddress tla;
 			var BSSMAP_IE_SpeechCodec codec;
 			var BSSMAP_IE_Osmo_OsmuxCID osmuxCID;
 			log("f_mt_call_complete 6");
@@ -853,8 +846,8 @@
 					mtc.stop;
 				}
 				osmuxCID := valueof(ts_OsmuxCID(0));
-				if (cpars.use_osmux and not match(bssap.pdu.bssmap.assignmentRequest.osmuxCID, osmuxCID)) {
-					setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
+				if (not match(bssap.pdu.bssmap.assignmentRequest.osmuxCID, osmuxCID)) {
+					setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE. Expected ", osmuxCID, " Got ", bssap.pdu.bssmap.assignmentRequest.osmuxCID);
 					mtc.stop;
 				}
 				bssap := valueof(ts_BSSMAP_AssignmentComplete(omit, tla, codec, osmuxCID));
@@ -877,9 +870,9 @@
 		/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
 		[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
 			log("f_mt_call_complete 8");
-			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
 								hex2str(cpars.mgcp_call_id), "42",
-								cpars.mgw_rtp_port_mss,
+								cpars.mgw_conn_2.mgw_rtp_port,
 								{ int2str(cpars.rtp_payload_type) },
 								{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
 											cpars.rtp_sdp_format)),
@@ -890,9 +883,9 @@
 					setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != 0");
 					mtc.stop;
 				}
-				mgcp_resp := ts_MDCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
+				mgcp_resp := ts_MDCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgw_conn_1.mgcp_connection_id, osmux_cid, sdp);
 			} else {
-				mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp);
+				mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_2.mgcp_connection_id, sdp);
 			}
 			MGCP.send(mgcp_resp);
 			}
@@ -900,25 +893,25 @@
 		/* MDCX setting up the CN side remote RTP address received from MNCC CONNECT */
 		[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
 			log("f_mt_call_complete 9");
-			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
 								hex2str(cpars.mgcp_call_id), "42",
-								cpars.mgw_rtp_port_mss,
+								cpars.mgw_conn_2.mgw_rtp_port,
 								{ int2str(cpars.rtp_payload_type) },
 								{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
 											cpars.rtp_sdp_format)),
 								  valueof(ts_SDP_ptime(20)) }));
-			MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+			MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_2.mgcp_connection_id, sdp));
 			}
 
 		}
 	} else {
-		var template TransportLayerAddress rab_tla := ? /* FIXME: encode the mgw_rtp_ip_bss/mgw_rtp_port_bss */
+		var template TransportLayerAddress rab_tla := ? /* FIXME: encode the mgw_rtp_ip/mgw_rtp_port */
 		var template RAB_SetupOrModifyList rab_sml := tr_RAB_SML(rab_id := ?, tla := rab_tla, binding_id := ?);
 
 		interleave {
 		[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
 			var SDP_Message sdp := valueof(ts_SDP_CRCX_CN(cpars));
-			MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+			MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_2.mgcp_connection_id, sdp));
 			/* MSC acknowledges the MNCC_CREATE to the MNCC handler */
 			MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref));
 			}
@@ -930,6 +923,13 @@
 		}
 	}
 
+	if (cpars.use_osmux == (cpars.got_osmux_count != 0)) {
+		log("Osmux ok: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
+	} else {
+		setverdict(fail, "Osmux failure: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
+		mtc.stop;
+	}
+
 	log("f_mt_call_complete DONE");
 }
 
@@ -958,6 +958,139 @@
 	setverdict(pass);
 }
 
+/* Reply to a received CRCX with an OK (or the reply configured in cpars), using the given parameters.
+ * Return true when an OK reply was sent, false otherwise.
+ * Count occurence of Osmux, include Osmux parameters in the reply if necessary. */
+function f_handle_crcx(inout CallParameters cpars, MgcpCommand mgcp_cmd)
+runs on BSC_ConnHdlr
+return boolean {
+	var CrcxResponse conn := cpars.mgw_conn_1;
+	if (cpars.got_crcx_count > 0) {
+		conn := cpars.mgw_conn_2;
+	}
+	cpars.got_crcx_count := cpars.got_crcx_count + 1;
+
+	var MgcpMessage mgcp_msg := {
+		command := mgcp_cmd
+	}
+	var template MgcpResponse mgcp_resp;
+	var MgcpOsmuxCID osmux_cid;
+	var MgcpCallId call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
+	if (ispresent(cpars.mgcp_call_id)) {
+		if (cpars.mgcp_call_id != call_id) {
+			setverdict(fail, "CRCX contained unexpected call id. Expected:", cpars.mgcp_call_id, " got:", call_id);
+			mtc.stop;
+		}
+	} else {
+		cpars.mgcp_call_id := call_id;
+	}
+
+	/* When the endpoint contains a wildcard we keep the endpoint
+	 * identifier we have set up in cpars. Otherwise we use the
+	 * endpoint name that the call agent has supplied */
+	if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
+		cpars.mgcp_ep := mgcp_cmd.line.ep;
+	}
+
+	if (conn.resp == -1) {
+		/* Reply with error */
+		var MgcpResponse mgcp_rsp := {
+			line := {
+				code := "542",
+				trans_id := mgcp_cmd.line.trans_id,
+				string := "FORCED_FAIL"
+			},
+			sdp := omit
+
+		}
+		var MgcpParameter mgcp_rsp_param := {
+			code := "Z",
+			val := cpars.mgcp_ep
+		};
+		mgcp_rsp.params[0] := mgcp_rsp_param;
+		MGCP.send(mgcp_rsp);
+		return false;
+	}
+
+	if (conn.resp == 0) {
+		/* Do not reply at all */
+		return false;
+	}
+
+	if (conn.resp != 1) {
+		setverdict(fail, "Unexpected value for cpars.mgw_conn_*.resp, expect -1, 0 or 1");
+		mtc.stop;
+	}
+
+	var SDP_Message sdp := valueof(ts_SDP(conn.mgw_rtp_ip, conn.mgw_rtp_ip,
+						hex2str(cpars.mgcp_call_id), "42",
+						conn.mgw_rtp_port,
+						{ int2str(cpars.rtp_payload_type) },
+						{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+									cpars.rtp_sdp_format)),
+						  valueof(ts_SDP_ptime(20)) }));
+
+	if (f_mgcp_contains_par(mgcp_msg, "X-OSMUX")) {
+		if (not cpars.use_osmux) {
+			setverdict(fail, "MSC sent X-Osmux parameter in MGCP, but not expecting any Osmux");
+			mtc.stop;
+		}
+		cpars.got_osmux_count := cpars.got_osmux_count + 1;
+		/* we expect MSC to use wildcard here, i.e. osmux_cid == -1 */
+		osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
+		log("f_handle_crcx(): got Osmux CID: ", osmux_cid);
+		if (osmux_cid != -1) {
+			setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
+			mtc.stop;
+		}
+
+		osmux_cid := 0;
+		mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, osmux_cid, sdp);
+	} else {
+		mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, sdp);
+	}
+
+	f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(cpars.mgcp_ep));
+	MGCP.send(mgcp_resp);
+	return true;
+}
+
+
+altstep as_optional_mgcp_crcx(CallParameters cpars) runs on BSC_ConnHdlr {
+	var MgcpCommand mgcp_cmd;
+	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
+		log("as_optional_mgcp_crcx: rx CRCX");
+		f_handle_crcx(cpars, mgcp_cmd);
+
+		/* Without this 'repeat', the as_optional_mgcp_crcx() exits currently waiting interleaves as soon as an
+		 * CRCX is handled. */
+		repeat;
+		}
+}
+
+private altstep as_optional_mgcp_mdcx(HostName mgw_rtp_ip, PortNumber mgw_rtp_port) runs on BSC_ConnHdlr {
+	var MgcpCommand mgcp_cmd;
+	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
+		log("as_optional_mgcp_mdcx: rx MDCX");
+		log(mgcp_cmd);
+		var charstring conn_id;
+		var charstring rtp_payload_type;
+		f_mgcp_find_param_entry(mgcp_cmd.params, "I", conn_id);
+		rtp_payload_type := mgcp_cmd.sdp.media_list[0].media_field.fmts[0];
+
+		var SDP_Message sdp := valueof(ts_SDP(mgw_rtp_ip, mgw_rtp_ip,
+							mgcp_cmd.sdp.origin.session_id, "42",
+							mgw_rtp_port,
+							{ rtp_payload_type },
+							{ valueof(ts_SDP_ptime(20)) }));
+		MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, str2hex(conn_id), sdp));
+
+		/* Without this 'repeat', currently active other interleave and alt series exit as soon as an MDCX is
+		 * handled. */
+		repeat;
+	}
+}
+
 function f_mo_call_establish(inout CallParameters cpars)
 runs on BSC_ConnHdlr {
 
@@ -968,6 +1101,8 @@
 	var PDU_BSSAP bssap;
 	var MgcpOsmuxCID osmux_cid;
 
+	cpars.mo_call := true;
+
 	if (cpars.emergency) {
 		f_establish_fully(EST_TYPE_EMERG_CALL);
 	} else {
@@ -984,8 +1119,14 @@
 		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
 	}
 
-	var BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
-		valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_rtp_ip_bss),cpars.mgw_rtp_port_bss));
+	if (cpars.stop_after_cc_setup) {
+		return;
+	}
+
+	var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
+		tr_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_conn_1.mgw_rtp_ip), ?);
+
+	var default mdcx := activate(as_optional_mgcp_mdcx(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_port));
 
 	interleave {
 	[] MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc {
@@ -994,43 +1135,20 @@
 		MNCC.send(ts_MNCC_RTP_CREATE(cpars.mncc_callref));
 		}
 
-	/* First MGCP CRCX (for BSS/RAN side) */
+	/* First MGCP CRCX */
 	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
 		log("f_mo_call_establish 2: rx 1st CRCX");
-		cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
-
-		/* When the endpoint contains a wildcard we keep the endpoint
-		 * identifier we have set up in cpars. Otherwise we use the
-		 * endpoint name that the call agent has supplied */
-		if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
-			cpars.mgcp_ep := mgcp_cmd.line.ep;
+		if (not f_handle_crcx(cpars, mgcp_cmd)) {
+			break;
+		}
 		}
 
-		if (cpars.use_osmux) {
-			osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
+	/* Second MGCP CRCX */
+	[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
+		log("f_mo_call_establish 6: rx 2nd CRCX");
+		if (not f_handle_crcx(cpars, mgcp_cmd)) {
+			break;
 		}
-
-		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_bss, cpars.mgw_rtp_ip_bss,
-							hex2str(cpars.mgcp_call_id), "42",
-							cpars.mgw_rtp_port_bss,
-							{ int2str(cpars.rtp_payload_type) },
-							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
-										cpars.rtp_sdp_format)),
-							  valueof(ts_SDP_ptime(20)) }));
-
-		if (cpars.use_osmux) {
-			osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
-			if (osmux_cid != -1) { /* we expect MSC to use wildcard here */
-				setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
-				mtc.stop;
-			}
-			osmux_cid := 0;
-			mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
-		} else {
-			mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, sdp);
-		}
-		f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(cpars.mgcp_ep));
-		MGCP.send(mgcp_resp);
 		}
 
 	[] MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref)) {
@@ -1050,7 +1168,7 @@
 		var BSSMAP_IE_SpeechCodec codec;
 		var BSSMAP_IE_Osmo_OsmuxCID osmuxCID;
 
-		if (tla_ass != bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer) {
+		if (not match(bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer, tla_ass)) {
 			log("Expected:", tla_ass);
 			log("Got:", bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer);
 			setverdict(fail, "MSC sent Assignment Request with unexpected AoIP Transport Layer IE");
@@ -1084,9 +1202,9 @@
 	/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
 	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
 		log("f_mo_call_establish 5: rx MDCX for the RAN side");
-		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
 							hex2str(cpars.mgcp_call_id), "42",
-							cpars.mgw_rtp_port_mss,
+							cpars.mgw_conn_2.mgw_rtp_port,
 							{ int2str(cpars.rtp_payload_type) },
 							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
 										cpars.rtp_sdp_format)),
@@ -1098,22 +1216,25 @@
 				setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != 0");
 				mtc.stop;
 			}
-			mgcp_resp := ts_MDCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
+			mgcp_resp := ts_MDCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgw_conn_1.mgcp_connection_id, osmux_cid, sdp);
 		} else {
-			mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp);
+			mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_2.mgcp_connection_id, sdp);
 		}
 		MGCP.send(mgcp_resp);
 		}
 
-	/* Second MGCP CRCX (this time for MSS/CN side) */
-	[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
-		log("f_mo_call_establish 6: rx 2nd CRCX, for CN side");
-		var SDP_Message sdp := valueof(ts_SDP_CRCX_CN(cpars));
-		MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
-		}
-
 	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id))) {
 		log("f_mo_call_establish 7: rx CC Alerting");
+
+		if (cpars.ran_clear_when_alerting) {
+			if (g_pars.ran_is_geran) {
+				BSSAP.send(ts_BSSMAP_ClearRequest(0));
+			} else {
+				BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
+			}
+			break;
+		}
+
 		cpars.mncc_callref := mncc.u.signal.callref;
 		/* Call Proceeding */
 		MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
@@ -1127,33 +1248,32 @@
 		log("f_mo_call_establish 8: rx MNCC SETUP COMPLETE ind");
 		}
 
-	/* second MDCX setting up the CN side remote RTP address and codec received from MNCC RTP CONNECT */
-	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
-		log("f_mo_call_establish 9: rx MDCX for CN side");
-		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
-							hex2str(cpars.mgcp_call_id), "42",
-							cpars.mgw_rtp_port_mss,
-							{ int2str(cpars.rtp_payload_type) },
-							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
-										cpars.rtp_sdp_format)),
-							  valueof(ts_SDP_ptime(20)) }));
-		MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
-		}
-
 	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CONNECT(cpars.transaction_id))) {
 		log("f_mo_call_establish 10: rx CC CONNECT");
 		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT_ACK(cpars.transaction_id)));
 		}
+
+	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
+		log("f_mo_call_establish 11: rx CC RELEASE");
+		f_expect_clear();
+		break;
+		}
+	}
+
+	f_sleep(0.5);
+	deactivate(mdcx);
+
+	if (cpars.use_osmux == (cpars.got_osmux_count != 0)) {
+		log("Osmux ok: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
+	} else {
+		setverdict(fail, "Osmux failure: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
+		mtc.stop;
 	}
 
 	log("f_mo_call_establish DONE");
 	setverdict(pass);
 }
 
-private altstep as_optional_mgcp_mdcx() runs on BSC_ConnHdlr {
-	[] MGCP.receive(tr_MDCX) {};
-}
-
 function f_call_hangup(inout CallParameters cpars, boolean release_by_ms, boolean is_csfb := false)
 runs on BSC_ConnHdlr {
 
@@ -1194,7 +1314,7 @@
 
 	respond_to_dlcx := not (isbound(cpars.mgw_drop_dlcx) and valueof(cpars.mgw_drop_dlcx));
 
-	var default mdcx := activate(as_optional_mgcp_mdcx());
+	var default mdcx := activate(as_optional_mgcp_mdcx(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_port));
 
 	/* clearing of radio channel */
 	interleave {
diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn
index c290d7c..b4db43d 100644
--- a/msc/MSC_Tests.ttcn
+++ b/msc/MSC_Tests.ttcn
@@ -608,12 +608,7 @@
 
 friend function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
-	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '22222'H;
-	cpars.mgcp_connection_id_mss := '33333'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-
+	var CallParameters cpars := valueof(t_CallParams);
 	f_perform_lu();
 	f_mo_call(cpars);
 }
@@ -939,7 +934,6 @@
 private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
 	var CallParameters cpars := valueof(t_CallParams('112'H, 0));
 	cpars.emergency := true;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
 
 	f_mo_call(cpars);
 }
@@ -1213,14 +1207,14 @@
 	f_init_handler(pars, 190.0);
 
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
+	cpars.mgw_conn_2.resp := 0;
+	cpars.stop_after_cc_setup := true;
+
+	f_vty_config(MSCVTY, "msc", "mncc guard-timeout 20");
 
 	f_perform_lu();
 
-	f_establish_fully();
-	f_create_mncc_expect(hex2str(cpars.called_party));
-	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
-
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
+	f_mo_call_establish(cpars);
 
 	var default ccrel := activate(as_optional_cc_rel(cpars));
 
@@ -1247,28 +1241,15 @@
 	var MgcpCommand mgcp_cmd;
 
 	f_perform_lu();
+	/* Do not respond to the second CRCX */
+	cpars.mgw_conn_2.resp := 0;
+	f_mo_call_establish(cpars);
 
-	f_establish_fully();
-	f_create_mncc_expect(hex2str(cpars.called_party));
-	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
+	var default ccrel := activate(as_optional_cc_rel(cpars));
 
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
-	MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
-	cpars.mncc_callref := mncc.u.signal.callref;
-	MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
-	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
+	f_expect_clear(60.0);
 
-	MGCP.receive(tr_CRCX) -> value mgcp_cmd;
-	cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
-	cpars.mgcp_ep := mgcp_cmd.line.ep;
-	/* never respond to this */
-
-	/* When the connection with the MGW fails, the MSC will first request
-	 * a release via call control. We will answer this request normally. */
-	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
-
-	f_expect_clear(30.0);
+	deactivate(ccrel);
 }
 testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
 	var BSC_ConnHdlr vc_conn;
@@ -1282,75 +1263,18 @@
 /* Test MO Call with reject to RAN-side CRCX */
 friend function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
+
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	var MNCC_PDU mncc;
-	var MgcpCommand mgcp_cmd;
+
+	/* Respond with error for the first CRCX */
+	cpars.mgw_conn_1.resp := -1;
 
 	f_perform_lu();
+	f_mo_call_establish(cpars);
 
-	f_establish_fully();
-	f_create_mncc_expect(hex2str(cpars.called_party));
-	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
-
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
-	MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
-	cpars.mncc_callref := mncc.u.signal.callref;
-	MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
-	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
-
-	MGCP.receive(tr_CRCX) -> value mgcp_cmd;
-
-	/* Detect if the received CRCX is a wildcarded CRCX request. If yes,
-	 * set an endpoint name that fits the pattern. If not, just use the
-	 * endpoint name from the request */
-	if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
-		cpars.mgcp_ep := "rtpbridge/1 at mgw";
-	} else {
-		cpars.mgcp_ep := mgcp_cmd.line.ep;
-	}
-
-	cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
-
-	/* Respond to CRCX with error */
-	var MgcpResponse mgcp_rsp := {
-		line := {
-			code := "542",
-			trans_id := mgcp_cmd.line.trans_id,
-			string := "FORCED_FAIL"
-		},
-		sdp := omit
-	}
-	var MgcpParameter mgcp_rsp_param := {
-		code := "Z",
-		val := cpars.mgcp_ep
-	};
-	mgcp_rsp.params[0] := mgcp_rsp_param;
-	MGCP.send(mgcp_rsp);
-
-	timer T := 30.0;
-	T.start;
-	alt {
-	[] T.timeout {
-		setverdict(fail, "Timeout waiting for channel release");
-		mtc.stop;
-		}
-	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
-		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
-		repeat;
-		}
-	[] MNCC.receive { repeat; }
-	[] GSUP.receive { repeat; }
-	/* Note: As we did not respond properly to the CRCX from the MSC we
-	 * expect the MSC to omit any further MGCP operation (At least in the
-	 * the current implementation, there is no recovery mechanism implemented
-	 * and a DLCX can not be performed as the MSC does not know a specific
-	 * endpoint yet. */
-	[] MGCP.receive {
-		setverdict(fail, "Unexpected MGCP message");
-		mtc.stop;
-		}
-	[] as_clear_cmd_compl_disc();
-	}
+	var default ccrel := activate(as_optional_cc_rel(cpars));
+	f_expect_clear(60.0);
+	deactivate(ccrel);
 }
 testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
 	var BSC_ConnHdlr vc_conn;
@@ -1520,10 +1444,6 @@
 friend function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '22222'H;
-	cpars.mgcp_connection_id_mss := '33333'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
 
 	/* Location Update to make subscriber known */
 	f_perform_lu();
@@ -1741,15 +1661,8 @@
 private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '10004'H;
-	cpars.mgcp_connection_id_mss := '10005'H;
 	cpars.use_osmux := pars.use_osmux;
 
-	/* Note: This is an optional parameter. When the call-agent (MSC) does
-	 * supply a full endpoint name this setting will be overwritten. */
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-
 	f_perform_lu();
 	f_mt_call(cpars);
 }
@@ -1773,11 +1686,6 @@
 private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '22222'H;
-	cpars.mgcp_connection_id_mss := '33333'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-	cpars.mo_call := true;
 
 	f_perform_lu();
 	f_mo_seq_dtmf_dup(cpars);
@@ -1838,20 +1746,11 @@
 	var MNCC_PDU mncc;
 	var MgcpCommand mgcp_cmd;
 
+	/* Do not respond to the second CRCX */
+	cpars.mgw_conn_2.resp := 0;
+
 	f_perform_lu();
-
-	f_establish_fully();
-	f_create_mncc_expect(hex2str(cpars.called_party));
-	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
-
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
-	MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
-	cpars.mncc_callref := mncc.u.signal.callref;
-	MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
-	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
-
-	/* Drop CRCX */
-	MGCP.receive(tr_CRCX) -> value mgcp_cmd;
+	f_mo_call_establish(cpars);
 
 	var default ccrel := activate(as_optional_cc_rel(cpars));
 
@@ -1872,13 +1771,6 @@
 private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '10004'H;
-	cpars.mgcp_connection_id_mss := '10005'H;
-
-	/* Note: This is an optional parameter. When the call-agent (MSC) does
-	 * supply a full endpoint name this setting will be overwritten. */
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
 
 	/* Intentionally disable the CRCX response */
 	cpars.mgw_drop_dlcx := true;
@@ -3107,10 +2999,6 @@
 
 	/* Call parameters taken from f_tc_lu_and_mt_call */
 	var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
-	cpars.mgcp_connection_id_bss := '10004'H;
-	cpars.mgcp_connection_id_mss := '10005'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-	cpars.bss_rtp_port := 1110;
 
 	/* Perform location update */
 	f_perform_lu();
@@ -3190,51 +3078,13 @@
 friend function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	var MNCC_PDU mncc;
-	var MgcpCommand mgcp_cmd;
+	cpars.ran_clear_when_alerting := true;
 
 	f_perform_lu();
 
-	f_establish_fully();
-	f_create_mncc_expect(hex2str(cpars.called_party));
-	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
-
-	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
-	MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
-	cpars.mncc_callref := mncc.u.signal.callref;
-	log("mncc_callref=", cpars.mncc_callref);
-	MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
-	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
-
-	MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
-	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id)));
-	MGCP.receive(tr_CRCX);
-
-	f_sleep(1.0);
-	if (pars.ran_is_geran) {
-		BSSAP.send(ts_BSSMAP_ClearRequest(0));
-	} else {
-		BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
-	}
-
 	var default ccrel := activate(as_optional_cc_rel(cpars));
-
-	if (pars.ran_is_geran) {
-		interleave {
-		[] MNCC.receive(tr_MNCC_REL_ind(?, ?)) { };
-		[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
-			BSSAP.send(ts_BSSMAP_ClearComplete);
-			};
-		}
-	} else {
-		interleave {
-		[] MNCC.receive(tr_MNCC_REL_ind(?, ?)) { };
-		[] BSSAP.receive(tr_RANAP_IuReleaseCommand(?)) {
-			BSSAP.send(ts_RANAP_IuReleaseComplete);
-			};
-		}
-	}
-
+	f_mo_call_establish(cpars);
+	f_expect_clear()
 	deactivate(ccrel);
 
 	f_sleep(1.0);
@@ -3255,10 +3105,6 @@
 
 	/* Call parameters taken from f_tc_lu_and_mt_call */
 	var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
-	cpars.mgcp_connection_id_bss := '10004'H;
-	cpars.mgcp_connection_id_mss := '10005'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-	cpars.bss_rtp_port := 1110;
 
 	/* Perform location update */
 	f_perform_lu();
@@ -5020,13 +4866,6 @@
 
 	var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '10004'H;
-	cpars.mgcp_connection_id_mss := '10005'H;
-
-	/* Note: This is an optional parameter. When the call-agent (MSC) does
-	 * supply a full endpoint name this setting will be overwritten. */
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
 
 	/* Initiate a call via MNCC interface */
 	f_mt_call_initate(cpars);
@@ -5142,11 +4981,6 @@
 private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	f_init_handler(pars);
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '22222'H;
-	cpars.mgcp_connection_id_mss := '33333'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-	cpars.mo_call := true;
 
 	f_perform_lu();
 	f_mo_call_establish(cpars);
@@ -5175,25 +5009,20 @@
 private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {
 	var MgcpCommand mgcp_cmd;
 	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
-			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
 								hex2str(cpars.mgcp_call_id), "42",
-								cpars.mgw_rtp_port_mss,
+								cpars.mgw_conn_2.mgw_rtp_port,
 								{ int2str(cpars.rtp_payload_type) },
 								{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
 											cpars.rtp_sdp_format)),
 								  valueof(ts_SDP_ptime(20)) }));
-			MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+			MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_2.mgcp_connection_id, sdp));
 			repeat;
 		}
 }
 
 private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '22222'H;
-	cpars.mgcp_connection_id_mss := '33333'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-	cpars.mo_call := true;
 
 	f_init_handler(pars);
 
@@ -5353,11 +5182,6 @@
 
 private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
 	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
-	cpars.bss_rtp_port := 1110;
-	cpars.mgcp_connection_id_bss := '22222'H;
-	cpars.mgcp_connection_id_mss := '33333'H;
-	cpars.mgcp_ep := "rtpbridge/1 at mgw";
-	cpars.mo_call := true;
 	var hexstring ho_number := f_gen_msisdn(99999);
 
 	f_init_handler(pars);

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/15938
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I8b82476f55a98f7a94d5c4f1cd80eac427b2d20f
Gerrit-Change-Number: 15938
Gerrit-PatchSet: 5
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191123/3cbee1cd/attachment.htm>


More information about the gerrit-log mailing list