First code commit
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/SCTP_Daemon_Dynamic_CNL113630.tpd b/SCTP_Daemon_Dynamic_CNL113630.tpd
new file mode 100644
index 0000000..e6c2931
--- /dev/null
+++ b/SCTP_Daemon_Dynamic_CNL113630.tpd
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TITAN_Project_File_Information version="1.0">
+ <ProjectName>SCTP_Daemon_Dynamic_CNL113630</ProjectName>
+ <ReferencedProjects>
+ <ReferencedProject name="IPL4asp_CNL113531" projectLocationURI="../../TestPorts/IPL4asp_CNL113531/IPL4asp_CNL113531.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"/>
+ <FolderResource projectRelativePath="src" relativeURI="src"/>
+ </Folders>
+ <Files>
+ <FileResource projectRelativePath="doc/IR_doc.doc" relativeURI="doc/IR_doc.doc"/>
+ <FileResource projectRelativePath="doc/IR_src.doc" relativeURI="doc/IR_src.doc"/>
+ <FileResource projectRelativePath="doc/SCTP_Daemon_Dynamic_CNL113630_FS.doc" relativeURI="doc/SCTP_Daemon_Dynamic_CNL113630_FS.doc"/>
+ <FileResource projectRelativePath="doc/SCTP_Daemon_Dynamic_CNL113630_FS.pdf" relativeURI="doc/SCTP_Daemon_Dynamic_CNL113630_FS.pdf"/>
+ <FileResource projectRelativePath="doc/SCTP_Daemon_Dynamic_CNL113630_PRI.doc" relativeURI="doc/SCTP_Daemon_Dynamic_CNL113630_PRI.doc"/>
+ <FileResource projectRelativePath="doc/SCTP_Daemon_Dynamic_CNL113630_PRI.pdf" relativeURI="doc/SCTP_Daemon_Dynamic_CNL113630_PRI.pdf"/>
+ <FileResource projectRelativePath="doc/SCTP_Daemon_Dynamic_CNL113630_UG.doc" relativeURI="doc/SCTP_Daemon_Dynamic_CNL113630_UG.doc"/>
+ <FileResource projectRelativePath="doc/SCTP_Daemon_Dynamic_CNL113630_UG.pdf" relativeURI="doc/SCTP_Daemon_Dynamic_CNL113630_UG.pdf"/>
+ <FileResource projectRelativePath="src/SCTP_Daemon_Dynamic.ttcn" relativeURI="src/SCTP_Daemon_Dynamic.ttcn"/>
+ <FileResource projectRelativePath="src/SCTP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc" relativeURI="src/SCTP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc"/>
+ <FileResource projectRelativePath="src/SCTP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn" relativeURI="src/SCTP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn"/>
+ <FileResource projectRelativePath="src/SCTP_Daemon_Dynamic_Interface_Definitions.ttcn" relativeURI="src/SCTP_Daemon_Dynamic_Interface_Definitions.ttcn"/>
+ <FileResource projectRelativePath="src/SCTP_Daemon_Dynamic_Types.ttcn" relativeURI="src/SCTP_Daemon_Dynamic_Types.ttcn"/>
+ </Files>
+ <ActiveConfiguration>Default</ActiveConfiguration>
+ <Configurations>
+ <Configuration name="Default">
+ <ProjectProperties>
+ <MakefileSettings>
+ <generateInternalMakefile>true</generateInternalMakefile>
+ <GNUMake>true</GNUMake>
+ <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+ <targetExecutable>bin/SCTP_Daemon_Dynamic_CNL113630</targetExecutable>
+ <buildLevel>Level 3 - Creating object files with dependency update</buildLevel>
+ </MakefileSettings>
+ <LocalBuildSettings>
+ <workingDirectory>bin</workingDirectory>
+ </LocalBuildSettings>
+ </ProjectProperties>
+ <FolderProperties>
+ <FolderResource>
+ <FolderPath>doc</FolderPath>
+ <FolderProperties>
+ <ExcludeFromBuild>true</ExcludeFromBuild>
+ </FolderProperties>
+ </FolderResource>
+ </FolderProperties>
+ </Configuration>
+ </Configurations>
+</TITAN_Project_File_Information>
\ No newline at end of file
diff --git a/demo/SCTP_Daemon_Dynamic.cfg b/demo/SCTP_Daemon_Dynamic.cfg
new file mode 100644
index 0000000..53b39de
--- /dev/null
+++ b/demo/SCTP_Daemon_Dynamic.cfg
@@ -0,0 +1,74 @@
+[MODULE_PARAMETERS]
+tsp_SDD_AssociationList :=
+{
+ {
+ serverAssociation := true, // true := server, false: client
+ autoReconnect := false,
+ localInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "172.31.21.197",
+ portNumber := 33333//(1..65535)
+ },
+ remoteInterface := omit
+ },
+ {
+ serverAssociation := false, // true := server, false: client
+ autoReconnect := false,
+ localInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "172.31.21.197",
+ portNumber := 60000//(1..65535)
+ },
+ remoteInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "172.31.21.197",
+ portNumber := 33333//(1..65535)
+ }
+ },
+ {
+ serverAssociation := false, // true := server, false: client
+ autoReconnect := false,
+ localInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "172.31.21.197",
+ portNumber := 60001//(1..65535)
+ },
+ remoteInterface :=
+ {
+ hostNameLength := 0,
+ hostName := "172.31.21.197",
+ portNumber := 33333//(1..65535)
+ }
+ }
+};
+
+[LOGGING]
+MatchingHints := Compact
+AppendFile := No
+TimeStampFormat := Time
+LogEntityName := Yes
+LogEventTypes := Yes
+LogFile := "sctp_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]
+*.SCTP_PCO.server_mode := "NO"
+*.*.extendedPortEvents := "YES"
+*.daemonPort.socket_debugging := "NO"
+*.daemonPort.use_connection_ASPs := "YES"
+*.daemonPort.packet_hdr_length_offset := "2"
+*.daemonPort.packet_hdr_nr_bytes_in_length := "2"
+*.daemonPort.packet_hdr_byte_order := "MSB"
+
+[EXECUTE]
+#SCTP_Daemon_Dynamic.tc_SDD
+SCTP_Daemon_Dynamic_with_DiameterAutoReplies.tc_SDD_with_DiameterAutoReplies
diff --git a/demo/SCTP_Daemon_Dynamic_Test.cfg b/demo/SCTP_Daemon_Dynamic_Test.cfg
new file mode 100644
index 0000000..e75019f
--- /dev/null
+++ b/demo/SCTP_Daemon_Dynamic_Test.cfg
@@ -0,0 +1,24 @@
+[LOGGING]
+ConsoleMask := USER
+LogFile := "sctp_daemon_test.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]
+
+*.daemonPort.socket_debugging := "NO"
+*.daemonPort.use_connection_ASPs := "YES"
+*.daemonPort.packet_hdr_length_offset := "2"
+*.daemonPort.packet_hdr_nr_bytes_in_length := "2"
+*.daemonPort.packet_hdr_byte_order := "MSB"
+
+[EXECUTE]
+SCTP_Daemon_Dynamic_Test.tc_InitClientServer_StopServer_CheckClientAssocChange
+SCTP_Daemon_Dynamic_Test.tc_InitClientServer_StopServer_StartServer_CheckClientAssocChange
+SCTP_Daemon_Dynamic_Test.tc_InitClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer
+SCTP_Daemon_Dynamic_Test.tc_3Servers_and_3Clients
+SCTP_Daemon_Dynamic_Test.tc_AutoReplyDeviceWatchdog
diff --git a/demo/SCTP_Daemon_Dynamic_Test.ttcn b/demo/SCTP_Daemon_Dynamic_Test.ttcn
new file mode 100644
index 0000000..32892b3
--- /dev/null
+++ b/demo/SCTP_Daemon_Dynamic_Test.ttcn
@@ -0,0 +1,715 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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_Test.ttcn
+// Description: SDD test
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2010-11-26
+// Contact: http://ttcn.ericsson.se
+
+module SCTP_Daemon_Dynamic_Test
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from SCTP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+import from SCTP_Daemon_Dynamic_IPL4_CtrlFunct all;
+//=========================================================================
+// Module Parameters
+//=========================================================================
+
+modulepar {
+
+ // Host name where the SCTP Daemon listens for the testcases
+ charstring tsp_SDD_Host := "127.0.0.1";
+
+ // Port number where the SCTP Daemon listens for the testcases
+ integer tsp_SDD_Port := 1314;
+
+ //charstring tsp_remoteHost := "127.0.0.1";
+ //integer tsp_remotePort := 1315;
+
+ charstring tsp_serverInterface := "127.0.0.1";
+ integer tsp_serverPort := 1315;
+}
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+// Insert data type defintions here if applicable!
+// You can use the data_type skeleton!
+
+//=========================================================================
+//Port Types
+//=========================================================================
+
+// Insert port type defintions here if applicable!
+// You can use the port_type skeleton!
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+type component MAIN_CT {
+ port SDD_Interface_PT daemonPort;
+
+ var SDD_Message_with_ClientId vc_daemonMessage;
+
+ var integer vc_tcp_client_id;
+ var integer vc_serverAssociationId := -1;
+ var integer vc_clientAssociationId := -1;
+ var integer vc_connectedClientAssociationId := -1;
+}
+
+//=========================================================================
+// 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_SDD() 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 := SCTP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_connect
+ (
+ daemonPort,
+ tsp_SDD_Host,
+ tsp_SDD_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 SCTP Daemon2 on " & tsp_SDD_Host & ":" & int2str(tsp_SDD_Port));
+ vc_tcp_client_id := vl_result.connId;
+
+ var f_IPL4_getMsgLen sdd_msglen := refers(f_SDD_getMsgLen);
+ f_IPL4_setGetMsgLen(daemonPort,vc_tcp_client_id,sdd_msglen,{});
+
+ }else{
+ log("Could not connect to the SCTP Daemon2 on " & tsp_SDD_Host & ":" & int2str(tsp_SDD_Port));
+ }
+ t_wait.start(2.0); t_wait.timeout;
+}
+
+// initialize a server and a client connection if they are not already present
+function f_Init_SCTP_Client(in charstring remoteIf, in integer remotePort) runs on MAIN_CT {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, { queryAssociations := { 0 } } });
+
+ timer t_wait := 5.0; t_wait.start;
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : { ?, { associations := ? } }) -> value vc_daemonMessage {
+ vc_clientAssociationId := -1;
+ for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.associations.associationList); i := i + 1) {
+ if((vc_clientAssociationId < 0) and ispresent(vc_daemonMessage.msg.associations.associationList[i].remoteInterface)) {
+ if(vc_daemonMessage.msg.associations.associationList[i].remoteInterface.hostName == remoteIf and
+ vc_daemonMessage.msg.associations.associationList[i].remoteInterface.portNumber == remotePort) {
+ vc_clientAssociationId := vc_daemonMessage.msg.associations.associationList[i].associationId;
+ }
+ }
+ }
+
+ if(vc_clientAssociationId < 0) {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpConnect := {
+ messageType := 0, // use dummy value
+ autoReconnect := true,
+ localInterfacePresent := false, // enter always false
+ localInterface :={
+ hostNameLength := 0, // use dummy value
+ hostName := remoteIf,
+ portNumber := remotePort + 1000
+ },
+ remoteInterface := {
+ hostNameLength := 0, // use dummy value
+ hostName := remoteIf,
+ portNumber := remotePort
+ }
+ }
+ }});
+
+ t_wait.stop; t_wait.start;
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : { vc_tcp_client_id, { sctpResult := ? } }) -> value vc_daemonMessage {
+ if(not vc_daemonMessage.msg.sctpResult.errorStatus) {
+ vc_clientAssociationId := vc_daemonMessage.msg.sctpResult.associationId;
+ } else {
+ log("*** ERROR: error response received for defineClientAssociation: " ,vc_daemonMessage.msg.sctpResult);
+ setverdict(fail);
+ }
+ repeat;
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId : { vc_tcp_client_id, { sctpConnected := ? } }) -> value vc_daemonMessage {
+ log("*** INFO: Client connected: ", vc_daemonMessage);
+ vc_connectedClientAssociationId := vc_daemonMessage.msg.sctpConnected.associationId;
+ repeat;
+ }
+ [] t_wait.timeout {
+ if((vc_clientAssociationId==-1) and (vc_connectedClientAssociationId==-1)){
+ log("*** ERROR: no response to defineClientAssociation!");
+ setverdict(fail);
+ }
+ }
+ }
+ } else {
+ log("*** INFO: Client association is already defined, subscribing to it...");
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ subscribeToAssociation := {
+ messageType := 0,
+ associationId := vc_clientAssociationId
+ }
+ }
+ });
+ }
+ }
+
+ [] daemonPort.receive {
+ log("INFO: dropping this message.");
+ }
+
+ [] t_wait.timeout {
+ log("Error: there is no response for association list query!");
+ }
+ }
+ log("vc_clientAssociationId: ",vc_clientAssociationId);
+ log("vc_connectedClientAssociationId: ",vc_connectedClientAssociationId);
+}
+
+
+function f_Init_SCTP_Server(in charstring localIf, in integer localPort) runs on MAIN_CT {
+
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, { queryAssociations := { 0 } } });
+
+ timer t_wait := 5.0; t_wait.start;
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : { ?, { associations := ? } }) -> value vc_daemonMessage {
+ vc_serverAssociationId := -1;
+ for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.associations.associationList); i := i + 1) {
+ if((vc_serverAssociationId < 0) and ispresent(vc_daemonMessage.msg.associations.associationList[i].localInterface)) {
+ if(vc_daemonMessage.msg.associations.associationList[i].localInterface.hostName == localIf and
+ vc_daemonMessage.msg.associations.associationList[i].localInterface.portNumber == localPort) {
+ vc_serverAssociationId := vc_daemonMessage.msg.associations.associationList[i].associationId;
+ }
+ }
+
+ // connected client: not server and the local interface is the same as the server's local interface
+ if((vc_connectedClientAssociationId < 0) and ispresent(vc_daemonMessage.msg.associations.associationList[i].localInterface)) {
+ if(not vc_daemonMessage.msg.associations.associationList[i].serverAssociation and
+ vc_daemonMessage.msg.associations.associationList[i].localInterface.hostName == localIf and
+ vc_daemonMessage.msg.associations.associationList[i].localInterface.portNumber == localPort) {
+ vc_connectedClientAssociationId := vc_daemonMessage.msg.associations.associationList[i].associationId;
+ }
+ }
+ }
+
+ if(vc_connectedClientAssociationId > -1) {
+ log("*** INFO: Server's connected client association is already present, subscribing to it...");
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ subscribeToAssociation := {
+ messageType := 0,
+ associationId := vc_connectedClientAssociationId
+ }
+ }
+ });
+ }
+
+ if(vc_serverAssociationId < 0) {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpListen := {
+ messageType := 0, // use dummy value
+ localInterface := {
+ hostNameLength := 0, // use dummy value
+ hostName := localIf,
+ portNumber := localPort
+ }
+ }
+ } });
+
+ t_wait.stop; t_wait.start;
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : { vc_tcp_client_id, { sctpResult := ? } }) -> value vc_daemonMessage {
+ log("Received result message: ",vc_daemonMessage);
+ if(not vc_daemonMessage.msg.sctpResult.errorStatus) {
+ vc_serverAssociationId := vc_daemonMessage.msg.sctpResult.associationId;
+ } else {
+ log("*** ERROR: error response received for defineServerAssociation: ", vc_daemonMessage.msg.sctpResult);
+ setverdict(fail);
+ }
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId:?) {
+ log("Message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** ERROR: no response to defineServerAssociation!");
+ setverdict(fail);
+ }
+ }
+ } else {
+ log("*** INFO: Server association is already defined, subscribing to it...");
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ subscribeToAssociation := {
+ messageType := 0,
+ associationId := vc_serverAssociationId
+ }
+ }
+ });
+ }
+ }
+
+ [] daemonPort.receive {
+ log("INFO: dropping this message.");
+ repeat;
+ }
+
+ [] t_wait.timeout {
+ log("Error: there is no response for association list query!");
+ }
+ }
+ log("vc_serverAssociationId: ",vc_serverAssociationId);
+ log("vc_connectedClientAssociationId: ",vc_connectedClientAssociationId);
+}
+
+function f_StopServer() runs on MAIN_CT {
+ if(vc_connectedClientAssociationId > 0) {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpClose := { messageType := 0, associationId := vc_connectedClientAssociationId }
+ }});
+ }
+
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpClose := { messageType := 0, associationId := vc_serverAssociationId }
+ }});
+}
+
+function f_StopClient() runs on MAIN_CT {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpClose := { messageType := 0, associationId := vc_clientAssociationId }
+ }});
+}
+
+// initialize a server and a client connection if they are not already present
+function f_StopMyAssociations() runs on MAIN_CT {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, { queryAssociations := { 0 } } });
+
+ timer t_wait := 5.0; t_wait.start;
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : { ?, { associations := ? } }) -> value vc_daemonMessage {
+ log("Current associations: ", vc_daemonMessage.msg.associations.associationList);
+ vc_clientAssociationId := -1;
+ for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.associations.associationList); i := i + 1) {
+ if(ispresent(vc_daemonMessage.msg.associations.associationList[i].localInterface)) {
+ if(vc_daemonMessage.msg.associations.associationList[i].localInterface.hostName == tsp_serverInterface) {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpClose := { messageType := 0, associationId := vc_daemonMessage.msg.associations.associationList[i].associationId }
+ }});
+ }
+ }
+
+ if(ispresent(vc_daemonMessage.msg.associations.associationList[i].remoteInterface)) {
+ if(vc_daemonMessage.msg.associations.associationList[i].remoteInterface.hostName == tsp_serverInterface) {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpClose := { messageType := 0, associationId := vc_daemonMessage.msg.associations.associationList[i].associationId }
+ }});
+ }
+ }
+ }
+ }
+
+ [] t_wait.timeout {
+ log("Error: there is no response for association list query!");
+ }
+ }
+}
+
+function f_CheckClientAssociation_Gets(in SAC_STATE pl_state) runs on MAIN_CT {
+ timer t_wait := 55.0; t_wait.start;
+ log("WAITING: waiting client association #", vc_clientAssociationId, " to report state: ", pl_state);
+
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ associationChanged := {
+ messageType := ?,
+ associationId := vc_clientAssociationId,
+ state := pl_state
+ }
+ }
+ }) {
+ log("*** PASS: associationStateChanged ", pl_state, " received!");
+ setverdict(pass);
+ /*if(pl_state == SCTP_COMM_LOST) {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ closeAssociation := { messageType := 0, associationId := vc_clientAssociationId }
+ }});
+ }*/
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId:?){
+ log("Message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** FAIL: No associationStateChanged ", pl_state," received!");
+ setverdict(fail);
+ }
+ }
+}
+
+function f_serverWaitForConnection() runs on MAIN_CT {
+ timer t_wait := 55.0; t_wait.start;
+ log("WAITING: waiting for client connection");
+ var SDD_Message_with_ClientId vl_msg;
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ sctpConnected := ?
+ }
+ }) -> value vl_msg
+ {
+ log("*** PASS: Connected! ");
+ vc_serverAssociationId := vl_msg.msg.sctpConnected.associationId;
+ setverdict(pass);
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId:?) {
+ log("Message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** FAIL: No connection was received!");
+ setverdict(fail);
+ }
+ }
+}
+
+function f_sendDataFromClient(in octetstring dataToSend) runs on MAIN_CT {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpData := {
+ messageType := 0, // encoder will replace
+ associationId := vc_clientAssociationId,
+ sinfo_stream := 11,
+ sinfo_ppid := 22,
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+}
+
+
+function f_sendDataFromServer(in octetstring dataToSend) runs on MAIN_CT {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpData := {
+ messageType := 0, // encoder will replace
+ associationId := vc_serverAssociationId,
+ sinfo_stream := 11,
+ sinfo_ppid := 22,
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+}
+
+
+function f_sendData(in integer assocId, in octetstring dataToSend) runs on MAIN_CT {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpData := {
+ messageType := 0, // encoder will replace
+ associationId := assocId,
+ sinfo_stream := 11,
+ sinfo_ppid := 22,
+ dataLength := 0, // encoder will replace
+ data := dataToSend
+ }
+ }});
+}
+
+function f_CheckDataReceive(in integer associationId, in octetstring dataToReceive) runs on MAIN_CT {
+ timer t_wait := 5.0; t_wait.start;
+
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ sctpData := {
+ messageType := ?,
+ associationId := associationId,
+ sinfo_stream := 11,
+ sinfo_ppid := ?,//22,
+ dataLength := ?,
+ data := dataToReceive
+ }
+ }
+ }) {
+ log("*** PASS: sctpData ", dataToReceive, " received!");
+ setverdict(pass);
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId:?) {
+ log("Message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** FAIL: No sctpData ", dataToReceive, " received!");
+ setverdict(fail);
+ }
+ }
+}
+
+function f_CheckDataReceive_noOtherData(in template integer associationId, in template octetstring dataToReceive) runs on MAIN_CT {
+ timer t_wait := 5.0; t_wait.start;
+
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ sctpData := {
+ messageType := ?,
+ associationId := associationId,
+ sinfo_stream := 11,
+ sinfo_ppid := ?,//22,
+ dataLength := ?,
+ data := dataToReceive
+ }
+ }
+ }) {
+ log("*** PASS: sctpData ", dataToReceive, " received!");
+ setverdict(pass);
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ sctpData := {
+ messageType := ?,
+ associationId := associationId,
+ sinfo_stream := 11,
+ sinfo_ppid := ?,//22,
+ dataLength := ?,
+ data := ?
+ }
+ }
+ }) {
+ log("*** FAIL: invalid sctpData received!");
+ setverdict(fail);
+ repeat;
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId:?) {
+ log("Message ignored.");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("*** FAIL: No sctpData ", 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 SDD_Message_with_ClientId vl_inc;
+
+ alt {
+ [] daemonPort.receive(SDD_Message_with_ClientId : {
+ client_id := vc_tcp_client_id,
+ msg := {
+ sctpData := {
+ messageType := ?,
+ associationId := ?,
+ sinfo_stream := 11,
+ sinfo_ppid := ?,//22,
+ dataLength := ?,
+ data := ?
+ }
+ }
+ }) -> value vl_inc
+ {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_tcp_client_id, {
+ sctpData := {
+ messageType := 0, // encoder will replace
+ associationId := vc_serverAssociationId,
+ sinfo_stream := 11,
+ sinfo_ppid := 22,
+ dataLength := 0, // encoder will replace
+ data := vl_inc.msg.sctpData.data
+ }
+ }});
+ repeat;
+ }
+ [] daemonPort.receive(SDD_Message_with_ClientId:?) {
+ log("Message ignored in Echo mode");
+ repeat;
+ }
+ [] t_wait.timeout {
+ log("Exiting from echo service");
+ }
+ }
+}
+
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_InitClientServer_StopServer_CheckClientAssocChange() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+ f_StopServer();
+
+ f_CheckClientAssociation_Gets(SCTP_COMM_LOST);
+
+ f_StopClient();
+
+ //timer t_wait := 5.0; t_wait.start; t_wait.timeout;
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_InitClientServer_StopServer_StartServer_CheckClientAssocChange() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+ f_CheckClientAssociation_Gets(SCTP_COMM_UP);
+
+ f_StopServer();
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+
+ f_CheckClientAssociation_Gets(SCTP_COMM_UP);
+
+ f_StopServer();
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_InitClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+
+ // could be sending ASP_TCP_Close too
+ unmap(mtc:daemonPort, system:daemonPort);
+
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+
+ f_sendDataFromClient('EEDDAADD'O);
+
+ f_CheckDataReceive(vc_connectedClientAssociationId, 'EEDDAADD'O);
+
+ f_StopServer();
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_3Servers_and_3Clients() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ vc_connectedClientAssociationId := -1;
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort + 2);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort + 2);
+ f_sendDataFromClient('EEDDAADD00'O);
+ f_CheckDataReceive(vc_connectedClientAssociationId, 'EEDDAADD00'O);
+
+ vc_connectedClientAssociationId := -1;
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort + 1);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort + 1);
+ f_sendDataFromClient('EEDDAADD11'O);
+ f_CheckDataReceive(vc_connectedClientAssociationId, 'EEDDAADD11'O);
+
+ vc_connectedClientAssociationId := -1;
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+ f_sendDataFromClient('EEDDAADD22'O);
+ f_CheckDataReceive(vc_connectedClientAssociationId, 'EEDDAADD22'O);
+
+
+ f_StopMyAssociations();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_AutoReplyDeviceWatchdog() runs on MAIN_CT {
+ map(mtc:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+
+ // 4th byte/bit1: request == 0
+ // 5-7th byte: 280 == hex 118
+ f_sendDataFromClient('00112200000118778899AABBCCDDEEFF'O);
+
+ // 4th byte/bit1: reply == 1
+ f_CheckDataReceive(vc_clientAssociationId, '00112280000118778899AABBCCDDEEFF'O);
+
+ f_StopServer();
+ f_StopClient();
+
+ unmap(mtc:daemonPort, system:daemonPort);
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+ execute(tc_InitClientServer_StopServer_CheckClientAssocChange());
+ execute(tc_InitClientServer_StopServer_StartServer_CheckClientAssocChange());
+ execute(tc_InitClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer());
+ execute(tc_AutoReplyDeviceWatchdog());
+}
+
+} // end of module
diff --git a/demo/SCTP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn b/demo/SCTP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
new file mode 100644
index 0000000..aff5777
--- /dev/null
+++ b/demo/SCTP_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: SCTP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
+// Description: SDD behaviour with Diameter Auto Replies
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2010-11-24
+// Contact: http://ttcn.ericsson.se
+
+module SCTP_Daemon_Dynamic_with_DiameterAutoReplies
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from SCTP_Daemon_Dynamic all;
+import from SCTP_Daemon_Dynamic_Types all;
+import from SCTP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+
+type record of boolean BooleanList;
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+//type component DIAMETER_SDD_CT extends SDD_CT {
+// var BooleanList vc_userStates := {};
+//}
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_HandleDeviceWatchdog(in integer associationIndex, in ASP_RecvFrom sctpReceived, out ASP_Send sctpReply)
+runs on SDD_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 SDD_CT
+return boolean {
+ if(newState == SCTP_COMM_UP) {
+ if(vc_associationRuntimeAttributesList[associationIndex].userState == "") {
+ sctpMsg := {
+ vc_associationRuntimeAttributesList[associationIndex].socket,
+ {sctp:={0,0,omit,omit}},
+ 'AABBCCDDEEFF'O
+ }
+ return true;
+ }
+ } else if(vc_associationRuntimeAttributesList[associationIndex].userState == "INITIALIZED") {
+ // do something different
+ } else {
+ log("ERROR: unhandled user state ", vc_associationRuntimeAttributesList[associationIndex].userState);
+ }
+
+
+ return false;
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_SDD_with_DiameterAutoReplies() runs on SDD_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 SCTP Daemon's main function
+ f_SDD();
+
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+ execute(tc_SDD_with_DiameterAutoReplies());
+}
+
+} // end of module
diff --git a/demo/SDD.prj b/demo/SDD.prj
new file mode 100644
index 0000000..32ada3e
--- /dev/null
+++ b/demo/SDD.prj
@@ -0,0 +1,62 @@
+<!DOCTYPE TITAN_GUI_project_file>
+<Project TITAN_version="1.8.pl4" >
+ <General>
+ <Project_Name>SDD</Project_Name>
+ <Executable_Path>bin/SDD</Executable_Path>
+ <Working_Dir>bin</Working_Dir>
+ <Build_Host>alpha</Build_Host>
+ <Execution_Mode>Parallel</Execution_Mode>
+ <Code_Splitting_Mode>None</Code_Splitting_Mode>
+ <ScriptFile_AfterMake>lksctp107_script</ScriptFile_AfterMake>
+ <Log_Format>yes</Log_Format>
+ <Update_Symlinks>yes</Update_Symlinks>
+ <Create_Absolute_Symlinks>no</Create_Absolute_Symlinks>
+ <Update_Makefile>yes</Update_Makefile>
+ <Localhost_Execute>yes</Localhost_Execute>
+ <Execute_Command>rsh %host "cd %project_working_dir ; "%executable" %localhost %mctr_port"</Execute_Command>
+ <Execute_Hosts>alfa, beta, gamma</Execute_Hosts>
+ <UnUsed_List></UnUsed_List>
+ </General>
+ <Modules>
+ <Module>../src/SCTP_Daemon_Dynamic_Interface_Definitions.ttcn</Module>
+ <Module>../src/SCTP_Daemon_Dynamic.ttcn</Module>
+ <Module>../src/SCTP_Daemon_Dynamic_Types.ttcn</Module>
+ <Module>../src/SCTP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn</Module>
+ <Module>SCTP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn</Module>
+ </Modules>
+ <Other_Sources>
+ <Other_Source>../src/SCTP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc</Other_Source>
+ </Other_Sources>
+ <Configs>
+ <Config>SCTP_Daemon_Dynamic.cfg</Config>
+ </Configs>
+ <Test_Cases>
+ <Test_Case>SCTP_Daemon_Dynamic.control</Test_Case>
+ <Test_Case>SCTP_Daemon_Dynamic.tc_SDD</Test_Case>
+ <Test_Case>SCTP_Daemon_Dynamic_with_DiameterAutoReplies.control</Test_Case>
+ <Test_Case>SCTP_Daemon_Dynamic_with_DiameterAutoReplies.tc_SDD_with_DiameterAutoReplies</Test_Case>
+ </Test_Cases>
+ <File_Group name="MainFileGroup" >
+ <File_Groups>
+ <File_Group name="IPL4" >
+ <File path="../../../TestPorts/IPL4asp_CNL113531/src/IPL4asp_discovery.cc" />
+ <File path="../../../TestPorts/IPL4asp_CNL113531/src/IPL4asp_Functions.ttcn" />
+ <File path="../../../TestPorts/IPL4asp_CNL113531/src/IPL4asp_PortType.ttcn" />
+ <File path="../../../TestPorts/IPL4asp_CNL113531/src/IPL4asp_protocol_L234.hh" />
+ <File path="../../../TestPorts/IPL4asp_CNL113531/src/IPL4asp_PT.cc" />
+ <File path="../../../TestPorts/IPL4asp_CNL113531/src/IPL4asp_PT.hh" />
+ <File path="../../../TestPorts/IPL4asp_CNL113531/src/IPL4asp_Types.ttcn" />
+ </File_Group>
+ <File_Group name="TCC" >
+ <File path="../../../Libraries/TCCUsefulFunctions_CNL113472/src/TCCInterface.cc" />
+ <File path="../../../Libraries/TCCUsefulFunctions_CNL113472/src/TCCInterface_Functions.ttcn" />
+ <File path="../../../Libraries/TCCUsefulFunctions_CNL113472/src/TCCInterface_ip.h" />
+ </File_Group>
+ <File_Group name="Common" >
+ <File path="../../../TestPorts/Common_Components/Abstract_Socket_CNL113384/src/Abstract_Socket.cc" />
+ <File path="../../../TestPorts/Common_Components/Abstract_Socket_CNL113384/src/Abstract_Socket.hh" />
+ <File path="../../../TestPorts/Common_Components/Socket_API_CNL113686/src/Socket_API_Definitions.ttcn" />
+ </File_Group>
+ </File_Groups>
+ </File_Group>
+</Project>
diff --git a/demo/SGsAP_SCTP_Daemon.cfg b/demo/SGsAP_SCTP_Daemon.cfg
new file mode 100644
index 0000000..7bbb9d8
--- /dev/null
+++ b/demo/SGsAP_SCTP_Daemon.cfg
@@ -0,0 +1,36 @@
+[MODULE_PARAMETERS]
+tsp_SDD_TCP_ListenPort := 1334;
+tsp_debug := true;
+tsp_SGsAP_enableDebug := true;
+tsp_SDD_AssociationList :=
+{
+};
+
+[LOGGING]
+MatchingHints := Compact
+AppendFile := No
+TimeStampFormat := Time
+LogEntityName := Yes
+LogEventTypes := Yes
+LogFile := "sctp_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]
+*.SCTP_PCO.server_mode := "NO"
+
+*.daemonPort.socket_debugging := "NO"
+*.daemonPort.use_connection_ASPs := "YES"
+*.daemonPort.packet_hdr_length_offset := "2"
+*.daemonPort.packet_hdr_nr_bytes_in_length := "2"
+*.daemonPort.packet_hdr_byte_order := "MSB"
+*.*.extendedPortEvents := "YES"
+*.*.debug := "yes"
+
+[EXECUTE]
+SGsAP_SCTP_Daemon.control
+
diff --git a/demo/SGsAP_SCTP_Daemon.ttcn b/demo/SGsAP_SCTP_Daemon.ttcn
new file mode 100644
index 0000000..db10cb9
--- /dev/null
+++ b/demo/SGsAP_SCTP_Daemon.ttcn
@@ -0,0 +1,286 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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: SGsAP_SCTP_Daemon.ttcn
+// Description: SGsAP SDD behavior
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2010-10-20
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+
+module SGsAP_SCTP_Daemon
+
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from SGsAP_SCTP_Daemon_Types all;
+import from SGsAP_Types all;
+import from SCTP_Daemon_Dynamic all;
+import from SCTP_Daemon_Dynamic_Types all;
+import from EPTF_CLL_HashMapStr2Int_Functions all;
+import from EPTF_CLL_HashMapInt2Int_Functions all;
+import from EPTF_CLL_FBQ_Definitions all;
+import from EPTF_CLL_FBQ_Functions all;
+
+
+modulepar
+{
+ boolean tsp_SGsAP_enableDebug := false;
+}
+
+const charstring c_SGsAP_HashMap_Imsi2ConnDbIdx := "SGsAP_hashmap_imsi_connDbIdx";
+const charstring c_SGsAP_HashMap_ConnDbIdx2ConnId := "SGsAP_hashmap_connDbIdx_connId"
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_getIMSI_fromSGSAP(in octetstring pl_data, out charstring vl_imsi)
+return boolean
+{
+ f_SGsAP_debugLog(log2str(%definitionId, " enter"));
+
+ var PDU_SGsAP vl_PDU_SGsAP:=dec_PDU_SGsAP(pl_data);
+ var boolean vl_ret := true;
+
+ if (ischosen(vl_PDU_SGsAP.sGsAP_ALERT_ACK))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_ALERT_ACK.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_ALERT_REJECT))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_ALERT_REJECT.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_ALERT_REQUEST))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_ALERT_REQUEST.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_DOWNLINK_UNITDATA))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_DOWNLINK_UNITDATA.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_EPS_DETACH_ACK))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_EPS_DETACH_ACK.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_EPS_DETACH_INDICATION))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_EPS_DETACH_INDICATION.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_ACK))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_ACK.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_INDICATION))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_INDICATION.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_ACCEPT))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_ACCEPT.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REJECT))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REJECT.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REQUEST))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REQUEST.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_MM_INFORMATION_REQUEST))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_MM_INFORMATION_REQUEST.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_PAGING_REJECT))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_PAGING_REJECT.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_PAGING_REQUEST))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_PAGING_REQUEST.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_SERVICE_REQUEST))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_SERVICE_REQUEST.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_STATUS))
+ {
+ if (ispresent(vl_PDU_SGsAP.sGsAP_STATUS.iMSI))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_STATUS.iMSI.iMSI.digits) }
+ else
+ { vl_ret := false; }
+ }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_TMSI_REALLOCATION_COMPLETE))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_TMSI_REALLOCATION_COMPLETE.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_UE_ACTIVITY_INDICATION))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_UE_ACTIVITY_INDICATION.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_UE_UNREACHABLE))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_UE_UNREACHABLE.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_UPLINK_UNITDATA))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_UPLINK_UNITDATA.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_RELEASE_REQUEST))
+ { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_RELEASE_REQUEST.iMSI.iMSI.digits) }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_RESET_ACK))
+ { vl_ret := false }
+ else if (ischosen(vl_PDU_SGsAP.sGsAP_RESET_INDICATION))
+ { vl_ret := false }
+ else
+ {
+ vl_ret := false;
+ log(%definitionId, " WARNING: Cannot fetch IMSI from SGsAP PDU: ", vl_PDU_SGsAP);
+ }
+
+ f_SGsAP_debugLog(log2str(%definitionId, " returns: ", vl_ret));
+
+ return vl_ret;
+}
+
+function f_SGsAP_SDD_getAllConnIds()
+runs on SGsAP_SDD_CT
+return TCP_connections_List
+{
+ f_SGsAP_debugLog(log2str(%definitionId, " enter"));
+
+ var TCP_connections_List vl_list := {};
+ var integer vl_idx := -1;
+
+ if (f_EPTF_FBQ_getBusyHeadIdx(vl_idx, v_connDB.queue))
+ {
+ vl_list[sizeof(vl_list)] := v_connDB.data[vl_idx].connId;
+ while(f_EPTF_FBQ_getFwdBusyItemIdx(vl_idx, v_connDB.queue))
+ {
+ vl_list[sizeof(vl_list)] := v_connDB.data[vl_idx].connId;
+ }
+ }
+
+ f_SGsAP_debugLog(log2str(%definitionId, " finished: ", vl_list));
+
+ return vl_list;
+}
+
+function f_SGsAP_SDD_Insert(octetstring pl_data, integer pl_id) runs on SGsAP_SDD_CT
+{
+ f_SGsAP_debugLog(log2str(%definitionId, " enter"));
+
+ var charstring vl_imsi := "";
+ var integer vl_connDbIdx := -1;
+ var integer vl_lookedUpConnDbIdx := -1;
+
+ if (f_getIMSI_fromSGSAP(pl_data, vl_imsi))
+ {
+ if (not f_EPTF_int2int_HashMap_Find(v_connDB.hashRef, pl_id, vl_connDbIdx))
+ {
+ vl_connDbIdx := f_EPTF_FBQ_getOrCreateFreeSlot(v_connDB.queue);
+ v_connDB.data[vl_connDbIdx] := ConnectionEntry_empty;
+ v_connDB.data[vl_connDbIdx].connId := pl_id;
+
+ f_EPTF_int2int_HashMap_Insert(v_connDB.hashRef, pl_id, vl_connDbIdx);
+
+ f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_connDB.queue);
+ }
+
+ if (not f_EPTF_str2int_HashMap_Find(v_imsi2connDbIdx, vl_imsi, vl_lookedUpConnDbIdx) or vl_connDbIdx != vl_lookedUpConnDbIdx)
+ {
+ v_connDB.data[vl_connDbIdx].imsiList[sizeof(v_connDB.data[vl_connDbIdx].imsiList)] := vl_imsi;
+ f_EPTF_str2int_HashMap_Insert(v_imsi2connDbIdx, vl_imsi, vl_connDbIdx);
+ }
+ }
+
+ f_SGsAP_debugLog(log2str(%definitionId, " finished"));
+}
+
+function f_SGsAP_SDD_Lookup(octetstring pl_data) runs on SGsAP_SDD_CT
+return TCP_connections_List
+{
+ f_SGsAP_debugLog(log2str(%definitionId, " enter"));
+
+ var TCP_connections_List vl_list := {};
+ var charstring vl_imsi := "";
+ var integer vl_connDbIdx := -1;
+
+ if (f_getIMSI_fromSGSAP(pl_data, vl_imsi))
+ {
+ if (f_EPTF_str2int_HashMap_Find(v_imsi2connDbIdx, vl_imsi, vl_connDbIdx))
+ {
+ vl_list := { v_connDB.data[vl_connDbIdx].connId }
+ }
+ else { log(%definitionId, "IMSI: ",vl_imsi," wasn't found in the SGsAP routing table: Dropping!"); }
+ }
+ else
+ {
+ vl_list := f_SGsAP_SDD_getAllConnIds();
+ }
+
+ f_SGsAP_debugLog(log2str(%definitionId, " returns: ", vl_list));
+
+ return vl_list;
+}
+
+function f_SGsAP_SDD_Delete(integer pl_id) runs on SGsAP_SDD_CT
+{
+ f_SGsAP_debugLog(log2str(%definitionId, " enter"));
+
+ var integer vl_connDbIdx := -1;
+
+ if (f_EPTF_int2int_HashMap_Find(v_connDB.hashRef, pl_id, vl_connDbIdx))
+ {
+ // Removing IMSI->ConnDbIdx mappings
+ for (var integer i:=0; i<sizeof(v_connDB.data[vl_connDbIdx].imsiList); i:=i+1)
+ {
+ var integer vl_imsiConn := -1;
+ if (f_EPTF_str2int_HashMap_Find(v_imsi2connDbIdx, v_connDB.data[vl_connDbIdx].imsiList[i], vl_imsiConn))
+ {
+ if (vl_imsiConn == vl_connDbIdx) { f_EPTF_str2int_HashMap_Erase(v_imsi2connDbIdx, v_connDB.data[vl_connDbIdx].imsiList[i]); }
+ else
+ {
+ // IMSI is already on an other connection
+ }
+ }
+ }
+
+ f_EPTF_int2int_HashMap_Erase(v_connDB.hashRef, pl_id);
+
+ if (f_EPTF_FBQ_itemIsBusy(vl_connDbIdx, v_connDB.queue))
+ {
+ f_EPTF_FBQ_moveFromBusyToFreeTail(vl_connDbIdx, v_connDB.queue);
+ }
+ }
+
+ f_SGsAP_debugLog(log2str(%definitionId, " finished"));
+}
+
+function f_SGsAP_SDD_init() runs on SGsAP_SDD_CT
+{
+ f_SGsAP_debugLog(log2str(%definitionId, " enter"));
+
+ f_EPTF_str2int_HashMap_Init();
+ f_EPTF_int2int_HashMap_Init();
+
+ v_imsi2connDbIdx := f_EPTF_str2int_HashMap_New(c_SGsAP_HashMap_Imsi2ConnDbIdx);
+
+ v_connDB.hashRef := f_EPTF_int2int_HashMap_New(c_SGsAP_HashMap_ConnDbIdx2ConnId);
+ v_connDB.data := {};
+ v_connDB.queue := c_EPTF_emptyFreeBusyQueue;
+
+ f_EPTF_FBQ_initFreeBusyQueue(v_connDB.queue);
+
+ v_Connection_Insert:=refers(f_SGsAP_SDD_Insert);
+ v_Connection_Lookup:=refers(f_SGsAP_SDD_Lookup);
+ v_Connection_Delete:=refers(f_SGsAP_SDD_Delete);
+
+ f_SGsAP_debugLog(log2str(%definitionId, " finished"));
+}
+
+function f_SGsAP_SDD_cleanUp() runs on SGsAP_SDD_CT
+{
+ f_SGsAP_debugLog(log2str(%definitionId, " enter"));
+
+ f_EPTF_str2int_HashMap_Delete(c_SGsAP_HashMap_Imsi2ConnDbIdx);
+ f_EPTF_int2int_HashMap_Delete(c_SGsAP_HashMap_ConnDbIdx2ConnId);
+
+ f_SGsAP_debugLog(log2str(%definitionId, " finished"));
+}
+
+function f_SGsAP_debugLog(in charstring p_log)
+{
+ if (tsp_SGsAP_enableDebug) { log(p_log); }
+}
+
+testcase tc_SGsAP_SDD() runs on SGsAP_SDD_CT
+{
+ f_SGsAP_SDD_init();
+
+ f_SDD();
+
+ f_SGsAP_SDD_cleanUp();
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control
+{
+ execute(tc_SGsAP_SDD());
+}
+
+} // end of module
diff --git a/demo/SGsAP_SCTP_Daemon_Test.cfg b/demo/SGsAP_SCTP_Daemon_Test.cfg
new file mode 100644
index 0000000..d42d2a0
--- /dev/null
+++ b/demo/SGsAP_SCTP_Daemon_Test.cfg
@@ -0,0 +1,32 @@
+[LOGGING]
+ConsoleMask := USER|STATISTICS|TESTCASE
+#LogFile := "sctp_daemon_test.log"
+SourceInfoFormat := Stack
+#ConsoleMask := STATISTICS|TESTCASE|ACTION|WARNING|ERROR|USER
+FileMask := LOG_ALL|DEBUG|WARNING|VERDICTOP|USER|TIMEROP|TESTCASE|STATISTICS|PORTEVENT|PARALLEL|FUNCTION|EXECUTOR|ERROR|DEFAULTOP|ACTION
+DiskFullAction := Error
+LogFileNumber := 1
+LogFileSize := 0
+
+[MODULE_PARAMETERS]
+#tsp_SDD_Port := 13105;
+#tsp_serverPort := 13115;
+
+tsp_debug := true;
+
+tsp_SDD_Port := 1334;
+tsp_serverPort := 1335;
+
+[TESTPORT_PARAMETERS]
+
+*.daemonPort.socket_debugging := "NO"
+*.daemonPort.use_connection_ASPs := "YES"
+*.daemonPort.packet_hdr_length_offset := "2"
+*.daemonPort.packet_hdr_nr_bytes_in_length := "2"
+*.daemonPort.packet_hdr_byte_order := "MSB"
+*.*.debug := "yes"
+
+[EXECUTE]
+SGsAP_SCTP_Daemon_Test.tc_SGsAP_lookup
+SGsAP_SCTP_Daemon_Test.tc_SGsAP_client
+SGsAP_SCTP_Daemon_Test.tc_SGsAP_clients
diff --git a/demo/SGsAP_SCTP_Daemon_Test.ttcn b/demo/SGsAP_SCTP_Daemon_Test.ttcn
new file mode 100644
index 0000000..6d2f8af
--- /dev/null
+++ b/demo/SGsAP_SCTP_Daemon_Test.ttcn
@@ -0,0 +1,225 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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: SGsAP_SCTP_Daemon_Test.ttcn
+// Description: SGsAP SDD test
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2010-11-26
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+
+
+module SGsAP_SCTP_Daemon_Test
+{
+ import from SGsAP_SCTP_Daemon all;
+ import from SGsAP_SCTP_Daemon_Types all;
+ import from SGsAP_Types all;
+ import from SCTP_Daemon_Dynamic_Test all;
+ import from SCTP_Daemon_Dynamic all;
+ import from SCTP_Daemon_Dynamic_Types all;
+
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_SGsAP_lookup() runs on SGsAP_SDD_CT
+{
+ f_SGsAP_SDD_init();
+
+ log("Starting inserts");
+ if (v_Connection_Insert!=null)
+ {
+ v_Connection_Insert.apply('100103AABBCC'O , 5);
+ v_Connection_Insert.apply('100103AABB01'O , 5);
+ v_Connection_Insert.apply('100103DDEEFF'O , 6);
+ v_Connection_Insert.apply('100103999999'O , 7);
+ v_Connection_Insert.apply('100103000000'O , 8);
+ v_Connection_Insert.apply('100103000001'O , 8);
+ }
+ log("Finished inserts");
+
+ log("Starting lookUps");
+ var TCP_connections_List vl_res;
+ if (v_Connection_Lookup!=null)
+ {
+ vl_res := v_Connection_Lookup.apply('100103000001'O);
+ log(vl_res);
+ if (vl_res == {8}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103000000'O);
+ log(vl_res);
+ if (vl_res == {8}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103999999'O);
+ log(vl_res);
+ if (vl_res == {7}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103DDEEFF'O);
+ log(vl_res);
+ if (vl_res == {6}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('100103AABB01'O);
+ log(vl_res);
+ if (vl_res == {5}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103AABBCC'O);
+ log(vl_res);
+ if (vl_res == {5}) { setverdict(pass); } else {setverdict(fail)};
+ }
+ log("Finished lookUps");
+
+ vl_res := f_SGsAP_SDD_getAllConnIds();
+ log("Get all connIds: ",vl_res);
+
+ if (vl_res == {5,6,7,8}) { setverdict(pass); } else {setverdict(fail)}
+
+ log("Starting deletes");
+ if (v_Connection_Delete!=null) {v_Connection_Delete.apply(8)}
+ log("Finished deletes");
+
+ log("Starting lookUps 2");
+
+ if (v_Connection_Lookup!=null)
+ {
+ vl_res := v_Connection_Lookup.apply('100103000001'O);
+ log(vl_res);
+ if (vl_res == {}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103000000'O);
+ log(vl_res);
+ if (vl_res == {}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103999999'O);
+ log(vl_res);
+ if (vl_res == {7}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103DDEEFF'O);
+ log(vl_res);
+ if (vl_res == {6}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('100103AABB01'O);
+ log(vl_res);
+ if (vl_res == {5}) { setverdict(pass); } else {setverdict(fail)};
+
+ vl_res := v_Connection_Lookup.apply('120103AABBCC'O);
+ log(vl_res);
+ if (vl_res == {5}) { setverdict(pass); } else {setverdict(fail)};
+ }
+ log("Finished lookUps 2");
+
+ vl_res := f_SGsAP_SDD_getAllConnIds();
+ log("Get all connIds: ",vl_res);
+
+ if (vl_res == {5,6,7}) { setverdict(pass); } else {setverdict(fail)}
+
+ f_SGsAP_SDD_cleanUp();
+}
+
+function f_delay(float p_time)
+{
+ timer t := p_time;
+ t.start;
+ t.timeout;
+}
+
+type component Dummy_CT {}
+
+testcase tc_SGsAP_client() runs on Dummy_CT
+{
+ var MAIN_CT vc_server := MAIN_CT.create;
+ var MAIN_CT vc_client := MAIN_CT.create;
+
+ vc_server.start(f_SGsAP_server());
+
+ f_delay(1.0);
+
+ vc_client.start(f_SGsAP_client());
+
+ all component.done;
+}
+
+function f_SGsAP_client() runs on MAIN_CT
+{
+ map(self:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+
+ f_sendDataFromClient('100103AABBCC'O);
+ f_CheckDataReceive_noOtherData(?,'100103AABBCC'O);
+ f_delay(5.0);
+
+ f_StopClient();
+
+ //f_StopMyAssociations();
+
+ unmap(self:daemonPort, system:daemonPort);
+}
+
+function f_SGsAP_server() runs on MAIN_CT
+{
+ map(self:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Server(tsp_serverInterface, tsp_serverPort);
+
+ f_serverWaitForConnection();
+
+ f_ServerEchoBack(5.0);
+
+ f_StopServer();
+
+ //f_StopMyAssociations();
+
+ unmap(self:daemonPort, system:daemonPort);
+}
+
+testcase tc_SGsAP_clients() runs on Dummy_CT
+{
+ var MAIN_CT vc_server := MAIN_CT.create;
+ var MAIN_CT vc_client := MAIN_CT.create;
+ var MAIN_CT vc_client_2 := MAIN_CT.create;
+
+ vc_server.start(f_SGsAP_server());
+
+ f_delay(1.0);
+
+ vc_client.start(f_SGsAP_client());
+
+ f_delay(1.0);
+
+ vc_client_2.start(f_SGsAP_client_2());
+ f_delay(5.0);
+
+ all component.done;
+}
+
+function f_SGsAP_client_2() runs on MAIN_CT
+{
+ map(self:daemonPort, system:daemonPort);
+
+ f_Connect_to_SDD();
+
+ f_Init_SCTP_Client(tsp_serverInterface, tsp_serverPort);
+
+ f_sendDataFromClient('100103999999'O);
+ f_CheckDataReceive_noOtherData(?,'100103999999'O);
+ f_delay(5.0);
+
+ f_StopClient();
+
+ //f_StopMyAssociations();
+
+ unmap(self:daemonPort, system:daemonPort);
+}
+
+}
diff --git a/demo/SGsAP_SCTP_Daemon_Types.ttcn b/demo/SGsAP_SCTP_Daemon_Types.ttcn
new file mode 100644
index 0000000..cd1662c
--- /dev/null
+++ b/demo/SGsAP_SCTP_Daemon_Types.ttcn
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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: SGsAP_SCTP_Daemon_Types.ttcn
+// Description: SGsAP SDD types
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2010-10-20
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+
+
+module SGsAP_SCTP_Daemon_Types
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from SCTP_Daemon_Dynamic_Types all;
+import from EPTF_CLL_FBQ_Definitions all
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record of charstring ro_charstring;
+
+type record ConnectionEntry
+{
+ integer connId,
+ ro_charstring imsiList
+}
+
+const ConnectionEntry ConnectionEntry_empty :=
+{
+ connId := -1,
+ imsiList := {}
+}
+
+type record of ConnectionEntry Connection_List;
+
+type record ConnectionDB
+{
+ integer hashRef,
+ Connection_List data,
+ EPTF_FreeBusyQueue queue
+}
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+type component SGsAP_SDD_CT extends SDD_CT
+{
+ var integer v_imsi2connDbIdx;
+ var ConnectionDB v_connDB;
+}
+
+} // end of module
diff --git a/demo/lksctp107_script b/demo/lksctp107_script
new file mode 100644
index 0000000..e739a8c
--- /dev/null
+++ b/demo/lksctp107_script
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+editcmd='
+
+s/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include -DUSE_SCTP -DLKSCTP_1_0_7 -DSCTP_REPORT_LISTEN_RESULT/g
+
+'
+sed -e "$editcmd" <$1 >$2
diff --git a/src/SCTP_Daemon_Dynamic.ttcn b/src/SCTP_Daemon_Dynamic.ttcn
new file mode 100644
index 0000000..890a931
--- /dev/null
+++ b/src/SCTP_Daemon_Dynamic.ttcn
@@ -0,0 +1,824 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.ttcn
+// Description: SDD behaviour
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2012-01-23
+// Contact: http://ttcn.ericsson.se
+
+module SCTP_Daemon_Dynamic
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from SCTP_Daemon_Dynamic_Types all;
+import from SCTP_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 SCTP_Daemon_Dynamic_IPL4_CtrlFunct all;
+//=========================================================================
+// Module Parameters
+//=========================================================================
+
+modulepar {
+
+ // Host name where the SCTP Daemon listens for the testcases
+ charstring tsp_SDD_TCP_ListenInterface := "127.0.0.1";
+
+ // Port number where the SCTP Daemon listens for the testcases
+ integer tsp_SDD_TCP_ListenPort := 1314;
+
+ // Default set of SCTP connections which the SCTP Daemon initializes on startup
+ // for associations with autoReconnect == true and server associations
+ SDD_AssociationConfigList tsp_SDD_AssociationList := {};
+
+ float tsp_SDD_ReconnectTimer := 2.0;
+
+ // inactivity timer -> client associations get closed
+ float tsp_SDD_InactivityTimer := 60.0;
+
+ boolean tsp_debug := false;
+}
+
+//=========================================================================
+// Altsteps
+//=========================================================================
+
+altstep as_Handle_SCTP_Events() runs on SDD_CT {
+ [] SCTP_PCO.receive(ASP_RecvFrom : ?) -> value vc_asp_SCTP_ReceivedMessage {
+ debuglog("INFO: ASP_SCTP");
+
+ f_RestartInactivityTimer();
+
+ var boolean vl_autoReplied := false;
+ var ASP_Send vl_sctpReply;
+ var integer index := 0;
+
+ for(index := 0; index < sizeof(vc_associationRuntimeAttributesList); index := index + 1) {
+ if(vc_associationRuntimeAttributesList[index].socket == vc_asp_SCTP_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_SCTP_ReceivedMessage, vl_sctpReply);
+ if(vl_autoReplied) {
+ SCTP_PCO.send(vl_sctpReply);
+ }
+ }
+
+ if(not vl_autoReplied) {
+ for(var integer i := 0; i < sizeof(vc_associationRuntimeAttributesList); i := i + 1) {
+ if(vc_associationRuntimeAttributesList[i].socket == vc_asp_SCTP_ReceivedMessage.connId) {
+ if (v_Connection_Lookup!=null){
+ v_TCP_connections_List:=v_Connection_Lookup.apply(vc_asp_SCTP_ReceivedMessage.msg);
+ for(var integer k := 0; k < sizeof(v_TCP_connections_List); k := k + 1) {
+ daemonPort.send(SDD_Message_with_ClientId : {
+ v_TCP_connections_List[k],
+ {
+ sctpData := {
+ messageType := 0, // encoder will replace
+ associationId := vc_associationList[i].associationId,
+ sinfo_stream := vc_asp_SCTP_ReceivedMessage.proto.sctp.sinfo_stream,
+ sinfo_ppid := vc_asp_SCTP_ReceivedMessage.proto.sctp.sinfo_ppid,
+ dataLength := 0, // encoder will replace
+ data := vc_asp_SCTP_ReceivedMessage.msg
+ }
+ }
+ });
+ }
+
+ }
+ else{
+ for(var integer j := 0; j < sizeof(vc_associationRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(SDD_Message_with_ClientId : {
+ vc_associationRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ sctpData := {
+ messageType := 0, // encoder will replace
+ associationId := vc_associationList[i].associationId,
+ sinfo_stream := vc_asp_SCTP_ReceivedMessage.proto.sctp.sinfo_stream,
+ sinfo_ppid := vc_asp_SCTP_ReceivedMessage.proto.sctp.sinfo_ppid,
+ dataLength := 0, // encoder will replace
+ data := vc_asp_SCTP_ReceivedMessage.msg
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+
+ repeat;
+ }
+
+ [] SCTP_PCO.receive(tr_S_SCTP_AssocChange(?,?)) -> value vc_asp_SCTP_Event {
+ debuglog("INFO: ASSOC_CHANGE vc_associationRuntimeAttributesList: " & log2str(vc_associationRuntimeAttributesList));
+ f_RestartInactivityTimer();
+
+ var boolean vl_autoHandled := false;
+ var ASP_Send vl_sctpMsg;
+
+ for(var integer i := 0; i < sizeof(vc_associationRuntimeAttributesList); i := i + 1) {
+ if(vc_associationRuntimeAttributesList[i].socket == vc_asp_SCTP_Event.sctpEvent.sctpAssocChange.clientId) {
+ //debuglog(log2str(vc_associationList[i]) & " subscribedTestcases: " & log2str(vc_associationRuntimeAttributesList[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_SCTP_Event.sctpEvent.sctpAssocChange.sac_state, vl_sctpMsg);
+ if(vl_autoHandled) {
+ SCTP_PCO.send(vl_sctpMsg);
+ }
+ }
+
+ if(not vl_autoHandled) {
+
+ for(var integer j := 0; j < sizeof( vc_associationRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(SDD_Message_with_ClientId : {
+ vc_associationRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ associationChanged := {
+ messageType := 0,
+ associationId := vc_associationList[i].associationId,
+ state := vc_asp_SCTP_Event.sctpEvent.sctpAssocChange.sac_state
+ }
+ }
+ });
+ }
+ }
+ vc_associationRuntimeAttributesList[i].associationState := vc_asp_SCTP_Event.sctpEvent.sctpAssocChange.sac_state;
+ if(vc_associationRuntimeAttributesList[i].associationState == SCTP_COMM_LOST) {
+ if(vc_associationList[i].serverAssociation) {
+ vc_associationRuntimeAttributesList[i].socket := -1;
+ // initiate reconnect
+ f_ScheduleReconnect();
+ }
+ else{
+ f_removeAssociation(vc_associationList[i].associationId);
+ }
+ }
+ }
+ }
+ repeat;
+ }
+
+ [] SCTP_PCO.receive(tr_S_SCTP_ShutdownEvent) -> value vc_asp_SCTP_Event {
+ debuglog("INFO: SHUTDOWN");
+ for(var integer i := 0; i < sizeof(vc_associationRuntimeAttributesList); i := i + 1) {
+ if(vc_associationRuntimeAttributesList[i].socket == vc_asp_SCTP_Event.sctpEvent.sctpShutDownEvent.clientId) {
+ vc_associationRuntimeAttributesList[i].associationState := SCTP_COMM_LOST;
+ vc_associationRuntimeAttributesList[i].socket := -1;
+
+ for(var integer j := 0; j < sizeof( vc_associationRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(SDD_Message_with_ClientId : {
+ vc_associationRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ associationChanged := {
+ messageType := 0,
+ associationId := vc_associationList[i].associationId,
+ state := SCTP_COMM_LOST
+ }
+ }
+ });
+ }
+ f_ScheduleReconnect();
+ }
+ }
+ f_RestartInactivityTimer();
+ repeat;
+ }
+
+ [] SCTP_PCO.receive(tr_ASP_SCTP_Connected) -> value vc_asp_SCTP_Event {
+ if(tsp_debug) {
+ log("@before ASP_SCTP_Connected vc_associationList: ", vc_associationList, ", vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList);
+ }
+
+ f_RestartInactivityTimer();
+
+ for(var integer i := 0; i < sizeof(vc_associationList); i := i + 1) {
+ if(ispresent(vc_associationList[i].localInterface)) {
+ if(vc_associationList[i].serverAssociation and
+ vc_asp_SCTP_Event.connOpened.locName == vc_associationList[i].localInterface.hostName and
+ vc_asp_SCTP_Event.connOpened.locPort == vc_associationList[i].localInterface.portNumber) {
+
+ // book the new association into the database
+ var integer newIndex := sizeof(vc_associationList);
+
+ vc_associationList[newIndex] := c_emptyAssociation;
+ vc_associationRuntimeAttributesList[newIndex] := c_emptyAssociationRuntimeAttribute;
+ vc_associationRuntimeAttributesList[newIndex].socket := vc_asp_SCTP_Event.connOpened.connId;
+ vc_associationRuntimeAttributesList[newIndex].endpointIndex := i;
+
+ vc_associationList[newIndex].associationId := f_getNextUniqueAssociationId();
+
+ vc_associationList[newIndex].localInterface.hostNameLength := 0;
+ vc_associationList[newIndex].localInterface.hostName := vc_asp_SCTP_Event.connOpened.locName;
+ vc_associationList[newIndex].localInterface.portNumber := vc_asp_SCTP_Event.connOpened.locPort;
+
+ vc_associationList[newIndex].remoteInterface.hostNameLength := 0;
+ vc_associationList[newIndex].remoteInterface.hostName := vc_asp_SCTP_Event.connOpened.remName;
+ vc_associationList[newIndex].remoteInterface.portNumber := vc_asp_SCTP_Event.connOpened.remPort;
+
+ vc_associationList[newIndex].autoReconnect := false;
+
+ // send notification to all subscribed testcases of the server
+ for(var integer j := 0; j < sizeof(vc_associationRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ daemonPort.send(SDD_Message_with_ClientId : {
+ vc_associationRuntimeAttributesList[i].subscribedTestcases[j],
+ {
+ sctpConnected := {
+ messageType := 0, // encoder will replace
+ associationId := vc_associationList[newIndex].associationId,
+ remoteInterface := {
+ hostNameLength := 0, // encoder will replace
+ hostName := vc_asp_SCTP_Event.connOpened.locName,
+ portNumber := vc_asp_SCTP_Event.connOpened.locPort
+ }
+ }
+ }
+ } );
+ }
+ // subscribe the connected association to the server's subscribed testcases
+ vc_associationRuntimeAttributesList[newIndex].subscribedTestcases := vc_associationRuntimeAttributesList[i].subscribedTestcases;
+ }
+ }
+ }
+ if(tsp_debug) {
+ log("@after ASP_SCTP_Connected vc_associationList: ", vc_associationList, ", vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList);
+ }
+ repeat;
+ }
+
+
+ [] SCTP_PCO.receive(tr_S_SCTP_PeerAddressChange) {
+ debuglog("INFO: ASP_SCTP_PEER_ADDR_CHANGE");
+ f_RestartInactivityTimer();
+ repeat;
+ }
+
+ [] SCTP_PCO.receive(tr_ASP_SCTP_Closed) {
+ debuglog("INFO: ASP_SCTP_Closed");
+ f_RestartInactivityTimer();
+ repeat;
+ }
+
+ [] SCTP_PCO.receive(tr_ASP_Result) -> value vc_sctpResult {
+ debuglog("INFO: ASP_SCTP_RESULT");
+ f_RestartInactivityTimer();
+ repeat;
+ }
+ [] SCTP_PCO.receive {
+ log("WARNING: unhandled SCTP message received!");
+ f_RestartInactivityTimer();
+ repeat;
+ }
+}
+
+altstep as_Handle_TCP_Events() runs on SDD_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_SDD_getMsgLen);
+ SCTP_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_associationRuntimeAttributesList.subscribedTestcases
+ for(var integer i := 0; i < sizeof(vc_associationRuntimeAttributesList); i := i + 1) {
+ vl_newSubsribedTestcases := {};
+ for(var integer j := 0; j < sizeof(vc_associationRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+ if(vc_associationRuntimeAttributesList[i].subscribedTestcases[j] != vc_tcpClose.connClosed.connId) {
+ vl_newSubsribedTestcases[sizeof(vl_newSubsribedTestcases)] := vc_associationRuntimeAttributesList[i].subscribedTestcases[j];
+ }
+ }
+ if(sizeof(vc_associationRuntimeAttributesList[i].subscribedTestcases) != sizeof(vl_newSubsribedTestcases)) {
+ vc_associationRuntimeAttributesList[i].subscribedTestcases := vl_newSubsribedTestcases;
+ }
+ }
+ }
+ repeat;
+ }
+
+ /* [] daemonPort.receive(tr_ASP_Result) {
+ log("*** ERROR: Could not send data on the TCP between the testcase and the SCTP Daemon!");
+ repeat;
+ }*/
+
+ [] daemonPort.receive(t_close) -> value vc_daemonMessage {
+ debuglog("INFO: t_close");
+ for(var integer i := 0; i < sizeof(vc_associationList); i := i + 1) {
+ if(vc_associationList[i].associationId == vc_daemonMessage.msg.sctpClose.associationId) {
+ if(vc_associationRuntimeAttributesList[i].socket >= 0) {
+ var Result vl_result := IPL4asp_PortType.f_IPL4_close(SCTP_PCO, vc_associationRuntimeAttributesList[i].socket, {sctp := {omit,omit,omit,omit}});
+ log("Result of closing socket: ",vl_result);
+ } else {
+ log("ERROR: association ", vc_daemonMessage.msg.sctpClose.associationId, " is not alive, not sending ASP_SCTP_Close!");
+ }
+ }
+ }
+ f_removeAssociation(vc_daemonMessage.msg.sctpClose.associationId);
+ debuglog("INFO: ASP_SCTP_Close sent, returning to the main alt");
+ repeat;
+ }
+
+ [] daemonPort.receive(t_queryAssociations) -> value vc_daemonMessage {
+ daemonPort.send(SDD_Message_with_ClientId : { vc_daemonMessage.client_id, { associations := {
+ 0, // encoder will replace
+ vc_associationList
+ } } });
+ repeat;
+ }
+
+ [] daemonPort.receive(t_connect) -> value vc_daemonMessage {
+ if(tsp_debug) {
+ log("@before sctpConnect vc_associationList: ", vc_associationList, ", vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList);
+ }
+ var integer newIndex := sizeof(vc_associationList);
+
+ vc_associationList[newIndex] := c_emptyAssociation;
+ vc_associationRuntimeAttributesList[newIndex] := c_emptyAssociationRuntimeAttribute;
+ vc_associationRuntimeAttributesList[newIndex].subscribedTestcases
+ [sizeof(vc_associationRuntimeAttributesList[newIndex].subscribedTestcases)] := vc_daemonMessage.client_id;
+
+ if(ispresent(vc_daemonMessage.msg.sctpConnect.localInterface)) {
+ vc_associationList[newIndex].localInterface := vc_daemonMessage.msg.sctpConnect.localInterface;
+ }
+
+ vc_associationList[newIndex].remoteInterface := vc_daemonMessage.msg.sctpConnect.remoteInterface;
+
+ vc_associationList[newIndex].autoReconnect := vc_daemonMessage.msg.sctpConnect.autoReconnect;
+
+ f_Reconnect_SCTP_Association(newIndex);
+
+ if(tsp_debug) {
+ log("@after defineClientAssociation vc_associationList: ", vc_associationList, ", vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList);
+ }
+ repeat;
+ }
+
+ [] daemonPort.receive(t_listen) -> value vc_daemonMessage {
+ if(tsp_debug) {
+ log("@before sctpListen vc_associationList: ", vc_associationList, ", vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList);
+ }
+ var integer newIndex := sizeof(vc_associationList);
+
+ vc_associationList[newIndex] := c_emptyAssociation;
+ vc_associationRuntimeAttributesList[newIndex] := c_emptyAssociationRuntimeAttribute;
+ vc_associationRuntimeAttributesList[newIndex].subscribedTestcases
+ [sizeof(vc_associationRuntimeAttributesList[newIndex].subscribedTestcases)] := vc_daemonMessage.client_id;
+
+ vc_associationList[newIndex].serverAssociation := true;
+
+ vc_associationList[newIndex].localInterface := {
+ hostNameLength := 0,
+ hostName := f_getIpAddr(vc_daemonMessage.msg.sctpListen.localInterface.hostName,f_addressType(vc_daemonMessage.msg.sctpListen.localInterface.hostName)),
+ portNumber := vc_daemonMessage.msg.sctpListen.localInterface.portNumber
+ };
+
+ f_Init_Server_SCTP_Association(newIndex);
+
+ if(tsp_debug) {
+ log("@after defineServerAssociation vc_associationList: ", vc_associationList, ", vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList);
+ }
+ repeat;
+ }
+
+ [] daemonPort.receive(t_subscribeToAssociation) -> value vc_daemonMessage {
+ debuglog("INFO: t_subscribeToAssociation");
+ var boolean vl_subscribed := false, vl_found := false;
+ for(var integer i := 0; i < sizeof(vc_associationList); i := i + 1) {
+ if(vc_associationList[i].associationId == vc_daemonMessage.msg.subscribeToAssociation.associationId) {
+ vl_found := false;
+ for(var integer j := 0; not vl_found and (j < sizeof(vc_associationRuntimeAttributesList[i].subscribedTestcases)); j := j + 1) {
+ if(vc_associationRuntimeAttributesList[i].subscribedTestcases[j] == vc_daemonMessage.client_id) {
+ vl_found := true
+ }
+ }
+ if(not vl_found) {
+ vc_associationRuntimeAttributesList[i].subscribedTestcases[sizeof(vc_associationRuntimeAttributesList[i].subscribedTestcases)] := vc_daemonMessage.client_id;
+ vl_subscribed := true;
+ } else {
+ log("*** WARNING: test case ", vc_daemonMessage.client_id, " is already subscribed to: ", vc_associationList[i]);
+ }
+ }
+ }
+
+ if(not vl_subscribed) {
+ log("*** WARNING: test case ", vc_daemonMessage.client_id, " was not subscribed to any association!");
+ }
+
+ repeat;
+ }
+
+ [] daemonPort.receive(t_sctpData) -> value vc_daemonMessage {
+ debuglog("INFO: t_sctpData");
+ for(var integer i := 0; i < sizeof(vc_associationList); i := i + 1) {
+ if(vc_associationList[i].associationId == vc_daemonMessage.msg.sctpData.associationId) {
+ if (v_Connection_Insert!=null) {v_Connection_Insert.apply(vc_daemonMessage.msg.sctpData.data,vc_daemonMessage.client_id)}
+ SCTP_PCO.send(ASP_Send:{
+ connId := vc_associationRuntimeAttributesList[i].socket,
+ proto :=
+ {
+ sctp:=
+ {
+ sinfo_stream := vc_daemonMessage.msg.sctpData.sinfo_stream,
+ sinfo_ppid := vc_daemonMessage.msg.sctpData.sinfo_ppid,
+ // Multiple remote addresses can be given in case of one-to-many connections.
+ remSocks := omit,
+ // Association ID to identify one specific connection in case of one-to-many connections.
+ assocId := omit
+ }
+ },
+ msg := vc_daemonMessage.msg.sctpData.data
+ });
+ }
+ }
+ repeat;
+ }
+}
+
+altstep as_Handle_Reconnect() runs on SDD_CT {
+ [] vc_reconnectTimer.timeout {
+ if(tsp_debug) {
+ log("On vc_reconnectTimer.timeout vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList, " vc_associationList: ", vc_associationList);
+ }
+ for(var integer i := 0; i < sizeof(vc_associationRuntimeAttributesList); i := i + 1) {
+ if(vc_associationRuntimeAttributesList[i].socket < 0 and vc_associationList[i].autoReconnect) {
+ f_Reconnect_SCTP_Association(i);
+ }
+ }
+ repeat;
+ }
+}
+
+altstep as_Handle_Inactivity() runs on SDD_CT {
+ [] vc_inactivityTimer.timeout {
+ if(tsp_debug) {
+ log("On vc_inactivityTimer.timeout vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList, " vc_associationList: ", vc_associationList);
+ }
+
+ log("*** SDD QUIT due to ", tsp_SDD_InactivityTimer, " seconds of inactivity.");
+ log("*** Please restart SDD if you need it again.");
+ }
+}
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function debuglog(in charstring str) {
+ if(tsp_debug) {
+ log(str);
+ }
+}
+
+function f_addressType(charstring ip_address)
+return TCCInterface_IPAddressType
+{
+ var integer v_index:=f_strstr(ip_address, ":");
+ log("v_index: ",v_index);
+ if(v_index == -1)
+ {
+ return IPv4;
+ }
+ return IPv6;
+}
+
+
+function f_getNextUniqueAssociationId() runs on SDD_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_associationList) and (not found); i := i + 1) {
+ if(vc_associationList[i].associationId == newId) {
+ found := true;
+ }
+ }
+
+ if(not found) {
+ exit := true;
+ } else {
+ newId := newId + 1;
+ }
+ }
+
+ debuglog("returning new association id: " & int2str(newId));
+ return newId;
+}
+
+function f_InitTCPServer() runs on SDD_CT {
+ var Result vl_result := { errorCode := omit, connId := omit, os_error_code:=omit, os_error_text:= omit };
+ vl_result := SCTP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_listen(daemonPort, tsp_SDD_TCP_ListenInterface, tsp_SDD_TCP_ListenPort, {tcp := {}});
+
+ if ((vl_result.errorCode == omit) or (vl_result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE))
+ {
+ log("Listening on port (TCP)",tsp_SDD_TCP_ListenPort);
+ var f_IPL4_getMsgLen sdd_msglen := refers(f_SDD_getMsgLen);
+ SCTP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_setGetMsgLen(daemonPort,vl_result.connId,sdd_msglen,{});
+ }else{
+ log("Error during initialization of the TCP port: ",vl_result);
+ setverdict(fail);
+ stop;
+ }
+
+
+ alt{
+ [] daemonPort.receive(tr_ASP_Result){
+ log("Result received");
+ }
+ [] daemonPort.receive{
+ log("ERROR: unhandled daemon message received.");
+ setverdict(fail);
+ stop;
+ }
+ }
+
+}
+
+function f_Init_Server_SCTP_Association(in integer assoc_idx) runs on SDD_CT {
+ if(vc_associationList[assoc_idx].serverAssociation) {
+ if(ispresent(vc_associationList[assoc_idx].localInterface)) {
+ if(vc_associationRuntimeAttributesList[assoc_idx].socket < 0) {
+ log("Association of server: ",assoc_idx);
+ vc_associationRuntimeAttributesList[assoc_idx].endpointIndex := f_GetEndpointIndex(vc_associationList[assoc_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(SCTP_PCO, vc_associationList[assoc_idx].localInterface.hostName, vc_associationList[assoc_idx].localInterface.portNumber, {sctp := {omit,omit,omit,omit}});
+
+ alt{
+ [] SCTP_PCO.receive(tr_ASP_Result){
+ log("Result received");
+ }
+ [] as_Handle_SCTP_Events();
+ }
+
+ if(vc_associationList[assoc_idx].associationId < 0) {
+ vc_associationList[assoc_idx].associationId := f_getNextUniqueAssociationId();
+ }
+
+
+ vc_associationRuntimeAttributesList[assoc_idx].socket := vl_result.connId;
+ for(var integer i := 0; i < sizeof(vc_associationRuntimeAttributesList[assoc_idx].subscribedTestcases); i := i + 1) {
+ daemonPort.send(SDD_Message_with_ClientId : {
+ vc_associationRuntimeAttributesList[assoc_idx].subscribedTestcases[i],
+ { sctpResult := {
+ messageType := 0, // encoder will replace
+ associationId := vc_associationList[assoc_idx].associationId,
+ errorStatus := not(vl_result.errorCode==omit),
+ errorMessage := vl_result.os_error_text
+ }}
+ } );
+ }
+ } else {
+ log("*** WARNING: SCTP server association ", vc_associationList[assoc_idx].localInterface, " is already listening!");
+ }
+ } else {
+ log("*** ERROR: SCTP server association #", assoc_idx, " is declared as server, but has no localInterface defined!");
+ }
+ } else {
+ if(tsp_debug) {
+ log("*** INFO: SCTP association ", vc_associationList[assoc_idx], " is not server.");
+ }
+ }
+}
+
+function f_Reconnect_SCTP_Association(in integer assoc_idx) runs on SDD_CT {
+
+ if(vc_associationRuntimeAttributesList[assoc_idx].socket < 0) {
+ if(ispresent(vc_associationList[assoc_idx].remoteInterface)) {
+
+ if(ispresent(vc_associationList[assoc_idx].localInterface)) {
+ if(not vc_associationList[assoc_idx].serverAssociation) {
+
+ vc_associationRuntimeAttributesList[assoc_idx].endpointIndex := f_GetEndpointIndex(vc_associationList[assoc_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
+ (
+ SCTP_PCO,
+ vc_associationList[assoc_idx].remoteInterface.hostName,
+ vc_associationList[assoc_idx].remoteInterface.portNumber,
+ vc_associationList[assoc_idx].localInterface.hostName,
+ vc_associationList[assoc_idx].localInterface.portNumber,
+ connId := -1,
+ proto :=
+ {
+ sctp:=
+ {
+ sinfo_stream := omit,
+ sinfo_ppid := omit,
+ remSocks := omit,
+ assocId := omit
+ }
+ },
+ options := {}
+ );
+
+
+ } else {
+ if(vc_associationList[assoc_idx].serverAssociation) {
+ log("WARNING: association ", vc_associationList[assoc_idx].localInterface,
+ " is declared as server association, but also initiates client connection to ",
+ vc_associationList[assoc_idx].remoteInterface);}
+ }
+ }
+ else {
+ log("WARNING: association ", vc_associationList[assoc_idx].remoteInterface,
+ " localInterface is missing ");
+ }
+
+ timer t_wait := 10.0; t_wait.start;
+ alt {
+ [] SCTP_PCO.receive(tr_ASP_Result)-> value vc_sctpResult{
+
+ if ((vc_sctpResult.result.errorCode == omit) or (vc_sctpResult.result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE)) //if not error
+ {
+ vc_associationRuntimeAttributesList[assoc_idx].socket := vc_sctpResult.result.connId;
+ if(vc_associationList[assoc_idx].associationId < 0) {
+ vc_associationList[assoc_idx].associationId := f_getNextUniqueAssociationId();
+ }
+ }
+ else
+ {
+ f_ScheduleReconnect();
+ }
+
+ for(var integer i := 0; i < sizeof(vc_associationRuntimeAttributesList[assoc_idx].subscribedTestcases); i := i + 1) {
+ daemonPort.send(SDD_Message_with_ClientId : {
+ vc_associationRuntimeAttributesList[assoc_idx].subscribedTestcases[i],
+ { sctpResult := {
+ messageType := 0, // encoder will replace
+ associationId := vc_associationList[assoc_idx].associationId,
+ errorStatus := not(vc_sctpResult.result.errorCode==omit),
+ errorMessage := vc_sctpResult.result.os_error_text
+ }}
+ } );
+ }
+ if(tsp_debug) {
+ log("@after ASP_SCTP_RESULT vc_associationList: ",vc_associationList, ", vc_associationRuntimeAttributesList: ", vc_associationRuntimeAttributesList);
+ }
+ }
+
+ [] as_Handle_SCTP_Events();
+
+ [] t_wait.timeout {
+ log("WARNING: SCTP association to " & log2str(vc_associationList[assoc_idx].remoteInterface) & " could not be established!");
+ f_ScheduleReconnect();
+ }
+ }
+
+ } else {
+ if(vc_associationList[assoc_idx].serverAssociation) {
+ if(tsp_debug) {
+ log("*** INFO: SCTP association ", vc_associationList[assoc_idx].localInterface, " is server only.");
+ }
+ } else {
+ log("*** ERROR: SCTP association ", vc_associationList[assoc_idx].localInterface, " is not a server association!");
+ }
+ }
+ } else if(ispresent(vc_associationList[assoc_idx].remoteInterface)) {
+ log("*** WARNING: SCTP association to " & log2str(vc_associationList[assoc_idx].remoteInterface) & " is already active!");
+ }
+}
+
+function f_removeAssociation(in integer pl_associationId) runs on SDD_CT {
+ var SDD_AssociationList newAssociationList := {};
+ var AssociationRuntimeAttributesList newAssociationRuntimeAttributesList := {};
+
+ for(var integer i := 0; i < sizeof(vc_associationList); i := i + 1) {
+ if(vc_associationList[i].associationId != pl_associationId) {
+ newAssociationList[sizeof(newAssociationList)] := vc_associationList[i];
+ newAssociationRuntimeAttributesList[sizeof(newAssociationRuntimeAttributesList)] := vc_associationRuntimeAttributesList[i];
+ }
+ }
+
+ if(sizeof(newAssociationList) != sizeof(vc_associationList)) {
+ vc_associationList := newAssociationList;
+ vc_associationRuntimeAttributesList := newAssociationRuntimeAttributesList;
+ } else {
+ log("*** ERROR: SCTP association to delete: ", pl_associationId, " was not found in the database.");
+ }
+}
+
+function f_GetEndpointIndex(in SDD_Interface pl_interface) runs on SDD_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_ScheduleReconnect() runs on SDD_CT {
+ if(not vc_reconnectTimer.running) {
+ vc_reconnectTimer.start(tsp_SDD_ReconnectTimer);
+ }
+}
+
+function f_RestartInactivityTimer() runs on SDD_CT {
+ if(tsp_SDD_InactivityTimer > 0.0) {
+ if(vc_inactivityTimer.running) {
+ vc_inactivityTimer.stop;
+ };
+
+ vc_inactivityTimer.start(tsp_SDD_InactivityTimer);
+ debuglog("### Inactivity timer restarted.");
+ }
+}
+
+function f_RegisterAutoReplyFunction(in f_SDD_AutoReplyFunction autoReplyFunction) runs on SDD_CT {
+ vc_registeredAutoReplyFunctionList[sizeof(vc_registeredAutoReplyFunctionList)] := autoReplyFunction;
+}
+
+function f_RegisterAutoStateChangeHandlerFunction(in f_SDD_AutoStateChangeHandlerFunction autoStateChangeHandlerFunction) runs on SDD_CT {
+ vc_registeredAutoStateChangeHandlerFunctionList[sizeof(vc_registeredAutoStateChangeHandlerFunctionList)] := autoStateChangeHandlerFunction;
+}
+
+function f_SDD() runs on SDD_CT {
+ map(mtc:daemonPort, system:daemonPort);
+ map(mtc:SCTP_PCO, system:SCTP_PCO);
+
+ f_InitTCPServer();
+
+ for(var integer i := 0; i < sizeof(tsp_SDD_AssociationList); i := i + 1) {
+ vc_associationList[i] := {
+ associationId := -1,
+ serverAssociation:= tsp_SDD_AssociationList[i].serverAssociation,
+ autoReconnect := tsp_SDD_AssociationList[i].autoReconnect,
+ localInterfacePresent := false, // enter always false
+ localInterface := {
+ hostNameLength := 0,
+ hostName := f_getIpAddr(tsp_SDD_AssociationList[i].localInterface.hostName,f_addressType(tsp_SDD_AssociationList[i].localInterface.hostName)),
+ portNumber := tsp_SDD_AssociationList[i].localInterface.portNumber
+ },
+ remoteInterfacePresent := false, // enter always false
+ remoteInterface := tsp_SDD_AssociationList[i].remoteInterface
+ };
+ // clientIds: empty, associationState: SCTP_COMM_LOST
+ vc_associationRuntimeAttributesList[i] := c_emptyAssociationRuntimeAttribute;
+ }
+
+ for(var integer i := 0; i < sizeof(vc_associationList); i := i + 1) {
+ f_Init_Server_SCTP_Association(i);
+ f_Reconnect_SCTP_Association(i);
+ }
+
+ alt {
+ [] as_Handle_TCP_Events()
+ [] as_Handle_Reconnect()
+ [] as_Handle_SCTP_Events()
+ [] as_Handle_Inactivity()
+ }
+ //timer t_wait := 500.0; t_wait.start; t_wait.timeout;
+
+ unmap(mtc:daemonPort, system:daemonPort);
+ unmap(mtc:SCTP_PCO, system:SCTP_PCO);
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_SDD() runs on SDD_CT {
+ f_SDD();
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+ execute(tc_SDD());
+}
+
+} // end of module
diff --git a/src/SCTP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc b/src/SCTP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc
new file mode 100644
index 0000000..e85fde9
--- /dev/null
+++ b/src/SCTP_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: SCTP_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 "SCTP_Daemon_Dynamic_Interface_Definitions.hh"
+
+namespace SCTP__Daemon__Dynamic__IPL4__CtrlFunct {
+
+ IPL4asp__Types::Result f__IPL4__listen(
+ SCTP__Daemon__Dynamic__Interface__Definitions::SDD__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(
+ SCTP__Daemon__Dynamic__Interface__Definitions::SDD__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(
+ SCTP__Daemon__Dynamic__Interface__Definitions::SDD__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(
+ SCTP__Daemon__Dynamic__Interface__Definitions::SDD__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(
+ SCTP__Daemon__Dynamic__Interface__Definitions::SDD__Interface__PT& portRef,
+ const IPL4asp__Types::ConnectionId& connId,
+ IPL4asp__Types::UserData& userData)
+ {
+ return f__IPL4__PROVIDER__getUserData(portRef, connId, userData);
+ }
+
+ void f__IPL4__setGetMsgLen(
+ SCTP__Daemon__Dynamic__Interface__Definitions::SDD__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/SCTP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn b/src/SCTP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn
new file mode 100644
index 0000000..a92eead
--- /dev/null
+++ b/src/SCTP_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 SCTP_Daemon_Dynamic_IPL4_CtrlFunct {
+
+ import from SCTP_Daemon_Dynamic_Interface_Definitions all;
+ import from IPL4asp_Types all;
+
+ external function f_IPL4_listen(
+ inout SDD_Interface_PT portRef,
+ in HostName locName,
+ in PortNumber locPort,
+ in ProtoTuple proto,
+ in OptionList options := {}
+ ) return Result;
+
+ external function f_IPL4_connect(
+ inout SDD_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 SDD_Interface_PT portRef,
+ in ConnectionId id,
+ in ProtoTuple proto := { unspecified := {} }
+ ) return Result;
+
+ external function f_IPL4_setUserData(
+ inout SDD_Interface_PT portRef,
+ in ConnectionId id,
+ in UserData userData
+ ) return Result;
+
+ external function f_IPL4_getUserData(
+ inout SDD_Interface_PT portRef,
+ in ConnectionId id,
+ out UserData userData
+ ) return Result;
+
+ external function f_IPL4_setGetMsgLen(
+ inout SDD_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/SCTP_Daemon_Dynamic_Interface_Definitions.ttcn b/src/SCTP_Daemon_Dynamic_Interface_Definitions.ttcn
new file mode 100644
index 0000000..8513e4e
--- /dev/null
+++ b/src/SCTP_Daemon_Dynamic_Interface_Definitions.ttcn
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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: SDD <-> Testcase interface data and port types
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2012-01-20
+// Contact: http://ttcn.ericsson.se
+
+
+module SCTP_Daemon_Dynamic_Interface_Definitions
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record SDD_Message_with_ClientId {
+ integer client_id optional,
+ SDD_Message msg
+}
+
+type union SDD_Message {
+
+ // Both-way traffic
+ SDD_SCTPData sctpData, // send SCTP data
+
+ // Requests
+ SDD_QueryAssociations queryAssociations, // query the state of the active associations
+ SDD_Listen sctpListen, // define a new server association
+ SDD_Connect sctpConnect, // define a new client association
+ SDD_Close sctpClose, // close an association
+ SDD_SubscribeToAssociation subscribeToAssociation, // subscribe to an association's events
+
+ // Indications
+ SDD_Result sctpResult, // result comes in response to defineServerAssociation and defineClientAssociation
+ // and contains the new associationId
+
+ SDD_Associations associations, // response to queryAssociations
+ SDD_AssociationChanged associationChanged, // indicates the change of the state of an association
+ SDD_Connected sctpConnected // indicates that a client has been connected to one of our SCTP server
+
+} with {
+ variant "TAG(
+ sctpData, messageType = 0;
+ queryAssociations, messageType = 1;
+ sctpListen, messageType = 2;
+ sctpConnect, messageType = 3;
+ sctpClose, messageType = 4;
+ subscribeToAssociation, messageType = 5;
+
+ sctpResult, messageType = 100;
+ associations, messageType = 101;
+ associationChanged, messageType = 102;
+ sctpConnected, messageType = 103)"
+
+}
+
+group MainMessageTypes {
+
+ type record SDD_SCTPData {
+ integer messageType,
+ integer associationId,
+ integer sinfo_stream,
+ integer sinfo_ppid,
+ integer dataLength (0..65526),
+ octetstring data
+ } with {
+ variant (associationId) "FIELDLENGTH(32), COMP(signbit)"
+ variant (dataLength) "FIELDLENGTH(16)"
+ variant (sinfo_stream, sinfo_ppid) "FIELDLENGTH(32)"
+ variant (dataLength) "LENGTHTO(data)";
+ }
+
+ type record SDD_QueryAssociations {
+ integer messageType
+ }
+
+ type record SDD_Listen {
+ integer messageType,
+ SDD_Interface localInterface
+ }
+
+ type record SDD_Connect {
+ integer messageType,
+ boolean autoReconnect,
+ boolean localInterfacePresent,
+ SDD_Interface localInterface optional,
+ SDD_Interface remoteInterface
+ } with {
+ variant (autoReconnect, localInterfacePresent) "FIELDLENGTH(8)"
+ variant (localInterface) "PRESENCE (localInterfacePresent=true)"
+ }
+
+ type record SDD_Close {
+ integer messageType,
+ integer associationId
+ } with {
+ variant (associationId) "FIELDLENGTH(32), COMP(signbit)"
+ }
+
+ type record SDD_SubscribeToAssociation {
+ integer messageType,
+ integer associationId
+ } with {
+ variant (associationId) "FIELDLENGTH(32), COMP(signbit)"
+ }
+
+ type record SDD_Result {
+ integer messageType,
+ integer associationId,
+ boolean errorStatus,
+ charstring errorMessage optional
+ } with {
+ variant (associationId) "FIELDLENGTH(32), COMP(signbit)"
+ variant (errorStatus) "FIELDLENGTH(8)"
+ variant (errorMessage) "PRESENCE (errorStatus=true)"
+ }
+
+ type record SDD_Associations {
+ integer messageType,
+ SDD_AssociationList associationList
+ }
+
+ type record SDD_AssociationChanged {
+ integer messageType,
+ integer associationId,
+ SAC_STATE state
+ } with {
+ variant (associationId) "FIELDLENGTH(32), COMP(signbit)"
+ variant (state) "FIELDLENGTH(8)"
+ }
+
+ type record SDD_Connected {
+ integer messageType,
+ integer associationId,
+ SDD_Interface remoteInterface
+ } with {
+ variant (associationId) "FIELDLENGTH(32), COMP(signbit)";
+ }
+
+}
+
+group SubTypes {
+
+ type record SDD_Interface {
+ integer hostNameLength,
+ charstring hostName,
+ integer portNumber (1..65535) optional
+ } with {
+ variant (hostNameLength) "LENGTHTO(hostName)";
+ variant (portNumber) "FIELDLENGTH(16)";
+ }
+
+ type record of SDD_Interface SDD_InterfaceList;
+
+ type record SDD_Association {
+ integer associationId,
+ boolean serverAssociation, // true := server, false: client
+ boolean autoReconnect,
+ boolean localInterfacePresent,
+ SDD_Interface localInterface optional,
+ boolean remoteInterfacePresent,
+ SDD_Interface remoteInterface optional
+ } with {
+ variant (associationId) "FIELDLENGTH(32), COMP(signbit)";
+ variant (localInterface) "PRESENCE (localInterfacePresent=true)"
+ variant (remoteInterface) "PRESENCE (remoteInterfacePresent=true)"
+ variant (serverAssociation, autoReconnect, localInterfacePresent, remoteInterfacePresent) "FIELDLENGTH(8)"; // take a byte to make debugging a little easier
+ }
+
+ type record of SDD_Association SDD_AssociationList;
+
+ type record SDD_AssociationConfig {
+ boolean serverAssociation, // true := server, false: client
+ boolean autoReconnect,
+ SDD_Interface localInterface optional,
+ SDD_Interface remoteInterface optional
+ }
+}
+
+//=========================================================================
+//Port Types
+//=========================================================================
+
+type port SDD_Interface_PT message {
+ in ASP_Event;
+ inout SDD_Message_with_ClientId
+} with { extension "user IPL4asp_PT
+ in( ASP_Event -> ASP_Event: simple;
+ ASP_RecvFrom -> SDD_Message_with_ClientId: function(f_dec_SDD_Message))
+ out(SDD_Message_with_ClientId -> ASP_Send: function(f_enc_SDD_Message))"
+}
+
+//=========================================================================
+// Constants
+//=========================================================================
+
+// none yet
+
+//=========================================================================
+// Encoder and Decoder Functions
+//=========================================================================
+function f_SDD_getMsgLen(in octetstring stream, inout ro_integer args) return integer {
+ var integer stream_length := lengthof(stream);
+ var integer pdu_length;
+ if (stream_length >=4) {
+ pdu_length:=oct2int(substr(stream,2,2));
+ if (stream_length >= pdu_length){
+ return pdu_length;
+ }
+ else{return 0;}
+ }
+ else{return 0;}
+}
+
+function f_dec_SDD_Message(in ASP_RecvFrom aspTCP, out SDD_Message_with_ClientId daemonMsg) return integer {
+ daemonMsg.client_id := aspTCP.connId;
+ daemonMsg.msg := dec_SDD_Message(substr(aspTCP.msg, 4, lengthof(aspTCP.msg)-4));
+ return 0;
+} with { extension "prototype(backtrack)" }
+
+function f_enc_SDD_Message(in SDD_Message_with_ClientId sctpMsg, out ASP_Send aspTCP) return integer {
+ aspTCP.connId := sctpMsg.client_id;
+ var octetstring vl_encoded := enc_SDD_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_SDD_Message(in SDD_Message pdu) return octetstring
+with { extension "prototype(convert) encode(RAW)" }
+
+// created automatically by compiler's RAW Encoder/Decoder code generator
+external function dec_SDD_Message(in octetstring stream) return SDD_Message
+with { extension "prototype(convert) decode(RAW)" }
+
+} with {encode "RAW"} // end of module
diff --git a/src/SCTP_Daemon_Dynamic_Types.ttcn b/src/SCTP_Daemon_Dynamic_Types.ttcn
new file mode 100644
index 0000000..ebd90fd
--- /dev/null
+++ b/src/SCTP_Daemon_Dynamic_Types.ttcn
@@ -0,0 +1,323 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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: SDD types
+// Rev: <RnXnn>
+// Prodnr: CNL 113 630
+// Updated: 2012-01-20
+// Contact: http://ttcn.ericsson.se
+
+module SCTP_Daemon_Dynamic_Types
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from SCTP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record of integer IntegerList;
+
+type record AssociationRuntimeAttributes {
+ IntegerList subscribedTestcases,
+ integer socket,
+ integer endpointIndex,
+ SAC_STATE associationState,
+ charstring userState
+}
+
+type record of AssociationRuntimeAttributes AssociationRuntimeAttributesList;
+
+type record SDD_AssociationConfig {
+ boolean serverAssociation, // true := server, false: client
+ boolean autoReconnect,
+ SDD_Interface localInterface optional,
+ SDD_Interface remoteInterface optional
+}
+
+type record of SDD_AssociationConfig SDD_AssociationConfigList;
+
+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
+//=========================================================================
+//Port Types
+//=========================================================================
+
+// Insert port type defintions here if applicable!
+// You can use the port_type skeleton!
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+type component SDD_CT {
+ port SDD_Interface_PT daemonPort;
+ port IPL4asp_PT SCTP_PCO;
+
+ var SDD_AssociationList vc_associationList := {};
+ var AssociationRuntimeAttributesList vc_associationRuntimeAttributesList := {};
+ var SDD_InterfaceList v_localEndpointList := {};
+
+ //var ASP_TCP_Connected vc_connected;
+ var SDD_Message_with_ClientId vc_daemonMessage;
+
+ timer vc_reconnectTimer;
+ timer vc_inactivityTimer;
+
+ var ASP_RecvFrom vc_asp_SCTP_ReceivedMessage;
+ var ASP_Event vc_asp_SCTP_Event;
+ var ASP_Event vc_asp_TCP_Event;
+ var ASP_Event vc_sctpResult;
+
+ var ASP_Event vc_tcpClose;
+
+ var RegisteredAutoReplyFunctionList vc_registeredAutoReplyFunctionList := {};
+ var RegisteredAutoStateChangeHandlerFunctionList vc_registeredAutoStateChangeHandlerFunctionList := {};
+
+ 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 sctpReply
+type function f_SDD_AutoReplyFunction(in integer associationIndex, in ASP_RecvFrom sctpReceived, out ASP_Send sctpReply)
+runs on self return boolean;
+
+type record of f_SDD_AutoReplyFunction RegisteredAutoReplyFunctionList;
+
+// return true if the state should not be passed to TTCN, but sctpMsg has to be automatically sent on the association
+type function f_SDD_AutoStateChangeHandlerFunction(in integer associationIndex, in SAC_STATE newState, out ASP_Send sctpMsg)
+runs on self return boolean;
+
+type record of f_SDD_AutoStateChangeHandlerFunction RegisteredAutoStateChangeHandlerFunctionList;
+
+//=========================================================================
+// Constants
+//=========================================================================
+
+const SDD_Association c_emptyAssociation := {
+ associationId := -1,
+ serverAssociation := false, // true := server, false: client
+ autoReconnect := true,
+ localInterfacePresent := false,
+ localInterface := omit,
+ remoteInterfacePresent := false,
+ remoteInterface := omit
+}
+
+const AssociationRuntimeAttributes c_emptyAssociationRuntimeAttribute := {
+ subscribedTestcases := {},
+ socket := -1,
+ endpointIndex := -1,
+ associationState := SCTP_COMM_LOST,
+ userState := ""
+}
+
+//=========================================================================
+// Templates
+//=========================================================================
+
+template SDD_Message_with_ClientId t_SDD_Message_with_ClientId := {
+ client_id := ?,
+ msg := ?
+}
+
+template SDD_Message_with_ClientId t_queryAssociations modifies t_SDD_Message_with_ClientId := {
+ msg := {
+ queryAssociations := ?
+ }
+}
+
+template SDD_Message_with_ClientId t_connect modifies t_SDD_Message_with_ClientId := {
+ msg := {
+ sctpConnect := ?
+ }
+}
+
+template SDD_Message_with_ClientId t_listen modifies t_SDD_Message_with_ClientId := {
+ msg := {
+ sctpListen := ?
+ }
+}
+
+template SDD_Message_with_ClientId t_close modifies t_SDD_Message_with_ClientId := {
+ msg := {
+ sctpClose := ?
+ }
+}
+
+template SDD_Message_with_ClientId t_sctpData modifies t_SDD_Message_with_ClientId := {
+ msg := {
+ sctpData := ?
+ }
+}
+
+template SDD_Message_with_ClientId t_subscribeToAssociation modifies t_SDD_Message_with_ClientId := {
+ msg := {
+ subscribeToAssociation := ?
+ }
+}
+
+//SCTP Assoc Change
+template ASP_Event tr_S_SCTP_AssocChange
+( template integer pl_associationID,
+ template SAC_STATE pl_state
+) :=
+{
+ sctpEvent :=
+ {
+ sctpAssocChange :=
+ {
+ clientId := pl_associationID,
+ proto :=
+ {
+ sctp:=
+ {
+ sinfo_stream := *,
+ sinfo_ppid := *,
+ remSocks := *,
+ assocId := *
+ }
+ },
+ 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 := *
+ }
+}
+
+//SCTP Connected
+template ASP_Event tr_ASP_SCTP_Connected:=
+{
+ connOpened :=
+ {
+ connId := ?,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ proto :=
+ {
+ sctp:=
+ {
+ sinfo_stream := *,
+ sinfo_ppid := *,
+ remSocks := *,
+ assocId := *
+ }
+ },
+ userData := ?
+ }
+}
+
+template ASP_Event tr_ASP_SCTP_Closed :=
+{
+ connClosed :=
+ {
+ connId := ?,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ proto :=
+ {
+ sctp:=
+ {
+ sinfo_stream := *,
+ sinfo_ppid := *,
+ remSocks := *,
+ assocId := *
+ }
+ },
+ 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