<p>laforge <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/14512">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lib/mgcp: Add new port with support to handle multiple MGCP sockets<br><br>* Some scenarios like MGW BSC-attached in SCCPlite require handling of<br>2 MGCP-over-UDP sockets in MGCP Emulation: 1 for regular<br>libosmomgcp-client from osmo-bsc and another one from the forward socket<br>from osmo-bsc (of MGCP-over-IPA messages communicated with MSC).<br><br>* Old port is kept for backward compatibility with other tests and<br>enabled by default. It's also interesting to keep it because it makes<br>tests without special needs (2 sockets) to use the old port/API which<br>produces simpler code to read and mantain.<br><br>* Users of the new port have to enable multi_conn_mode parameter and<br>expect to interact with port MGCP_CLIENT_MULTI instead of MGCP_CLIENT,<br>which will offer messages containing information about the UDP<br>connection being used by that message.<br><br>Change-Id: Ic0ba8c5cde068c07671512a83095d83e28b86746<br>---<br>M bsc/BSC_Tests.ttcn<br>M library/MGCP_CodecPort.ttcn<br>M library/MGCP_Emulation.ttcn<br>M msc/MSC_Tests.ttcn<br>4 files changed, 84 insertions(+), 13 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn</span><br><span>index 976bc46..4c86e51 100644</span><br><span>--- a/bsc/BSC_Tests.ttcn</span><br><span>+++ b/bsc/BSC_Tests.ttcn</span><br><span>@@ -294,7 +294,8 @@</span><br><span>               callagent_ip := mp_bsc_ip,</span><br><span>           callagent_udp_port := -1,</span><br><span>            mgw_ip := mp_test_ip,</span><br><span style="color: hsl(0, 100%, 40%);">-           mgw_udp_port := 2427</span><br><span style="color: hsl(120, 100%, 40%);">+          mgw_udp_port := 2427,</span><br><span style="color: hsl(120, 100%, 40%);">+         multi_conn_mode := false</span><br><span>     };</span><br><span> </span><br><span>       vc_MGCP := MGCP_Emulation_CT.create(id);</span><br><span>diff --git a/library/MGCP_CodecPort.ttcn b/library/MGCP_CodecPort.ttcn</span><br><span>index d33afe1..8614eef 100644</span><br><span>--- a/library/MGCP_CodecPort.ttcn</span><br><span>+++ b/library/MGCP_CodecPort.ttcn</span><br><span>@@ -41,11 +41,33 @@</span><br><span>              MgcpMessage     msg</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ type record MGCP_SendTo {</span><br><span style="color: hsl(120, 100%, 40%);">+             ConnectionId    connId,</span><br><span style="color: hsl(120, 100%, 40%);">+               HostName        remName,</span><br><span style="color: hsl(120, 100%, 40%);">+              PortNumber      remPort,</span><br><span style="color: hsl(120, 100%, 40%);">+              MgcpMessage     msg</span><br><span style="color: hsl(120, 100%, 40%);">+   };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         template MGCP_Send t_MGCP_Send(template ConnectionId connId, template MgcpMessage msg) := {</span><br><span>          connId := connId,</span><br><span>            msg := msg</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ template MGCP_SendTo t_MGCP_SendTo(template ConnectionId connId, HostName remName,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     PortNumber remPort,template MgcpMessage msg) := {</span><br><span style="color: hsl(120, 100%, 40%);">+            connId := connId,</span><br><span style="color: hsl(120, 100%, 40%);">+             remName := remName,</span><br><span style="color: hsl(120, 100%, 40%);">+           remPort := remPort,</span><br><span style="color: hsl(120, 100%, 40%);">+           msg := msg</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   template MGCP_SendTo t_MGCP_SendToMrf(MGCP_RecvFrom mrf,template MgcpMessage msg) := {</span><br><span style="color: hsl(120, 100%, 40%);">+                connId := mrf.connId,</span><br><span style="color: hsl(120, 100%, 40%);">+         remName := mrf.remName,</span><br><span style="color: hsl(120, 100%, 40%);">+               remPort := mrf.remPort,</span><br><span style="color: hsl(120, 100%, 40%);">+               msg := msg</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  private function IPL4_to_MGCP_RecvFrom(in ASP_RecvFrom pin, out MGCP_RecvFrom pout) {</span><br><span>                pout.connId := pin.connId;</span><br><span>           pout.remName := pin.remName;</span><br><span>@@ -65,13 +87,23 @@</span><br><span>           pout.msg := char2oct(enc_MgcpMessage(pin.msg));</span><br><span>      } with { extension "prototype(fast)" };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ private function MGCP_to_IPL4_SendTo(in MGCP_SendTo pin, out ASP_SendTo out_ud) {</span><br><span style="color: hsl(120, 100%, 40%);">+             out_ud.connId := pin.connId;</span><br><span style="color: hsl(120, 100%, 40%);">+          out_ud.remName := pin.remName;</span><br><span style="color: hsl(120, 100%, 40%);">+                out_ud.remPort := pin.remPort;</span><br><span style="color: hsl(120, 100%, 40%);">+                out_ud.proto := { udp := {} };</span><br><span style="color: hsl(120, 100%, 40%);">+                out_ud.msg := char2oct(enc_MgcpMessage(pin.msg));</span><br><span style="color: hsl(120, 100%, 40%);">+     } with { extension "prototype(fast)" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  type port MGCP_CODEC_PT message {</span><br><span style="color: hsl(0, 100%, 40%);">-               out     MGCP_Send;</span><br><span style="color: hsl(120, 100%, 40%);">+            out     MGCP_Send,</span><br><span style="color: hsl(120, 100%, 40%);">+                    MGCP_SendTo;</span><br><span>                 in      MGCP_RecvFrom,</span><br><span>                       ASP_ConnId_ReadyToRelease,</span><br><span>                   ASP_Event;</span><br><span>   } with { extension "user IPL4asp_PT</span><br><span style="color: hsl(0, 100%, 40%);">-                out(MGCP_Send -> ASP_Send:function(MGCP_to_IPL4_Send))</span><br><span style="color: hsl(120, 100%, 40%);">+             out(MGCP_Send -> ASP_Send:function(MGCP_to_IPL4_Send);</span><br><span style="color: hsl(120, 100%, 40%);">+                 MGCP_SendTo -> ASP_SendTo: function(MGCP_to_IPL4_SendTo))</span><br><span>             in(ASP_RecvFrom -> MGCP_RecvFrom: function(IPL4_to_MGCP_RecvFrom);</span><br><span>                   ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple;</span><br><span>                   ASP_Event -> ASP_Event: simple)"</span><br><span>diff --git a/library/MGCP_Emulation.ttcn b/library/MGCP_Emulation.ttcn</span><br><span>index 23cfeb4..494b171 100644</span><br><span>--- a/library/MGCP_Emulation.ttcn</span><br><span>+++ b/library/MGCP_Emulation.ttcn</span><br><span>@@ -37,8 +37,11 @@</span><br><span> import from IPL4asp_Types all;</span><br><span> </span><br><span> type component MGCP_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Simple send/recv without caring about peer addr+port. Used with multi_conn_mode=false. */</span><br><span>         port MGCP_Conn_PT MGCP;</span><br><span style="color: hsl(0, 100%, 40%);">- /* procedure based port to register for incoming connections */</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Handle multiple connections concurrently. Used with multi_conn_mode=true. */</span><br><span style="color: hsl(120, 100%, 40%);">+       port MGCP_Conn_Multi_PT MGCP_MULTI;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* procedure based port to register for incoming connections. */</span><br><span>     port MGCPEM_PROC_PT MGCP_PROC;</span><br><span> }</span><br><span> </span><br><span>@@ -47,6 +50,11 @@</span><br><span>         inout MgcpCommand, MgcpResponse;</span><br><span> } with { extension "internal" };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* port between individual per-connection components and this dispatcher */</span><br><span style="color: hsl(120, 100%, 40%);">+type port MGCP_Conn_Multi_PT message {</span><br><span style="color: hsl(120, 100%, 40%);">+       inout MGCP_RecvFrom, MGCP_SendTo;</span><br><span style="color: hsl(120, 100%, 40%);">+} with { extension "internal" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* represents a single MGCP Endpoint */</span><br><span> type record EndpointData {</span><br><span>     MGCP_ConnHdlr   comp_ref,</span><br><span>@@ -63,6 +71,8 @@</span><br><span>         * MGCP_Emulation_CT.main needs to figure out what messages</span><br><span>   * to send where with CLIENT.send() to vc_conn */</span><br><span>    port MGCP_Conn_PT MGCP_CLIENT;</span><br><span style="color: hsl(120, 100%, 40%);">+        /* This one is used with multi_conn_mode=true and allows differentiating UDP sockets */</span><br><span style="color: hsl(120, 100%, 40%);">+       port MGCP_Conn_Multi_PT MGCP_CLIENT_MULTI;</span><br><span>   /* currently tracked connections */</span><br><span>  var EndpointData MgcpEndpointTable[16];</span><br><span>      var MgcpTransIds MgcpPendingTrans := {};</span><br><span>@@ -73,6 +83,8 @@</span><br><span> </span><br><span>     var charstring g_mgcp_id;</span><br><span>    var integer g_mgcp_conn_id := -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   var MGCP_conn_parameters g_pars;</span><br><span> }</span><br><span> </span><br><span> type function MGCPCreateCallback(MgcpCommand cmd, charstring id)</span><br><span>@@ -90,7 +102,8 @@</span><br><span>   HostName callagent_ip,</span><br><span>       PortNumber callagent_udp_port,</span><br><span>       HostName mgw_ip,</span><br><span style="color: hsl(0, 100%, 40%);">-        PortNumber mgw_udp_port</span><br><span style="color: hsl(120, 100%, 40%);">+       PortNumber mgw_udp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+      boolean multi_conn_mode</span><br><span> }</span><br><span> </span><br><span> function tr_MGCP_RecvFrom_R(template MgcpMessage msg)</span><br><span>@@ -224,14 +237,23 @@</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+private function f_forward_to_client(MGCP_RecvFrom mrf, MGCP_ConnHdlr vc_conn) runs on MGCP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (g_pars.multi_conn_mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+         MGCP_CLIENT_MULTI.send(mrf) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              MGCP_CLIENT.send(mrf.msg.command) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_Emulation_CT {</span><br><span>      var Result res;</span><br><span style="color: hsl(120, 100%, 40%);">+       g_pars := p;</span><br><span>         g_mgcp_id := id;</span><br><span>     f_ep_table_init();</span><br><span>   f_expect_table_init();</span><br><span> </span><br><span>   map(self:MGCP, system:MGCP_CODEC_PT);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (p.callagent_udp_port == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+     if (p.multi_conn_mode or p.callagent_udp_port == -1) {</span><br><span>               res := MGCP_CodecPort_CtrlFunct.f_IPL4_listen(MGCP, p.mgw_ip, p.mgw_udp_port, { udp:={} });</span><br><span>  } else {</span><br><span>             res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.callagent_ip, p.callagent_udp_port, p.mgw_ip, p.mgw_udp_port, -1, { udp:={} });</span><br><span>@@ -246,6 +268,7 @@</span><br><span>                 var MGCP_ConnHdlr vc_conn;</span><br><span>           var ExpectCriteria crit;</span><br><span>             var MGCP_RecvFrom mrf;</span><br><span style="color: hsl(120, 100%, 40%);">+                var MGCP_SendTo mst;</span><br><span>                 var MgcpMessage msg;</span><br><span>                 var MgcpCommand cmd;</span><br><span>                 var MgcpResponse resp;</span><br><span>@@ -253,7 +276,7 @@</span><br><span> </span><br><span>             alt {</span><br><span>                /* MGCP from client */</span><br><span style="color: hsl(0, 100%, 40%);">-          [] MGCP_CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn {</span><br><span style="color: hsl(120, 100%, 40%);">+              [not p.multi_conn_mode] MGCP_CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn {</span><br><span>                        msg := {</span><br><span>                             response := resp</span><br><span>                     };</span><br><span>@@ -265,9 +288,23 @@</span><br><span>                    /* TODO: check which ConnectionID client has allocated + store in table? */</span><br><span>                  MGCP.send(t_MGCP_Send(g_mgcp_conn_id, msg));</span><br><span>                         }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* MGCP from client in Multi Conn mode */</span><br><span style="color: hsl(120, 100%, 40%);">+             [p.multi_conn_mode] MGCP_CLIENT_MULTI.receive(MGCP_SendTo:?) -> value mst sender vc_conn {</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* If this is the resposne to a pending CRCX, extract Endpoint and store in table */</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (f_trans_id_was_pending(mst.msg.response.line.trans_id)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         f_ep_table_add(vc_conn, f_mgcp_ep(mst.msg));</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* Pass message through */</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* TODO: check which ConnectionID client has allocated + store in table? */</span><br><span style="color: hsl(120, 100%, 40%);">+                   MGCP.send(mst);</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span>            [] MGCP.receive(tr_MGCP_RecvFrom_R(?)) -> value mrf {</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (p.callagent_udp_port == -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               /* we aren't yet connected to the remote side port, let's fix this */</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (not p.multi_conn_mode and p.callagent_udp_port == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           /* we aren't yet connected to the remote side</span><br><span style="color: hsl(120, 100%, 40%);">+                                port, let's fix this. This way upper layers</span><br><span style="color: hsl(120, 100%, 40%);">+                               can use Send/Recv without caring about UDP</span><br><span style="color: hsl(120, 100%, 40%);">+                            src/dst addr + port */</span><br><span>                            p.callagent_udp_port := mrf.remPort;</span><br><span>                                 res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.callagent_ip, p.callagent_udp_port, p.mgw_ip, p.mgw_udp_port, g_mgcp_conn_id, { udp:={} });</span><br><span>                           if (not ispresent(res.connId)) {</span><br><span>@@ -279,7 +316,7 @@</span><br><span>                               cmd := mrf.msg.command;</span><br><span>                              if (f_ep_known(cmd.line.ep)) {</span><br><span>                                       vc_conn := f_comp_by_ep(cmd.line.ep);</span><br><span style="color: hsl(0, 100%, 40%);">-                                   MGCP_CLIENT.send(cmd) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                                     f_forward_to_client(mrf, vc_conn);</span><br><span>                           } else {</span><br><span>                                     if (cmd.line.verb == "CRCX") {</span><br><span>                                             vc_conn := ops.create_cb.apply(cmd, id);</span><br><span>@@ -290,12 +327,12 @@</span><br><span>                                                     /* add this transaction to list of pending transactions */</span><br><span>                                                   MgcpPendingTrans := MgcpPendingTrans & {cmd.line.trans_id};</span><br><span>                                              }</span><br><span style="color: hsl(0, 100%, 40%);">-                                               MGCP_CLIENT.send(cmd) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                                             f_forward_to_client(mrf, vc_conn);</span><br><span>                                   } else {</span><br><span>                                             /* connectionless MGCP, i.e. messages without ConnectionId */</span><br><span>                                                var template MgcpMessage r := ops.unitdata_cb.apply(mrf.msg);</span><br><span>                                                if (isvalue(r)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                                       MGCP.send(t_MGCP_Send(g_mgcp_conn_id, r));</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    MGCP.send(t_MGCP_SendToMrf(mrf, r));</span><br><span>                                                 }</span><br><span>                                    }</span><br><span>                            }</span><br><span>diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn</span><br><span>index b00e032..4b00e34 100644</span><br><span>--- a/msc/MSC_Tests.ttcn</span><br><span>+++ b/msc/MSC_Tests.ttcn</span><br><span>@@ -230,7 +230,8 @@</span><br><span>                 callagent_ip := mp_msc_ip,</span><br><span>           callagent_udp_port := -1,</span><br><span>            mgw_ip := mp_mgw_ip,</span><br><span style="color: hsl(0, 100%, 40%);">-            mgw_udp_port := mp_mgw_port</span><br><span style="color: hsl(120, 100%, 40%);">+           mgw_udp_port := mp_mgw_port,</span><br><span style="color: hsl(120, 100%, 40%);">+          multi_conn_mode := false</span><br><span>     }</span><br><span> </span><br><span>        vc_MGCP := MGCP_Emulation_CT.create(id);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/14512">change 14512</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/14512"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-ttcn3-hacks </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ic0ba8c5cde068c07671512a83095d83e28b86746 </div>
<div style="display:none"> Gerrit-Change-Number: 14512 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>