neels has uploaded this change for review. ( 
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).

Split f_mgcp_find_param_entry() out of f_mgcp_find_param() to be able to act on
an MgcpParameterList without an enclosing MgcpMessage.

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 library/MGCP_Templates.ttcn
M msc/BSC_ConnectionHandler.ttcn
M msc/MSC_Tests.ttcn
4 files changed, 294 insertions(+), 345 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks 
refs/changes/38/15938/1

diff --git a/library/BSSMAP_Templates.ttcn b/library/BSSMAP_Templates.ttcn
index 41755db..b40ec61 100644
--- a/library/BSSMAP_Templates.ttcn
+++ b/library/BSSMAP_Templates.ttcn
@@ -407,15 +407,15 @@
        return cic;
 }

-template (value) BSSMAP_IE_AoIP_TransportLayerAddress 
ts_BSSMAP_IE_AoIP_TLA(BSSMAP_FIELD_IPAddress addr,
-                                                                           
uint16_t udp_port,
+template BSSMAP_IE_AoIP_TransportLayerAddress 
ts_BSSMAP_IE_AoIP_TLA(BSSMAP_FIELD_IPAddress addr,
+                                                                           
template uint16_t udp_port,
                                                                            
integer len) := {
        elementIdentifier := '7C'O,
        lengthIndicator := len, /* overwritten */
        ipAddress := addr,
        uDPPortValue := udp_port
 }
-template (value) BSSMAP_IE_AoIP_TransportLayerAddress 
ts_BSSMAP_IE_AoIP_TLA4(OCT4 ip, uint16_t pt) :=
+template BSSMAP_IE_AoIP_TransportLayerAddress ts_BSSMAP_IE_AoIP_TLA4(OCT4 ip, 
template uint16_t pt) :=
                                                        
ts_BSSMAP_IE_AoIP_TLA({ipv4:=ip}, pt, 6);
 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);
diff --git a/library/MGCP_Templates.ttcn b/library/MGCP_Templates.ttcn
index dae379e..e03fd8e 100644
--- a/library/MGCP_Templates.ttcn
+++ b/library/MGCP_Templates.ttcn
@@ -453,6 +453,17 @@
                sdp := *
        }

+       function f_mgcp_find_param_entry(MgcpParameterList pars, MgcpInfoCode 
code, out charstring ret)
+       return boolean {
+               for (var integer i := 0; i < sizeof(pars); i := i+1) {
+                       if (pars[i].code == code) {
+                               ret := pars[i].val;
+                               return true;
+                       }
+               }
+               return false;
+       }
+
        function f_mgcp_find_param(MgcpMessage msg, MgcpInfoCode code, out 
charstring ret)
        return boolean {
                var MgcpParameterList pars;
@@ -461,13 +472,7 @@
                } else {
                        pars := msg.response.params;
                }
-               for (var integer i := 0; i < sizeof(pars); i := i+1) {
-                       if (pars[i].code == code) {
-                               ret := pars[i].val;
-                               return true;
-                       }
-               }
-               return false;
+               return f_mgcp_find_param_entry(pars, code, ret);
        }

        /* template to determine if a MGCP endpoint is a wildcard endpoint */
diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn
index 7a94d85..23697da 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
 }

-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@mgw",
+       use_osmux := false,
+       got_osmux := 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 := 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 :=
+                       
ts_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 != 0)) {
+               log("Osmux ok: use_osmux = ", cpars.use_osmux, " got_osmux = ", 
cpars.got_osmux);
+       } else {
+               setverdict(fail, "Osmux failure: use_osmux = ", 
cpars.use_osmux, " got_osmux = ", cpars.got_osmux);
+               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 := cpars.got_osmux + 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 :=
+               
ts_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 != 0)) {
+               log("Osmux ok: use_osmux = ", cpars.use_osmux, " got_osmux = ", 
cpars.got_osmux);
+       } else {
+               setverdict(fail, "Osmux failure: use_osmux = ", 
cpars.use_osmux, " got_osmux = ", cpars.got_osmux);
+               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@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@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@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@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@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@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@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@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@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@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@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@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@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: 1
Gerrit-Owner: neels <nhofm...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to