<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/14512">View Change</a></p><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;">git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/12/14512/1</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_Recv>From 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: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>