First code commit
diff --git a/IP_Daemon_Dynamic_CNL113739.tpd b/IP_Daemon_Dynamic_CNL113739.tpd
new file mode 100644
index 0000000..9e2108b
--- /dev/null
+++ b/IP_Daemon_Dynamic_CNL113739.tpd
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TITAN_Project_File_Information version="1.0">
+ <ProjectName>IP_Daemon_Dynamic_CNL113739</ProjectName>
+ <ReferencedProjects>
+ <ReferencedProject name="IPL4asp_CNL113531" projectLocationURI="../../TestPorts/IPL4asp_CNL113531/IPL4asp_CNL113531.tpd"/>
+ <ReferencedProject name="Socket_API_CNL113686" projectLocationURI="../../TestPorts/Common_Components/Socket_API_CNL113686/Socket_API_CNL113686.tpd"/>
+ <ReferencedProject name="TCCUsefulFunctions_CNL113472_Common" projectLocationURI="../../Libraries/TCCUsefulFunctions_CNL113472/TCCUsefulFunctions_CNL113472_Common.tpd"/>
+ <ReferencedProject name="TCCUsefulFunctions_CNL113472_Interface" projectLocationURI="../../Libraries/TCCUsefulFunctions_CNL113472/TCCUsefulFunctions_CNL113472_Interface.tpd"/>
+ </ReferencedProjects>
+ <Folders>
+ <FolderResource projectRelativePath="doc" relativeURI="doc"/>
+ </Folders>
+ <Files>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic.cfg" relativeURI="demo/IP_Daemon_Dynamic.cfg"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic.ttcn" relativeURI="src/IP_Daemon_Dynamic.ttcn"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc" relativeURI="src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn" relativeURI="src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_Interface_Definitions.ttcn" relativeURI="src/IP_Daemon_Dynamic_Interface_Definitions.ttcn"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_Types.ttcn" relativeURI="src/IP_Daemon_Dynamic_Types.ttcn"/>
+ <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_FS.doc" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_FS.doc"/>
+ <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_FS.pdf" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_FS.pdf"/>
+ <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_PRI.doc" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_PRI.doc"/>
+ <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_PRI.pdf" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_PRI.pdf"/>
+ <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_UG.doc" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_UG.doc"/>
+ <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_UG.pdf" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_UG.pdf"/>
+ <FileResource projectRelativePath="doc/IR_doc.doc" relativeURI="doc/IR_doc.doc"/>
+ <FileResource projectRelativePath="doc/IR_src.doc" relativeURI="doc/IR_src.doc"/>
+ </Files>
+ <ActiveConfiguration>Default</ActiveConfiguration>
+ <Configurations>
+ <Configuration name="Default">
+ <ProjectProperties>
+ <MakefileSettings>
+ <generateInternalMakefile>true</generateInternalMakefile>
+ <GNUMake>true</GNUMake>
+ <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+ <singleMode>true</singleMode>
+ <targetExecutable>bin/IP_Daemon_Dynamic_CNL113739</targetExecutable>
+ <preprocessorDefines>
+ <listItem>LKSCTP_1_0_9</listItem>
+ </preprocessorDefines>
+ </MakefileSettings>
+ <LocalBuildSettings>
+ <workingDirectory>bin</workingDirectory>
+ </LocalBuildSettings>
+ <NamingCoventions>
+ <enableProjectSpecificSettings>true</enableProjectSpecificSettings>
+ <function>.*</function>
+ <externalFunction>.*</externalFunction>
+ <localVariable>.*</localVariable>
+ <formalParameter>.*</formalParameter>
+ </NamingCoventions>
+ <ConfigurationRequirements>
+ <configurationRequirement>
+ <projectName>IPL4asp_CNL113531</projectName>
+ <rerquiredConfiguration>SSL_SCTP109</rerquiredConfiguration>
+ </configurationRequirement>
+ </ConfigurationRequirements>
+ </ProjectProperties>
+ <FolderProperties>
+ <FolderResource>
+ <FolderPath>doc</FolderPath>
+ <FolderProperties>
+ <ExcludeFromBuild>true</ExcludeFromBuild>
+ </FolderProperties>
+ </FolderResource>
+ </FolderProperties>
+ </Configuration>
+ </Configurations>
+</TITAN_Project_File_Information>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3534f2f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0
+
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+ PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+ OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial content
+ Distributed under this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+ where such changes and/or additions to the Program originate from
+ and are Distributed by that particular Contributor. A Contribution
+ "originates" from a Contributor if it was added to the Program by
+ such Contributor itself or anyone acting on such Contributor's behalf.
+ Contributions do not include changes or additions to the Program that
+ are not Modified Works.
+
+"Contributor" means any person or entity that Distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions Distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement
+or any Secondary License (as applicable), including Contributors.
+
+"Derivative Works" shall mean any work, whether in Source Code or other
+form, that is based on (or derived from) the Program and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship.
+
+"Modified Works" shall mean any work in Source Code or other form that
+results from an addition to, deletion from, or modification of the
+contents of the Program, including, for purposes of clarity any new file
+in Source Code form that contains any contents of the Program. Modified
+Works shall not include works that contain only declarations,
+interfaces, types, classes, structures, or files of the Program solely
+in each case in order to link to, bind by name, or subclass the Program
+or Modified Works thereof.
+
+"Distribute" means the acts of a) distributing or b) making available
+in any manner that enables the transfer of a copy.
+
+"Source Code" means the form of a Program preferred for making
+modifications, including but not limited to software source code,
+documentation source, and configuration files.
+
+"Secondary License" means either the GNU General Public License,
+Version 2.0, or any later versions of that license, including any
+exceptions or additional permissions as identified by the initial
+Contributor.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free copyright
+ license to reproduce, prepare Derivative Works of, publicly display,
+ publicly perform, Distribute and sublicense the Contribution of such
+ Contributor, if any, and such Derivative Works.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free patent
+ license under Licensed Patents to make, use, sell, offer to sell,
+ import and otherwise transfer the Contribution of such Contributor,
+ if any, in Source Code or other form. This patent license shall
+ apply to the combination of the Contribution and the Program if, at
+ the time the Contribution is added by the Contributor, such addition
+ of the Contribution causes such combination to be covered by the
+ Licensed Patents. The patent license shall not apply to any other
+ combinations which include the Contribution. No hardware per se is
+ licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the
+ licenses to its Contributions set forth herein, no assurances are
+ provided by any Contributor that the Program does not infringe the
+ patent or other intellectual property rights of any other entity.
+ Each Contributor disclaims any liability to Recipient for claims
+ brought by any other entity based on infringement of intellectual
+ property rights or otherwise. As a condition to exercising the
+ rights and licenses granted hereunder, each Recipient hereby
+ assumes sole responsibility to secure any other intellectual
+ property rights needed, if any. For example, if a third party
+ patent license is required to allow Recipient to Distribute the
+ Program, it is Recipient's responsibility to acquire that license
+ before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has
+ sufficient copyright rights in its Contribution, if any, to grant
+ the copyright license set forth in this Agreement.
+
+ e) Notwithstanding the terms of any Secondary License, no
+ Contributor makes additional grants to any Recipient (other than
+ those set forth in this Agreement) as a result of such Recipient's
+ receipt of the Program under the terms of a Secondary License
+ (if permitted under the terms of Section 3).
+
+3. REQUIREMENTS
+
+3.1 If a Contributor Distributes the Program in any form, then:
+
+ a) the Program must also be made available as Source Code, in
+ accordance with section 3.2, and the Contributor must accompany
+ the Program with a statement that the Source Code for the Program
+ is available under this Agreement, and informs Recipients how to
+ obtain it in a reasonable manner on or through a medium customarily
+ used for software exchange; and
+
+ b) the Contributor may Distribute the Program under a license
+ different than this Agreement, provided that such license:
+ i) effectively disclaims on behalf of all other Contributors all
+ warranties and conditions, express and implied, including
+ warranties or conditions of title and non-infringement, and
+ implied warranties or conditions of merchantability and fitness
+ for a particular purpose;
+
+ ii) effectively excludes on behalf of all other Contributors all
+ liability for damages, including direct, indirect, special,
+ incidental and consequential damages, such as lost profits;
+
+ iii) does not attempt to limit or alter the recipients' rights
+ in the Source Code under section 3.2; and
+
+ iv) requires any subsequent distribution of the Program by any
+ party to be under a license that satisfies the requirements
+ of this section 3.
+
+3.2 When the Program is Distributed as Source Code:
+
+ a) it must be made available under this Agreement, or if the
+ Program (i) is combined with other material in a separate file or
+ files made available under a Secondary License, and (ii) the initial
+ Contributor attached to the Source Code the notice described in
+ Exhibit A of this Agreement, then the Program may be made available
+ under the terms of such Secondary Licenses, and
+
+ b) a copy of this Agreement must be included with each copy of
+ the Program.
+
+3.3 Contributors may not remove or alter any copyright, patent,
+trademark, attribution notices, disclaimers of warranty, or limitations
+of liability ("notices") contained within the Program from any copy of
+the Program which they Distribute, provided that Contributors may add
+their own appropriate notices.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program,
+the Contributor who includes the Program in a commercial product
+offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes
+the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and indemnify every
+other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits
+and other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the Program
+in a commercial product offering. The obligations in this section do not
+apply to any claims or Losses relating to any actual or alleged
+intellectual property infringement. In order to qualify, an Indemnified
+Contributor must: a) promptly notify the Commercial Contributor in
+writing of such claim, and b) allow the Commercial Contributor to control,
+and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those performance
+claims and warranties, and if a court requires any other Contributor to
+pay any damages as a result, the Commercial Contributor must pay
+those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE. Each Recipient is solely responsible for determining the
+appropriateness of using and distributing the Program and assumes all
+risks associated with its exercise of rights under this Agreement,
+including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs
+or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software
+or hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably practicable.
+However, Recipient's obligations under this Agreement and any licenses
+granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+Distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to Distribute the Program (including its
+Contributions) under the new version.
+
+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+receives no rights or licenses to the intellectual property of any
+Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted
+under this Agreement are reserved. Nothing in this Agreement is intended
+to be enforceable by any entity that is not a Contributor or Recipient.
+No third-party beneficiary rights are created under this Agreement.
+
+Exhibit A - Form of Secondary Licenses Notice
+
+"This Source Code may also be made available under the following
+Secondary Licenses when the conditions for such availability set forth
+in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+version(s), and exceptions or additional permissions here}."
+
+ Simply including a copy of this Agreement, including this Exhibit A
+ is not sufficient to license the Source Code under Secondary Licenses.
+
+ If it is not possible or desirable to put the notice in a particular
+ file, then You may include the notice in a location (such as a LICENSE
+ file in a relevant directory) where a recipient would be likely to
+ look for such a notice.
+
+ You may add additional accurate notices of copyright ownership.
\ No newline at end of file
diff --git a/demo/IP_Daemon_Dynamic.cfg b/demo/IP_Daemon_Dynamic.cfg
new file mode 100644
index 0000000..3b97817
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic.cfg
@@ -0,0 +1,72 @@
+[MODULE_PARAMETERS]
+tsp_IPDD_ConnectionList :=
+{
+ {
+ serverConnection := true, // true := server, false: client
+ autoReconnect := false,
+ localInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "127.0.0.1",
+ portNumber := 33333//(1..65535)
+ },
+ remoteInterface := omit,
+ proto := udp//tcp//sctp
+ },
+ {
+ serverConnection := false, // true := server, false: client
+ autoReconnect := false,
+ localInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "127.0.0.1",
+ portNumber := 60000//(1..65535)
+ },
+ remoteInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "127.0.0.1",
+ portNumber := 33333//(1..65535)
+ },
+ proto := udp//tcp//sctp
+ },
+ {
+ serverConnection := false, // true := server, false: client
+ autoReconnect := false,
+ localInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "127.0.0.1",
+ portNumber := 60001//(1..65535)
+ },
+ remoteInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "127.0.0.1",
+ portNumber := 33333//(1..65535)
+ },
+ proto := udp//tcp//sctp
+ }
+};
+
+[LOGGING]
+MatchingHints := Compact
+AppendFile := No
+TimeStampFormat := Time
+LogEntityName := Yes
+LogEventTypes := Yes
+LogFile := "ip_daemon.log"
+SourceInfoFormat := Stack
+ConsoleMask := STATISTICS|TESTCASE|ACTION|WARNING|ERROR|USER
+FileMask :=DEBUG|WARNING|VERDICTOP|USER|TIMEROP|TESTCASE|STATISTICS|PORTEVENT|PARALLEL|FUNCTION|EXECUTOR|ERROR|DEFAULTOP|ACTION
+DiskFullAction := Error
+LogFileNumber := 1
+LogFileSize := 0
+
+[TESTPORT_PARAMETERS]
+*.IP_PCO.pureNonBlocking := "NO"
+*.IP_PCO.debug := "YES"
+
+[EXECUTE]
+IP_Daemon_Dynamic.tc_IPDD
+//IP_Daemon_Dynamic_with_DiameterAutoReplies
diff --git a/demo/IP_Daemon_Dynamic_CNL113739_demo.tpd b/demo/IP_Daemon_Dynamic_CNL113739_demo.tpd
new file mode 100644
index 0000000..0cc2093
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_CNL113739_demo.tpd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TITAN_Project_File_Information version="1.0">
+ <ProjectName>IP_Daemon_Dynamic_CNL113739_demo</ProjectName>
+ <ReferencedProjects>
+ <ReferencedProject name="IP_Daemon_Dynamic_CNL113739" projectLocationURI="../IP_Daemon_Dynamic_CNL113739.tpd"/>
+ </ReferencedProjects>
+ <Files>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic.cfg" relativeURI="IP_Daemon_Dynamic.cfg"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_Test.cfg" relativeURI="IP_Daemon_Dynamic_Test.cfg"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_Test.ttcn" relativeURI="IP_Daemon_Dynamic_Test.ttcn"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn" relativeURI="IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn"/>
+ <FileResource projectRelativePath="IP_Daemon_Dynamic_with_StartupCallback.ttcn" relativeURI="IP_Daemon_Dynamic_with_StartupCallback.ttcn"/>
+ </Files>
+ <ActiveConfiguration>Default</ActiveConfiguration>
+ <Configurations>
+ <Configuration name="Default">
+ <ProjectProperties>
+ <MakefileSettings>
+ <generateInternalMakefile>true</generateInternalMakefile>
+ <GNUMake>true</GNUMake>
+ <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+ <singleMode>true</singleMode>
+ <targetExecutable>bin/IP_Daemon_Dynamic_CNL113739_demo</targetExecutable>
+ </MakefileSettings>
+ <LocalBuildSettings>
+ <workingDirectory>bin</workingDirectory>
+ </LocalBuildSettings>
+ </ProjectProperties>
+ </Configuration>
+ </Configurations>
+</TITAN_Project_File_Information>
\ No newline at end of file
diff --git a/demo/IP_Daemon_Dynamic_Test.cfg b/demo/IP_Daemon_Dynamic_Test.cfg
new file mode 100644
index 0000000..1854ded
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_Test.cfg
@@ -0,0 +1,35 @@
+[LOGGING]
+LogFile := "ip_daemon_test_%p.log"
+TimeStampFormat := Time
+LogEntityName := Yes
+LogEventTypes := Yes
+SourceInfoFormat := Stack
+ConsoleMask := STATISTICS|TESTCASE|ACTION|WARNING|ERROR|USER
+FileMask := DEBUG|WARNING|VERDICTOP|USER|TIMEROP|TESTCASE|STATISTICS|PORTEVENT|PARALLEL|FUNCTION|EXECUTOR|ERROR|DEFAULTOP|ACTION
+DiskFullAction := Error
+LogFileNumber := 1
+LogFileSize := 0
+
+[TESTPORT_PARAMETERS]
+*.daemonPort.debug := "YES"
+*.IP_PCO.debug := "YES"
+
+[EXECUTE]
+//*** SCTP testcases
+IP_Daemon_Dynamic_Test.tc_Init_SCTP_ClientServer_StopServer_CheckClientConnChange
+//IP_Daemon_Dynamic_Test.tc_Init_SCTP_ClientServer_CheckClientConnChange_StopServer_CheckClientConnChange_StartServer_CheckClientConnChange
+//IP_Daemon_Dynamic_Test.tc_Init_SCTP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer
+//IP_Daemon_Dynamic_Test.tc_3_SCTP_Servers_and_3_SCTP_Clients
+//..Run this testcase only with IP_Daemon_Dynamic_with_DiameterAutoReplies
+//IP_Daemon_Dynamic_Test.tc_SCTP_AutoReplyDeviceWatchdog
+
+//*** TCP testcases
+//IP_Daemon_Dynamic_Test.tc_Init_TCP_ClientServer_StopServer_CheckClientConnClosed
+//IP_Daemon_Dynamic_Test.tc_Init_TCP_CLientServer_SendDataFromClient_CheckDataReceiveOnServer
+//IP_Daemon_Dynamic_Test.tc_Init_TCP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer
+//IP_Daemon_Dynamic_Test.tc_2_TCP_Servers_and_2_TCP_Clients
+//..Run this testcase only with IP_Daemon_Dynamic_with_DiameterAutoReplies
+//IP_Daemon_Dynamic_Test.tc_TCP_AutoReplyDeviceWatchdog
+
+//*** UDP testcases
+//IP_Daemon_Dynamic_Test.tc_Init_2_UDP_Clients_sendData_checkDataReceived
diff --git a/demo/IP_Daemon_Dynamic_Test.ttcn b/demo/IP_Daemon_Dynamic_Test.ttcn
new file mode 100644
index 0000000..289dc44
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_Test.ttcn
@@ -0,0 +1,1083 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: IP_Daemon_Dynamic_Test.ttcn
+// Description: IPDD test
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2012-05-07
+// Contact: http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_Test
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+import from IP_Daemon_Dynamic_IPL4_CtrlFunct all;
+//=========================================================================
+// Module Parameters
+//=========================================================================
+
+modulepar {
+
+ // Host name where the IP Daemon listens for the testcases
+ charstring tsp_IPDD_Host := "127.0.0.1";
+
+ // Port number where the IP Daemon listens for the testcases
+ integer tsp_IPDD_Port := 1314;
+
+ charstring tsp_serverInterface := "127.0.0.1";
+ integer tsp_serverPort := 1315;
+}
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record of integer clientConnectionIds;
+
+//=========================================================================
+//Port Types
+//=========================================================================
+
+// Insert port type defintions here if applicable!
+// You can use the port_type skeleton!
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+type component MAIN_CT {
+ port IPDD_Interface_PT daemonPort;
+
+ var IPDD_Message_with_ClientId vc_daemonMessage;
+
+ var clientConnectionIds vc_clientConnIds := {};
+
+ var integer vc_tcp_client_id;
+ var integer vc_serverConnectionId := -1;
+ var integer vc_clientConnectionId := -1;
+ var integer vc_connectedClientConnectionId := -1;
+ var boolean vc_isClientConnected := false;
+}
+
+//=========================================================================
+// Constants
+//=========================================================================
+
+// Insert constants here if applicable!
+// You can use the constant skeleton!
+
+//=========================================================================
+// Templates
+//=========================================================================
+
+// Insert templates here if applicable!
+// You can use the template skeleton!
+
+//=========================================================================
+// Altsteps
+//=========================================================================
+
+// Insert altsteps here if applicable!
+// You can use the altstep skeleton!
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_Connect_to_IPDD() runs on MAIN_CT {
+ timer t_wait;
+
+ var Result vl_result := { errorCode := omit, connId := omit, os_error_code:=omit, os_error_text:= omit };
+
+ vl_result := IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_connect
+ (
+ daemonPort,
+ tsp_IPDD_Host,
+ tsp_IPDD_Port,
+ tsp_serverInterface,
+ 0,
+ connId := -1,
+ proto := { tcp := {} },
+ options := {}
+ );
+ if ((vl_result.errorCode == omit) or (vl_result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE)) { //if not error
+ log("Connected to the IP Daemon on " & tsp_IPDD_Host & ":" & int2str(tsp_IPDD_Port));
+ vc_tcp_client_id := vl_result.connId;
+
+ var f_IPL4_getMsgLen sdd_msglen := refers(f_IPDD_getMsgLen);
+ f_IPL4_setGetMsgLen(daemonPort, vc_tcp_client_id,sdd_msglen, {});
+
+ }else{
+ log("Could not connect to the IP Daemon on " & tsp_IPDD_Host & ":" & int2str(tsp_IPDD_Port));
+ }
+}
+
+// initialize a server and a client connection if they are not already present
+function f_Init_IP_Client(in charstring remoteIf, in integer remotePort, in ProtoTupleEnum proto) runs on MAIN_CT {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+ timer t_wait := 5.0; t_wait.start;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+
+ vc_clientConnectionId := -1;
+
+ for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+ if((vc_clientConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface)) {
+ if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.hostName == remoteIf and
+ vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.portNumber == remotePort) {
+ vc_clientConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+ }
+ }
+ }
+
+ if(vc_clientConnectionId < 0) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_connect := {
+ messageType := 0, // use dummy value
+ autoReconnect := true,
+ localInterfacePresent := false, // enter always false
+ localInterface :={
+ hostNameLength := 0, // use dummy value
+ hostName := remoteIf,
+ portNumber := 0
+ },
+ remoteInterface := {
+ hostNameLength := 0, // use dummy value
+ hostName := remoteIf,
+ portNumber := remotePort
+ },
+ proto := proto,
+ sctpProtoAttributesPresent := false,
+ sctpProtoAttributes := omit
+ }
+ }});
+
+ t_wait.stop; t_wait.start;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_result := ? } }) -> value vc_daemonMessage {
+ if(not vc_daemonMessage.msg.ipdd_result.errorStatus) {
+ vc_clientConnectionId := vc_daemonMessage.msg.ipdd_result.connectionId;
+ } else {
+ log("*** ERROR: error response received for f_Init_IP_Client: " ,vc_daemonMessage.msg.ipdd_result);
+ setverdict(fail);
+ }
+ repeat;
+ }
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_connected := ? } }) -> value vc_daemonMessage {
+ log("*** INFO: client connected: ", vc_daemonMessage);
+ vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connected.connectionId;
+ vc_isClientConnected := true;
+ repeat;
+ }
+ [] t_wait.timeout {
+ if((vc_clientConnectionId == -1) and (vc_connectedClientConnectionId == -1)){
+ log("*** ERROR: no response to f_Init_IP_Client!");
+ setverdict(fail);
+ }
+ }
+ }
+ } else {
+ log("*** INFO: client connection is already defined, subscribing to it...");
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_subscribeToConnection := {
+ messageType := 0,
+ connectionId := vc_clientConnectionId
+ }
+ }
+ });
+ }
+ }
+
+ [] daemonPort.receive {
+ log("*** INFO: message ignored.");
+ }
+
+ [] t_wait.timeout {
+ log("*** ERROR: there is no response for connection list query!");
+ }
+ }
+ log("vc_clientConnectionId: ",vc_clientConnectionId);
+ log("vc_connectedClientConnectionId: ",vc_connectedClientConnectionId);
+}
+
+function f_Init_IP_Server(in charstring localIf, in integer localPort, in ProtoTupleEnum pl_proto) runs on MAIN_CT {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+ timer t_wait := 5.0; t_wait.start;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+
+ vc_serverConnectionId := -1;
+ vc_connectedClientConnectionId := -1;
+
+ for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+ if((vc_serverConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface)) {
+ if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].serverConnection and
+ vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.hostName == localIf and
+ vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.portNumber == localPort) {
+ vc_serverConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+ }
+ }
+
+ // connected client: not server and the local interface is the same as the server's local interface
+ if((vc_connectedClientConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface)) {
+ if(not vc_daemonMessage.msg.ipdd_connections.connectionList[i].serverConnection and
+ vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.hostName == localIf and
+ vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.portNumber == localPort) {
+ vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+ }
+ }
+ }
+
+ if(vc_connectedClientConnectionId > -1) {
+ log("*** INFO: server's connected client connection is already present, subscribing to it...");
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_subscribeToConnection := {
+ messageType := 0,
+ connectionId := vc_connectedClientConnectionId
+ }
+ }
+ });
+ }
+
+ if(vc_serverConnectionId < 0) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_listen := {
+ messageType := 0, // use dummy value
+ localInterface := {
+ hostNameLength := 0, // use dummy value
+ hostName := localIf,
+ portNumber := localPort
+ },
+ proto := pl_proto,
+ sctpProtoAttributesPresent := false,
+ sctpProtoAttributes := omit
+ }
+ } });
+
+ t_wait.stop; t_wait.start;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_result := ? } }) -> value vc_daemonMessage {
+ log("*** INFO: received result message: ",vc_daemonMessage);
+ if(not vc_daemonMessage.msg.ipdd_result.errorStatus) {
+ vc_serverConnectionId := vc_daemonMessage.msg.ipdd_result.connectionId;
+ } else {
+ log("*** ERROR: error response received for f_Init_IP_Server: ", vc_daemonMessage.msg.ipdd_result);
+ setverdict(fail);
+ }
+ }
+ [] daemonPort.receive(IPDD_Message_with_ClientId : ?) {
+ log("*** INFO: message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** ERROR: no response to f_Init_IP_Server!");
+ setverdict(fail);
+ }
+ }
+ } else {
+ log("*** INFO: server connection is already defined, subscribing to it...");
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_subscribeToConnection := {
+ messageType := 0,
+ connectionId := vc_serverConnectionId
+ }
+ }
+ });
+ }
+ }
+
+ [] daemonPort.receive {
+ log("*** INFO: message ignored.");
+ repeat;
+ }
+
+ [] t_wait.timeout {
+ log("*** ERROR: there is no response for connection list query!");
+ }
+ }
+ log("vc_serverConnectionId: ",vc_serverConnectionId);
+ log("vc_connectedClientConnectionId: ",vc_connectedClientConnectionId);
+}
+
+function f_StopServer() runs on MAIN_CT {
+ if(vc_connectedClientConnectionId > 0) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_close := { messageType := 0, connectionId := vc_connectedClientConnectionId }
+ }});
+ }
+
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_close := { messageType := 0, connectionId := vc_serverConnectionId }
+ }});
+}
+
+function f_StopClient() runs on MAIN_CT {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_close := { messageType := 0, connectionId := vc_clientConnectionId }
+ }});
+}
+
+function f_StopMultipleClients() runs on MAIN_CT {
+ for(var integer i := 0; i < sizeof(vc_clientConnIds); i := i + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_close := { messageType := 0, connectionId := vc_clientConnIds[i] }
+ }});
+ }
+
+ vc_clientConnIds := {};
+}
+
+// initialize a server and a client connection if they are not already present
+function f_StopMyConnections() runs on MAIN_CT {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+ timer t_wait := 5.0; t_wait.start;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+ log("*** INFO: current ipdd_connections: ", vc_daemonMessage.msg.ipdd_connections.connectionList);
+ vc_clientConnectionId := -1;
+ for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+ if(ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface)) {
+ if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.hostName == tsp_serverInterface) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_close := { messageType := 0, connectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId }
+ }});
+ }
+ }
+
+ if(ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface)) {
+ if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.hostName == tsp_serverInterface) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_close := { messageType := 0, connectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId }
+ }});
+ }
+ }
+ }
+ }
+
+ [] t_wait.timeout {
+ log("*** ERROR: there is no response for connection list query!");
+ }
+ }
+}
+
+function f_CheckClientConnection_Gets(in SAC_STATE pl_state) runs on MAIN_CT {
+ timer t_wait := 55.0; t_wait.start;
+
+ log("*** INFO: waiting client connection #", vc_clientConnectionId, " to report state: ", pl_state, ".");
+
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_connectionChanged := {
+ messageType := ?,
+ connectionId := vc_clientConnectionId,
+ eventPresent := false,
+ event := omit,
+ sctpStatePresent := true,
+ sctpState := pl_state
+ }
+ }
+ }) {
+ log("*** PASS: connectionChanged ", pl_state, " received!");
+ setverdict(pass);
+ }
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_connected := ? } }) -> value vc_daemonMessage {
+ log("*** INFO: client connected: ", vc_daemonMessage);
+ vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connected.connectionId;
+ repeat;
+ }
+ [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+ log("*** INFO: message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** FAIL: no connectionChanged ", pl_state," received!");
+ setverdict(fail);
+ }
+ }
+}
+
+function f_serverWaitForConnection() runs on MAIN_CT {
+ timer t_wait := 55.0; t_wait.start;
+ log("*** INFO: waiting for client connection...");
+ var IPDD_Message_with_ClientId vl_msg;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_connected := ?
+ }
+ }) -> value vl_msg
+ {
+ log("*** PASS: Connected! ");
+ vc_serverConnectionId := vl_msg.msg.ipdd_connected.connectionId;
+ setverdict(pass);
+ }
+ [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+ log("*** INFO: message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** FAIL: no connection was received!");
+ setverdict(fail);
+ }
+ }
+}
+
+function f_sendDataFromClient(in octetstring dataToSend, in ProtoTupleEnum proto) runs on MAIN_CT {
+ if(proto == sctp) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_clientConnectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := 22
+ },
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+ }
+ if(proto == tcp or proto == udp) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_clientConnectionId,
+ sctpAttributesPresent := false,
+ sctpAttributes := omit,
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+ }
+}
+
+function f_sendDataFromServer(in octetstring dataToSend, in ProtoTupleEnum proto) runs on MAIN_CT {
+ if(proto == sctp) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_serverConnectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := 22
+ },
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+ }
+ if(proto == tcp or proto == udp) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_serverConnectionId,
+ sctpAttributesPresent := false,
+ sctpAttributes := omit,
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+ }
+}
+
+function f_sendData(in integer connId, in octetstring dataToSend, in ProtoTupleEnum proto) runs on MAIN_CT {
+ if(proto == sctp) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := connId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := 22
+ },
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+ }
+ if(proto == tcp or proto == udp) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := connId,
+ sctpAttributesPresent := false,
+ sctpAttributes := omit,
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+ }
+}
+
+function f_CheckDataReceive(in integer connectionId, in octetstring dataToReceive) runs on MAIN_CT {
+ timer t_wait := 5.0; t_wait.start;
+
+ log("*** INFO: waiting for incoming data: ", dataToReceive, "...");
+
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_data := {
+ messageType := ?,
+ connectionId := connectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := ? //22
+ },
+ dataLength := ?,
+ data := dataToReceive
+ }
+ }
+ }) {
+ log("*** PASS: ipdd_data ", dataToReceive, " received!");
+ setverdict(pass);
+ }
+
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_data := {
+ messageType := ?,
+ connectionId := connectionId,
+ sctpAttributesPresent := false,
+ sctpAttributes := omit,
+ dataLength := ?,
+ data := dataToReceive
+ }
+ }
+ }) {
+ log("*** PASS: ipdd_data ", dataToReceive, " received!");
+ setverdict(pass);
+ }
+
+ [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+ log("*** INFO: message ignored.");
+ repeat;
+ }
+
+ [] t_wait.timeout {
+ log("*** FAIL: no ipdd_data ", dataToReceive, " received!");
+ setverdict(fail);
+ }
+ }
+}
+
+function f_CheckDataReceive_noOtherData(in template integer connectionId, in template octetstring dataToReceive) runs on MAIN_CT {
+ timer t_wait := 5.0; t_wait.start;
+
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_data := {
+ messageType := ?,
+ connectionId := connectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := ? //22
+ },
+ dataLength := ?,
+ data := dataToReceive
+ }
+ }
+ }) {
+ log("*** PASS: ipdd_data ", dataToReceive, " received!");
+ setverdict(pass);
+ }
+
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_data := {
+ messageType := ?,
+ connectionId := connectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := ? //22
+ },
+ dataLength := ?,
+ data := ?
+ }
+ }
+ }) {
+ log("*** FAIL: invalid ipdd_data received!");
+ setverdict(fail);
+ repeat;
+ }
+
+ [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+ log("*** INFO: message ignored.");
+ repeat;
+ }
+
+ [] t_wait.timeout {
+ log("*** FAIL: no ipdd_data ", dataToReceive, " received!");
+ setverdict(fail);
+ }
+ }
+}
+
+function f_ServerEchoBack(in float p_serviceTime := 5.0) runs on MAIN_CT {
+ timer t_wait := p_serviceTime; t_wait.start;
+
+ var IPDD_Message_with_ClientId vl_inc;
+
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_data := {
+ messageType := ?,
+ connectionId := ?,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := ? //22
+ },
+ dataLength := ?,
+ data := ?
+ }
+ }
+ }) -> value vl_inc
+ {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_serverConnectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := 11,
+ sinfo_ppid := 22
+ },
+ dataLength := 0, // encoder will replace
+ data := vl_inc.msg.ipdd_data.data
+ }
+ }});
+ repeat;
+ }
+
+ [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+ log("*** INFO: message ignored in Echo mode.");
+ repeat;
+ }
+
+ [] t_wait.timeout {
+ log("*** INFO: exiting from echo service.");
+ }
+ }
+}
+
+function f_Check_ConnClosed_Received(in integer pl_connId) runs on MAIN_CT {
+ timer t := 5.0; t.start;
+
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ ipdd_closed := {
+ messageType := ?,
+ connectionId := pl_connId
+ }
+ }
+ }) {
+ log("*** PASS: ipdd_closed message from IPDD received for connectionId: ", pl_connId, "!");
+ setverdict(pass);
+ t.stop; t.start;
+ repeat;
+ }
+
+ [] daemonPort.receive {
+ log("*** INFO: message ignored.");
+ repeat;
+ }
+
+ [] t.timeout {
+ log("*** INFO: no more relevant messages received.");
+ }
+ }
+}
+
+function f_Init_IP_Client_with_localInterface(
+ in charstring localIf, in integer localPort, in charstring remoteIf, in integer remotePort, in ProtoTupleEnum proto) runs on MAIN_CT {
+
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+ timer t_wait := 5.0; t_wait.start;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+
+ vc_clientConnectionId := -1;
+
+ for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+ if((vc_clientConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface)) {
+ if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.hostName == remoteIf and
+ vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.portNumber == remotePort) {
+ vc_clientConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+ }
+ }
+ }
+
+ if(vc_clientConnectionId < 0) {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_connect := {
+ messageType := 0, // use dummy value
+ autoReconnect := true,
+ localInterfacePresent := true,
+ localInterface :={
+ hostNameLength := 0, // use dummy value
+ hostName := localIf,
+ portNumber := localPort
+ },
+ remoteInterface := {
+ hostNameLength := 0, // use dummy value
+ hostName := remoteIf,
+ portNumber := remotePort
+ },
+ proto := proto,
+ sctpProtoAttributesPresent := false,
+ sctpProtoAttributes := omit
+ }
+ }});
+
+ t_wait.stop; t_wait.start;
+ alt {
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_result := ? } }) -> value vc_daemonMessage {
+ if(not vc_daemonMessage.msg.ipdd_result.errorStatus) {
+ vc_clientConnectionId := vc_daemonMessage.msg.ipdd_result.connectionId;
+ vc_clientConnIds[sizeof(vc_clientConnIds)] := vc_clientConnectionId;
+ } else {
+ log("*** ERROR: error response received for ipdd_connect: " ,vc_daemonMessage.msg.ipdd_result);
+ setverdict(fail);
+ }
+ repeat;
+ }
+ [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_connected := ? } }) -> value vc_daemonMessage {
+ log("*** INFO: client connected: ", vc_daemonMessage);
+ vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connected.connectionId;
+ vc_isClientConnected := true;
+ repeat;
+ }
+ [] t_wait.timeout {
+ if((vc_clientConnectionId == -1) and (vc_connectedClientConnectionId == -1)){
+ log("*** ERROR: no response to ipdd_connect!");
+ setverdict(fail);
+ }
+ }
+ }
+ } else {
+ log("*** INFO: client connection is already defined, subscribing to it...");
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+ ipdd_subscribeToConnection := {
+ messageType := 0,
+ connectionId := vc_clientConnectionId
+ }
+ }
+ });
+ }
+ }
+
+ [] daemonPort.receive {
+ log("*** INFO: message ignored.");
+ }
+
+ [] t_wait.timeout {
+ log("*** ERROR: there is no response for connection list query!");
+ }
+ }
+ log("vc_clientConnectionId: ",vc_clientConnectionId);
+ log("vc_connectedClientConnectionId: ",vc_connectedClientConnectionId);
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_Init_2_UDP_Clients_sendData_checkDataReceived() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort, tsp_serverInterface, tsp_serverPort + 1, udp);
+ f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort + 1, tsp_serverInterface, tsp_serverPort, udp);
+
+ f_sendData(vc_clientConnIds[0], '0123456789ABCDEF'O, udp);
+
+ f_CheckDataReceive(vc_clientConnIds[1], '0123456789ABCDEF'O);
+
+ f_StopMultipleClients();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_TCP_ClientServer_StopServer_CheckClientConnClosed() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+ f_StopServer();
+
+ f_Check_ConnClosed_Received(vc_clientConnectionId);
+
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_SCTP_ClientServer_StopServer_CheckClientConnChange() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+ f_StopServer();
+
+ f_CheckClientConnection_Gets(SCTP_COMM_LOST);
+
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_SCTP_ClientServer_CheckClientConnChange_StopServer_CheckClientConnChange_StartServer_CheckClientConnChange() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+ f_CheckClientConnection_Gets(SCTP_COMM_UP);
+
+ f_StopServer();
+ f_CheckClientConnection_Gets(SCTP_COMM_LOST);
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_CheckClientConnection_Gets(SCTP_COMM_UP);
+
+ f_StopClient();
+ f_StopServer();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_TCP_CLientServer_SendDataFromClient_CheckDataReceiveOnServer() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+ f_sendDataFromClient('DB4720FFCA'O, sctp);
+
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'DB4720FFCA'O);
+
+ f_StopClient();
+ f_StopServer();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_SCTP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+ // could be sending ASP_TCP_Close too
+ unmap(mtc:daemonPort, system:daemonPort);
+
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+ f_sendDataFromClient('EEDDAADD'O, sctp);
+
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD'O);
+
+ f_StopServer();
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_TCP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+ // could be sending ASP_TCP_Close too
+ unmap(mtc:daemonPort, system:daemonPort);
+
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+ f_sendDataFromClient('DF07A9FB'O, tcp);
+
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'DF07A9FB'O);
+
+ f_StopServer();
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_3_SCTP_Servers_and_3_SCTP_Clients() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ vc_connectedClientConnectionId := -1;
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort + 2, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort + 2, sctp);
+ f_sendDataFromClient('EEDDAADD00'O, sctp);
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD00'O);
+
+ vc_connectedClientConnectionId := -1;
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort + 1, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort + 1, sctp);
+ f_sendDataFromClient('EEDDAADD11'O, sctp);
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD11'O);
+
+ vc_connectedClientConnectionId := -1;
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+ f_sendDataFromClient('EEDDAADD22'O, sctp);
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD22'O);
+
+ f_StopMyConnections();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_2_TCP_Servers_and_2_TCP_Clients() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ vc_connectedClientConnectionId := -1;
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort + 1, tcp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort + 1, tcp);
+ f_sendDataFromClient('BC579C4D00'O, tcp);
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'BC579C4D00'O);
+
+ vc_connectedClientConnectionId := -1;
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+ f_sendDataFromClient('BC579C4D11'O, tcp);
+ f_CheckDataReceive(vc_connectedClientConnectionId, 'BC579C4D11'O);
+
+ f_StopMyConnections();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_SCTP_AutoReplyDeviceWatchdog() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+ // 4th byte/bit1: request == 0
+ // 5-7th byte: 280 == hex 118
+ f_sendDataFromClient('00112200000118778899AABBCCDDEEFF'O, sctp);
+
+ // 4th byte/bit1: reply == 1
+ f_CheckDataReceive(vc_clientConnectionId, '00112280000118778899AABBCCDDEEFF'O);
+
+ f_StopServer();
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_TCP_AutoReplyDeviceWatchdog() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+ f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+ // 4th byte/bit1: request == 0
+ // 5-7th byte: 280 == hex 118
+ f_sendDataFromClient('EE81F300000118C98B6FF4'O, tcp);
+
+ // 4th byte/bit1: reply == 1
+ f_CheckDataReceive(vc_clientConnectionId, 'EE81F380000118C98B6FF4'O);
+
+ f_StopServer();
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_UDP_CheckStartupCallback() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_IPDD();
+
+ f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort, tsp_serverInterface, tsp_serverPort + 1, udp);
+ var integer vl_firstConnectionId := vc_clientConnectionId;
+ f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort + 1, tsp_serverInterface, tsp_serverPort, udp);
+ f_CheckDataReceive(vl_firstConnectionId, 'BBCCDDEE'O);
+
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+ //execute(tc_InitClientServer_StopServer_CheckClientConnChange());
+ //execute(tc_InitClientServer_StopServer_StartServer_CheckClientConnChange());
+ //execute(tc_InitClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer());
+ //execute(tc_AutoReplyDeviceWatchdog());
+}
+
+} // end of module
diff --git a/demo/IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn b/demo/IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
new file mode 100644
index 0000000..4ed2061
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
+// Description: IPDD behaviour with Diameter Auto Replies
+// Rev: <RnXnn>
+// Prodnr: CNL 113 739
+// Updated: 2012-02-28
+// Contact: http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_with_DiameterAutoReplies
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic all;
+import from IP_Daemon_Dynamic_Types all;
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+
+type record of boolean BooleanList;
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+//type component DIAMETER_IPDD_CT extends IPDD_CT {
+// var BooleanList vc_userStates := {};
+//}
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_HandleDeviceWatchdog(in integer associationIndex, in ASP_RecvFrom sctpReceived, out ASP_Send sctpReply)
+runs on IPDD_CT
+return boolean {
+ if(lengthof(sctpReceived.msg) > 6) {
+ // Device Watchdog: bytes #4-6 of the Diameter message
+ if(sctpReceived.msg[4] == '00'O and sctpReceived.msg[5] == '01'O and sctpReceived.msg[6] == '18'O) {
+ // bit #1 of the 3rd byte indicates whether the message is reply(1) or request(0)
+ var bitstring thirdByte := oct2bit(sctpReceived.msg[3]);
+ // we only send reply to the incoming request
+ if(thirdByte[0] == '0'B) {
+ thirdByte[0] := '1'B;
+
+ sctpReply.connId := sctpReceived.connId;
+ sctpReply.proto := sctpReceived.proto;
+ sctpReply.msg := sctpReceived.msg;
+ sctpReply.msg[3] := bit2oct(thirdByte);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+function f_SendAutoSetup(in integer associationIndex, in SAC_STATE newState, out ASP_Send sctpMsg)
+runs on IPDD_CT
+return boolean {
+ if(newState == SCTP_COMM_UP) {
+ if(vc_connectionRuntimeAttributesList[associationIndex].userState == "") {
+ sctpMsg := {
+ vc_connectionRuntimeAttributesList[associationIndex].socket,
+ {sctp:={0,0,omit,omit}},
+ 'AABBCCDDEEFF'O
+ }
+ return true;
+ }
+ } else if(vc_connectionRuntimeAttributesList[associationIndex].userState == "INITIALIZED") {
+ // do something different
+ } else {
+ log("ERROR: unhandled user state ", vc_connectionRuntimeAttributesList[associationIndex].userState);
+ }
+
+
+ return false;
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_IPDD_with_DiameterAutoReplies() runs on IPDD_CT {
+
+ // register my Device Watchdog detector & answerer
+ f_RegisterAutoReplyFunction(refers(f_HandleDeviceWatchdog));
+
+ // register my auto setup sending function
+ f_RegisterAutoStateChangeHandlerFunction(refers(f_SendAutoSetup));
+
+ // run the IP Daemon's main function
+ f_IPDD();
+
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+ execute(tc_IPDD_with_DiameterAutoReplies());
+}
+
+}
diff --git a/demo/IP_Daemon_Dynamic_with_StartupCallback.ttcn b/demo/IP_Daemon_Dynamic_with_StartupCallback.ttcn
new file mode 100644
index 0000000..e7153b0
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_with_StartupCallback.ttcn
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: IP_Daemon_Dynamic_with_StartupCallback.ttcn
+// Description: IPDD behaviour with Startup callback
+// Rev: <RnXnn>
+// Prodnr: CNL 113 739
+// Updated: 2012-05-04
+// Contact: http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_with_StartupCallback
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic all;
+import from IP_Daemon_Dynamic_Types all;
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_SendAutoStartup(in integer connectionIndex, out ASP_Send ipMsg)
+runs on IPDD_CT
+return boolean {
+ log("connectionIndex: ", connectionIndex);
+ ipMsg := {
+ vc_connectionRuntimeAttributesList[connectionIndex].socket,
+ { udp:={} },
+ 'BBCCDDEE'O
+ }
+
+ return true;
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_IPDD_with_StartupCallback() runs on IPDD_CT {
+
+ // register my auto startup function
+ f_RegisterAutoStartupFunction(refers(f_SendAutoStartup));
+
+ // run the IP Daemon's main function
+ f_IPDD();
+
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+ execute(tc_IPDD_with_StartupCallback());
+}
+
+}
+
diff --git a/src/IP_Daemon_Dynamic.ttcn b/src/IP_Daemon_Dynamic.ttcn
new file mode 100644
index 0000000..a0becd6
--- /dev/null
+++ b/src/IP_Daemon_Dynamic.ttcn
@@ -0,0 +1,1053 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: IP_Daemon_Dynamic.ttcn
+// Description: IPDD behaviour
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2012-05-07
+// Contact: http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic_Types all;
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from TCCInterface_Functions all;
+import from TCCConversion_Functions all;
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+import from IP_Daemon_Dynamic_IPL4_CtrlFunct all;
+
+//=========================================================================
+// Module Parameters
+//=========================================================================
+
+modulepar {
+
+ // Host name where the IP Daemon listens for the testcases
+ charstring tsp_IPDD_TCP_ListenInterface := "127.0.0.1";
+
+ // Port number where the IP Daemon listens for the testcases
+ integer tsp_IPDD_TCP_ListenPort := 1314;
+
+ // Default set of IP connections which the IP Daemon initializes on startup
+ // for connections with autoReconnect == true and server connections
+ IPDD_ConnectionConfigList tsp_IPDD_ConnectionList := {};
+
+ float tsp_IPDD_ReconnectTimer := 2.0;
+
+ // inactivity timer -> client connections get closed
+ float tsp_IPDD_InactivityTimer := 60.0;
+
+ boolean tsp_debug := false;
+}
+
+//=========================================================================
+// Altsteps
+//=========================================================================
+
+altstep as_Handle_IP_Events() runs on IPDD_CT {
+ [] IP_PCO.receive(ASP_RecvFrom : ?) -> value vc_asp_IP_ReceivedMessage {
+ debuglog("INFO: ASP_IP");
+
+ f_RestartInactivityTimer();
+
+ var boolean vl_autoReplied := false;
+ var ASP_Send vl_ipReply;
+ var integer index := 0;
+
+ for(index := 0; index < sizeof(vc_connectionRuntimeAttributesList); index := index + 1) {
+ if(vc_connectionRuntimeAttributesList[index].socket == vc_asp_IP_ReceivedMessage.connId) {
+ break;
+ }
+ }
+
+ for(var integer i := 0; not vl_autoReplied and (i < sizeof(vc_registeredAutoReplyFunctionList)); i := i + 1) {
+ vl_autoReplied := vc_registeredAutoReplyFunctionList[i].apply(index, vc_asp_IP_ReceivedMessage, vl_ipReply);
+ if(vl_autoReplied and vl_ipReply.connId > 0)
+ {
+ if(ischosen(vc_asp_IP_ReceivedMessage.proto.udp))
+ {
+ var ASP_SendTo vl_udpReply :=
+ {
+ connId := vl_ipReply.connId,
+ remName := vc_asp_IP_ReceivedMessage.remName,
+ remPort := vc_asp_IP_ReceivedMessage.remPort,
+ proto := vl_ipReply.proto,
+ msg := vl_ipReply.msg
+ };
+ IP_PCO.send(vl_udpReply);
+ }
+ else
+ {
+ IP_PCO.send(vl_ipReply);
+ }
+ }
+ }
+
+ if(not vl_autoReplied) {
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+ if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_ReceivedMessage.connId) {
+ if(ischosen(vc_asp_IP_ReceivedMessage.proto.sctp)) {
+ if(v_Connection_Lookup != null) {
+ v_TCP_connections_List:=v_Connection_Lookup.apply(vc_asp_IP_ReceivedMessage.msg);
+ for(var integer k := 0; k < sizeof(v_TCP_connections_List); k := k + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ v_TCP_connections_List[k],
+ {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[i].connectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_stream,
+ sinfo_ppid := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_ppid
+ },
+ dataLength := 0, // encoder will replace
+ data := vc_asp_IP_ReceivedMessage.msg
+ }
+ }
+ });
+ }
+ }
+ else {
+ for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[i].connectionId,
+ sctpAttributesPresent := true,
+ sctpAttributes := {
+ sinfo_stream := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_stream,
+ sinfo_ppid := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_ppid
+ },
+ dataLength := 0, // encoder will replace
+ data := vc_asp_IP_ReceivedMessage.msg
+ }
+ }
+ });
+ }
+ }
+ }
+
+ if(ischosen(vc_asp_IP_ReceivedMessage.proto.tcp) or ischosen(vc_asp_IP_ReceivedMessage.proto.udp)) {
+ if(v_Connection_Lookup != null) {
+ v_TCP_connections_List:=v_Connection_Lookup.apply(vc_asp_IP_ReceivedMessage.msg);
+ for(var integer k := 0; k < sizeof(v_TCP_connections_List); k := k + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ v_TCP_connections_List[k],
+ {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[i].connectionId,
+ sctpAttributesPresent := false,
+ sctpAttributes := omit,
+ dataLength := 0, // encoder will replace
+ data := vc_asp_IP_ReceivedMessage.msg
+ }
+ }
+ });
+ }
+ }
+ else {
+ for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ ipdd_data := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[i].connectionId,
+ sctpAttributesPresent := false,
+ sctpAttributes := omit,
+ dataLength := 0, // encoder will replace
+ data := vc_asp_IP_ReceivedMessage.msg
+ }
+ }
+ });
+ }
+ }
+ }
+ if(ischosen(vc_asp_IP_ReceivedMessage.proto.udp))
+ {
+ vc_connectionList[i].remoteInterface :=
+ {
+ hostNameLength := 0,
+ hostName := vc_asp_IP_ReceivedMessage.remName,
+ portNumber := vc_asp_IP_ReceivedMessage.remPort
+ }
+ }
+ }
+ }
+ }
+
+ repeat;
+ }
+
+ [] IP_PCO.receive(ASP_Event : { result := ? } ) -> value vc_asp_IP_Event {
+ debuglog("INFO: ASSOC_CHANGE vc_connectionRuntimeAttributesList: " & log2str(vc_connectionRuntimeAttributesList));
+ f_RestartInactivityTimer();
+
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+
+ if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.result.connId) {
+ //debuglog(log2str(vc_connectionList[i]) & " subscribedTestcases: " & log2str(vc_connectionRuntimeAttributesList[i].subscribedTestcases));
+
+ for(var integer j := 0; j < sizeof( vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ ipdd_connectionChanged := {
+ messageType := 0,
+ connectionId := vc_connectionList[i].connectionId,
+ eventPresent := true,
+ event := {
+ errorCodePresent := true,
+ errorCode := vc_asp_IP_Event.result.errorCode,
+ os_error_codePresent := true,
+ os_error_code := vc_asp_IP_Event.result.os_error_code,
+ os_error_textLength := 0,
+ os_error_text := vc_asp_IP_Event.result.os_error_text
+ },
+ sctpStatePresent := false,
+ sctpState := omit
+ }
+ }
+ });
+ }
+ }
+ }
+ repeat;
+ }
+
+ [] IP_PCO.receive(tr_sctpEvent(?, ?)) -> value vc_asp_IP_Event {
+ debuglog("INFO: ASSOC_CHANGE vc_connectionRuntimeAttributesList: " & log2str(vc_connectionRuntimeAttributesList));
+ f_RestartInactivityTimer();
+
+ var boolean vl_autoHandled := false;
+ var ASP_Send vl_ipMsg;
+
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+
+ if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.sctpEvent.sctpAssocChange.clientId) {
+ //debuglog(log2str(vc_connectionList[i]) & " subscribedTestcases: " & log2str(vc_connectionRuntimeAttributesList[i].subscribedTestcases));
+
+ vl_autoHandled := false;
+
+ for(var integer j := 0; not vl_autoHandled and (j < sizeof(vc_registeredAutoStateChangeHandlerFunctionList)); j := j + 1) {
+ vl_autoHandled := vc_registeredAutoStateChangeHandlerFunctionList[j].apply(i, vc_asp_IP_Event.sctpEvent.sctpAssocChange.sac_state, vl_ipMsg);
+ if(vl_autoHandled) {
+ IP_PCO.send(vl_ipMsg);
+ }
+ }
+
+ if(not vl_autoHandled) {
+
+ for(var integer j := 0; j < sizeof( vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ ipdd_connectionChanged := {
+ messageType := 0,
+ connectionId := vc_connectionList[i].connectionId,
+ eventPresent := false,
+ event := omit,
+ sctpStatePresent := true,
+ sctpState := vc_asp_IP_Event.sctpEvent.sctpAssocChange.sac_state
+ }
+ }
+ });
+ }
+ }
+ vc_connectionRuntimeAttributesList[i].sctpState := vc_asp_IP_Event.sctpEvent.sctpAssocChange.sac_state;
+ if(vc_connectionRuntimeAttributesList[i].sctpState == SCTP_COMM_LOST) {
+ if(vc_connectionList[i].serverConnection) {
+ vc_connectionRuntimeAttributesList[i].socket := -1;
+ // initiate reconnect
+ f_ScheduleReconnect();
+ }
+ else{
+ f_removeConnection(vc_connectionList[i].connectionId);
+ }
+ }
+ }
+ }
+ repeat;
+ }
+
+ [] IP_PCO.receive(tr_S_SCTP_ShutdownEvent) -> value vc_asp_IP_Event {
+ debuglog("INFO: SHUTDOWN");
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+ if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.sctpEvent.sctpShutDownEvent.clientId) {
+ vc_connectionRuntimeAttributesList[i].sctpState := SCTP_COMM_LOST;
+
+ for(var integer j := 0; j < sizeof( vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ ipdd_connectionChanged := {
+ messageType := 0,
+ connectionId := vc_connectionList[i].connectionId,
+ eventPresent := false,
+ event := omit,
+ sctpStatePresent := true,
+ sctpState := vc_connectionRuntimeAttributesList[i].sctpState
+ }
+ }
+ });
+ }
+ f_ScheduleReconnect();
+ }
+ }
+ f_RestartInactivityTimer();
+ repeat;
+ }
+
+ [] IP_PCO.receive(tr_ASP_IP_Connected) -> value vc_asp_IP_Event {
+ if(tsp_debug) {
+ log("@before ASP_IP_Connected vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+ }
+
+ f_RestartInactivityTimer();
+
+ for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+ if(ispresent(vc_connectionList[i].localInterface)) {
+ if(vc_connectionList[i].serverConnection and
+ vc_asp_IP_Event.connOpened.locName == vc_connectionList[i].localInterface.hostName and
+ vc_asp_IP_Event.connOpened.locPort == vc_connectionList[i].localInterface.portNumber and
+ f_IPDD_ProtoMatches(vc_asp_IP_Event.connOpened.proto, vc_connectionList[i].proto)) {
+
+ // book the new connection into the database
+ var integer newIndex := sizeof(vc_connectionList);
+
+ vc_connectionList[newIndex] := c_emptyConnection;
+ vc_connectionRuntimeAttributesList[newIndex] := c_emptyConnectionRuntimeAttribute;
+ vc_connectionRuntimeAttributesList[newIndex].socket := vc_asp_IP_Event.connOpened.connId;
+ vc_connectionRuntimeAttributesList[newIndex].endpointIndex := i;
+
+ vc_connectionList[newIndex].connectionId := f_getNextUniqueConnectionId();
+
+ vc_connectionList[newIndex].localInterface.hostNameLength := 0;
+ vc_connectionList[newIndex].localInterface.hostName := vc_asp_IP_Event.connOpened.locName;
+ vc_connectionList[newIndex].localInterface.portNumber := vc_asp_IP_Event.connOpened.locPort;
+
+ vc_connectionList[newIndex].remoteInterface.hostNameLength := 0;
+ vc_connectionList[newIndex].remoteInterface.hostName := vc_asp_IP_Event.connOpened.remName;
+ vc_connectionList[newIndex].remoteInterface.portNumber := vc_asp_IP_Event.connOpened.remPort;
+
+ vc_connectionList[newIndex].autoReconnect := false;
+ vc_connectionList[newIndex].proto := vc_connectionList[i].proto;
+
+ // send notification to all subscribed testcases of the server
+ for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ ipdd_connected := {
+ messageType := 0, // encoder will replace
+ serverId := vc_connectionList[i].connectionId,
+ connectionId := vc_connectionList[newIndex].connectionId,
+ remoteInterface := {
+ hostNameLength := 0, // encoder will replace
+ hostName := vc_asp_IP_Event.connOpened.locName,
+ portNumber := vc_asp_IP_Event.connOpened.locPort
+ }
+ }
+ }
+ } );
+ }
+ // subscribe the connected connection to the server's subscribed testcases
+ vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases := vc_connectionRuntimeAttributesList[i].subscribedTestcases;
+ }
+ }
+ }
+ if(tsp_debug) {
+ log("@after ASP_IP_Connected vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+ }
+ repeat;
+ }
+
+
+ [] IP_PCO.receive(tr_S_SCTP_PeerAddressChange) {
+ debuglog("INFO: ASP_IP_PEER_ADDR_CHANGE");
+ f_RestartInactivityTimer();
+ repeat;
+ }
+
+ [] IP_PCO.receive(tr_ASP_IP_Closed) -> value vc_asp_IP_Event {
+ debuglog("INFO: ASP_IP_Closed");
+
+ for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+
+ if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.connClosed.connId) {
+
+ for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ ipdd_closed := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[i].connectionId
+ }
+ }
+ });
+ }
+ vc_connectionRuntimeAttributesList[i].socket := -1;
+
+ }
+ }
+
+ f_RestartInactivityTimer();
+
+ repeat;
+ }
+
+ [] IP_PCO.receive(tr_ASP_Result) -> value vc_ipResult {
+ debuglog("INFO: ASP_IP_RESULT");
+ f_RestartInactivityTimer();
+ repeat;
+ }
+
+ [] IP_PCO.receive {
+ log("*** WARNING: unhandled IP message received!");
+ f_RestartInactivityTimer();
+ repeat;
+ }
+}
+
+altstep as_Handle_TCP_Events() runs on IPDD_CT {
+ [] daemonPort.receive(tr_ASP_TCP_Connected) -> value vc_asp_TCP_Event {
+ debuglog("INFO: ASP_TCP_Connected");
+ var f_IPL4_getMsgLen sdd_msglen := refers(f_IPDD_getMsgLen);
+ IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_setGetMsgLen(daemonPort,vc_asp_TCP_Event.connOpened.connId,sdd_msglen,{});
+ repeat;
+ }
+
+ [] daemonPort.receive(tr_ASP_TCP_Close) -> value vc_tcpClose {
+ debuglog("INFO: ASP_TCP_Close");
+ var IntegerList vl_newSubsribedTestcases := {};
+
+ if (v_Connection_Delete!=null)
+ {
+ v_Connection_Delete.apply(vc_tcpClose.connClosed.connId)
+ }
+ else{
+ // remove subscrition belonging to this client from the vc_connectionRuntimeAttributesList.subscribedTestcases
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+ vl_newSubsribedTestcases := {};
+ for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ if(vc_connectionRuntimeAttributesList[i].subscribedTestcases[j] != vc_tcpClose.connClosed.connId) {
+ vl_newSubsribedTestcases[sizeof(vl_newSubsribedTestcases)] := vc_connectionRuntimeAttributesList[i].subscribedTestcases[j];
+ }
+ }
+ if(sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases) != sizeof(vl_newSubsribedTestcases)) {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases := vl_newSubsribedTestcases;
+ }
+ }
+ }
+ repeat;
+ }
+
+ [] daemonPort.receive(t_close) -> value vc_daemonMessage {
+ debuglog("INFO: t_close");
+ for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+ if(vc_connectionList[i].connectionId == vc_daemonMessage.msg.ipdd_close.connectionId) {
+ if(vc_connectionRuntimeAttributesList[i].socket >= 0) {
+
+ var Result vl_result := IPL4asp_PortType.f_IPL4_close(IP_PCO, vc_connectionRuntimeAttributesList[i].socket, f_IPDD_getIPL4_Proto(i));
+ log("*** INFO: result of closing socket: ", vl_result);
+
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_daemonMessage.client_id,
+ { ipdd_result := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[i].connectionId,
+ errorStatus := not(vl_result.errorCode==omit),
+ errorMessage := vl_result.os_error_text
+ }}
+ } );
+
+ } else {
+ log("*** ERROR: connection ", vc_daemonMessage.msg.ipdd_close.connectionId, " is not alive, not sending ASP_IP_Close!");
+ }
+ }
+ }
+ f_removeConnection(vc_daemonMessage.msg.ipdd_close.connectionId);
+ debuglog("INFO: ASP_IP_Close sent, returning to the main alt");
+ repeat;
+ }
+
+ [] daemonPort.receive(t_queryConnections) -> value vc_daemonMessage {
+ daemonPort.send(IPDD_Message_with_ClientId : { vc_daemonMessage.client_id, { ipdd_connections := {
+ 0, // encoder will replace
+ vc_connectionList
+ } } });
+ repeat;
+ }
+
+ [] daemonPort.receive(t_connect) -> value vc_daemonMessage {
+ if(tsp_debug) {
+ log("@before ipdd_connect vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+ }
+ var integer newIndex := sizeof(vc_connectionList);
+
+ vc_connectionList[newIndex] := c_emptyConnection;
+ vc_connectionRuntimeAttributesList[newIndex] := c_emptyConnectionRuntimeAttribute;
+ vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases
+ [sizeof(vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases)] := vc_daemonMessage.client_id;
+
+ if(ispresent(vc_daemonMessage.msg.ipdd_connect.localInterface)) {
+ vc_connectionList[newIndex].localInterface := vc_daemonMessage.msg.ipdd_connect.localInterface;
+ }
+
+ vc_connectionList[newIndex].remoteInterface := vc_daemonMessage.msg.ipdd_connect.remoteInterface;
+
+ vc_connectionList[newIndex].autoReconnect := vc_daemonMessage.msg.ipdd_connect.autoReconnect;
+
+ vc_connectionList[newIndex].proto := vc_daemonMessage.msg.ipdd_connect.proto;
+
+ f_Reconnect_IP_Connection(newIndex);
+ f_RunAutoStartupFunctions(newIndex);
+
+ if(tsp_debug) {
+ log("@after defineClientConnection vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+ }
+ repeat;
+ }
+
+ [] daemonPort.receive(t_listen) -> value vc_daemonMessage {
+ if(tsp_debug) {
+ log("@before sctpListen vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+ }
+ var integer newIndex := sizeof(vc_connectionList);
+
+ vc_connectionList[newIndex] := c_emptyConnection;
+ vc_connectionRuntimeAttributesList[newIndex] := c_emptyConnectionRuntimeAttribute;
+ vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases
+ [sizeof(vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases)] := vc_daemonMessage.client_id;
+
+ vc_connectionList[newIndex].serverConnection := true;
+
+ vc_connectionList[newIndex].localInterface := {
+ hostNameLength := 0,
+ hostName := f_getIpAddr(vc_daemonMessage.msg.ipdd_listen.localInterface.hostName,f_addressType(vc_daemonMessage.msg.ipdd_listen.localInterface.hostName)),
+ portNumber := vc_daemonMessage.msg.ipdd_listen.localInterface.portNumber
+ };
+
+ vc_connectionList[newIndex].proto := vc_daemonMessage.msg.ipdd_listen.proto;
+
+ f_Init_Server_IP_Connection(newIndex);
+ f_RunAutoStartupFunctions(newIndex);
+
+ if(tsp_debug) {
+ log("@after defineServerConnection vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+ }
+ repeat;
+ }
+
+ [] daemonPort.receive(t_subscribeToConnection) -> value vc_daemonMessage {
+ debuglog("INFO: t_subscribeToConnection");
+ var boolean vl_subscribed := false, vl_found := false;
+ for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+ if(vc_connectionList[i].connectionId == vc_daemonMessage.msg.ipdd_subscribeToConnection.connectionId) {
+ vl_found := false;
+ for(var integer j := 0; not vl_found and (j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases)); j := j + 1) {
+ if(vc_connectionRuntimeAttributesList[i].subscribedTestcases[j] == vc_daemonMessage.client_id) {
+ vl_found := true
+ }
+ }
+ if(not vl_found) {
+ vc_connectionRuntimeAttributesList[i].subscribedTestcases[sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases)] := vc_daemonMessage.client_id;
+ vl_subscribed := true;
+ } else {
+ log("*** WARNING: test case ", vc_daemonMessage.client_id, " is already subscribed to: ", vc_connectionList[i]);
+ }
+ }
+ }
+
+ if(not vl_subscribed) {
+ log("*** WARNING: test case ", vc_daemonMessage.client_id, " was not subscribed to any connection!");
+ }
+
+ repeat;
+ }
+
+ [] daemonPort.receive(t_ipData) -> value vc_daemonMessage {
+ debuglog("INFO: t_sctpData");
+ for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+ if(vc_connectionList[i].connectionId == vc_daemonMessage.msg.ipdd_data.connectionId) {
+ if (v_Connection_Insert!=null) {v_Connection_Insert.apply(vc_daemonMessage.msg.ipdd_data.data,vc_daemonMessage.client_id)}
+
+ if(vc_connectionList[i].proto != udp)
+ {
+ var ASP_Send vl_send := {
+ connId := vc_connectionRuntimeAttributesList[i].socket,
+ proto := { tcp := {} },
+ msg := vc_daemonMessage.msg.ipdd_data.data
+ }
+
+ vl_send.proto := f_IPDD_getIPL4_Proto(i);
+
+ if (vc_connectionList[i].proto == sctp and vc_daemonMessage.msg.ipdd_data.sctpAttributesPresent) {
+ vl_send.proto.sctp.sinfo_stream := vc_daemonMessage.msg.ipdd_data.sctpAttributes.sinfo_stream;
+ vl_send.proto.sctp.sinfo_ppid := vc_daemonMessage.msg.ipdd_data.sctpAttributes.sinfo_ppid;
+ }
+ IP_PCO.send(vl_send);
+ }
+ else
+ {
+ var ASP_SendTo vl_send := {
+ connId := vc_connectionRuntimeAttributesList[i].socket,
+ remName := vc_connectionList[i].remoteInterface.hostName,
+ remPort := vc_connectionList[i].remoteInterface.portNumber,
+ proto := { udp := { } },
+ msg := vc_daemonMessage.msg.ipdd_data.data
+ }
+
+ IP_PCO.send(vl_send);
+ }
+ }
+ }
+ repeat;
+ }
+
+ [] daemonPort.receive(PortEvent : { result := ? }) -> value vc_asp_TCP_Event {
+ log("*** INFO: ignoring result.");
+ repeat;
+ }
+
+}
+
+altstep as_Handle_Reconnect() runs on IPDD_CT {
+ [] vc_reconnectTimer.timeout {
+ if(tsp_debug) {
+ log("On vc_reconnectTimer.timeout vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList, " vc_connectionList: ", vc_connectionList);
+ }
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+ if(vc_connectionRuntimeAttributesList[i].socket < 0 and vc_connectionList[i].autoReconnect) {
+ f_Reconnect_IP_Connection(i);
+ f_RunAutoStartupFunctions(i);
+ }
+ }
+ repeat;
+ }
+}
+
+altstep as_Handle_Inactivity() runs on IPDD_CT {
+ [] vc_inactivityTimer.timeout {
+ if(tsp_debug) {
+ log("On vc_inactivityTimer.timeout vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList, " vc_connectionList: ", vc_connectionList);
+ }
+
+ log("*** IPDD QUIT due to ", tsp_IPDD_InactivityTimer, " seconds of inactivity.");
+ log("*** Please restart IPDD if you need it again.");
+ }
+}
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function debuglog(in charstring str) {
+ if(tsp_debug) {
+ log(str);
+ }
+}
+
+function f_IPDD_ProtoMatches(in ProtoTuple pl_protoTuple, in ProtoTupleEnum pl_protoTupleEnum) return boolean {
+ select (pl_protoTupleEnum) {
+ case (udp) {
+ if(ischosen(pl_protoTuple.udp)) {
+ return true;
+ }
+ }
+ case (tcp) {
+ if(ischosen(pl_protoTuple.tcp)) {
+ return true;
+ }
+ }
+ case (sctp) {
+ if(ischosen(pl_protoTuple.sctp)) {
+ return true;
+ }
+ }
+ case (ssl) {
+ if(ischosen(pl_protoTuple.ssl)) {
+ return true;
+ }
+ }
+ case (unspecified) {
+ if(ischosen(pl_protoTuple.unspecified)) {
+ return true;
+ }
+ }
+ case else {
+ log("*** WARNING: unhandled protoTuple type!");
+ }
+ }
+
+ return false;
+}
+
+function f_IPDD_getIPL4_Proto(in integer pl_idx) runs on IPDD_CT return ProtoTuple {
+ var ProtoTuple vl_ret := { sctp := { omit, omit, omit, omit} };
+
+ select (vc_connectionList[pl_idx].proto) {
+ case (sctp) {
+ vl_ret := { sctp := { omit, omit, omit, omit} }
+ }
+ case (tcp) {
+ vl_ret := { tcp := { } };
+ }
+ case (udp) {
+ vl_ret := { udp := { } };
+ }
+ case (ssl) {
+ vl_ret := { ssl := { } };
+ }
+ case (unspecified) {
+ vl_ret := { unspecified := { } };
+ }
+ case else {
+ log("*** WARNING: unhandled protoTuple type!!!");
+ }
+ }
+
+ return vl_ret;
+}
+
+function f_addressType(charstring ip_address) return TCCInterface_IPAddressType {
+ var integer v_index := f_strstr(ip_address, ":");
+
+ if(v_index == -1) {
+ return IPv4;
+ }
+
+ return IPv6;
+}
+
+function f_getNextUniqueConnectionId() runs on IPDD_CT return integer {
+ var integer newId := 0;
+ var boolean found := false;
+ var boolean exit := false;
+
+ while(not exit) {
+ found := false;
+
+ for(var integer i := 0; i < sizeof(vc_connectionList) and (not found); i := i + 1) {
+ if(vc_connectionList[i].connectionId == newId) {
+ found := true;
+ }
+ }
+
+ if(not found) {
+ exit := true;
+ } else {
+ newId := newId + 1;
+ }
+ }
+
+ debuglog("returning new connection id: " & int2str(newId));
+ return newId;
+}
+
+function f_InitTCPServer() runs on IPDD_CT {
+ var Result vl_result := { errorCode := omit, connId := omit, os_error_code:=omit, os_error_text:= omit };
+ vl_result := IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_listen(daemonPort, tsp_IPDD_TCP_ListenInterface, tsp_IPDD_TCP_ListenPort, {tcp := {}});
+
+ if ((vl_result.errorCode == omit) or (vl_result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE)) {
+ log("*** INFO: listening on port (TCP): ", tsp_IPDD_TCP_ListenPort, "; result: ", vl_result);
+ var f_IPL4_getMsgLen ipdd_msglen := refers(f_IPDD_getMsgLen);
+ IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_setGetMsgLen(daemonPort,vl_result.connId,ipdd_msglen,{});
+ } else {
+ log("*** ERROR: error during initialization of the TCP port: ",vl_result);
+ setverdict(fail);
+ stop;
+ }
+}
+
+function f_Init_Server_IP_Connection(in integer conn_idx) runs on IPDD_CT {
+ if(vc_connectionList[conn_idx].serverConnection) {
+ if(ispresent(vc_connectionList[conn_idx].localInterface)) {
+ if(vc_connectionRuntimeAttributesList[conn_idx].socket < 0) {
+ log("init server: #", conn_idx);
+ vc_connectionRuntimeAttributesList[conn_idx].endpointIndex := f_GetEndpointIndex(vc_connectionList[conn_idx].localInterface);
+ var Result vl_result := { errorCode := omit, connId := omit, os_error_code := omit, os_error_text := omit };
+
+ vl_result := IPL4asp_PortType.f_IPL4_listen(
+ IP_PCO,
+ vc_connectionList[conn_idx].localInterface.hostName,
+ vc_connectionList[conn_idx].localInterface.portNumber,
+ f_IPDD_getIPL4_Proto(conn_idx)
+ );
+
+ if(vc_connectionList[conn_idx].connectionId < 0) {
+ vc_connectionList[conn_idx].connectionId := f_getNextUniqueConnectionId();
+ }
+
+ vc_connectionRuntimeAttributesList[conn_idx].socket := vl_result.connId;
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases); i := i + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases[i],
+ { ipdd_result := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[conn_idx].connectionId,
+ errorStatus := not(vl_result.errorCode==omit),
+ errorMessage := vl_result.os_error_text
+ }}
+ } );
+ }
+ } else {
+ log("*** WARNING: IP server connection ", vc_connectionList[conn_idx].localInterface, " is already listening!");
+ }
+ } else {
+ log("*** ERROR: IP server connection #", conn_idx, " is declared as server, but has no localInterface defined!");
+ }
+ } else {
+ if(tsp_debug) {
+ log("*** INFO: IP connection ", vc_connectionList[conn_idx], " is not server.");
+ }
+ }
+}
+
+function f_Reconnect_IP_Connection(in integer conn_idx) runs on IPDD_CT {
+ if(vc_connectionRuntimeAttributesList[conn_idx].socket < 0) {
+ if(ispresent(vc_connectionList[conn_idx].remoteInterface)) {
+
+ if(ispresent(vc_connectionList[conn_idx].localInterface)) {
+ if(not vc_connectionList[conn_idx].serverConnection) {
+
+ vc_connectionRuntimeAttributesList[conn_idx].endpointIndex := f_GetEndpointIndex(vc_connectionList[conn_idx].localInterface);
+
+ var Result vl_result := { errorCode := omit, connId := omit, os_error_code:=omit, os_error_text:= omit };
+
+ vl_result := IPL4asp_PortType.f_IPL4_connect
+ (
+ IP_PCO,
+ vc_connectionList[conn_idx].remoteInterface.hostName,
+ vc_connectionList[conn_idx].remoteInterface.portNumber,
+ vc_connectionList[conn_idx].localInterface.hostName,
+ vc_connectionList[conn_idx].localInterface.portNumber,
+ connId := -1,
+ proto := f_IPDD_getIPL4_Proto(conn_idx),
+ options := {}
+ );
+
+ if ((vl_result.errorCode == omit) or (vl_result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE)) //if not error
+ {
+ vc_connectionRuntimeAttributesList[conn_idx].socket := vl_result.connId;
+ log("**** INFO: New client socket: ", vc_connectionRuntimeAttributesList[conn_idx].socket);
+ if(vc_connectionList[conn_idx].connectionId < 0) {
+ vc_connectionList[conn_idx].connectionId := f_getNextUniqueConnectionId();
+ }
+ }
+ else
+ {
+ f_ScheduleReconnect();
+ }
+
+ for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases); i := i + 1) {
+ daemonPort.send(IPDD_Message_with_ClientId : {
+ vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases[i],
+ { ipdd_result := {
+ messageType := 0, // encoder will replace
+ connectionId := vc_connectionList[conn_idx].connectionId,
+ errorStatus := not(vl_result.errorCode==omit),
+ errorMessage := vl_result.os_error_text
+ }}
+ } );
+ }
+
+ } else {
+ if(vc_connectionList[conn_idx].serverConnection) {
+ log("*** WARNING: connection ", vc_connectionList[conn_idx].localInterface,
+ " is declared as server connection, but also initiates client connection to ",
+ vc_connectionList[conn_idx].remoteInterface, ".");}
+ }
+ }
+ else {
+ log("*** WARNING: connection ", vc_connectionList[conn_idx].remoteInterface, " localInterface is missing.");
+ }
+
+ if(tsp_debug) {
+ log("@after ASP_IP_RESULT vc_connectionList: ",vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+ }
+
+ } else {
+ if(vc_connectionList[conn_idx].serverConnection) {
+ if(tsp_debug) {
+ log("*** INFO: IP connection ", vc_connectionList[conn_idx].localInterface, " is server only.");
+ }
+ } else {
+ log("*** ERROR: IP connection ", vc_connectionList[conn_idx].localInterface, " is not a server connection!");
+ }
+ }
+ } else if(ispresent(vc_connectionList[conn_idx].remoteInterface)) {
+ log("*** WARNING: IP connection to " & log2str(vc_connectionList[conn_idx].remoteInterface) & " is already active!");
+ }
+}
+
+function f_removeConnection(in integer pl_connectionId) runs on IPDD_CT {
+ var IPDD_ConnectionList newConnectionList := {};
+ var ConnectionRuntimeAttributesList newConnectionRuntimeAttributesList := {};
+
+ for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+ if(vc_connectionList[i].connectionId != pl_connectionId) {
+ newConnectionList[sizeof(newConnectionList)] := vc_connectionList[i];
+ newConnectionRuntimeAttributesList[sizeof(newConnectionRuntimeAttributesList)] := vc_connectionRuntimeAttributesList[i];
+ }
+ }
+
+ if(sizeof(newConnectionList) != sizeof(vc_connectionList)) {
+ vc_connectionList := newConnectionList;
+ vc_connectionRuntimeAttributesList := newConnectionRuntimeAttributesList;
+ } else {
+ log("*** WARNING: IP connection to delete: ", pl_connectionId, " was not found in the database.");
+ }
+}
+
+function f_GetEndpointIndex(in IPDD_Interface pl_interface) runs on IPDD_CT return integer {
+
+ for(var integer vl_i := 0; vl_i < sizeof(v_localEndpointList); vl_i := vl_i + 1) {
+ if((v_localEndpointList[vl_i].hostName == pl_interface.hostName) and (v_localEndpointList[vl_i].portNumber == pl_interface.portNumber)) {
+ return vl_i;
+ }
+ }
+
+ v_localEndpointList[sizeof(v_localEndpointList)] := pl_interface;
+
+ return sizeof(v_localEndpointList) - 1;
+}
+
+function f_RunAutoStartupFunctions(in integer conn_idx) runs on IPDD_CT {
+
+ var boolean vl_send;
+ var ASP_Send vl_ipMsg;
+
+ for(var integer i := 0; i < sizeof(vc_registeredAutoStartupFunctionList); i := i + 1) {
+ vl_send := vc_registeredAutoStartupFunctionList[i].apply(conn_idx, vl_ipMsg);
+ if(vl_send and vl_ipMsg.connId > 0) {
+ if(ischosen(vl_ipMsg.proto.udp)) {
+ var ASP_SendTo vl_udpMsg :=
+ {
+ connId := vl_ipMsg.connId,
+ remName := vc_connectionList[conn_idx].remoteInterface.hostName,
+ remPort := vc_connectionList[conn_idx].remoteInterface.portNumber,
+ proto := vl_ipMsg.proto,
+ msg := vl_ipMsg.msg
+ };
+ IP_PCO.send(vl_udpMsg);
+ }
+ else
+ {
+ IP_PCO.send(vl_ipMsg);
+ }
+ }
+ }
+}
+
+function f_ScheduleReconnect() runs on IPDD_CT {
+ if(not vc_reconnectTimer.running) {
+ vc_reconnectTimer.start(tsp_IPDD_ReconnectTimer);
+ }
+}
+
+function f_RestartInactivityTimer() runs on IPDD_CT {
+ if(tsp_IPDD_InactivityTimer > 0.0) {
+ if(vc_inactivityTimer.running) {
+ vc_inactivityTimer.stop;
+ };
+
+ vc_inactivityTimer.start(tsp_IPDD_InactivityTimer);
+ debuglog("*** INFO: Inactivity timer restarted.");
+ }
+}
+
+function f_RegisterAutoReplyFunction(in f_IPDD_AutoReplyFunction autoReplyFunction) runs on IPDD_CT {
+ vc_registeredAutoReplyFunctionList[sizeof(vc_registeredAutoReplyFunctionList)] := autoReplyFunction;
+}
+
+function f_RegisterAutoStateChangeHandlerFunction(in f_IPDD_AutoStateChangeHandlerFunction autoStateChangeHandlerFunction) runs on IPDD_CT {
+ vc_registeredAutoStateChangeHandlerFunctionList[sizeof(vc_registeredAutoStateChangeHandlerFunctionList)] := autoStateChangeHandlerFunction;
+}
+
+function f_RegisterAutoStartupFunction(in f_IPDD_AutoStartupFunction autoStartupFunction) runs on IPDD_CT {
+ vc_registeredAutoStartupFunctionList[sizeof(vc_registeredAutoStartupFunctionList)] := autoStartupFunction;
+}
+
+function f_IPDD() runs on IPDD_CT {
+ map(mtc:daemonPort, system:daemonPort);
+ map(mtc:IP_PCO, system:IP_PCO);
+
+ f_InitTCPServer();
+
+ for(var integer i := 0; i < sizeof(tsp_IPDD_ConnectionList); i := i + 1) {
+ vc_connectionList[i] := {
+ connectionId := -1,
+ serverConnection:= tsp_IPDD_ConnectionList[i].serverConnection,
+ autoReconnect := tsp_IPDD_ConnectionList[i].autoReconnect,
+ localInterfacePresent := false, // enter always false
+ localInterface := {
+ hostNameLength := 0,
+ hostName := f_getIpAddr(tsp_IPDD_ConnectionList[i].localInterface.hostName, f_addressType(tsp_IPDD_ConnectionList[i].localInterface.hostName)),
+ portNumber := tsp_IPDD_ConnectionList[i].localInterface.portNumber
+ },
+ remoteInterfacePresent := false, // enter always false
+ remoteInterface := tsp_IPDD_ConnectionList[i].remoteInterface,
+ proto := tsp_IPDD_ConnectionList[i].proto,
+ sctpProtoAttributesPresent := false,
+ sctpProtoAttributes := omit
+ };
+ // clientIds: empty, sctpState: SCTP_COMM_LOST
+ vc_connectionRuntimeAttributesList[i] := c_emptyConnectionRuntimeAttribute;
+ }
+
+ log("*** INFO: initial config: ", vc_connectionList);
+
+ for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+ f_Init_Server_IP_Connection(i);
+ f_Reconnect_IP_Connection(i);
+ f_RunAutoStartupFunctions(i);
+ }
+
+ alt {
+ [] as_Handle_TCP_Events()
+ [] as_Handle_Reconnect()
+ [] as_Handle_IP_Events()
+ [] as_Handle_Inactivity()
+ }
+
+ unmap(mtc:daemonPort, system:daemonPort);
+ unmap(mtc:IP_PCO, system:IP_PCO);
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_IPDD() runs on IPDD_CT {
+ f_IPDD();
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+ execute(tc_IPDD());
+}
+
+} //end of module
diff --git a/src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc b/src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc
new file mode 100644
index 0000000..92c1cda
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2010-11-24
+// Contact: http://ttcn.ericsson.se
+// Reference:
+
+
+#include "IPL4asp_PortType.hh"
+#include "IPL4asp_PT.hh"
+#include "IP_Daemon_Dynamic_Interface_Definitions.hh"
+
+namespace IP__Daemon__Dynamic__IPL4__CtrlFunct {
+
+ IPL4asp__Types::Result f__IPL4__listen(
+ IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+ const IPL4asp__Types::HostName& locName,
+ const IPL4asp__Types::PortNumber& locPort,
+ const IPL4asp__Types::ProtoTuple& proto,
+ const IPL4asp__Types::OptionList& options)
+ {
+ return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options);
+ }
+
+ IPL4asp__Types::Result f__IPL4__connect(
+ IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+ const IPL4asp__Types::HostName& remName,
+ const IPL4asp__Types::PortNumber& remPort,
+ const IPL4asp__Types::HostName& locName,
+ const IPL4asp__Types::PortNumber& locPort,
+ const IPL4asp__Types::ConnectionId& connId,
+ const IPL4asp__Types::ProtoTuple& proto,
+ const IPL4asp__Types::OptionList& options)
+ {
+ return f__IPL4__PROVIDER__connect(portRef, remName, remPort,
+ locName, locPort, connId, proto, options);
+ }
+
+ IPL4asp__Types::Result f__IPL4__close(
+ IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+ const IPL4asp__Types::ConnectionId& connId,
+ const IPL4asp__Types::ProtoTuple& proto)
+ {
+ return f__IPL4__PROVIDER__close(portRef, connId, proto);
+ }
+
+ IPL4asp__Types::Result f__IPL4__setUserData(
+ IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+ const IPL4asp__Types::ConnectionId& connId,
+ const IPL4asp__Types::UserData& userData)
+ {
+ return f__IPL4__PROVIDER__setUserData(portRef, connId, userData);
+ }
+
+ IPL4asp__Types::Result f__IPL4__getUserData(
+ IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+ const IPL4asp__Types::ConnectionId& connId,
+ IPL4asp__Types::UserData& userData)
+ {
+ return f__IPL4__PROVIDER__getUserData(portRef, connId, userData);
+ }
+
+ void f__IPL4__setGetMsgLen(
+ IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+ const IPL4asp__Types::ConnectionId& connId,
+ IPL4asp__Types::f__getMsgLen& f,
+ const IPL4asp__Types::ro__integer& msgLenArgs)
+ {
+ f__IPL4__PROVIDER__setGetMsgLen(portRef, connId, f, msgLenArgs);
+ }
+
+} // namespace IPL4__user__CtrlFunct
+
diff --git a/src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn b/src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn
new file mode 100644
index 0000000..e5ff2ea
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: SCTP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2010-11-24
+// Contact: http://ttcn.ericsson.se
+// Reference:
+//
+
+module IP_Daemon_Dynamic_IPL4_CtrlFunct {
+
+ import from IP_Daemon_Dynamic_Interface_Definitions all;
+ import from IPL4asp_Types all;
+
+ external function f_IPL4_listen(
+ inout IPDD_Interface_PT portRef,
+ in HostName locName,
+ in PortNumber locPort,
+ in ProtoTuple proto,
+ in OptionList options := {}
+ ) return Result;
+
+ external function f_IPL4_connect(
+ inout IPDD_Interface_PT portRef,
+ in HostName remName,
+ in PortNumber remPort,
+ in HostName locName,
+ in PortNumber locPort,
+ in ConnectionId connId,
+ in ProtoTuple proto,
+ in OptionList options := {}
+ ) return Result;
+
+ external function f_IPL4_close(
+ inout IPDD_Interface_PT portRef,
+ in ConnectionId id,
+ in ProtoTuple proto := { unspecified := {} }
+ ) return Result;
+
+ external function f_IPL4_setUserData(
+ inout IPDD_Interface_PT portRef,
+ in ConnectionId id,
+ in UserData userData
+ ) return Result;
+
+ external function f_IPL4_getUserData(
+ inout IPDD_Interface_PT portRef,
+ in ConnectionId id,
+ out UserData userData
+ ) return Result;
+
+ external function f_IPL4_setGetMsgLen(
+ inout IPDD_Interface_PT portRef,
+ in ConnectionId id := -1,
+ inout f_getMsgLen f,
+ in ro_integer msgLenArgs
+ );
+
+} // module SCTP_Daemon_Dynamic_IPL4_CtrlFunct
+
diff --git a/src/IP_Daemon_Dynamic_Interface_Definitions.ttcn b/src/IP_Daemon_Dynamic_Interface_Definitions.ttcn
new file mode 100644
index 0000000..ea1d2a7
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_Interface_Definitions.ttcn
@@ -0,0 +1,315 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: SCTP_Daemon_Dynamic_Interface_Definitions.ttcn
+// Description: IPDD <-> Testcase interface data and port types
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2012-11-10
+// Contact: http://ttcn.ericsson.se
+
+
+module IP_Daemon_Dynamic_Interface_Definitions
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record IPDD_Message_with_ClientId {
+ integer client_id optional,
+ IPDD_Message msg
+}
+
+type union IPDD_Message {
+
+ // Both-way traffic
+ IPDD_Data ipdd_data, // send data
+
+ // Requests
+ IPDD_QueryConnections ipdd_queryConnections, // query the state of the active connections
+ IPDD_Listen ipdd_listen, // define a new server connection
+ IPDD_Connect ipdd_connect, // define a new client connection
+ IPDD_Close ipdd_close, // close a connection
+ IPDD_SubscribeToConnection ipdd_subscribeToConnection, // subscribe to an connection's events
+
+ // Indications
+ IPDD_Result ipdd_result, // result comes in response to Listen and Connect, and contains the new connectionId
+ IPDD_Connections ipdd_connections, // response to queryConnections
+ IPDD_ConnectionChanged ipdd_connectionChanged, // indicates the change of the state of a connection
+ IPDD_Connected ipdd_connected, // indicates that a client has been connected to one of our IP server
+ IPDD_Closed ipdd_closed // indicates that a connection has been closed
+
+} with {
+ variant "TAG(
+ ipdd_data, messageType = 0;
+ ipdd_queryConnections, messageType = 1;
+ ipdd_listen, messageType = 2;
+ ipdd_connect, messageType = 3;
+ ipdd_close, messageType = 4;
+ ipdd_subscribeToConnection, messageType = 5;
+
+ ipdd_result, messageType = 100;
+ ipdd_connections, messageType = 101;
+ ipdd_connectionChanged, messageType = 102;
+ ipdd_connected, messageType = 103;
+ ipdd_closed, messageType = 104)"
+}
+
+group MainMessageTypes {
+
+ type record IPDD_Data {
+ integer messageType,
+ IPDD_INT32 connectionId,
+ boolean sctpAttributesPresent,
+ IPDD_SctpAttributes sctpAttributes optional,
+ integer dataLength (0..65526),
+ octetstring data
+ } with {
+ variant (sctpAttributesPresent) "FIELDLENGTH(8)"
+ variant (sctpAttributes) "PRESENCE (sctpAttributesPresent=true)"
+ variant (dataLength) "FIELDLENGTH(16)"
+ variant (dataLength) "LENGTHTO(data)"
+ }
+
+ type record IPDD_QueryConnections {
+ integer messageType
+ }
+
+ type record IPDD_Listen {
+ integer messageType,
+ IPDD_Interface localInterface,
+ ProtoTupleEnum proto,
+ boolean sctpProtoAttributesPresent,
+ IPDD_SctpProtoAttributes sctpProtoAttributes optional
+ } with {
+ variant (sctpProtoAttributesPresent) "FIELDLENGTH(8)"
+ variant (sctpProtoAttributes) "PRESENCE (sctpProtoAttributesPresent=true)"
+ }
+
+ type record IPDD_Connect {
+ integer messageType,
+ boolean autoReconnect,
+ boolean localInterfacePresent,
+ IPDD_Interface localInterface optional,
+ IPDD_Interface remoteInterface,
+ ProtoTupleEnum proto,
+ boolean sctpProtoAttributesPresent,
+ IPDD_SctpProtoAttributes sctpProtoAttributes optional
+ } with {
+ variant (autoReconnect, localInterfacePresent, sctpProtoAttributesPresent) "FIELDLENGTH(8)"
+ variant (localInterface) "PRESENCE (localInterfacePresent=true)"
+ variant (sctpProtoAttributes) "PRESENCE (sctpProtoAttributesPresent=true)"
+ }
+
+ type record IPDD_Close {
+ integer messageType,
+ IPDD_INT32 connectionId
+ }
+
+ type record IPDD_SubscribeToConnection {
+ integer messageType,
+ IPDD_INT32 connectionId
+ }
+
+ type record IPDD_Result {
+ integer messageType,
+ IPDD_INT32 connectionId,
+ boolean errorStatus,
+ charstring errorMessage optional
+ } with {
+ variant (errorStatus) "FIELDLENGTH(8)"
+ variant (errorMessage) "PRESENCE (errorStatus=true)"
+ }
+
+ type record IPDD_Connections {
+ integer messageType,
+ IPDD_ConnectionList connectionList
+ }
+
+ type record IPDD_ConnectionChanged {
+ integer messageType,
+ IPDD_INT32 connectionId,
+ boolean eventPresent,
+ IPDD_Event event optional,
+ boolean sctpStatePresent,
+ SAC_STATE sctpState optional
+ } with {
+ variant (eventPresent, sctpStatePresent, sctpState) "FIELDLENGTH(8)"
+ variant (event) "PRESENCE (eventPresent=true)"
+ variant (sctpState) "PRESENCE (sctpStatePresent=true)"
+ }
+
+ type record IPDD_Connected {
+ integer messageType,
+ IPDD_INT32 serverId,
+ IPDD_INT32 connectionId,
+ IPDD_Interface remoteInterface
+ }
+
+ type record IPDD_Closed {
+ integer messageType,
+ IPDD_INT32 connectionId
+ }
+}
+
+group SubTypes {
+
+ type integer IPDD_INT32 with {
+ variant "FIELDLENGTH(32), COMP(signbit)"
+ }
+
+ type integer IPDD_ULONG with {
+ variant "FIELDLENGTH(32), COMP(nosign)"
+ }
+
+ type record IPDD_SctpAttributes {
+ IPDD_ULONG sinfo_stream,
+ IPDD_ULONG sinfo_ppid
+ }
+
+ type enumerated ProtoTupleEnum {
+ udp,
+ tcp,
+ sctp,
+ ssl,
+ unspecified
+ } with {
+ variant "FIELDLENGTH(8)"
+ }
+
+ type record IPDD_SctpProtoAttributes {
+ boolean sinfo_streamAttributesPresent,
+ IPDD_ULONG sinfo_stream optional,
+ boolean sinfo_ppidPresent,
+ IPDD_ULONG sinfo_ppid optional,
+ boolean remSocksPresent,
+ IPDD_InterfaceList remSocks optional,
+ boolean assocIdPresent,
+ IPDD_ULONG assocId optional
+ } with {
+ variant (sinfo_streamAttributesPresent, sinfo_ppidPresent, remSocksPresent, assocIdPresent) "FIELDLENGTH(8)"
+ variant (sinfo_stream) "PRESENCE (sinfo_streamAttributesPresent=true)"
+ variant (sinfo_ppid) "PRESENCE (sinfo_ppidPresent=true)"
+ variant (remSocks) "PRESENCE (remSocksPresent=true)"
+ variant (assocId) "PRESENCE (assocIdPresent=true)"
+ }
+
+ type record IPDD_Event {
+ boolean errorCodePresent,
+ PortError errorCode optional,
+ boolean os_error_codePresent,
+ integer os_error_code optional,
+ integer os_error_textLength,
+ charstring os_error_text optional
+ } with {
+ variant (errorCodePresent, os_error_codePresent, os_error_textLength) "FIELDLENGTH(8)"
+ variant (errorCode) "PRESENCE (errorCodePresent=true)"
+ variant (os_error_code) "PRESENCE (os_error_codePresent=true)"
+ variant (os_error_textLength) "LENGTHTO (os_error_text)"
+ }
+
+ type record IPDD_Interface {
+ integer hostNameLength,
+ charstring hostName,
+ integer portNumber (0..65535) optional
+ } with {
+ variant (hostNameLength) "LENGTHTO(hostName)";
+ variant (portNumber) "FIELDLENGTH(16)";
+ }
+
+ type record of IPDD_Interface IPDD_InterfaceList;
+
+ type record IPDD_Connection {
+ IPDD_INT32 connectionId,
+ boolean serverConnection, // true := server, false: client
+ boolean autoReconnect,
+ boolean localInterfacePresent,
+ IPDD_Interface localInterface optional,
+ boolean remoteInterfacePresent,
+ IPDD_Interface remoteInterface optional,
+ ProtoTupleEnum proto,
+ boolean sctpProtoAttributesPresent,
+ IPDD_SctpProtoAttributes sctpProtoAttributes optional
+ } with {
+ variant (localInterface) "PRESENCE (localInterfacePresent=true)"
+ variant (remoteInterface) "PRESENCE (remoteInterfacePresent=true)"
+ variant (sctpProtoAttributes) "PRESENCE (sctpProtoAttributesPresent=true)"
+ variant (serverConnection, autoReconnect, localInterfacePresent, remoteInterfacePresent, sctpProtoAttributesPresent) "FIELDLENGTH(8)"; // take a byte to make debugging a little easier
+ }
+
+ type record of IPDD_Connection IPDD_ConnectionList;
+
+ type record IPDD_ConnectionConfig {
+ boolean serverConnection, // true := server, false: client
+ boolean autoReconnect,
+ IPDD_Interface localInterface optional,
+ IPDD_Interface remoteInterface optional
+ }
+}
+
+//=========================================================================
+//Port Types
+//=========================================================================
+
+type port IPDD_Interface_PT message {
+ in ASP_Event;
+ inout IPDD_Message_with_ClientId
+} with { extension "user IPL4asp_PT
+ in( ASP_Event -> ASP_Event: simple;
+ ASP_RecvFrom -> IPDD_Message_with_ClientId: function(f_dec_IPDD_Message))
+ out(IPDD_Message_with_ClientId -> ASP_Send: function(f_enc_IPDD_Message))"
+}
+
+//=========================================================================
+// Encoder and Decoder Functions
+//=========================================================================
+function f_IPDD_getMsgLen(in octetstring stream, inout ro_integer args) return integer {
+ var integer stream_length := lengthof(stream);
+
+ if (stream_length >=4) {
+ return oct2int(substr(stream,2,2));
+ }
+
+ return -1;
+}
+
+function f_dec_IPDD_Message(in ASP_RecvFrom aspTCP, out IPDD_Message_with_ClientId daemonMsg) return integer {
+ daemonMsg.client_id := aspTCP.connId;
+ daemonMsg.msg := dec_IPDD_Message(substr(aspTCP.msg, 4, lengthof(aspTCP.msg)-4));
+ return 0;
+} with { extension "prototype(backtrack)" }
+
+function f_enc_IPDD_Message(in IPDD_Message_with_ClientId sctpMsg, out ASP_Send aspTCP) return integer {
+ aspTCP.connId := sctpMsg.client_id;
+ var octetstring vl_encoded := enc_IPDD_Message(sctpMsg.msg);
+ // assemble TPKT here; TPKT:
+ // 1st octet: version
+ // 2nd octet: '00'O
+ // 3rd-4th octet: message length; used to separate the messages travelling on TCP
+ aspTCP.msg := '0300'O & int2oct((lengthof(vl_encoded) + 4), 2) & vl_encoded;
+ aspTCP.proto := {tcp:={}};
+ return 0;
+} with { extension "prototype(backtrack)" }
+
+// created automatically by compiler's RAW Encoder/Decoder code generator
+external function enc_IPDD_Message(in IPDD_Message pdu) return octetstring
+with { extension "prototype(convert) encode(RAW)" }
+
+// created automatically by compiler's RAW Encoder/Decoder code generator
+external function dec_IPDD_Message(in octetstring stream) return IPDD_Message
+with { extension "prototype(convert) decode(RAW)" }
+
+} with {encode "RAW"} // end of module
diff --git a/src/IP_Daemon_Dynamic_Types.ttcn b/src/IP_Daemon_Dynamic_Types.ttcn
new file mode 100644
index 0000000..3ce19f7
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_Types.ttcn
@@ -0,0 +1,304 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+// File: SCTP_Daemon_Dynamic_Types.ttcn
+// Description: IPDD types
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2012-05-07
+// Contact: http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_Types
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record of integer IntegerList;
+
+type record ConnectionRuntimeAttributes {
+ IntegerList subscribedTestcases,
+ integer socket,
+ integer endpointIndex,
+ SAC_STATE sctpState,
+ charstring userState
+}
+
+type record of ConnectionRuntimeAttributes ConnectionRuntimeAttributesList;
+
+type record IPDD_ConnectionConfig {
+ boolean serverConnection, // true := server, false: client
+ boolean autoReconnect,
+ IPDD_Interface localInterface optional,
+ IPDD_Interface remoteInterface optional,
+ ProtoTupleEnum proto
+}
+
+type record of IPDD_ConnectionConfig IPDD_ConnectionConfigList;
+
+type record of integer TCP_connections_List; //xxx for added SGsAP functionality
+
+type function Connection_Insert(octetstring pl_data, integer pl_id) runs on self; //xxx
+type function Connection_Lookup(octetstring pl_data) runs on self return TCP_connections_List; //xxx
+type function Connection_Delete(integer pl_id) runs on self; //xxx
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+type component IPDD_CT {
+ port IPDD_Interface_PT daemonPort;
+ port IPL4asp_PT IP_PCO;
+
+ var IPDD_ConnectionList vc_connectionList := {};
+ var ConnectionRuntimeAttributesList vc_connectionRuntimeAttributesList := {};
+ var IPDD_InterfaceList v_localEndpointList := {};
+
+ //var ASP_TCP_Connected vc_connected;
+ var IPDD_Message_with_ClientId vc_daemonMessage;
+
+ timer vc_reconnectTimer;
+ timer vc_inactivityTimer;
+
+ var ASP_RecvFrom vc_asp_IP_ReceivedMessage;
+ var ASP_Event vc_asp_IP_Event;
+ var ASP_Event vc_asp_TCP_Event;
+ var ASP_Event vc_ipResult;
+
+ var ASP_Event vc_tcpClose;
+
+ var RegisteredAutoReplyFunctionList vc_registeredAutoReplyFunctionList := {};
+ var RegisteredAutoStateChangeHandlerFunctionList vc_registeredAutoStateChangeHandlerFunctionList := {};
+ var RegisteredAutoStartupFunctionList vc_registeredAutoStartupFunctionList := {};
+
+ var Connection_Insert v_Connection_Insert:=null;
+ var Connection_Lookup v_Connection_Lookup:=null;
+ var Connection_Delete v_Connection_Delete:=null;
+ var TCP_connections_List v_TCP_connections_List;
+}
+
+//=========================================================================
+// Signatures
+//=========================================================================
+
+// return true if the message should not be passed to TTCN but replied with the ipReply
+type function f_IPDD_AutoReplyFunction(in integer connectionIndex, in ASP_RecvFrom ipReceived, out ASP_Send ipReply)
+runs on self return boolean;
+
+type record of f_IPDD_AutoReplyFunction RegisteredAutoReplyFunctionList;
+
+// return true if the state should not be passed to TTCN, but ipMsg has to be automatically sent on the connection
+type function f_IPDD_AutoStateChangeHandlerFunction(in integer connectionIndex, in SAC_STATE newState, out ASP_Send ipMsg)
+runs on self return boolean;
+
+type record of f_IPDD_AutoStateChangeHandlerFunction RegisteredAutoStateChangeHandlerFunctionList;
+
+// return true if the message should be sent to SUT and put the message in the ipMsg
+type function f_IPDD_AutoStartupFunction(in integer connectionIndex, out ASP_Send ipMsg)
+runs on self return boolean;
+
+type record of f_IPDD_AutoStartupFunction RegisteredAutoStartupFunctionList;
+
+//=========================================================================
+// Constants
+//=========================================================================
+
+const IPDD_Connection c_emptyConnection := {
+ connectionId := -1,
+ serverConnection := false, // true := server, false: client
+ autoReconnect := true,
+ localInterfacePresent := false,
+ localInterface := omit,
+ remoteInterfacePresent := false,
+ remoteInterface := omit,
+ sctpProtoAttributesPresent := false,
+ sctpProtoAttributes := omit
+}
+
+const ConnectionRuntimeAttributes c_emptyConnectionRuntimeAttribute := {
+ subscribedTestcases := {},
+ socket := -1,
+ endpointIndex := -1,
+ sctpState := SCTP_COMM_LOST,
+ userState := ""
+}
+
+//=========================================================================
+// Templates
+//=========================================================================
+
+template IPDD_Message_with_ClientId t_IPDD_Message_with_ClientId := {
+ client_id := ?,
+ msg := ?
+}
+
+template IPDD_Message_with_ClientId t_queryConnections modifies t_IPDD_Message_with_ClientId := {
+ msg := {
+ ipdd_queryConnections := ?
+ }
+}
+
+template IPDD_Message_with_ClientId t_connect modifies t_IPDD_Message_with_ClientId := {
+ msg := {
+ ipdd_connect := ?
+ }
+}
+
+template IPDD_Message_with_ClientId t_listen modifies t_IPDD_Message_with_ClientId := {
+ msg := {
+ ipdd_listen := ?
+ }
+}
+
+template IPDD_Message_with_ClientId t_close modifies t_IPDD_Message_with_ClientId := {
+ msg := {
+ ipdd_close := ?
+ }
+}
+
+template IPDD_Message_with_ClientId t_ipData modifies t_IPDD_Message_with_ClientId := {
+ msg := {
+ ipdd_data := ?
+ }
+}
+
+template IPDD_Message_with_ClientId t_subscribeToConnection modifies t_IPDD_Message_with_ClientId := {
+ msg := {
+ ipdd_subscribeToConnection := ?
+ }
+}
+
+//SCTP Assoc Change
+template ASP_Event tr_sctpEvent
+( template integer pl_connectionID,
+ template SAC_STATE pl_state
+) :=
+{
+ sctpEvent :=
+ {
+ sctpAssocChange :=
+ {
+ clientId := pl_connectionID,
+ proto :=
+ {
+ sctp := ?
+ },
+ sac_state := pl_state
+ }
+ }
+}
+
+//SCTP ShutdownEvent
+template ASP_Event tr_S_SCTP_ShutdownEvent:=
+{
+ sctpEvent :=
+ {
+ sctpShutDownEvent :=
+ {
+ clientId := ?
+ }
+ }
+}
+
+//Result
+template ASP_Event tr_ASP_Result :=
+{
+ result :=
+ {
+ errorCode := *,
+ connId := *,
+ os_error_code := *,
+ os_error_text := *
+ }
+}
+
+//IP Connected
+template ASP_Event tr_ASP_IP_Connected:=
+{
+ connOpened :=
+ {
+ connId := ?,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ proto := ?,
+ userData := ?
+ }
+}
+
+//IP Closed
+template ASP_Event tr_ASP_IP_Closed :=
+{
+ connClosed :=
+ {
+ connId := ?,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ proto := ?,
+ userData := ?
+ }
+}
+
+//SCTP Peer Address Change
+template ASP_Event tr_S_SCTP_PeerAddressChange:=
+{
+ sctpEvent :=
+ {
+ sctpPeerAddrChange :=
+ {
+ clientId :=?,
+ spc_state := ?
+ }
+ }
+}
+
+//TCP Connection Openned
+template ASP_Event tr_ASP_TCP_Connected :=
+{
+ connOpened :=
+ {
+ connId := ?,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ proto :={tcp:={}},
+ userData := ?
+ }
+}
+
+
+//TCP Close Connection
+template ASP_Event tr_ASP_TCP_Close:=
+{
+ connClosed :=
+ {
+ connId := ?,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ proto :={tcp:={}},
+ userData := ?
+ }
+}
+
+} // end of module