<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/19765">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">library: Add BSSLAP_LE_{CodecPort,Emulation}<br><br>Those two modules are analogous to BSSAP/BSSMAP CodecPort and Emulation,<br>but for the Lb interface (BSC-SMLC) instead of the A interface.<br><br>Change-Id: I92fd91056731abb8d3c01560f80c01c6a48a6fc9<br>---<br>A library/BSSAP_LE_Adapter.ttcn<br>A library/BSSAP_LE_CodecPort.ttcn<br>A library/BSSAP_LE_Emulation.ttcn<br>M library/RAN_Emulation.ttcnpp<br>4 files changed, 1,216 insertions(+), 2 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/65/19765/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/library/BSSAP_LE_Adapter.ttcn b/library/BSSAP_LE_Adapter.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..dba8841</span><br><span>--- /dev/null</span><br><span>+++ b/library/BSSAP_LE_Adapter.ttcn</span><br><span>@@ -0,0 +1,130 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module BSSAP_LE_Adapter {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* This module implements a 'dumb' BSSAP_LE adapter. It creates the M3UA and SCCP components and stacks a</span><br><span style="color: hsl(120, 100%, 40%);">+ * BSSAP_LE codec port on top. As a result, it provides the ability to transceive SCCP-User-SAP primitives</span><br><span style="color: hsl(120, 100%, 40%);">+ * with deoded BSSAP_LE payload. Use this if you want to have full control about what you transmit or</span><br><span style="color: hsl(120, 100%, 40%);">+ * receive, without any automatisms in place. Allows you to refuse connections or other abnormal behavior. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2017-2020 Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * contributions by sysmocom - s.f.m.c. GmbH</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%);">+ * SPDX-License-Identifier: GPL-2.0-or-later</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 General_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from M3UA_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from MTP3asp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from MTP3asp_PortType all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPA_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCCP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCCPasp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCCP_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCCP_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCTPasp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCTPasp_PortType all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSMAP_LE_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSAP_LE_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type record BSSAP_LE_Adapter {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* component references */</span><br><span style="color: hsl(120, 100%, 40%);">+ M3UA_CT vc_M3UA, /* only in 3GPP AoIP */</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_CT vc_SCCP,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ MSC_SCCP_MTP3_parameters sccp_pars,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address sccp_addr_own,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address sccp_addr_peer,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* handler mode */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_Emulation_CT vc_BSSAP_LE</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 BSSAP_LE_Configuration {</span><br><span style="color: hsl(120, 100%, 40%);">+ charstring sccp_service_type,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCTP_Association_Address sctp_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer own_pc,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer own_ssn,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer peer_pc,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer peer_ssn,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring sio,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer rctx</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+type record of BSSAP_LE_Configuration BSSAP_LE_Configurations;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function init_pars(inout BSSAP_LE_Adapter ba, in BSSAP_LE_Configuration cfg) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.sccp_pars := {</span><br><span style="color: hsl(120, 100%, 40%);">+ sio := {</span><br><span style="color: hsl(120, 100%, 40%);">+ ni := substr(oct2bit(cfg.sio),0,2),</span><br><span style="color: hsl(120, 100%, 40%);">+ prio := substr(oct2bit(cfg.sio),2,2),</span><br><span style="color: hsl(120, 100%, 40%);">+ si := substr(oct2bit(cfg.sio),4,4)</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ opc := cfg.own_pc,</span><br><span style="color: hsl(120, 100%, 40%);">+ dpc := cfg.peer_pc,</span><br><span style="color: hsl(120, 100%, 40%);">+ sls := 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ sccp_serviceType := cfg.sccp_service_type,</span><br><span style="color: hsl(120, 100%, 40%);">+ ssn := cfg.own_ssn</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(cfg.own_pc, cfg.own_ssn, cfg.sio, cfg.sccp_service_type));</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(cfg.peer_pc, cfg.peer_ssn, cfg.sio, cfg.sccp_service_type));</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 f_bssap_le_adapter_init(inout BSSAP_LE_Adapter ba, in BSSAP_LE_Configuration cfg, charstring id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template BssapLeOps ops) {</span><br><span style="color: hsl(120, 100%, 40%);">+ init_pars(ba, cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+ ops.sccp_addr_local := ba.sccp_addr_own;</span><br><span style="color: hsl(120, 100%, 40%);">+ ops.sccp_addr_peer := ba.sccp_addr_peer;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* create components */</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_SCCP := SCCP_CT.create(id & "-SCCP");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (isvalue(ops)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_BSSAP_LE := BSSAP_LE_Emulation_CT.create(id & "-BSSAP_LE");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_BSSAP_LE := null;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_M3UA := M3UA_CT.create(id & "-M3UA");</span><br><span style="color: hsl(120, 100%, 40%);">+ map(ba.vc_M3UA:SCTP_PORT, system:sctp);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* connect MTP3 service provider (M3UA) to lower side of SCCP */</span><br><span style="color: hsl(120, 100%, 40%);">+ connect(ba.vc_M3UA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_M3UA.start(f_M3UA_Emulation(cfg.sctp_addr, cfg.rctx));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (isvalue(ops)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ timer T := 5.0;</span><br><span style="color: hsl(120, 100%, 40%);">+ T.start;</span><br><span style="color: hsl(120, 100%, 40%);">+ //T.timeout;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* connect BSSNAP component to upper side of SCCP */</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Connecting BSSAP_LE_Emulation to SCCP_SP_PORT");</span><br><span style="color: hsl(120, 100%, 40%);">+ connect(ba.vc_BSSAP_LE:BSSAP_LE, ba.vc_SCCP:SCCP_SP_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Starting BSSAP_LE_Emulation");</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_BSSAP_LE.start(BSSAP_LE_Emulation.main(valueof(ops), ""));</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%);">+function f_bssap_le_adapter_start(inout BSSAP_LE_Adapter ba) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_SCCP.start(SCCPStart(ba.sccp_pars));</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_bssap_le_adapter_cleanup(inout BSSAP_LE_Adapter ba) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ba.vc_BSSAP_LE != null) {</span><br><span style="color: hsl(120, 100%, 40%);">+ disconnect(ba.vc_BSSAP_LE:BSSAP_LE, ba.vc_SCCP:SCCP_SP_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_BSSAP_LE.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ unmap(ba.vc_M3UA:SCTP_PORT, system:sctp);</span><br><span style="color: hsl(120, 100%, 40%);">+ disconnect(ba.vc_M3UA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_M3UA.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ ba.vc_SCCP.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%);">+}</span><br><span>diff --git a/library/BSSAP_LE_CodecPort.ttcn b/library/BSSAP_LE_CodecPort.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..f1d930f</span><br><span>--- /dev/null</span><br><span>+++ b/library/BSSAP_LE_CodecPort.ttcn</span><br><span>@@ -0,0 +1,380 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module BSSAP_LE_CodecPort {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Simple BSSAP_LE Codec Port, translating between raw SCCP primitives with</span><br><span style="color: hsl(120, 100%, 40%);">+ * octetstring payload towards the SCCP provider, and BSSAP_LE-SCCP primitives</span><br><span style="color: hsl(120, 100%, 40%);">+ * which carry the decoded BSSAP_LE data types as payload.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2017 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%);">+ * SPDX-License-Identifier: GPL-2.0-or-later</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 General_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Osmocom_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCCPasp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCCP_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSAP_LE_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type record BSSAP_LE_N_CONNECT_req</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address calledAddress,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address callingAddress optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Expedited_Data_Sel expeditedDataSel optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Quality_Of_Service qualityOfService optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_CONNECT_req ts_BSSAP_LE_CONNECT_req(SCCP_PAR_Address called,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address calling,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE bssap := omit) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ calledAddress := called,</span><br><span style="color: hsl(120, 100%, 40%);">+ callingAddress := calling,</span><br><span style="color: hsl(120, 100%, 40%);">+ expeditedDataSel := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ qualityOfService := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := 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%);">+type record BSSAP_LE_N_CONNECT_ind</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address calledAddress,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address callingAddress optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Quality_Of_Service qualityOfService optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_CONNECT_ind tr_BSSAP_LE_CONNECT_ind(template SCCP_PAR_Address called,</span><br><span style="color: hsl(120, 100%, 40%);">+ template SCCP_PAR_Address calling,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE payload := *) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ calledAddress := called,</span><br><span style="color: hsl(120, 100%, 40%);">+ callingAddress := calling,</span><br><span style="color: hsl(120, 100%, 40%);">+ qualityOfService := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := payload,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := *</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 BSSAP_LE_N_CONNECT_res</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address respondingAddress optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Expedited_Data_Sel expeditedDataSel optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Quality_Of_Service qualityOfService optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_CONNECT_res ts_BSSAP_LE_CONNECT_res(SCCP_PAR_Connection_Id conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE bssap := omit) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ respondingAddress := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ expeditedDataSel := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ qualityOfService := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := 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%);">+type record BSSAP_LE_N_CONNECT_cfm</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address respondingAddress optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Quality_Of_Service qualityOfService optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_CONNECT_cfm tr_BSSAP_LE_CONNECT_cfm(template SCCP_PAR_Connection_Id conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE bssap := *) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ respondingAddress := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ qualityOfService := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := *</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 BSSAP_LE_N_DATA_req</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_DATA_req ts_BSSAP_LE_DATA_req(SCCP_PAR_Connection_Id conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE bssap) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := 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%);">+type record BSSAP_LE_N_DATA_ind</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_DATA_ind tr_BSSAP_LE_DATA_ind(SCCP_PAR_Connection_Id conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE bssap := *) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := *</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%);">+type record BSSAP_LE_N_DISCONNECT_req</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address respondingAddress optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Reason reason ,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_DISCONNECT_req ts_BSSAP_LE_DISC_req(SCCP_PAR_Connection_Id conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template SCCP_PAR_Reason reason,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE bssap := omit) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ respondingAddress := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ reason := reason,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := 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%);">+type record BSSAP_LE_N_DISCONNECT_ind</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Originator originator ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address respondingAddress optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Reason reason ,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Connection_Id connectionId optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_DISCONNECT_ind tr_BSSAP_LE_DISC_ind(template SCCP_PAR_Connection_Id conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ template SCCP_PAR_Originator originator,</span><br><span style="color: hsl(120, 100%, 40%);">+ template SCCP_PAR_Reason reason,</span><br><span style="color: hsl(120, 100%, 40%);">+ template PDU_BSSAP_LE bssap := *) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ originator := originator,</span><br><span style="color: hsl(120, 100%, 40%);">+ respondingAddress:= *,</span><br><span style="color: hsl(120, 100%, 40%);">+ reason := reason,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ connectionId := conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := *</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 BSSAP_LE_N_UNITDATA_req</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address calledAddress ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address callingAddress ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Sequence_Control sequenceControl optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Return_Option returnOption optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_UNITDATA_req ts_BSSAP_LE_UNITDATA_req(SCCP_PAR_Address called, SCCP_PAR_Address calling, template PDU_BSSAP_LE payload) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ calledAddress := called,</span><br><span style="color: hsl(120, 100%, 40%);">+ callingAddress := calling,</span><br><span style="color: hsl(120, 100%, 40%);">+ sequenceControl := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ returnOption := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := payload,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := 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%);">+type record BSSAP_LE_N_UNITDATA_ind</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address calledAddress ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address callingAddress ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Sequence_Control sequenceControl optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Return_Option returnOption optional ,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+template BSSAP_LE_N_UNITDATA_ind tr_BSSAP_LE_UNITDATA_ind(template SCCP_PAR_Address called, template SCCP_PAR_Address calling, template PDU_BSSAP_LE payload) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ calledAddress := called,</span><br><span style="color: hsl(120, 100%, 40%);">+ callingAddress := calling,</span><br><span style="color: hsl(120, 100%, 40%);">+ sequenceControl := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ returnOption := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ userData := payload,</span><br><span style="color: hsl(120, 100%, 40%);">+ importance := *</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 BSSAP_LE_N_NOTICE_ind</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address calledAddress ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address callingAddress ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Reason_For_Return reasonForReturn ,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE userData ,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Importance importance 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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_dec_ConnectInd(in ASP_SCCP_N_CONNECT_ind pin, out BSSAP_LE_N_CONNECT_ind pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.calledAddress := pin.calledAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.callingAddress := pin.callingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.qualityOfService := pin.qualityOfService;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(pin.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := dec_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_dec_ConnectCfm(in ASP_SCCP_N_CONNECT_cfm pin, out BSSAP_LE_N_CONNECT_cfm pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.respondingAddress := pin.respondingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.qualityOfService := pin.qualityOfService;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(pin.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := dec_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_dec_DataInd(in ASP_SCCP_N_DATA_ind pin, out BSSAP_LE_N_DATA_ind pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := dec_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_dec_DisconnectInd(in ASP_SCCP_N_DISCONNECT_ind pin, out BSSAP_LE_N_DISCONNECT_ind pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.originator := pin.originator;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.respondingAddress := pin.respondingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.reason := pin.reason;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(pin.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := dec_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_dec_UnitdataInd(in ASP_SCCP_N_UNITDATA_ind pin, out BSSAP_LE_N_UNITDATA_ind pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.calledAddress := pin.calledAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.callingAddress := pin.callingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.sequenceControl := pin.sequenceControl;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.returnOption := pin.returnOption;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := dec_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_dec_NoticeInd(in ASP_SCCP_N_NOTICE_ind pin, out BSSAP_LE_N_NOTICE_ind pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.calledAddress := pin.calledAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.callingAddress := pin.callingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.reasonForReturn := pin.reasonForReturn;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := dec_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_enc_ConnectReq(in BSSAP_LE_N_CONNECT_req pin, out ASP_SCCP_N_CONNECT_req pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.calledAddress := pin.calledAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.callingAddress := pin.callingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.expeditedDataSel := pin.expeditedDataSel;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.qualityOfService := pin.qualityOfService;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(pin.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := enc_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_enc_ConnectRes(in BSSAP_LE_N_CONNECT_res pin, out ASP_SCCP_N_CONNECT_res pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.respondingAddress := pin.respondingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.expeditedDataSel := pin.expeditedDataSel;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.qualityOfService := pin.qualityOfService;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(pin.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := enc_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_enc_DataReq(in BSSAP_LE_N_DATA_req pin, out ASP_SCCP_N_DATA_req pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := enc_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_enc_DisconnectReq(in BSSAP_LE_N_DISCONNECT_req pin, out ASP_SCCP_N_DISCONNECT_req pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.respondingAddress := pin.respondingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.reason := pin.reason;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(pin.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := enc_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.connectionId := pin.connectionId;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 f_enc_UnitdataReq(in BSSAP_LE_N_UNITDATA_req pin, out ASP_SCCP_N_UNITDATA_req pout) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.calledAddress := pin.calledAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.callingAddress := pin.callingAddress;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.userData := enc_PDU_BSSAP_LE(pin.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.sequenceControl := pin.sequenceControl;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.returnOption := pin.returnOption;</span><br><span style="color: hsl(120, 100%, 40%);">+ pout.importance := pin.importance;</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 BSSAP_LE_CODEC_PT message {</span><br><span style="color: hsl(120, 100%, 40%);">+ out BSSAP_LE_N_CONNECT_req,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_CONNECT_res,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_DATA_req,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_DISCONNECT_req,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_UNITDATA_req,</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_RESET_req;</span><br><span style="color: hsl(120, 100%, 40%);">+ in BSSAP_LE_N_CONNECT_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_CONNECT_cfm,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_DATA_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_DISCONNECT_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_UNITDATA_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_NOTICE_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_RESET_ind,</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_RESET_cfm,</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_STATE_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+} with { extension "internal user SCCPasp_PT</span><br><span style="color: hsl(120, 100%, 40%);">+ out(BSSAP_LE_N_CONNECT_req -> ASP_SCCP_N_CONNECT_req: function(f_enc_ConnectReq);</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_CONNECT_res -> ASP_SCCP_N_CONNECT_res: function(f_enc_ConnectRes);</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_DATA_req -> ASP_SCCP_N_DATA_req: function(f_enc_DataReq);</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_DISCONNECT_req -> ASP_SCCP_N_DISCONNECT_req: function(f_enc_DisconnectReq);</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_UNITDATA_req -> ASP_SCCP_N_UNITDATA_req: function(f_enc_UnitdataReq);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_RESET_req -> ASP_SCCP_N_RESET_req: simple)</span><br><span style="color: hsl(120, 100%, 40%);">+ in(ASP_SCCP_N_CONNECT_ind -> BSSAP_LE_N_CONNECT_ind: function(f_dec_ConnectInd);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_CONNECT_cfm -> BSSAP_LE_N_CONNECT_cfm: function(f_dec_ConnectCfm);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_DATA_ind -> BSSAP_LE_N_DATA_ind: function(f_dec_DataInd);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_DISCONNECT_ind -> BSSAP_LE_N_DISCONNECT_ind: function(f_dec_DisconnectInd);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_UNITDATA_ind -> BSSAP_LE_N_UNITDATA_ind: function(f_dec_UnitdataInd);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_NOTICE_ind -> BSSAP_LE_N_NOTICE_ind: function(f_dec_NoticeInd);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_RESET_ind -> ASP_SCCP_N_RESET_ind: simple;</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_RESET_cfm -> ASP_SCCP_N_RESET_cfm: simple;</span><br><span style="color: hsl(120, 100%, 40%);">+ ASP_SCCP_N_STATE_ind -> ASP_SCCP_N_STATE_ind: simple)"</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/BSSAP_LE_Emulation.ttcn b/library/BSSAP_LE_Emulation.ttcn</span><br><span>new file mode 100644</span><br><span>index 0000000..0b9fe16</span><br><span>--- /dev/null</span><br><span>+++ b/library/BSSAP_LE_Emulation.ttcn</span><br><span>@@ -0,0 +1,704 @@</span><br><span style="color: hsl(120, 100%, 40%);">+module BSSAP_LE_Emulation {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* BSSAP_LE Emulation, runs on top of BSSAP_LE_CodecPort. It multiplexes/demultiplexes</span><br><span style="color: hsl(120, 100%, 40%);">+ * the individual connections, so there can be separate TTCN-3 components handling</span><br><span style="color: hsl(120, 100%, 40%);">+ * each of the connections.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The BSSAP_LE_Emulation.main() function processes SCCP primitives from the SCCP</span><br><span style="color: hsl(120, 100%, 40%);">+ * stack via the BSSAP_CodecPort, and dispatches them to the per-connection components.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Outbound BSSAP/SCCP connections are initiated by sending a BSSAP_LE_Conn_Req primitive</span><br><span style="color: hsl(120, 100%, 40%);">+ * to the component running the BSSAP_LE_Emulation.main() function.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * For each new inbound connections, the BssapLeOps.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 inbound</span><br><span style="color: hsl(120, 100%, 40%);">+ * connection 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 connection, it can</span><br><span style="color: hsl(120, 100%, 40%);">+ * do so by registering an "expect" with the expected Layer 3 (DTAP) payload. This is e.g. useful</span><br><span style="color: hsl(120, 100%, 40%);">+ * if you are simulating BTS + MSC, and first trigger a connection from BTS/RSL side in a</span><br><span style="color: hsl(120, 100%, 40%);">+ * component which then subsequently should also handle the MSC emulation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Inbound Unit Data messages (such as are dispatched to the BssapLeOps.unitdata_cb() callback,</span><br><span style="color: hsl(120, 100%, 40%);">+ * which is registered with an argument to the main() function below.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2017-2020 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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from General_Types 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 SCCP_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from SCCPasp_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from IPA_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from MobileL3_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from Misc_Helpers all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSAP_LE_Types all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSAP_LE_CodecPort all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSMAP_LE_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from BSSMAP_Templates all;</span><br><span style="color: hsl(120, 100%, 40%);">+import from RAN_Emulation all;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* General "base class" component definition, of which specific implementations</span><br><span style="color: hsl(120, 100%, 40%);">+ * derive themselves by means of the "extends" feature */</span><br><span style="color: hsl(120, 100%, 40%);">+type component BSSAP_LE_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* port towards MSC Emulator core / SCCP connection dispatchar */</span><br><span style="color: hsl(120, 100%, 40%);">+ port BSSAP_LE_Conn_PT BSSAP_LE;</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 BSSAP_LE_PROC_PT BSSAP_LE_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%);">+/* Auxiliary primitive that can happen on the port between per-connection client and this dispatcher */</span><br><span style="color: hsl(120, 100%, 40%);">+type enumerated BSSAP_LE_Conn_Prim {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* SCCP tell us that connection was released */</span><br><span style="color: hsl(120, 100%, 40%);">+ CONN_PRIM_DISC_IND,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* we tell SCCP to release connection */</span><br><span style="color: hsl(120, 100%, 40%);">+ CONN_PRIM_DISC_REQ,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Connection confirmed indication */</span><br><span style="color: hsl(120, 100%, 40%);">+ CONN_PRIM_CONF_IND</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 BSSAP_LE_Conn_PT message {</span><br><span style="color: hsl(120, 100%, 40%);">+ inout</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_BSSAP_LE,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_N_UNITDATA_req,</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%);">+ BSSAP_LE_Conn_Req,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* direct DTAP messages from/to clients */</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_DTAP_MO, PDU_DTAP_MT,</span><br><span style="color: hsl(120, 100%, 40%);">+ PDU_DTAP_PS_MO, PDU_DTAP_PS_MT,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* misc indications / requests between SCCP and client */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_Conn_Prim;</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%);">+type uint2_t N_Sd_Array[4];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* represents a single BSSAP connection over SCCP */</span><br><span style="color: hsl(120, 100%, 40%);">+type record ConnectionData {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* reference to the instance of the per-connection component */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_ConnHdlr comp_ref,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer sccp_conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* array of N(SD) values for MO DTAP messages, indexed by discriminator */</span><br><span style="color: hsl(120, 100%, 40%);">+ N_Sd_Array n_sd</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 ImsiMapping {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_ConnHdlr comp_ref,</span><br><span style="color: hsl(120, 100%, 40%);">+ hexstring imsi optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ OCT4 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%);">+type component BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* SCCP ports on the bottom side, using ASP primitives */</span><br><span style="color: hsl(120, 100%, 40%);">+ port BSSAP_LE_CODEC_PT BSSAP_LE;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* BSSAP port to the per-connection clients */</span><br><span style="color: hsl(120, 100%, 40%);">+ port BSSAP_LE_Conn_PT CLIENT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* use 16 as this is also the number of SCCP connections that SCCP_Emulation can handle */</span><br><span style="color: hsl(120, 100%, 40%);">+ var ConnectionData ConnectionTable[16];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* pending expected incoming connections */</span><br><span style="color: hsl(120, 100%, 40%);">+ var ExpectData ExpectTable[8];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* tables for mapping inbound unitdata (like paging) */</span><br><span style="color: hsl(120, 100%, 40%);">+ var ImsiMapping ImsiTable[16];</span><br><span style="color: hsl(120, 100%, 40%);">+</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 BSSAP_LE_PROC_PT PROC;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var charstring g_ran_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer g_next_e1_ts := 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BssapLeOps g_ran_ops;</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_conn_id_known(integer sccp_conn_id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_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(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ConnectionTable[i].sccp_conn_id == sccp_conn_id){</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(BSSAP_LE_ConnHdlr client)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_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(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ConnectionTable[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%);">+/* resolve component reference by connection ID */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_comp_by_conn_id(integer sccp_conn_id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return BSSAP_LE_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(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ConnectionTable[i].sccp_conn_id == sccp_conn_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return ConnectionTable[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, "BSSAP-LE Connection table not found by SCCP Connection ID ", sccp_conn_id);</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%);">+/* resolve connection ID by component reference */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_conn_id_by_comp(BSSAP_LE_ConnHdlr client)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return integer {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ConnectionTable[i].comp_ref == client) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return ConnectionTable[i].sccp_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%);">+ setverdict(fail, "BSSAP-LE Connection 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%);">+/* resolve ConnectionTable index component reference */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_idx_by_comp(BSSAP_LE_ConnHdlr client)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return integer {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ConnectionTable[i].comp_ref == client) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return i;</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, "BSSAP-LE Connection 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_gen_conn_id()</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return integer {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer conn_id;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ conn_id := float2int(rnd()*SCCP_Emulation.tsp_max_ConnectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (f_conn_id_known(conn_id) == true);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 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%);">+private function f_conn_table_init()</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].comp_ref := null;</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].sccp_conn_id := -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].n_sd := { 0, 0, 0, 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ImsiTable[i].comp_ref := null;</span><br><span style="color: hsl(120, 100%, 40%);">+ ImsiTable[i].imsi := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ ImsiTable[i].tmsi := 'FFFFFFFF'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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_conn_table_add(BSSAP_LE_ConnHdlr comp_ref, integer sccp_conn_id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ConnectionTable[i].sccp_conn_id == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].comp_ref := comp_ref;</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].sccp_conn_id := sccp_conn_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].n_sd := { 0, 0, 0, 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Added conn table entry ", i, comp_ref, sccp_conn_id);</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("BSSAP-LE Connection 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_conn_table_del(integer sccp_conn_id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ConnectionTable[i].sccp_conn_id == sccp_conn_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Deleted conn table entry ", i,</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].comp_ref, sccp_conn_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[i].sccp_conn_id := -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[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, "BSSAP-LE Connection table attempt to delete non-existant ", sccp_conn_id);</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_find(hexstring imsi, template OCT4 tmsi)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return BSSAP_LE_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ImsiTable[i].imsi == imsi or</span><br><span style="color: hsl(120, 100%, 40%);">+ isvalue(tmsi) and match(ImsiTable[i].tmsi, tmsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return ImsiTable[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%);">+ return null;</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 BSSAP_LE_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%);">+ PDU_BSSAP_LE bssap</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+template BSSAP_LE_Conn_Req ts_BSSAP_LE_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, PDU_BSSAP_LE bssap) := {</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%);">+ bssap := bssap</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%);">+/* handle (optional) userData portion of various primitives and dispatch it to the client */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_handle_userData(BSSAP_LE_ConnHdlr client, PDU_BSSAP_LE bssap)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* decode + send decoded BSSAP to client */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ischosen(bssap.pdu.dtap) and g_ran_ops.decode_dtap) {</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 := bssap.dlci,</span><br><span style="color: hsl(120, 100%, 40%);">+ dtap := dec_PDU_ML3_NW_MS(bssap.pdu.dtap)</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 := bssap.dlci,</span><br><span style="color: hsl(120, 100%, 40%);">+ dtap := dec_PDU_ML3_MS_NW(bssap.pdu.dtap)</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%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ CLIENT.send(bssap) 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%);">+/* 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 BssmapLeCreateCallback(BSSAP_LE_N_CONNECT_ind conn_ind, charstring id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return BSSAP_LE_ConnHdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type function BssmapLeUnitdataCallback(PDU_BSSAP_LE bssap)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return template PDU_BSSAP_LE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* handle common Unitdata such as Paging */</span><br><span style="color: hsl(120, 100%, 40%);">+private function CommonBssmapUnitdataCallback(PDU_BSSAP_LE bssap)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return template PDU_BSSAP_LE {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match(bssap, tr_BSSMAP_LE_Paging)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_ConnHdlr client := null;</span><br><span style="color: hsl(120, 100%, 40%);">+ client := f_imsi_table_find(bssap.pdu.bssmap.paging.iMSI.digits,</span><br><span style="color: hsl(120, 100%, 40%);">+ bssap.pdu.bssmap.paging.tMSI.tmsiOctets);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (client != null) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("CommonBssmapUnitdataCallback: 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(bssap) 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("CommonBssmapUnitdataCallback: 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("CommonBssmapUnitdataCallback: Not a paging message");</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.unitdata_cb.apply(bssap);</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_bssap_le_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ timer T := 5.0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE.send(ts_BSSAP_LE_UNITDATA_req(peer, own, ts_BSSMAP_LE_Reset(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE)));</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%);">+ [] BSSAP_LE.receive(tr_BSSAP_LE_UNITDATA_ind(own, peer, tr_BSSMAP_LE_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%);">+ [] BSSAP_LE.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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_bssap_l3_is_rr(PDU_BSSAP_LE bssap) return boolean {</span><br><span style="color: hsl(120, 100%, 40%);">+ var template octetstring l3 := f_bssap_le_extract_l3(bssap);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type record BssapLeOps {</span><br><span style="color: hsl(120, 100%, 40%);">+ BssmapLeCreateCallback create_cb optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ BssmapLeUnitdataCallback unitdata_cb optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ boolean decode_dtap,</span><br><span style="color: hsl(120, 100%, 40%);">+ boolean role_ms,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* needed for performing BSSMAP RESET */</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address sccp_addr_local optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ SCCP_PAR_Address sccp_addr_peer 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%);">+private altstep as_reset_ack() runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_N_UNITDATA_ind ud_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BSSAP_LE.receive(tr_BSSAP_LE_UNITDATA_ind(?, ?, tr_BSSMAP_LE_Reset)) -> value ud_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Respoding to inbound RESET with RESET-ACK");</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE.send(ts_BSSAP_LE_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,</span><br><span style="color: hsl(120, 100%, 40%);">+ ts_BSSMAP_LE_ResetAck));</span><br><span style="color: hsl(120, 100%, 40%);">+ repeat;</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 altstep as_main_bssap_le() runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_N_UNITDATA_ind ud_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_N_CONNECT_ind conn_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_N_CONNECT_cfm conn_cfm;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_N_DATA_ind data_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_N_DISCONNECT_ind disc_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_Conn_Req creq;</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP_LE bssap;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_N_UNITDATA_req bssap_ud;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer targetPointCode;</span><br><span style="color: hsl(120, 100%, 40%);">+ var N_Sd_Array last_n_sd;</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%);">+ [] BSSAP_LE.receive(BSSAP_LE_N_UNITDATA_ind:?) -> value ud_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 PDU_BSSAP_LE resp;</span><br><span style="color: hsl(120, 100%, 40%);">+ resp := CommonBssmapUnitdataCallback(ud_ind.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (isvalue(resp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE.send(ts_BSSAP_LE_UNITDATA_req(ud_ind.callingAddress,</span><br><span style="color: hsl(120, 100%, 40%);">+ ud_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%);">+ [] BSSAP_LE.receive(BSSAP_LE_N_CONNECT_ind:?) -> value conn_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn := g_ran_ops.create_cb.apply(conn_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, conn_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(vc_conn, conn_ind.userData);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* confirm connection establishment */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE.send(ts_BSSAP_LE_CONNECT_res(conn_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%);">+ [] BSSAP_LE.receive(BSSAP_LE_N_DATA_ind:?) -> value data_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn := f_comp_by_conn_id(data_ind.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(data_ind.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_handle_userData(vc_conn, data_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%);">+ [] BSSAP_LE.receive(BSSAP_LE_N_DISCONNECT_ind:?) -> value disc_ind {</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn := f_comp_by_conn_id(disc_ind.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(disc_ind.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_handle_userData(vc_conn, disc_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 BSSAP_LE_Conn_Prim prim := 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(disc_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%);">+ [] BSSAP_LE.receive(BSSAP_LE_N_CONNECT_cfm:?) -> value conn_cfm {</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn := f_comp_by_conn_id(conn_cfm.connectionId);</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_Conn_Prim prim := 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(conn_cfm.userData)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_handle_userData(vc_conn, conn_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%);">+ [] CLIENT.receive(PDU_BSSAP_LE:?) -> value bssap 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%);">+ BSSAP_LE.send(ts_BSSAP_LE_DATA_req(conn_id, bssap));</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(BSSAP_LE_N_UNITDATA_req:?) -> value bssap_ud sender vc_conn {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE.send(bssap_ud);</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(BSSAP_LE_Conn_Prim: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%);">+ BSSAP_LE.send(ts_BSSAP_LE_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(BSSAP_LE_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%);">+ BSSAP_LE.send(ts_BSSAP_LE_CONNECT_req(creq.addr_peer, creq.addr_own, conn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ creq.bssap));</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%);">+ BSSAP_LE.send(ts_BSSAP_LE_DATA_req(conn_id, creq.bssap));</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_bssap_l3_is_rr(creq.bssap)) {</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%);">+ [] PROC.getcall(BSSAP_LE_last_n_sd:{?,-}) -> param(vc_conn) {</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%);">+ last_n_sd := ConnectionTable[idx].n_sd;</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(BSSAP_LE_last_n_sd:{vc_conn, last_n_sd}) 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%);">+ [] PROC.getcall(BSSAP_LE_continue_after_n_sd:{?,?}) -> param(last_n_sd, vc_conn) {</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 := last_n_sd;</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(BSSAP_LE_continue_after_n_sd:{last_n_sd, 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%);">+/* send a raw (encoded) L3 message over given SCCP connection */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_xmit_raw_l3(integer sccp_conn_id, OCT1 dlci, octetstring l3_enc) runs on BSSAP_LE_Emulation_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP_LE bssap;</span><br><span style="color: hsl(120, 100%, 40%);">+ bssap := valueof(ts_BSSAP_LE_DTAP(l3_enc, dlci));</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE.send(ts_BSSAP_LE_DATA_req(sccp_conn_id, bssap));</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%);">+/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer n_sd_idx := f_ML3_n_sd_idx(dtap);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (n_sd_idx < 0) {</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%);">+ var uint2_t seq_nr := f_next_n_sd(cd.n_sd, n_sd_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ML3_patch_seq_nr(seq_nr, enc_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 main(BssapLeOps ops, charstring id) runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ g_ran_id := id;</span><br><span style="color: hsl(120, 100%, 40%);">+ g_ran_ops := ops;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_conn_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%);">+ if (isvalue(ops.sccp_addr_peer) and isvalue(ops.sccp_addr_local)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0); /* HACK to wait for M3UA/ASP to be ACTIVE */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_bssap_le_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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (true) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_DTAP_MO dtap_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_DTAP_MT dtap_mt;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_ConnHdlr vc_hdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring l3_info;</span><br><span style="color: hsl(120, 100%, 40%);">+ var hexstring imsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ var OCT4 tmsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer targetPointCode;</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%);">+ [] as_main_bssap_le();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ [g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MO:?) -> value dtap_mo sender vc_conn {</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%);">+ /* convert from decoded DTAP to encoded DTAP */</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring l3_enc := enc_PDU_ML3_MS_NW(dtap_mo.dtap);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* patch correct L3 send sequence number N(SD) into l3_enc */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (dtap_mo.skip_seq_patching == false) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ML3_patch_seq(ConnectionTable[idx], dtap_mo.dtap, l3_enc);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ f_xmit_raw_l3(ConnectionTable[idx].sccp_conn_id, dtap_mo.dlci, l3_enc);</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%);">+ [not g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MT:?) -> value dtap_mt sender vc_conn {</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%);">+ /* convert from decoded DTAP to encoded DTAP */</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring l3_enc := enc_PDU_ML3_NW_MS(dtap_mt.dtap);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_xmit_raw_l3(ConnectionTable[idx].sccp_conn_id, dtap_mt.dlci, l3_enc);</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%);">+ [] PROC.getcall(BSSAP_LE_register:{?,?}) -> param(l3_info, vc_hdlr) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_expect(l3_info, vc_hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(BSSAP_LE_register:{l3_info, vc_hdlr}) to vc_hdlr;</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%);">+ [] PROC.getcall(BSSAP_LE_register_handoverRequest:{?,?}) -> param(targetPointCode, vc_hdlr) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_expect(omit, vc_hdlr, targetPointCode);</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(BSSAP_LE_register_handoverRequest:{targetPointCode, vc_hdlr}) to vc_hdlr;</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%);">+ [] PROC.getcall(BSSAP_LE_register_imsi:{?,?,?}) -> param(imsi, tmsi, vc_hdlr) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_imsi(imsi, tmsi, vc_hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(BSSAP_LE_register_imsi:{imsi, tmsi, vc_hdlr}) to vc_hdlr;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * "Expect" Handling (mapping for expected incoming SCCP connections)</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%);">+/* data about an expected future incoming connection */</span><br><span style="color: hsl(120, 100%, 40%);">+type record ExpectData {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L3 payload based on which we can match it */</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring l3_payload optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer handoverRequestPointCode optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* component reference for this connection */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_LE_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%);">+/* procedure based port to register for incoming connections */</span><br><span style="color: hsl(120, 100%, 40%);">+signature BSSAP_LE_register(in octetstring l3, in BSSAP_LE_ConnHdlr hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+signature BSSAP_LE_register_handoverRequest(in integer targetPointCode, in BSSAP_LE_ConnHdlr hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* procedure based port to register for incoming IMSI/TMSI */</span><br><span style="color: hsl(120, 100%, 40%);">+signature BSSAP_LE_register_imsi(in hexstring imsi, in OCT4 tmsi, in BSSAP_LE_ConnHdlr hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* If DTAP happens across other channels (e.g. GSUP), provide manual advancing of the n_sd sequence number */</span><br><span style="color: hsl(120, 100%, 40%);">+signature BSSAP_LE_last_n_sd(in BSSAP_LE_ConnHdlr hdlr, out N_Sd_Array last_n_sd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Update conn's n_sd sequence nr after the connection was taken over from elsewhere */</span><br><span style="color: hsl(120, 100%, 40%);">+signature BSSAP_LE_continue_after_n_sd(N_Sd_Array last_n_sd, in BSSAP_LE_ConnHdlr hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type port BSSAP_LE_PROC_PT procedure {</span><br><span style="color: hsl(120, 100%, 40%);">+ inout BSSAP_LE_register, BSSAP_LE_register_imsi, BSSAP_LE_register_handoverRequest, BSSAP_LE_last_n_sd, BSSAP_LE_continue_after_n_sd;</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%);">+/* CreateCallback that can be used as create_cb and will use the expectation table */</span><br><span style="color: hsl(120, 100%, 40%);">+function ExpectedCreateCallback(BSSAP_LE_N_CONNECT_ind conn_ind, charstring id)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT return BSSAP_LE_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSAP_LE_ConnHdlr ret := null;</span><br><span style="color: hsl(120, 100%, 40%);">+ var 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%);">+ if (ischosen(conn_ind.userData.pdu.bssmap.perf_loc_req)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSMAP_LE_PerfLocReq plr := conn_ind.userData.pdu.bssmap.perf_loc_req;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (not ispresent(plr.imsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("ExpectedCreateCallback: Cannot handle PerformLocReq without 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%);">+ var hexstring imsi := plr.imsi.imsi.oddEvenInd_identity.imsi.digits;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Find the component by the IMSI [usually] contained in this message */</span><br><span style="color: hsl(120, 100%, 40%);">+ ret := f_imsi_table_find(imsi, omit);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret != null) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("ExpectedCreateCallback: Found ConnHdlr ", ret, " for IMSI ", imsi);</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%);">+ } else if (ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;</span><br><span style="color: hsl(120, 100%, 40%);">+ log("ExpectedCreateCallback completeLayer3Information");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3");</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(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 (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%);">+}</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(template octetstring l3, BSSAP_LE_ConnHdlr hdlr,</span><br><span style="color: hsl(120, 100%, 40%);">+ template integer handoverRequestPointCode := omit)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+ log("f_create_expect(l3 := ", l3, ", handoverRequest := ", handoverRequestPointCode);</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%);">+ and not ispresent(ExpectTable[i].handoverRequestPointCode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(l3)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ExpectTable[i].l3_payload := valueof(l3);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(handoverRequestPointCode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ExpectTable[i].handoverRequestPointCode := valueof(handoverRequestPointCode);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ExpectTable[i].vc_conn := hdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(handoverRequestPointCode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Created Expect[", i, "] for handoverRequest to be handled at ", hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</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 ExpectTable");</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_imsi(hexstring imsi, OCT4 tmsi, BSSAP_LE_ConnHdlr hdlr)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (not ispresent(ImsiTable[i].imsi)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ImsiTable[i].imsi := imsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ ImsiTable[i].tmsi := tmsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ ImsiTable[i].comp_ref := hdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Created IMSI[", i, "] for ", imsi, tmsi, " 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 ImsiTable");</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 BSSAP_LE_Emulation_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {</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].handoverRequestPointCode := 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%);">+/* helper function for clients to register their IMSI/TMSI */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_bssap_le_register_imsi(hexstring imsi, template (omit) OCT4 tmsi_or_omit)</span><br><span style="color: hsl(120, 100%, 40%);">+runs on BSSAP_LE_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ var OCT4 tmsi;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Resolve omit to a special reserved value */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (istemplatekind(tmsi_or_omit, "omit")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ tmsi := 'FFFFFFFF'O;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ tmsi := valueof(tmsi_or_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%);">+ BSSAP_LE_PROC.call(BSSAP_LE_register_imsi:{imsi, tmsi, self}) {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BSSAP_LE_PROC.getreply(BSSAP_LE_register_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%);">+}</span><br><span>diff --git a/library/RAN_Emulation.ttcnpp b/library/RAN_Emulation.ttcnpp</span><br><span>index c1dc036..f410427 100644</span><br><span>--- a/library/RAN_Emulation.ttcnpp</span><br><span>+++ b/library/RAN_Emulation.ttcnpp</span><br><span>@@ -720,7 +720,7 @@</span><br><span> </span><br><span> template BIT4 t_ML3_DISC_CC_MM_SS := ('0011'B, '0101'B, '1011'B);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-private function f_L3_is_rr(template octetstring l3) return boolean {</span><br><span style="color: hsl(120, 100%, 40%);">+function f_L3_is_rr(template octetstring l3) return boolean {</span><br><span> if (not isvalue(l3)) {</span><br><span> return false;</span><br><span> }</span><br><span>@@ -773,7 +773,7 @@</span><br><span> }</span><br><span> </span><br><span> /* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */</span><br><span style="color: hsl(0, 100%, 40%);">-function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {</span><br><span> var integer n_sd_idx := f_ML3_n_sd_idx(dtap);</span><br><span> if (n_sd_idx < 0) {</span><br><span> return;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/19765">change 19765</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/19765"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-ttcn3-hacks </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I92fd91056731abb8d3c01560f80c01c6a48a6fc9 </div>
<div style="display:none"> Gerrit-Change-Number: 19765 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>