<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/11306">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add SGsAP_CodecPort + SGsAP_Emulation module<br><br>Change-Id: I530f8f444d1c7ea0bf11d510da7b97f64a2039f5<br>---<br>A library/SGsAP_CodecPort.ttcn<br>A library/SGsAP_CodecPort_CtrlFunct.ttcn<br>A library/SGsAP_CodecPort_CtrlFunctDef.cc<br>A library/SGsAP_Emulation.ttcn<br>M regen-makefile.sh<br>5 files changed, 591 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/library/SGsAP_CodecPort.ttcn b/library/SGsAP_CodecPort.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..2981fa2</span><br><span>--- /dev/null</span><br><span>+++ b/library/SGsAP_CodecPort.ttcn</span><br><span>@@ -0,0 +1,72 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module SGsAP_CodecPort {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Simple SGsAP Codec Port, translating between raw SCTP primitives with</span><br><span style="color: hsl(120, 100%, 40%);">+ * octetstring payload towards the IPL4asp provider, and SGsAP primitives</span><br><span style="color: hsl(120, 100%, 40%);">+ * which carry the decoded SGsAP data types as payload.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * All rights reserved.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Released under the terms of GNU General Public License, Version 2 or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</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%);">+       import from IPL4asp_PortType all;</span><br><span style="color: hsl(120, 100%, 40%);">+     import from IPL4asp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+        import from SGsAP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        type record SGsAP_RecvFrom {</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%);">+              HostName        locName,</span><br><span style="color: hsl(120, 100%, 40%);">+              PortNumber      locPort,</span><br><span style="color: hsl(120, 100%, 40%);">+              PDU_SGsAP       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 SGsAP_RecvFrom t_SGsAP_RecvFrom(template PDU_SGsAP msg) := {</span><br><span style="color: hsl(120, 100%, 40%);">+         connId := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+          remName := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+         remPort := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+         locName := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+         locPort := ?,</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%);">+   type record SGsAP_Send {</span><br><span style="color: hsl(120, 100%, 40%);">+              ConnectionId    connId,</span><br><span style="color: hsl(120, 100%, 40%);">+               PDU_SGsAP       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 SGsAP_Send t_SGsAP_Send(template ConnectionId connId, template PDU_SGsAP msg) := {</span><br><span style="color: hsl(120, 100%, 40%);">+           connId := connId,</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%);">+   private function IPL4_to_SGsAP_RecvFrom(in ASP_RecvFrom pin, out SGsAP_RecvFrom pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+               pout.connId := pin.connId;</span><br><span style="color: hsl(120, 100%, 40%);">+            pout.remName := pin.remName;</span><br><span style="color: hsl(120, 100%, 40%);">+          pout.remPort := pin.remPort;</span><br><span style="color: hsl(120, 100%, 40%);">+          pout.locName := pin.locName;</span><br><span style="color: hsl(120, 100%, 40%);">+          pout.locPort := pin.locPort;</span><br><span style="color: hsl(120, 100%, 40%);">+          pout.msg := dec_PDU_SGsAP(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 style="color: hsl(120, 100%, 40%);">+   private function SGsAP_to_IPL4_Send(in SGsAP_Send pin, out ASP_Send pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+           pout.connId := pin.connId;</span><br><span style="color: hsl(120, 100%, 40%);">+            pout.proto := { sctp := {} };</span><br><span style="color: hsl(120, 100%, 40%);">+         pout.msg := enc_PDU_SGsAP(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 style="color: hsl(120, 100%, 40%);">+   type port SGsAP_CODEC_PT message {</span><br><span style="color: hsl(120, 100%, 40%);">+            out     SGsAP_Send;</span><br><span style="color: hsl(120, 100%, 40%);">+           in      SGsAP_RecvFrom,</span><br><span style="color: hsl(120, 100%, 40%);">+                       ASP_ConnId_ReadyToRelease,</span><br><span style="color: hsl(120, 100%, 40%);">+                    ASP_Event;</span><br><span style="color: hsl(120, 100%, 40%);">+    } with { extension "user IPL4asp_PT</span><br><span style="color: hsl(120, 100%, 40%);">+              out(SGsAP_Send -> ASP_Send:function(SGsAP_to_IPL4_Send))</span><br><span style="color: hsl(120, 100%, 40%);">+           in(ASP_RecvFrom -> SGsAP_RecvFrom: function(IPL4_to_SGsAP_RecvFrom);</span><br><span style="color: hsl(120, 100%, 40%);">+                  ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple;</span><br><span style="color: hsl(120, 100%, 40%);">+            ASP_Event -> ASP_Event: simple)"</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/library/SGsAP_CodecPort_CtrlFunct.ttcn b/library/SGsAP_CodecPort_CtrlFunct.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..b09fc94</span><br><span>--- /dev/null</span><br><span>+++ b/library/SGsAP_CodecPort_CtrlFunct.ttcn</span><br><span>@@ -0,0 +1,44 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module SGsAP_CodecPort_CtrlFunct {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  import from SGsAP_CodecPort all;</span><br><span style="color: hsl(120, 100%, 40%);">+  import from IPL4asp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  external function f_IPL4_listen(</span><br><span style="color: hsl(120, 100%, 40%);">+    inout SGsAP_CODEC_PT portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    in HostName locName,</span><br><span style="color: hsl(120, 100%, 40%);">+    in PortNumber locPort,</span><br><span style="color: hsl(120, 100%, 40%);">+    in ProtoTuple proto,</span><br><span style="color: hsl(120, 100%, 40%);">+    in OptionList options := {}</span><br><span style="color: hsl(120, 100%, 40%);">+  ) return Result;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  external function f_IPL4_connect(</span><br><span style="color: hsl(120, 100%, 40%);">+    inout SGsAP_CODEC_PT portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    in HostName remName,</span><br><span style="color: hsl(120, 100%, 40%);">+    in PortNumber remPort,</span><br><span style="color: hsl(120, 100%, 40%);">+    in HostName locName,</span><br><span style="color: hsl(120, 100%, 40%);">+    in PortNumber locPort,</span><br><span style="color: hsl(120, 100%, 40%);">+    in ConnectionId connId,</span><br><span style="color: hsl(120, 100%, 40%);">+    in ProtoTuple proto,</span><br><span style="color: hsl(120, 100%, 40%);">+    in OptionList options := {}</span><br><span style="color: hsl(120, 100%, 40%);">+  ) return Result;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  external function f_IPL4_close(</span><br><span style="color: hsl(120, 100%, 40%);">+    inout SGsAP_CODEC_PT portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    in ConnectionId id,</span><br><span style="color: hsl(120, 100%, 40%);">+    in ProtoTuple proto := { unspecified := {} }</span><br><span style="color: hsl(120, 100%, 40%);">+  ) return Result;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  external function f_IPL4_setUserData(</span><br><span style="color: hsl(120, 100%, 40%);">+    inout SGsAP_CODEC_PT portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    in ConnectionId id,</span><br><span style="color: hsl(120, 100%, 40%);">+    in UserData userData</span><br><span style="color: hsl(120, 100%, 40%);">+  ) return Result;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  external function f_IPL4_getUserData(</span><br><span style="color: hsl(120, 100%, 40%);">+    inout SGsAP_CODEC_PT portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    in ConnectionId id,</span><br><span style="color: hsl(120, 100%, 40%);">+    out UserData userData</span><br><span style="color: hsl(120, 100%, 40%);">+  ) return Result;</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>diff --git a/library/SGsAP_CodecPort_CtrlFunctDef.cc b/library/SGsAP_CodecPort_CtrlFunctDef.cc</span><br><span>new file mode 100644</span><br><span>index 0000000..aa38e51</span><br><span>--- /dev/null</span><br><span>+++ b/library/SGsAP_CodecPort_CtrlFunctDef.cc</span><br><span>@@ -0,0 +1,56 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#include "IPL4asp_PortType.hh"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "SGsAP_CodecPort.hh"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "IPL4asp_PT.hh"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+namespace SGsAP__CodecPort__CtrlFunct {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  IPL4asp__Types::Result f__IPL4__listen(</span><br><span style="color: hsl(120, 100%, 40%);">+    SGsAP__CodecPort::SGsAP__CODEC__PT& portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::HostName& locName,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::PortNumber& locPort,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::ProtoTuple& proto,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::OptionList& options)</span><br><span style="color: hsl(120, 100%, 40%);">+  {</span><br><span style="color: hsl(120, 100%, 40%);">+    return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options);</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%);">+  IPL4asp__Types::Result f__IPL4__connect(</span><br><span style="color: hsl(120, 100%, 40%);">+    SGsAP__CodecPort::SGsAP__CODEC__PT& portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::HostName& remName,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::PortNumber& remPort,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::HostName& locName,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::PortNumber& locPort,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::ConnectionId& connId,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::ProtoTuple& proto,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::OptionList& options)</span><br><span style="color: hsl(120, 100%, 40%);">+  {</span><br><span style="color: hsl(120, 100%, 40%);">+    return f__IPL4__PROVIDER__connect(portRef, remName, remPort,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      locName, locPort, connId, proto, options);</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%);">+  IPL4asp__Types::Result f__IPL4__close(</span><br><span style="color: hsl(120, 100%, 40%);">+    SGsAP__CodecPort::SGsAP__CODEC__PT& portRef, </span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::ConnectionId& connId, </span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::ProtoTuple& proto)</span><br><span style="color: hsl(120, 100%, 40%);">+  {</span><br><span style="color: hsl(120, 100%, 40%);">+      return f__IPL4__PROVIDER__close(portRef, connId, proto);</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%);">+  IPL4asp__Types::Result f__IPL4__setUserData(</span><br><span style="color: hsl(120, 100%, 40%);">+    SGsAP__CodecPort::SGsAP__CODEC__PT& portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::ConnectionId& connId,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::UserData& userData)</span><br><span style="color: hsl(120, 100%, 40%);">+  {</span><br><span style="color: hsl(120, 100%, 40%);">+    return f__IPL4__PROVIDER__setUserData(portRef, connId, userData);</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%);">+  IPL4asp__Types::Result f__IPL4__getUserData(</span><br><span style="color: hsl(120, 100%, 40%);">+    SGsAP__CodecPort::SGsAP__CODEC__PT& portRef,</span><br><span style="color: hsl(120, 100%, 40%);">+    const IPL4asp__Types::ConnectionId& connId,</span><br><span style="color: hsl(120, 100%, 40%);">+    IPL4asp__Types::UserData& userData)</span><br><span style="color: hsl(120, 100%, 40%);">+  {</span><br><span style="color: hsl(120, 100%, 40%);">+    return f__IPL4__PROVIDER__getUserData(portRef, connId, userData);</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 style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/library/SGsAP_Emulation.ttcn b/library/SGsAP_Emulation.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..0c37840</span><br><span>--- /dev/null</span><br><span>+++ b/library/SGsAP_Emulation.ttcn</span><br><span>@@ -0,0 +1,418 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module SGsAP_Emulation {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* SGsAP Emulation, runs on top of SGsAP_CodecPort.  It multiplexes/demultiplexes</span><br><span style="color: hsl(120, 100%, 40%);">+ * the individual IMSIs/subscribers, so there can be separate TTCN-3 components handling</span><br><span style="color: hsl(120, 100%, 40%);">+ * each of them.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The SGsAP_Emulation.main() function processes SGsAP primitives from the SGsAP</span><br><span style="color: hsl(120, 100%, 40%);">+ * socket via the SGsAP_CodecPort, and dispatches them to the per-IMSI components.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * For each new IMSI, the SgsapOps.create_cb() is called.  It can create</span><br><span style="color: hsl(120, 100%, 40%);">+ * or resolve a TTCN-3 component, and returns a component reference to which that IMSI</span><br><span style="color: hsl(120, 100%, 40%);">+ * is routed/dispatched.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * If a pre-existing component wants to register to handle a future inbound IMSI, it can</span><br><span style="color: hsl(120, 100%, 40%);">+ * do so by registering an "expect" with the expected IMSI.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Inbound SGsAP messages without IMSI (such as RESET-IND/ACK) are dispatched to</span><br><span style="color: hsl(120, 100%, 40%);">+ * the SgsapOps.unitdata_cb() callback, which is registered with an argument to the</span><br><span style="color: hsl(120, 100%, 40%);">+ * main() function below.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * All rights reserved.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Released under the terms of GNU General Public License, Version 2 or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</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%);">+import from SGsAP_CodecPort all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SGsAP_CodecPort_CtrlFunct all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SGsAP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SGsAP_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPL4asp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type component SGsAP_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+    port SGsAP_Conn_PT SGsAP;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* procedure based port to register for incoming connections */</span><br><span style="color: hsl(120, 100%, 40%);">+       port SGsAPEM_PROC_PT SGsAP_PROC;</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%);">+/* port between individual per-connection components and this dispatcher */</span><br><span style="color: hsl(120, 100%, 40%);">+type port SGsAP_Conn_PT message {</span><br><span style="color: hsl(120, 100%, 40%);">+ inout PDU_SGsAP;</span><br><span style="color: hsl(120, 100%, 40%);">+} with { extension "internal" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* represents a single SGsAP Association */</span><br><span style="color: hsl(120, 100%, 40%);">+type record AssociationData {</span><br><span style="color: hsl(120, 100%, 40%);">+    SGsAP_ConnHdlr  comp_ref,</span><br><span style="color: hsl(120, 100%, 40%);">+     hexstring       imsi optional</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%);">+type component SGsAP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Port facing to the UDP SUT */</span><br><span style="color: hsl(120, 100%, 40%);">+      port SGsAP_CODEC_PT SGsAP;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* All SGsAP_ConnHdlr SGsAP ports connect here</span><br><span style="color: hsl(120, 100%, 40%);">+         * SGsAP_Emulation_CT.main needs to figure out what messages</span><br><span style="color: hsl(120, 100%, 40%);">+   * to send where with CLIENT.send() to vc_conn */</span><br><span style="color: hsl(120, 100%, 40%);">+     port SGsAP_Conn_PT SGsAP_CLIENT;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* currently tracked connections */</span><br><span style="color: hsl(120, 100%, 40%);">+   var AssociationData SgsapAssociationTable[16];</span><br><span style="color: hsl(120, 100%, 40%);">+        /* pending expected CRCX */</span><br><span style="color: hsl(120, 100%, 40%);">+   var ExpectData SgsapExpectTable[8];</span><br><span style="color: hsl(120, 100%, 40%);">+   /* procedure based port to register for incoming connections */</span><br><span style="color: hsl(120, 100%, 40%);">+       port SGsAPEM_PROC_PT SGsAP_PROC;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    var charstring g_sgsap_id;</span><br><span style="color: hsl(120, 100%, 40%);">+    var integer g_sgsap_conn_id := -1;</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%);">+type function SGsAPCreateCallback(PDU_SGsAP msg, hexstring imsi, charstring id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type function SGsAPUnitdataCallback(PDU_SGsAP msg)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return template PDU_SGsAP;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type record SGsAPOps {</span><br><span style="color: hsl(120, 100%, 40%);">+    SGsAPCreateCallback create_cb,</span><br><span style="color: hsl(120, 100%, 40%);">+        SGsAPUnitdataCallback unitdata_cb</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%);">+type record SGsAP_conn_parameters {</span><br><span style="color: hsl(120, 100%, 40%);">+   HostName remote_ip,</span><br><span style="color: hsl(120, 100%, 40%);">+   PortNumber remote_sctp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+  HostName local_ip,</span><br><span style="color: hsl(120, 100%, 40%);">+    PortNumber local_sctp_port</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%);">+function tr_SGsAP_RecvFrom_R(template PDU_SGsAP msg)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return template SGsAP_RecvFrom {</span><br><span style="color: hsl(120, 100%, 40%);">+    var template SGsAP_RecvFrom mrf := {</span><br><span style="color: hsl(120, 100%, 40%);">+          connId := g_sgsap_conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+            remName := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+         remPort := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+         locName := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+         locPort := ?,</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%);">+     return mrf;</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%);">+private function f_imsi_known(hexstring imsi)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return boolean {</span><br><span style="color: hsl(120, 100%, 40%);">+  var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (SgsapAssociationTable[i].imsi == imsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  return true;</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%);">+     return false;</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%);">+private function f_comp_known(SGsAP_ConnHdlr client)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return boolean {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (SgsapAssociationTable[i].comp_ref == client) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    return true;</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%);">+     return false;</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%);">+private function f_comp_by_imsi(hexstring imsi)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+       var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (SgsapAssociationTable[i].imsi == imsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  return SgsapAssociationTable[i].comp_ref;</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%);">+     setverdict(fail, "SGsAP Association Table not found by IMSI", imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+        mtc.stop;</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%);">+private function f_imsi_by_comp(SGsAP_ConnHdlr client)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return hexstring {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (SgsapAssociationTable[i].comp_ref == client) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    return SgsapAssociationTable[i].imsi;</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%);">+     setverdict(fail, "SGsAP Association Table not found by component ", client);</span><br><span style="color: hsl(120, 100%, 40%);">+        mtc.stop;</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%);">+private function f_imsi_table_add(SGsAP_ConnHdlr comp_ref, hexstring imsi)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+      var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (not isvalue(SgsapAssociationTable[i].imsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     SgsapAssociationTable[i].imsi := imsi;</span><br><span style="color: hsl(120, 100%, 40%);">+                        SgsapAssociationTable[i].comp_ref := comp_ref;</span><br><span style="color: hsl(120, 100%, 40%);">+                        return;</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%);">+     testcase.stop("SGsAP Association Table full!");</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%);">+private function f_imsi_table_del(SGsAP_ConnHdlr comp_ref, hexstring imsi)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+      var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (SgsapAssociationTable[i].comp_ref == comp_ref and</span><br><span style="color: hsl(120, 100%, 40%);">+             SgsapAssociationTable[i].imsi == imsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  SgsapAssociationTable[i].imsi := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+                        SgsapAssociationTable[i].comp_ref := null;</span><br><span style="color: hsl(120, 100%, 40%);">+                    return;</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%);">+     setverdict(fail, "SGsAP Association Table: Couldn't find to-be-deleted entry!");</span><br><span style="color: hsl(120, 100%, 40%);">+        mtc.stop;</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 style="color: hsl(120, 100%, 40%);">+private function f_imsi_table_init()</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+  for (var integer i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            SgsapAssociationTable[i].comp_ref := null;</span><br><span style="color: hsl(120, 100%, 40%);">+            SgsapAssociationTable[i].imsi := omit;</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 style="color: hsl(120, 100%, 40%);">+private function f_SGsAP_get_imsi(PDU_SGsAP pdu) return template (omit) IMSI</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ischosen(pdu.sGsAP_ALERT_ACK)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          return pdu.sGsAP_ALERT_ACK.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (ischosen(pdu.sGsAP_ALERT_REJECT)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return pdu.sGsAP_ALERT_REJECT.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+   } else if (ischosen(pdu.sGsAP_ALERT_REQUEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return pdu.sGsAP_ALERT_REQUEST.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else if (ischosen(pdu.sGsAP_DOWNLINK_UNITDATA)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return pdu.sGsAP_DOWNLINK_UNITDATA.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (ischosen(pdu.sGsAP_EPS_DETACH_ACK)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_EPS_DETACH_ACK.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_EPS_DETACH_INDICATION)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return pdu.sGsAP_EPS_DETACH_INDICATION.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else if (ischosen(pdu.sGsAP_IMSI_DETACH_ACK)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return pdu.sGsAP_IMSI_DETACH_ACK.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (ischosen(pdu.sGsAP_IMSI_DETACH_INDICATION)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_IMSI_DETACH_INDICATION.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_ACCEPT)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_LOCATION_UPDATE_ACCEPT.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_REJECT)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_LOCATION_UPDATE_REJECT.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_REQUEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return pdu.sGsAP_LOCATION_UPDATE_REQUEST.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (ischosen(pdu.sGsAP_MM_INFORMATION_REQUEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_MM_INFORMATION_REQUEST.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_PAGING_REJECT)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return pdu.sGsAP_PAGING_REJECT.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else if (ischosen(pdu.sGsAP_PAGING_REQUEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_PAGING_REQUEST.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_SERVICE_REQUEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return pdu.sGsAP_SERVICE_REQUEST.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (ischosen(pdu.sGsAP_STATUS)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_STATUS.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_TMSI_REALLOCATION_COMPLETE)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          return pdu.sGsAP_TMSI_REALLOCATION_COMPLETE.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else if (ischosen(pdu.sGsAP_UE_ACTIVITY_INDICATION)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_UE_ACTIVITY_INDICATION.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_UE_UNREACHABLE)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return pdu.sGsAP_UE_UNREACHABLE.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(pdu.sGsAP_UPLINK_UNITDATA)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return pdu.sGsAP_UPLINK_UNITDATA.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (ischosen(pdu.sGsAP_RELEASE_REQUEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return pdu.sGsAP_RELEASE_REQUEST.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (ischosen(pdu.sGsAP_SERVICE_ABORT_REQUEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return pdu.sGsAP_SERVICE_ABORT_REQUEST.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else if (ischosen(pdu.sGsAP_MO_CSFB_INDICATION)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          return pdu.sGsAP_MO_CSFB_INDICATION.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return omit;</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%);">+private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := omit) := {</span><br><span style="color: hsl(120, 100%, 40%);">+      sinfo_stream := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ sinfo_ppid := ppid,</span><br><span style="color: hsl(120, 100%, 40%);">+   remSocks := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+     assocId := omit</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%);">+private template PortEvent tr_SctpAssocChange := {</span><br><span style="color: hsl(120, 100%, 40%);">+     sctpEvent := {</span><br><span style="color: hsl(120, 100%, 40%);">+                sctpAssocChange := ?</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%);">+private template PortEvent tr_SctpPeerAddrChange := {</span><br><span style="color: hsl(120, 100%, 40%);">+   sctpEvent := {</span><br><span style="color: hsl(120, 100%, 40%);">+                sctpPeerAddrChange := ?</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 style="color: hsl(120, 100%, 40%);">+private function f_sgsap_xceive(template (value) PDU_SGsAP tx,</span><br><span style="color: hsl(120, 100%, 40%);">+                                template PDU_SGsAP rx_t := ?)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT  return PDU_SGsAP {</span><br><span style="color: hsl(120, 100%, 40%);">+ timer T := 10.0;</span><br><span style="color: hsl(120, 100%, 40%);">+      var SGsAP_RecvFrom mrf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, tx));</span><br><span style="color: hsl(120, 100%, 40%);">+        alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] SGsAP.receive(tr_SGsAP_RecvFrom_R(rx_t)) -> value mrf { }</span><br><span style="color: hsl(120, 100%, 40%);">+       [] SGsAP.receive(tr_SctpAssocChange) { repeat; }</span><br><span style="color: hsl(120, 100%, 40%);">+      [] SGsAP.receive(tr_SctpPeerAddrChange)  { repeat; }</span><br><span style="color: hsl(120, 100%, 40%);">+  [] T.timeout {</span><br><span style="color: hsl(120, 100%, 40%);">+                setverdict(fail, "Timeout waiting for ", rx_t);</span><br><span style="color: hsl(120, 100%, 40%);">+             mtc.stop;</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%);">+     return mrf.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%);">+function main(SGsAPOps ops, SGsAP_conn_parameters p, charstring id) runs on SGsAP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        var Result res;</span><br><span style="color: hsl(120, 100%, 40%);">+       g_sgsap_id := id;</span><br><span style="color: hsl(120, 100%, 40%);">+     f_imsi_table_init();</span><br><span style="color: hsl(120, 100%, 40%);">+  f_expect_table_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      map(self:SGsAP, system:SGsAP_CODEC_PT);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (p.remote_sctp_port == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+               res := SGsAP_CodecPort_CtrlFunct.f_IPL4_listen(SGsAP, p.local_ip, p.local_sctp_port, { sctp := valueof(ts_SCTP) });</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              res := SGsAP_CodecPort_CtrlFunct.f_IPL4_connect(SGsAP, p.remote_ip, p.remote_sctp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               p.local_ip, p.local_sctp_port, -1, { sctp := valueof(ts_SCTP) });</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (not ispresent(res.connId)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              setverdict(fail, "Could not connect SGsAP socket, check your configuration");</span><br><span style="color: hsl(120, 100%, 40%);">+               mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     g_sgsap_conn_id := res.connId;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      while (true) {</span><br><span style="color: hsl(120, 100%, 40%);">+                var SGsAP_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+           var template IMSI imsi_t;</span><br><span style="color: hsl(120, 100%, 40%);">+             var hexstring imsi;</span><br><span style="color: hsl(120, 100%, 40%);">+           var SGsAP_RecvFrom mrf;</span><br><span style="color: hsl(120, 100%, 40%);">+               var PDU_SGsAP msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          alt {</span><br><span style="color: hsl(120, 100%, 40%);">+         /* SGsAP from client */</span><br><span style="color: hsl(120, 100%, 40%);">+               [] SGsAP_CLIENT.receive(PDU_SGsAP:?) -> value msg sender vc_conn {</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%);">+                   SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, msg));</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+             [] SGsAP.receive(tr_SGsAP_RecvFrom_R(?)) -> value mrf {</span><br><span style="color: hsl(120, 100%, 40%);">+                    imsi_t := f_SGsAP_get_imsi(mrf.msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (isvalue(imsi_t)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                imsi := valueof(imsi_t.iMSI.digits);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (f_imsi_known(imsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     vc_conn := f_comp_by_imsi(imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+                                      SGsAP_CLIENT.send(mrf.msg) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                                } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      vc_conn := ops.create_cb.apply(mrf.msg, imsi, id);</span><br><span style="color: hsl(120, 100%, 40%);">+                                    f_imsi_table_add(vc_conn, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+                                      SGsAP_CLIENT.send(mrf.msg) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                                }</span><br><span style="color: hsl(120, 100%, 40%);">+                     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              /* message contained no IMSI; is not IMSI-oriented */</span><br><span style="color: hsl(120, 100%, 40%);">+                         var template PDU_SGsAP resp := ops.unitdata_cb.apply(mrf.msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                                if (isvalue(resp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                  SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, valueof(resp)));</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 style="color: hsl(120, 100%, 40%);">+             [] SGsAP.receive(tr_SctpAssocChange) { }</span><br><span style="color: hsl(120, 100%, 40%);">+              [] SGsAP.receive(tr_SctpPeerAddrChange)  { }</span><br><span style="color: hsl(120, 100%, 40%);">+          [] SGsAP_PROC.getcall(SGsAPEM_register:{?,?}) -> param(imsi, vc_conn) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    f_create_expect(imsi, vc_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+                       SGsAP_PROC.reply(SGsAPEM_register:{imsi, vc_conn}) 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 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 style="color: hsl(120, 100%, 40%);">+/* "Expect" Handling */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type record ExpectData {</span><br><span style="color: hsl(120, 100%, 40%);">+ hexstring imsi optional,</span><br><span style="color: hsl(120, 100%, 40%);">+      SGsAP_ConnHdlr 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%);">+signature SGsAPEM_register(in hexstring imsi, in SGsAP_ConnHdlr hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type port SGsAPEM_PROC_PT procedure {</span><br><span style="color: hsl(120, 100%, 40%);">+  inout SGsAPEM_register;</span><br><span style="color: hsl(120, 100%, 40%);">+} with { extension "internal" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Function that can be used as create_cb and will usse the expect table */</span><br><span style="color: hsl(120, 100%, 40%);">+function ExpectedCreateCallback(PDU_SGsAP msg, hexstring imsi, charstring id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ var SGsAP_ConnHdlr ret := null;</span><br><span style="color: hsl(120, 100%, 40%);">+       var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (not ispresent(SgsapExpectTable[i].imsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (imsi == SgsapExpectTable[i].imsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       ret := SgsapExpectTable[i].vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* Release this entry */</span><br><span style="color: hsl(120, 100%, 40%);">+                      SgsapExpectTable[i].imsi := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+                     SgsapExpectTable[i].vc_conn := null;</span><br><span style="color: hsl(120, 100%, 40%);">+                  log("Found Expect[", i, "] for ", msg, " handled at ", ret);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return ret;</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%);">+     setverdict(fail, "Couldn't find Expect for ", msg);</span><br><span style="color: hsl(120, 100%, 40%);">+     mtc.stop;</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%);">+private function f_create_expect(hexstring imsi, SGsAP_ConnHdlr hdlr)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+   var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Check an entry like this is not already presnt */</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (imsi == SgsapExpectTable[i].imsi) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       setverdict(fail, "IMSI already present", imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+                     mtc.stop;</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%);">+     for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (not ispresent(SgsapExpectTable[i].imsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        SgsapExpectTable[i].imsi := imsi;</span><br><span style="color: hsl(120, 100%, 40%);">+                     SgsapExpectTable[i].vc_conn := hdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+                  log("Created Expect[", i, "] for ", imsi, " to be handled at ", hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return;</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%);">+     testcase.stop("No space left in SgsapExpectTable")</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%);">+/* client/conn_hdlr side function to use procedure port to create expect in emulation */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_create_sgsap_expect(hexstring imsi) runs on SGsAP_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+  SGsAP_PROC.call(SGsAPEM_register:{imsi, self}) {</span><br><span style="color: hsl(120, 100%, 40%);">+              [] SGsAP_PROC.getreply(SGsAPEM_register:{?,?}) {};</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 style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_expect_table_init()</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i := 0; i < sizeof(SgsapExpectTable); i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           SgsapExpectTable[i].imsi := omit;</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 style="color: hsl(120, 100%, 40%);">+function DummyUnitdataCallback(PDU_SGsAP msg)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on SGsAP_Emulation_CT return template PDU_SGsAP {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Ignoring SGsAP ", msg);</span><br><span style="color: hsl(120, 100%, 40%);">+        return omit;</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 style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/regen-makefile.sh b/regen-makefile.sh</span><br><span>index 6b32f75..b8be4ea 100755</span><br><span>--- a/regen-makefile.sh</span><br><span>+++ b/regen-makefile.sh</span><br><span>@@ -29,7 +29,7 @@</span><br><span> </span><br><span> # The -DMAKEDEPEND_RUN is a workaround for Debian packaging issue,</span><br><span> # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=879816 for details</span><br><span style="color: hsl(0, 100%, 40%);">-sed -i -e 's/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include/CPPFLAGS = -D$(PLATFORM) -DMAKEDEPEND_RUN -I$(TTCN3_DIR)\/include -I\/usr\/include\/titan/' Makefile</span><br><span style="color: hsl(120, 100%, 40%);">+sed -i -e 's/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include/CPPFLAGS = -D$(PLATFORM) -DMAKEDEPEND_RUN -DUSE_SCTP -I$(TTCN3_DIR)\/include -I\/usr\/include\/titan/' Makefile</span><br><span> </span><br><span> if [ "x$CPPFLAGS_TTCN3" != "x" ]; then</span><br><span>       sed -i -e 's/CPPFLAGS_TTCN3 =/CPPFLAGS_TTCN3 = '"$CPPFLAGS_TTCN3"'/' Makefile</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11306">change 11306</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/11306"/><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-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I530f8f444d1c7ea0bf11d510da7b97f64a2039f5 </div>
<div style="display:none"> Gerrit-Change-Number: 11306 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>