<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13653">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">RAN_Emulation: Add RANAP support<br><br>So far, RAN_Emulation only handled BSSAP and hence could be used<br>to emulate BSCs towards the MSC.  Let's extend it with RANAP support<br>so we can also emulate RNCs towards the MSC.<br><br>We try to share as much code and logic as possible betweeb the two.<br><br>Related: OS#2856, OS#2857<br>Change-Id: Ie79bda764162e5c5a42608bde5c5f486ea531f33<br>---<br>M library/RAN_Adapter.ttcnpp<br>M library/RAN_Emulation.ttcnpp<br>M library/ranap/RANAP_Templates.ttcn<br>3 files changed, 418 insertions(+), 10 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/53/13653/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/library/RAN_Adapter.ttcnpp b/library/RAN_Adapter.ttcnpp</span><br><span>index 43b4988..a97d148 100644</span><br><span>--- a/library/RAN_Adapter.ttcnpp</span><br><span>+++ b/library/RAN_Adapter.ttcnpp</span><br><span>@@ -43,7 +43,8 @@</span><br><span> type enumerated RAN_Transport {</span><br><span>  BSSAP_TRANSPORT_AoIP,   /* 3GPP AoIP: SCCP over M3UA over SCTP */</span><br><span>    BSSAP_TRANSPORT_SCCPlite_SERVER, /* SCCPlite: SCCP over IPA over TCP */</span><br><span style="color: hsl(0, 100%, 40%);">- BSSAP_TRANSPORT_SCCPlite_CLIENT  /* SCCPlite: SCCP over IPA over TCP */</span><br><span style="color: hsl(120, 100%, 40%);">+       BSSAP_TRANSPORT_SCCPlite_CLIENT, /* SCCPlite: SCCP over IPA over TCP */</span><br><span style="color: hsl(120, 100%, 40%);">+       RANAP_TRANSPORT_IuCS    /* 3GPP IuCS: SCCP over M3UA over SCTP */</span><br><span> };</span><br><span> </span><br><span> type record RAN_Configuration {</span><br><span>@@ -88,8 +89,7 @@</span><br><span>           ba.vc_RAN := RAN_Emulation_CT.create(id & "-RAN");</span><br><span>     }</span><br><span>    select (cfg.transport) {</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef RAN_EMULATION_BSSAP</span><br><span style="color: hsl(0, 100%, 40%);">-      case (BSSAP_TRANSPORT_AoIP) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case (BSSAP_TRANSPORT_AoIP, RANAP_TRANSPORT_IuCS) {</span><br><span>          ba.vc_M3UA := M3UA_CT.create(id & "-M3UA");</span><br><span>            map(ba.vc_M3UA:SCTP_PORT, system:sctp);</span><br><span>              /* connect MTP3 service provider (M3UA) to lower side of SCCP */</span><br><span>@@ -129,7 +129,6 @@</span><br><span>               ba.vc_WAIT.done;</span><br><span>             disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);</span><br><span>           }</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span>      case else {</span><br><span>          setverdict(fail, "Unsuppored RAN_Transport");</span><br><span>              mtc.stop;</span><br><span>@@ -141,16 +140,22 @@</span><br><span>            T.start;</span><br><span>             //T.timeout;</span><br><span>                 log("Connecting BSSMAP Emulation to SCCP_SP_PORT and starting emulation");</span><br><span style="color: hsl(0, 100%, 40%);">-#if RAN_EMULATION_BSSAP</span><br><span>          /* connect BSSNAP component to upper side of SCCP */</span><br><span style="color: hsl(0, 100%, 40%);">-            connect(ba.vc_RAN:BSSAP, ba.vc_SCCP:SCCP_SP_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (cfg.transport == RANAP_TRANSPORT_IuCS) {</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+                      ops.protocol := RAN_PROTOCOL_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+                    connect(ba.vc_RAN:RANAP, ba.vc_SCCP:SCCP_SP_PORT);</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+          } else {</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_BSSAP</span><br><span style="color: hsl(120, 100%, 40%);">+                  connect(ba.vc_RAN:BSSAP, ba.vc_SCCP:SCCP_SP_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span>            if (cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER or</span><br><span>                  cfg.transport == BSSAP_TRANSPORT_SCCPlite_CLIENT) {</span><br><span>                      /* connect IPA MGCP port with BSSMAP MGCP port */</span><br><span>                    connect(ba.vc_IPA:IPA_MGCP_PORT, ba.vc_RAN:MGCP);</span><br><span>            }</span><br><span style="color: hsl(0, 100%, 40%);">-               /* start the BSSMAP emulation */</span><br><span>             ba.vc_RAN.start(RAN_Emulation.main(valueof(ops), ""));</span><br><span>     }</span><br><span> </span><br><span>diff --git a/library/RAN_Emulation.ttcnpp b/library/RAN_Emulation.ttcnpp</span><br><span>index 21dbea9..b826982 100644</span><br><span>--- a/library/RAN_Emulation.ttcnpp</span><br><span>+++ b/library/RAN_Emulation.ttcnpp</span><br><span>@@ -48,6 +48,14 @@</span><br><span> import from MGCP_Templates all;</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+import from RANAP_CodecPort all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RANAP_PDU_Descriptions all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RANAP_Constants all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RANAP_IEs all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RANAP_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* General "base class" component definition, of which specific implementations</span><br><span>  * derive themselves by means of the "extends" feature */</span><br><span> type component RAN_ConnHdlr {</span><br><span>@@ -110,6 +118,11 @@</span><br><span>                /* Client requests us to create SCCP Connection */</span><br><span>           BSSAP_Conn_Req,</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+         RANAP_PDU,</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Client requests us to create SCCP Connection */</span><br><span style="color: hsl(120, 100%, 40%);">+            RANAP_Conn_Req,</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> #ifdef RAN_EMULATION_MGCP</span><br><span>                 /* MGCP, only used for IPA SCCPlite (MGCP in IPA mux) */</span><br><span>             MgcpCommand, MgcpResponse,</span><br><span>@@ -147,6 +160,9 @@</span><br><span> #ifdef RAN_EMULATION_BSSAP</span><br><span>       port BSSAP_CODEC_PT BSSAP;</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+      port RANAP_CODEC_PT RANAP;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>   /* BSSAP port to the per-connection clients */</span><br><span>       port RAN_Conn_PT CLIENT;</span><br><span> #ifdef RAN_EMULATION_MGCP</span><br><span>@@ -487,10 +503,137 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+type record RANAP_Conn_Req {</span><br><span style="color: hsl(120, 100%, 40%);">+   SCCP_PAR_Address        addr_peer,</span><br><span style="color: hsl(120, 100%, 40%);">+    SCCP_PAR_Address        addr_own,</span><br><span style="color: hsl(120, 100%, 40%);">+     RANAP_PDU               ranap</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+template (value) RANAP_Conn_Req ts_RANAP_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, RANAP_PDU ranap) := {</span><br><span style="color: hsl(120, 100%, 40%);">+        addr_peer := peer,</span><br><span style="color: hsl(120, 100%, 40%);">+    addr_own := own,</span><br><span style="color: hsl(120, 100%, 40%);">+      ranap := ranap</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 fake_dlci_from_sapi(template (omit) SAPI sapi) return template (omit) OCT1</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (istemplatekind(sapi, "omit")) {</span><br><span style="color: hsl(120, 100%, 40%);">+         return omit;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else if (valueof(sapi) == sapi_3) {</span><br><span style="color: hsl(120, 100%, 40%);">+         return '03'O;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     return '00'O;</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_handle_userData_RANAP(RAN_ConnHdlr client, RANAP_PDU ranap)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on RAN_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* decode + send decoded RANAP to client */</span><br><span style="color: hsl(120, 100%, 40%);">+   var template (omit) octetstring l3 := f_ranap_extract_l3(ranap);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (istemplatekind(ranap, "omit")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                CLIENT.send(ranap) to client;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              var template (omit) SAPI sapi := f_ranap_extract_sapi(ranap);</span><br><span style="color: hsl(120, 100%, 40%);">+         var template (omit) OCT1 dlci := fake_dlci_from_sapi(sapi);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (g_ran_ops.role_ms) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* we are the MS, so any message to us must be MT */</span><br><span style="color: hsl(120, 100%, 40%);">+                  var PDU_DTAP_MT mt := {</span><br><span style="color: hsl(120, 100%, 40%);">+                               dlci := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+                         dtap := dec_PDU_ML3_NW_MS(valueof(l3))</span><br><span style="color: hsl(120, 100%, 40%);">+                        };</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (isvalue(dlci)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          mt.dlci := valueof(dlci)</span><br><span style="color: hsl(120, 100%, 40%);">+                      }</span><br><span style="color: hsl(120, 100%, 40%);">+                     CLIENT.send(mt) to client;</span><br><span style="color: hsl(120, 100%, 40%);">+            } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* we are the Network, so any message to us must be MO */</span><br><span style="color: hsl(120, 100%, 40%);">+                     var PDU_DTAP_MO mo := {</span><br><span style="color: hsl(120, 100%, 40%);">+                               dlci := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+                         dtap := dec_PDU_ML3_MS_NW(valueof(l3))</span><br><span style="color: hsl(120, 100%, 40%);">+                        };</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (isvalue(dlci)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          mo.dlci := valueof(dlci)</span><br><span style="color: hsl(120, 100%, 40%);">+                      }</span><br><span style="color: hsl(120, 100%, 40%);">+                     CLIENT.send(mo) to client;</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%);">+/* call-back type, to be provided by specific implementation; called when new SCCP connection</span><br><span style="color: hsl(120, 100%, 40%);">+ * arrives */</span><br><span style="color: hsl(120, 100%, 40%);">+type function RanapCreateCallback(RANAP_N_CONNECT_ind conn_ind, charstring id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on RAN_Emulation_CT return RAN_ConnHdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type function RanapUnitdataCallback(RANAP_PDU ranap)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on RAN_Emulation_CT return template RANAP_PDU;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function CommonRanapUnitdataCallback(RANAP_PDU ranap)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on RAN_Emulation_CT return template RANAP_PDU {</span><br><span style="color: hsl(120, 100%, 40%);">+       if (match(ranap, tr_RANAP_Paging(?, ?))) {</span><br><span style="color: hsl(120, 100%, 40%);">+            var RAN_ConnHdlr client := null;</span><br><span style="color: hsl(120, 100%, 40%);">+              /* extract IMSI and (if present) TMSI */</span><br><span style="color: hsl(120, 100%, 40%);">+              var IMSI imsi := ranap.initiatingMessage.value_.paging.protocolIEs[1].value_.permanentNAS_UE_ID.iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+         var template OCT4 tmsi := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+               if (lengthof(ranap.initiatingMessage.value_.paging.protocolIEs) > 2 and</span><br><span style="color: hsl(120, 100%, 40%);">+                ranap.initiatingMessage.value_.paging.protocolIEs[2].id == id_TemporaryUE_ID) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   var TemporaryUE_ID ue_id;</span><br><span style="color: hsl(120, 100%, 40%);">+                     ue_id := ranap.initiatingMessage.value_.paging.protocolIEs[2].value_.temporaryUE_ID;</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (ischosen(ue_id.tMSI)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           tmsi := ue_id.tMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+                   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              tmsi := ue_id.p_TMSI;</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 := f_imsi_table_find(oct2hex(imsi), tmsi);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (isvalue(client)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        log("CommonRanapUnitdataCallback: IMSI/TMSI found in table, dispatching to ",</span><br><span style="color: hsl(120, 100%, 40%);">+                               client);</span><br><span style="color: hsl(120, 100%, 40%);">+                      CLIENT.send(ranap) to client;</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%);">+             log("CommonRanapUnitdataCallback: IMSI/TMSI not found in table");</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              log("CommonRanapUnitdataCallback: Not a paging message");</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%);">+   /* ELSE: handle in user callback */</span><br><span style="color: hsl(120, 100%, 40%);">+   return g_ran_ops.ranap_unitdata_cb.apply(ranap);</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_ranap_l3_is_rr(RANAP_PDU ranap) return boolean {</span><br><span style="color: hsl(120, 100%, 40%);">+    var template (omit) SAPI sapi;</span><br><span style="color: hsl(120, 100%, 40%);">+        var template octetstring l3 := f_ranap_extract_l3(ranap);</span><br><span style="color: hsl(120, 100%, 40%);">+     return f_L3_is_rr(l3);</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 f_ranap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on RAN_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+   timer T := 5.0;</span><br><span style="color: hsl(120, 100%, 40%);">+       var CN_DomainIndicator dom;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (g_ran_ops.ps_domain) {</span><br><span style="color: hsl(120, 100%, 40%);">+            dom := ps_domain;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              dom := cs_domain;</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%);">+   RANAP.send(ts_RANAP_UNITDATA_req(peer, own, ts_RANAP_Reset(ts_RanapCause_om_intervention, dom)));</span><br><span style="color: hsl(120, 100%, 40%);">+     T.start;</span><br><span style="color: hsl(120, 100%, 40%);">+      alt {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] RANAP.receive(tr_RANAP_UNITDATA_ind(own, peer, tr_RANAP_ResetAck)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               log("Received RESET-ACK in response to RESET, we're ready to go!");</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     [] as_reset_ack();</span><br><span style="color: hsl(120, 100%, 40%);">+    [] RANAP.receive { 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 RESET-ACK after sending RESET");</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%);">+#endif</span><br><span> </span><br><span> </span><br><span> type enumerated RanProtocol {</span><br><span style="color: hsl(0, 100%, 40%);">-   RAN_PROTOCOL_BSSAP</span><br><span style="color: hsl(120, 100%, 40%);">+    RAN_PROTOCOL_BSSAP,</span><br><span style="color: hsl(120, 100%, 40%);">+   RAN_PROTOCOL_RANAP</span><br><span> }</span><br><span> </span><br><span> type record RanOps {</span><br><span>@@ -498,6 +641,11 @@</span><br><span>   BssmapCreateCallback create_cb optional,</span><br><span>     BssmapUnitdataCallback unitdata_cb optional,</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+    RanapCreateCallback ranap_create_cb optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ RanapUnitdataCallback ranap_unitdata_cb optional,</span><br><span style="color: hsl(120, 100%, 40%);">+     boolean ps_domain,</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>   boolean decode_dtap,</span><br><span>         boolean role_ms,</span><br><span>     RanProtocol protocol,</span><br><span>@@ -551,6 +699,9 @@</span><br><span> #ifdef RAN_EMULATION_BSSAP</span><br><span>    var BSSAP_N_UNITDATA_ind ud_ind;</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+        var RANAP_N_UNITDATA_ind rud_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> #ifdef RAN_EMULATION_BSSAP</span><br><span>      [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {</span><br><span>          log("Respoding to inbound RESET with RESET-ACK");</span><br><span>@@ -559,6 +710,15 @@</span><br><span>           repeat;</span><br><span>      }</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+       [] RANAP.receive(tr_RANAP_UNITDATA_ind(?, ?, tr_RANAP_Reset)) -> value rud_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+           log("Respoding to inbound IuRESET with IuRESET-ACK");</span><br><span style="color: hsl(120, 100%, 40%);">+               var CN_DomainIndicator dom;</span><br><span style="color: hsl(120, 100%, 40%);">+           dom := rud_ind.userData.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;</span><br><span style="color: hsl(120, 100%, 40%);">+              RANAP.send(ts_RANAP_UNITDATA_req(rud_ind.callingAddress, rud_ind.calledAddress,</span><br><span style="color: hsl(120, 100%, 40%);">+                          ts_RANAP_ResetAck(dom)));</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> }</span><br><span> </span><br><span> </span><br><span>@@ -666,7 +826,116 @@</span><br><span> </span><br><span>                   }</span><br><span> #else</span><br><span style="color: hsl(0, 100%, 40%);">-              [false] CLIENT.receive(false) {}</span><br><span style="color: hsl(120, 100%, 40%);">+              [false] CLIENT.receive {}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</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 altstep as_main_ranap() runs on RAN_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+                var RANAP_N_UNITDATA_ind rud_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+             var RANAP_N_CONNECT_ind rconn_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+            var RANAP_N_CONNECT_cfm rconn_cfm;</span><br><span style="color: hsl(120, 100%, 40%);">+            var RANAP_N_DATA_ind rdata_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+               var RANAP_N_DISCONNECT_ind rdisc_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+         var RANAP_Conn_Req creq;</span><br><span style="color: hsl(120, 100%, 40%);">+              var RANAP_PDU ranap;</span><br><span style="color: hsl(120, 100%, 40%);">+          var RAN_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */</span><br><span style="color: hsl(120, 100%, 40%);">+           [] RANAP.receive(RANAP_N_UNITDATA_ind:?) -> value rud_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+                        /* Connectionless Procedures like RESET */</span><br><span style="color: hsl(120, 100%, 40%);">+                    var template RANAP_PDU resp;</span><br><span style="color: hsl(120, 100%, 40%);">+                  resp := CommonRanapUnitdataCallback(rud_ind.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (isvalue(resp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          RANAP.send(ts_RANAP_UNITDATA_req(rud_ind.callingAddress,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               rud_ind.calledAddress, 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%);">+             /* SCCP -> Client: new connection from BSC */</span><br><span style="color: hsl(120, 100%, 40%);">+              [] RANAP.receive(RANAP_N_CONNECT_ind:?) -> value rconn_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+                       vc_conn := g_ran_ops.ranap_create_cb.apply(rconn_ind, g_ran_id);</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* store mapping between client components and SCCP connectionId */</span><br><span style="color: hsl(120, 100%, 40%);">+                   f_conn_table_add(vc_conn, rconn_ind.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* handle user payload */</span><br><span style="color: hsl(120, 100%, 40%);">+                     f_handle_userData_RANAP(vc_conn, rconn_ind.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* confirm connection establishment */</span><br><span style="color: hsl(120, 100%, 40%);">+                        RANAP.send(ts_RANAP_CONNECT_res(rconn_ind.connectionId, omit));</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+             /* SCCP -> Client: connection-oriented data in existing connection */</span><br><span style="color: hsl(120, 100%, 40%);">+              [] RANAP.receive(RANAP_N_DATA_ind:?) -> value rdata_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+                  vc_conn := f_comp_by_conn_id(rdata_ind.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (ispresent(rdata_ind.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          f_handle_userData_RANAP(vc_conn, rdata_ind.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%);">+             /* SCCP -> Client: disconnect of an existing connection */</span><br><span style="color: hsl(120, 100%, 40%);">+         [] RANAP.receive(RANAP_N_DISCONNECT_ind:?) -> value rdisc_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+                    vc_conn := f_comp_by_conn_id(rdisc_ind.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (ispresent(rdisc_ind.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          f_handle_userData_RANAP(vc_conn, rdisc_ind.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* notify client about termination */</span><br><span style="color: hsl(120, 100%, 40%);">+                 var RAN_Conn_Prim prim := MSC_CONN_PRIM_DISC_IND;</span><br><span style="color: hsl(120, 100%, 40%);">+                     CLIENT.send(prim) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                 f_conn_table_del(rdisc_ind.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* TOOD: return confirm to other side? */</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+             /* SCCP -> Client: connection confirm for outbound connection */</span><br><span style="color: hsl(120, 100%, 40%);">+           [] RANAP.receive(RANAP_N_CONNECT_cfm:?) -> value rconn_cfm {</span><br><span style="color: hsl(120, 100%, 40%);">+                       vc_conn := f_comp_by_conn_id(rconn_cfm.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+                 var RAN_Conn_Prim prim := MSC_CONN_PRIM_CONF_IND;</span><br><span style="color: hsl(120, 100%, 40%);">+                     CLIENT.send(prim) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* handle user payload */</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (ispresent(rconn_cfm.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          f_handle_userData_RANAP(vc_conn, rconn_cfm.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%);">+           [] CLIENT.receive(RANAP_PDU:?) -> value ranap sender vc_conn {</span><br><span style="color: hsl(120, 100%, 40%);">+                     var integer conn_id := f_conn_id_by_comp(vc_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* send it to dispatcher */</span><br><span style="color: hsl(120, 100%, 40%);">+                   RANAP.send(ts_RANAP_DATA_req(conn_id, ranap));</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%);">+           /* Disconnect request client -> SCCP */</span><br><span style="color: hsl(120, 100%, 40%);">+            [] CLIENT.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ) -> sender vc_conn {</span><br><span style="color: hsl(120, 100%, 40%);">+                        var integer conn_id := f_conn_id_by_comp(vc_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+                    RANAP.send(ts_RANAP_DISC_req(conn_id, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+                    f_conn_table_del(conn_id);</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%);">+           /* BSSAP from client -> SCCP */</span><br><span style="color: hsl(120, 100%, 40%);">+            [] CLIENT.receive(RANAP_Conn_Req:?) -> value creq sender vc_conn {</span><br><span style="color: hsl(120, 100%, 40%);">+                 var integer conn_id;</span><br><span style="color: hsl(120, 100%, 40%);">+                  /* send to dispatcher */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (f_comp_known(vc_conn) == false) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         /* unknown client, create new connection */</span><br><span style="color: hsl(120, 100%, 40%);">+                           conn_id := f_gen_conn_id();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                         /* store mapping between client components and SCCP connectionId */</span><br><span style="color: hsl(120, 100%, 40%);">+                           f_conn_table_add(vc_conn, conn_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                         RANAP.send(ts_RANAP_CONNECT_req(creq.addr_peer, creq.addr_own, conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               creq.ranap));</span><br><span style="color: hsl(120, 100%, 40%);">+                 } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              /* known client, send via existing connection */</span><br><span style="color: hsl(120, 100%, 40%);">+                              conn_id := f_conn_id_by_comp(vc_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+                                RANAP.send(ts_RANAP_DATA_req(conn_id, creq.ranap));</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%);">+                   /* InitialL3 contains RR (PAG RESP) or MM (CM SRV REQ), we must increment</span><br><span style="color: hsl(120, 100%, 40%);">+                      * counter only on MM/CC/SS, but not on RR */</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (g_ran_ops.role_ms and not f_ranap_l3_is_rr(creq.ranap)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         /* we have just sent the first MM message, increment the counter */</span><br><span style="color: hsl(120, 100%, 40%);">+                           var integer idx := f_idx_by_comp(vc_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+                            ConnectionTable[idx].n_sd[0] := 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                            log("patch: N(SD) for ConnIdx ", idx, " set to 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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+            [false] CLIENT.receive {}</span><br><span> #endif</span><br><span> }</span><br><span> </span><br><span>@@ -730,6 +999,18 @@</span><br><span>          BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, bssap));</span><br><span>          }</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+       case (RAN_PROTOCOL_RANAP) {</span><br><span style="color: hsl(120, 100%, 40%);">+           var RANAP_PDU ranap;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (false /* SAPI */) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       var RANAP_IEs.SAPI sapi := sapi_0;</span><br><span style="color: hsl(120, 100%, 40%);">+                    ranap := valueof(ts_RANAP_DirectTransferSAPI(l3_enc, sapi));</span><br><span style="color: hsl(120, 100%, 40%);">+          } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ranap := valueof(ts_RANAP_DirectTransfer(l3_enc));</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             RANAP.send(ts_RANAP_DATA_req(sccp_conn_id, ranap));</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span>@@ -742,7 +1023,18 @@</span><br><span> </span><br><span>       if (isvalue(ops.sccp_addr_peer) and isvalue(ops.sccp_addr_local)) {</span><br><span>          f_sleep(1.0);   /* HACK to wait for M3UA/ASP to be ACTIVE */</span><br><span style="color: hsl(0, 100%, 40%);">-            f_bssap_reset(ops.sccp_addr_peer, ops.sccp_addr_local);</span><br><span style="color: hsl(120, 100%, 40%);">+               select (g_ran_ops.protocol) {</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_BSSAP</span><br><span style="color: hsl(120, 100%, 40%);">+             case (RAN_PROTOCOL_BSSAP) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   f_bssap_reset(ops.sccp_addr_peer, ops.sccp_addr_local);</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+         case (RAN_PROTOCOL_RANAP) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   f_ranap_reset(ops.sccp_addr_peer, ops.sccp_addr_local);</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span>    }</span><br><span> </span><br><span>        while (true) {</span><br><span>@@ -756,6 +1048,7 @@</span><br><span> </span><br><span>            alt {</span><br><span>                [g_ran_ops.protocol == RAN_PROTOCOL_BSSAP] as_main_bssap();</span><br><span style="color: hsl(120, 100%, 40%);">+           [g_ran_ops.protocol == RAN_PROTOCOL_RANAP] as_main_ranap();</span><br><span> </span><br><span>              [g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MO:?) -> value dtap_mo sender vc_conn {</span><br><span>                       var integer idx := f_idx_by_comp(vc_conn);</span><br><span>@@ -822,6 +1115,7 @@</span><br><span>    inout RAN_register, RAN_register_imsi;</span><br><span> } with { extension "internal" };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_BSSAP</span><br><span> /* CreateCallback that can be used as create_cb and will use the expectation table */</span><br><span> function ExpectedCreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id)</span><br><span> runs on RAN_Emulation_CT return RAN_ConnHdlr {</span><br><span>@@ -854,6 +1148,42 @@</span><br><span>      mtc.stop;</span><br><span>    return ret;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef RAN_EMULATION_RANAP</span><br><span style="color: hsl(120, 100%, 40%);">+/* CreateCallback that can be used as create_cb and will use the expectation table */</span><br><span style="color: hsl(120, 100%, 40%);">+function RanapExpectedCreateCallback(RANAP_N_CONNECT_ind conn_ind, charstring id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on RAN_Emulation_CT return RAN_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+      var RAN_ConnHdlr ret := null;</span><br><span style="color: hsl(120, 100%, 40%);">+ var template (omit) octetstring l3_info;</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%);">+      l3_info := f_ranap_extract_l3(conn_ind.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (istemplatekind(l3_info, "omit")) {</span><br><span style="color: hsl(120, 100%, 40%);">+              setverdict(fail, "N-CONNECT.ind without NAS payload");</span><br><span style="color: hsl(120, 100%, 40%);">+              mtc.stop;</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%);">+   for (i := 0; i < sizeof(ExpectTable); i:= i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (not ispresent(ExpectTable[i].l3_payload)) {</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 (valueof(l3_info) == ExpectTable[i].l3_payload) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  ret := ExpectTable[i].vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+                        /* release this entry to be used again */</span><br><span style="color: hsl(120, 100%, 40%);">+                     ExpectTable[i].l3_payload := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+                    ExpectTable[i].vc_conn := null;</span><br><span style="color: hsl(120, 100%, 40%);">+                       log("Found Expect[", i, "] for ", l3_info, " handled at ", ret);</span><br><span style="color: hsl(120, 100%, 40%);">+                        /* return the component reference */</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 incoming connection ", conn_ind);</span><br><span style="color: hsl(120, 100%, 40%);">+    mtc.stop;</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%);">+#endif</span><br><span> </span><br><span> private function f_create_expect(octetstring l3, RAN_ConnHdlr hdlr)</span><br><span> runs on RAN_Emulation_CT {</span><br><span>diff --git a/library/ranap/RANAP_Templates.ttcn b/library/ranap/RANAP_Templates.ttcn</span><br><span>index c50440c..4d18e1c 100644</span><br><span>--- a/library/ranap/RANAP_Templates.ttcn</span><br><span>+++ b/library/ranap/RANAP_Templates.ttcn</span><br><span>@@ -9,6 +9,8 @@</span><br><span> import from RANAP_PDU_Contents all;</span><br><span> import from RANAP_PDU_Descriptions all;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template (value) Cause ts_RanapCause_om_intervention := { misc := 113 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*****************************************************************************************************</span><br><span>  * Reset</span><br><span>  *****************************************************************************************************/</span><br><span>@@ -668,6 +670,37 @@</span><br><span>             }</span><br><span>    }</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+template RANAP_PDU</span><br><span style="color: hsl(120, 100%, 40%);">+tr_RANAP_Paging(template CN_DomainIndicator dom, template IMSI imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+              template Paging.protocolExtensions exts := *) := {</span><br><span style="color: hsl(120, 100%, 40%);">+    initiatingMessage := {</span><br><span style="color: hsl(120, 100%, 40%);">+                procedureCode := id_Paging,</span><br><span style="color: hsl(120, 100%, 40%);">+           criticality := ignore,</span><br><span style="color: hsl(120, 100%, 40%);">+                value_ := {</span><br><span style="color: hsl(120, 100%, 40%);">+                   paging := {</span><br><span style="color: hsl(120, 100%, 40%);">+                           protocolIEs := {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      {</span><br><span style="color: hsl(120, 100%, 40%);">+                                             id := id_CN_DomainIndicator,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          criticality := ignore,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                value_ := {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   cN_DomainIndicator := dom</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%);">+                                          id := id_PermanentNAS_UE_ID,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          criticality := ignore,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                value_ := {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   permanentNAS_UE_ID := {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               iMSI := 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%);">+                                     }, *</span><br><span style="color: hsl(120, 100%, 40%);">+                          },</span><br><span style="color: hsl(120, 100%, 40%);">+                            protocolExtensions := exts</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> </span><br><span> </span><br><span> /*****************************************************************************************************</span><br><span>@@ -1308,7 +1341,47 @@</span><br><span>  *</span><br><span>  *****************************************************************************************************/</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* extract the L3 (NAS) from a given RANAP message */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_ranap_extract_l3(RANAP_PDU ranap) return template (omit) octetstring</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     var integer i;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    if (match(ranap, tr_RANAP_initialUE_CS(?, ?, ?, ?, ?)) or</span><br><span style="color: hsl(120, 100%, 40%);">+         match(ranap, tr_RANAP_initialUE_PS(?, ?, ?, ?, ?, ?)) ) {</span><br><span style="color: hsl(120, 100%, 40%);">+         var InitialUE_Message.protocolIEs ies := ranap.initiatingMessage.value_.initialUE_Message.protocolIEs;</span><br><span style="color: hsl(120, 100%, 40%);">+                for (i := 0; i < lengthof(ies); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (ies[i].id == id_NAS_PDU) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                return ies[i].value_.nAS_PDU;</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%);">+     } else if (match(ranap, tr_RANAP_DirectTransfer(?, ?))) {</span><br><span style="color: hsl(120, 100%, 40%);">+             var DirectTransfer.protocolIEs ies := ranap.initiatingMessage.value_.directTransfer.protocolIEs;</span><br><span style="color: hsl(120, 100%, 40%);">+              for (i := 0; i < lengthof(ies); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (ies[i].id == id_NAS_PDU) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                return ies[i].value_.nAS_PDU;</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%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* relocationInformation not supported yet*/</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%);">+function f_ranap_extract_sapi(RANAP_PDU ranap) return template (omit) SAPI</span><br><span style="color: hsl(120, 100%, 40%);">+{</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%);">+      /* InitialUE message has no SAPI */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (match(ranap, tr_RANAP_DirectTransfer(?, ?))) {</span><br><span style="color: hsl(120, 100%, 40%);">+            var DirectTransfer.protocolIEs ies := ranap.initiatingMessage.value_.directTransfer.protocolIEs;</span><br><span style="color: hsl(120, 100%, 40%);">+              for (i := 0; i < lengthof(ies); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (ies[i].id == id_SAPI) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           return ies[i].value_.sAPI;</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%);">+     return omit;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span> </span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13653">change 13653</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/13653"/><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: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ie79bda764162e5c5a42608bde5c5f486ea531f33 </div>
<div style="display:none"> Gerrit-Change-Number: 13653 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>