First code commit
diff --git a/IP_Daemon_Dynamic_CNL113739.tpd b/IP_Daemon_Dynamic_CNL113739.tpd
new file mode 100644
index 0000000..9e2108b
--- /dev/null
+++ b/IP_Daemon_Dynamic_CNL113739.tpd
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TITAN_Project_File_Information version="1.0">
+  <ProjectName>IP_Daemon_Dynamic_CNL113739</ProjectName>
+  <ReferencedProjects>
+    <ReferencedProject name="IPL4asp_CNL113531" projectLocationURI="../../TestPorts/IPL4asp_CNL113531/IPL4asp_CNL113531.tpd"/>
+    <ReferencedProject name="Socket_API_CNL113686" projectLocationURI="../../TestPorts/Common_Components/Socket_API_CNL113686/Socket_API_CNL113686.tpd"/>
+    <ReferencedProject name="TCCUsefulFunctions_CNL113472_Common" projectLocationURI="../../Libraries/TCCUsefulFunctions_CNL113472/TCCUsefulFunctions_CNL113472_Common.tpd"/>
+    <ReferencedProject name="TCCUsefulFunctions_CNL113472_Interface" projectLocationURI="../../Libraries/TCCUsefulFunctions_CNL113472/TCCUsefulFunctions_CNL113472_Interface.tpd"/>
+  </ReferencedProjects>
+  <Folders>
+    <FolderResource projectRelativePath="doc" relativeURI="doc"/>
+  </Folders>
+  <Files>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic.cfg" relativeURI="demo/IP_Daemon_Dynamic.cfg"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic.ttcn" relativeURI="src/IP_Daemon_Dynamic.ttcn"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc" relativeURI="src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn" relativeURI="src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_Interface_Definitions.ttcn" relativeURI="src/IP_Daemon_Dynamic_Interface_Definitions.ttcn"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_Types.ttcn" relativeURI="src/IP_Daemon_Dynamic_Types.ttcn"/>
+    <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_FS.doc" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_FS.doc"/>
+    <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_FS.pdf" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_FS.pdf"/>
+    <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_PRI.doc" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_PRI.doc"/>
+    <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_PRI.pdf" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_PRI.pdf"/>
+    <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_UG.doc" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_UG.doc"/>
+    <FileResource projectRelativePath="doc/IP_Daemon_Dynamic_CNL113739_UG.pdf" relativeURI="doc/IP_Daemon_Dynamic_CNL113739_UG.pdf"/>
+    <FileResource projectRelativePath="doc/IR_doc.doc" relativeURI="doc/IR_doc.doc"/>
+    <FileResource projectRelativePath="doc/IR_src.doc" relativeURI="doc/IR_src.doc"/>
+  </Files>
+  <ActiveConfiguration>Default</ActiveConfiguration>
+  <Configurations>
+    <Configuration name="Default">
+      <ProjectProperties>
+        <MakefileSettings>
+          <generateInternalMakefile>true</generateInternalMakefile>
+          <GNUMake>true</GNUMake>
+          <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+          <singleMode>true</singleMode>
+          <targetExecutable>bin/IP_Daemon_Dynamic_CNL113739</targetExecutable>
+          <preprocessorDefines>
+            <listItem>LKSCTP_1_0_9</listItem>
+          </preprocessorDefines>
+        </MakefileSettings>
+        <LocalBuildSettings>
+          <workingDirectory>bin</workingDirectory>
+        </LocalBuildSettings>
+        <NamingCoventions>
+          <enableProjectSpecificSettings>true</enableProjectSpecificSettings>
+          <function>.*</function>
+          <externalFunction>.*</externalFunction>
+          <localVariable>.*</localVariable>
+          <formalParameter>.*</formalParameter>
+        </NamingCoventions>
+        <ConfigurationRequirements>
+          <configurationRequirement>
+            <projectName>IPL4asp_CNL113531</projectName>
+            <rerquiredConfiguration>SSL_SCTP109</rerquiredConfiguration>
+          </configurationRequirement>
+        </ConfigurationRequirements>
+      </ProjectProperties>
+      <FolderProperties>
+        <FolderResource>
+          <FolderPath>doc</FolderPath>
+          <FolderProperties>
+            <ExcludeFromBuild>true</ExcludeFromBuild>
+          </FolderProperties>
+        </FolderResource>
+      </FolderProperties>
+    </Configuration>
+  </Configurations>
+</TITAN_Project_File_Information>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3534f2f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0

+

+    THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE

+    PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION

+    OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.

+

+1. DEFINITIONS

+

+"Contribution" means:

+

+  a) in the case of the initial Contributor, the initial content

+     Distributed under this Agreement, and

+

+  b) in the case of each subsequent Contributor:

+     i) changes to the Program, and

+     ii) additions to the Program;

+  where such changes and/or additions to the Program originate from

+  and are Distributed by that particular Contributor. A Contribution

+  "originates" from a Contributor if it was added to the Program by

+  such Contributor itself or anyone acting on such Contributor's behalf.

+  Contributions do not include changes or additions to the Program that

+  are not Modified Works.

+

+"Contributor" means any person or entity that Distributes the Program.

+

+"Licensed Patents" mean patent claims licensable by a Contributor which

+are necessarily infringed by the use or sale of its Contribution alone

+or when combined with the Program.

+

+"Program" means the Contributions Distributed in accordance with this

+Agreement.

+

+"Recipient" means anyone who receives the Program under this Agreement

+or any Secondary License (as applicable), including Contributors.

+

+"Derivative Works" shall mean any work, whether in Source Code or other

+form, that is based on (or derived from) the Program and for which the

+editorial revisions, annotations, elaborations, or other modifications

+represent, as a whole, an original work of authorship.

+

+"Modified Works" shall mean any work in Source Code or other form that

+results from an addition to, deletion from, or modification of the

+contents of the Program, including, for purposes of clarity any new file

+in Source Code form that contains any contents of the Program. Modified

+Works shall not include works that contain only declarations,

+interfaces, types, classes, structures, or files of the Program solely

+in each case in order to link to, bind by name, or subclass the Program

+or Modified Works thereof.

+

+"Distribute" means the acts of a) distributing or b) making available

+in any manner that enables the transfer of a copy.

+

+"Source Code" means the form of a Program preferred for making

+modifications, including but not limited to software source code,

+documentation source, and configuration files.

+

+"Secondary License" means either the GNU General Public License,

+Version 2.0, or any later versions of that license, including any

+exceptions or additional permissions as identified by the initial

+Contributor.

+

+2. GRANT OF RIGHTS

+

+  a) Subject to the terms of this Agreement, each Contributor hereby

+  grants Recipient a non-exclusive, worldwide, royalty-free copyright

+  license to reproduce, prepare Derivative Works of, publicly display,

+  publicly perform, Distribute and sublicense the Contribution of such

+  Contributor, if any, and such Derivative Works.

+

+  b) Subject to the terms of this Agreement, each Contributor hereby

+  grants Recipient a non-exclusive, worldwide, royalty-free patent

+  license under Licensed Patents to make, use, sell, offer to sell,

+  import and otherwise transfer the Contribution of such Contributor,

+  if any, in Source Code or other form. This patent license shall

+  apply to the combination of the Contribution and the Program if, at

+  the time the Contribution is added by the Contributor, such addition

+  of the Contribution causes such combination to be covered by the

+  Licensed Patents. The patent license shall not apply to any other

+  combinations which include the Contribution. No hardware per se is

+  licensed hereunder.

+

+  c) Recipient understands that although each Contributor grants the

+  licenses to its Contributions set forth herein, no assurances are

+  provided by any Contributor that the Program does not infringe the

+  patent or other intellectual property rights of any other entity.

+  Each Contributor disclaims any liability to Recipient for claims

+  brought by any other entity based on infringement of intellectual

+  property rights or otherwise. As a condition to exercising the

+  rights and licenses granted hereunder, each Recipient hereby

+  assumes sole responsibility to secure any other intellectual

+  property rights needed, if any. For example, if a third party

+  patent license is required to allow Recipient to Distribute the

+  Program, it is Recipient's responsibility to acquire that license

+  before distributing the Program.

+

+  d) Each Contributor represents that to its knowledge it has

+  sufficient copyright rights in its Contribution, if any, to grant

+  the copyright license set forth in this Agreement.

+

+  e) Notwithstanding the terms of any Secondary License, no

+  Contributor makes additional grants to any Recipient (other than

+  those set forth in this Agreement) as a result of such Recipient's

+  receipt of the Program under the terms of a Secondary License

+  (if permitted under the terms of Section 3).

+

+3. REQUIREMENTS

+

+3.1 If a Contributor Distributes the Program in any form, then:

+

+  a) the Program must also be made available as Source Code, in

+  accordance with section 3.2, and the Contributor must accompany

+  the Program with a statement that the Source Code for the Program

+  is available under this Agreement, and informs Recipients how to

+  obtain it in a reasonable manner on or through a medium customarily

+  used for software exchange; and

+

+  b) the Contributor may Distribute the Program under a license

+  different than this Agreement, provided that such license:

+     i) effectively disclaims on behalf of all other Contributors all

+     warranties and conditions, express and implied, including

+     warranties or conditions of title and non-infringement, and

+     implied warranties or conditions of merchantability and fitness

+     for a particular purpose;

+

+     ii) effectively excludes on behalf of all other Contributors all

+     liability for damages, including direct, indirect, special,

+     incidental and consequential damages, such as lost profits;

+

+     iii) does not attempt to limit or alter the recipients' rights

+     in the Source Code under section 3.2; and

+

+     iv) requires any subsequent distribution of the Program by any

+     party to be under a license that satisfies the requirements

+     of this section 3.

+

+3.2 When the Program is Distributed as Source Code:

+

+  a) it must be made available under this Agreement, or if the

+  Program (i) is combined with other material in a separate file or

+  files made available under a Secondary License, and (ii) the initial

+  Contributor attached to the Source Code the notice described in

+  Exhibit A of this Agreement, then the Program may be made available

+  under the terms of such Secondary Licenses, and

+

+  b) a copy of this Agreement must be included with each copy of

+  the Program.

+

+3.3 Contributors may not remove or alter any copyright, patent,

+trademark, attribution notices, disclaimers of warranty, or limitations

+of liability ("notices") contained within the Program from any copy of

+the Program which they Distribute, provided that Contributors may add

+their own appropriate notices.

+

+4. COMMERCIAL DISTRIBUTION

+

+Commercial distributors of software may accept certain responsibilities

+with respect to end users, business partners and the like. While this

+license is intended to facilitate the commercial use of the Program,

+the Contributor who includes the Program in a commercial product

+offering should do so in a manner which does not create potential

+liability for other Contributors. Therefore, if a Contributor includes

+the Program in a commercial product offering, such Contributor

+("Commercial Contributor") hereby agrees to defend and indemnify every

+other Contributor ("Indemnified Contributor") against any losses,

+damages and costs (collectively "Losses") arising from claims, lawsuits

+and other legal actions brought by a third party against the Indemnified

+Contributor to the extent caused by the acts or omissions of such

+Commercial Contributor in connection with its distribution of the Program

+in a commercial product offering. The obligations in this section do not

+apply to any claims or Losses relating to any actual or alleged

+intellectual property infringement. In order to qualify, an Indemnified

+Contributor must: a) promptly notify the Commercial Contributor in

+writing of such claim, and b) allow the Commercial Contributor to control,

+and cooperate with the Commercial Contributor in, the defense and any

+related settlement negotiations. The Indemnified Contributor may

+participate in any such claim at its own expense.

+

+For example, a Contributor might include the Program in a commercial

+product offering, Product X. That Contributor is then a Commercial

+Contributor. If that Commercial Contributor then makes performance

+claims, or offers warranties related to Product X, those performance

+claims and warranties are such Commercial Contributor's responsibility

+alone. Under this section, the Commercial Contributor would have to

+defend claims against the other Contributors related to those performance

+claims and warranties, and if a court requires any other Contributor to

+pay any damages as a result, the Commercial Contributor must pay

+those damages.

+

+5. NO WARRANTY

+

+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT

+PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"

+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR

+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF

+TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR

+PURPOSE. Each Recipient is solely responsible for determining the

+appropriateness of using and distributing the Program and assumes all

+risks associated with its exercise of rights under this Agreement,

+including but not limited to the risks and costs of program errors,

+compliance with applicable laws, damage to or loss of data, programs

+or equipment, and unavailability or interruption of operations.

+

+6. DISCLAIMER OF LIABILITY

+

+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT

+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS

+SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST

+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE

+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE

+POSSIBILITY OF SUCH DAMAGES.

+

+7. GENERAL

+

+If any provision of this Agreement is invalid or unenforceable under

+applicable law, it shall not affect the validity or enforceability of

+the remainder of the terms of this Agreement, and without further

+action by the parties hereto, such provision shall be reformed to the

+minimum extent necessary to make such provision valid and enforceable.

+

+If Recipient institutes patent litigation against any entity

+(including a cross-claim or counterclaim in a lawsuit) alleging that the

+Program itself (excluding combinations of the Program with other software

+or hardware) infringes such Recipient's patent(s), then such Recipient's

+rights granted under Section 2(b) shall terminate as of the date such

+litigation is filed.

+

+All Recipient's rights under this Agreement shall terminate if it

+fails to comply with any of the material terms or conditions of this

+Agreement and does not cure such failure in a reasonable period of

+time after becoming aware of such noncompliance. If all Recipient's

+rights under this Agreement terminate, Recipient agrees to cease use

+and distribution of the Program as soon as reasonably practicable.

+However, Recipient's obligations under this Agreement and any licenses

+granted by Recipient relating to the Program shall continue and survive.

+

+Everyone is permitted to copy and distribute copies of this Agreement,

+but in order to avoid inconsistency the Agreement is copyrighted and

+may only be modified in the following manner. The Agreement Steward

+reserves the right to publish new versions (including revisions) of

+this Agreement from time to time. No one other than the Agreement

+Steward has the right to modify this Agreement. The Eclipse Foundation

+is the initial Agreement Steward. The Eclipse Foundation may assign the

+responsibility to serve as the Agreement Steward to a suitable separate

+entity. Each new version of the Agreement will be given a distinguishing

+version number. The Program (including Contributions) may always be

+Distributed subject to the version of the Agreement under which it was

+received. In addition, after a new version of the Agreement is published,

+Contributor may elect to Distribute the Program (including its

+Contributions) under the new version.

+

+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient

+receives no rights or licenses to the intellectual property of any

+Contributor under this Agreement, whether expressly, by implication,

+estoppel or otherwise. All rights in the Program not expressly granted

+under this Agreement are reserved. Nothing in this Agreement is intended

+to be enforceable by any entity that is not a Contributor or Recipient.

+No third-party beneficiary rights are created under this Agreement.

+

+Exhibit A - Form of Secondary Licenses Notice

+

+"This Source Code may also be made available under the following 

+Secondary Licenses when the conditions for such availability set forth 

+in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),

+version(s), and exceptions or additional permissions here}."

+

+  Simply including a copy of this Agreement, including this Exhibit A

+  is not sufficient to license the Source Code under Secondary Licenses.

+

+  If it is not possible or desirable to put the notice in a particular

+  file, then You may include the notice in a location (such as a LICENSE

+  file in a relevant directory) where a recipient would be likely to

+  look for such a notice.

+

+  You may add additional accurate notices of copyright ownership.
\ No newline at end of file
diff --git a/demo/IP_Daemon_Dynamic.cfg b/demo/IP_Daemon_Dynamic.cfg
new file mode 100644
index 0000000..3b97817
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic.cfg
@@ -0,0 +1,72 @@
+[MODULE_PARAMETERS]
+tsp_IPDD_ConnectionList := 
+{
+  {
+    serverConnection  := true, // true := server, false: client
+    autoReconnect     := false,
+    localInterface    := 
+    {
+      hostNameLength  := 0,
+      hostName        := "127.0.0.1",
+      portNumber      := 33333//(1..65535)
+    },
+    remoteInterface   := omit,
+    proto             := udp//tcp//sctp
+  },
+  {
+    serverConnection   := false, // true := server, false: client
+    autoReconnect       := false,
+    localInterface      := 
+    {
+      hostNameLength  := 0,
+      hostName        := "127.0.0.1",
+      portNumber      := 60000//(1..65535)
+    },
+    remoteInterface     :=
+    {
+      hostNameLength  := 0,
+      hostName        := "127.0.0.1",
+      portNumber      := 33333//(1..65535)
+    },
+    proto             := udp//tcp//sctp
+  },
+  {
+    serverConnection   := false, // true := server, false: client
+    autoReconnect       := false,
+    localInterface      := 
+    {
+      hostNameLength  := 0,
+      hostName        := "127.0.0.1",
+      portNumber      := 60001//(1..65535)
+    },
+    remoteInterface     :=
+    {
+      hostNameLength  := 0,
+      hostName        := "127.0.0.1",
+      portNumber      := 33333//(1..65535)
+    },
+    proto             := udp//tcp//sctp
+  }
+};
+
+[LOGGING]
+MatchingHints := Compact
+AppendFile := No
+TimeStampFormat := Time
+LogEntityName := Yes
+LogEventTypes := Yes
+LogFile := "ip_daemon.log"
+SourceInfoFormat := Stack
+ConsoleMask := STATISTICS|TESTCASE|ACTION|WARNING|ERROR|USER
+FileMask :=DEBUG|WARNING|VERDICTOP|USER|TIMEROP|TESTCASE|STATISTICS|PORTEVENT|PARALLEL|FUNCTION|EXECUTOR|ERROR|DEFAULTOP|ACTION
+DiskFullAction := Error
+LogFileNumber := 1
+LogFileSize := 0
+
+[TESTPORT_PARAMETERS]
+*.IP_PCO.pureNonBlocking := "NO"
+*.IP_PCO.debug := "YES"
+
+[EXECUTE]
+IP_Daemon_Dynamic.tc_IPDD
+//IP_Daemon_Dynamic_with_DiameterAutoReplies
diff --git a/demo/IP_Daemon_Dynamic_CNL113739_demo.tpd b/demo/IP_Daemon_Dynamic_CNL113739_demo.tpd
new file mode 100644
index 0000000..0cc2093
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_CNL113739_demo.tpd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TITAN_Project_File_Information version="1.0">
+  <ProjectName>IP_Daemon_Dynamic_CNL113739_demo</ProjectName>
+  <ReferencedProjects>
+    <ReferencedProject name="IP_Daemon_Dynamic_CNL113739" projectLocationURI="../IP_Daemon_Dynamic_CNL113739.tpd"/>
+  </ReferencedProjects>
+  <Files>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic.cfg" relativeURI="IP_Daemon_Dynamic.cfg"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_Test.cfg" relativeURI="IP_Daemon_Dynamic_Test.cfg"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_Test.ttcn" relativeURI="IP_Daemon_Dynamic_Test.ttcn"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn" relativeURI="IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn"/>
+    <FileResource projectRelativePath="IP_Daemon_Dynamic_with_StartupCallback.ttcn" relativeURI="IP_Daemon_Dynamic_with_StartupCallback.ttcn"/>
+  </Files>
+  <ActiveConfiguration>Default</ActiveConfiguration>
+  <Configurations>
+    <Configuration name="Default">
+      <ProjectProperties>
+        <MakefileSettings>
+          <generateInternalMakefile>true</generateInternalMakefile>
+          <GNUMake>true</GNUMake>
+          <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+          <singleMode>true</singleMode>
+          <targetExecutable>bin/IP_Daemon_Dynamic_CNL113739_demo</targetExecutable>
+        </MakefileSettings>
+        <LocalBuildSettings>
+          <workingDirectory>bin</workingDirectory>
+        </LocalBuildSettings>
+      </ProjectProperties>
+    </Configuration>
+  </Configurations>
+</TITAN_Project_File_Information>
\ No newline at end of file
diff --git a/demo/IP_Daemon_Dynamic_Test.cfg b/demo/IP_Daemon_Dynamic_Test.cfg
new file mode 100644
index 0000000..1854ded
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_Test.cfg
@@ -0,0 +1,35 @@
+[LOGGING]
+LogFile := "ip_daemon_test_%p.log"
+TimeStampFormat := Time
+LogEntityName := Yes
+LogEventTypes := Yes
+SourceInfoFormat := Stack
+ConsoleMask := STATISTICS|TESTCASE|ACTION|WARNING|ERROR|USER
+FileMask := DEBUG|WARNING|VERDICTOP|USER|TIMEROP|TESTCASE|STATISTICS|PORTEVENT|PARALLEL|FUNCTION|EXECUTOR|ERROR|DEFAULTOP|ACTION
+DiskFullAction := Error
+LogFileNumber := 1
+LogFileSize := 0
+
+[TESTPORT_PARAMETERS]
+*.daemonPort.debug := "YES"
+*.IP_PCO.debug := "YES"
+
+[EXECUTE]
+//*** SCTP testcases
+IP_Daemon_Dynamic_Test.tc_Init_SCTP_ClientServer_StopServer_CheckClientConnChange
+//IP_Daemon_Dynamic_Test.tc_Init_SCTP_ClientServer_CheckClientConnChange_StopServer_CheckClientConnChange_StartServer_CheckClientConnChange
+//IP_Daemon_Dynamic_Test.tc_Init_SCTP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer
+//IP_Daemon_Dynamic_Test.tc_3_SCTP_Servers_and_3_SCTP_Clients
+//..Run this testcase only with IP_Daemon_Dynamic_with_DiameterAutoReplies
+//IP_Daemon_Dynamic_Test.tc_SCTP_AutoReplyDeviceWatchdog
+
+//*** TCP testcases
+//IP_Daemon_Dynamic_Test.tc_Init_TCP_ClientServer_StopServer_CheckClientConnClosed
+//IP_Daemon_Dynamic_Test.tc_Init_TCP_CLientServer_SendDataFromClient_CheckDataReceiveOnServer
+//IP_Daemon_Dynamic_Test.tc_Init_TCP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer
+//IP_Daemon_Dynamic_Test.tc_2_TCP_Servers_and_2_TCP_Clients
+//..Run this testcase only with IP_Daemon_Dynamic_with_DiameterAutoReplies
+//IP_Daemon_Dynamic_Test.tc_TCP_AutoReplyDeviceWatchdog
+
+//*** UDP testcases
+//IP_Daemon_Dynamic_Test.tc_Init_2_UDP_Clients_sendData_checkDataReceived
diff --git a/demo/IP_Daemon_Dynamic_Test.ttcn b/demo/IP_Daemon_Dynamic_Test.ttcn
new file mode 100644
index 0000000..289dc44
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_Test.ttcn
@@ -0,0 +1,1083 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:           IP_Daemon_Dynamic_Test.ttcn
+//  Description:    IPDD test
+//  Rev:            <RnXnn>
+//  Prodnr:         CNL 113 630
+//  Updated:        2012-05-07
+//  Contact:        http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_Test
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+import from IP_Daemon_Dynamic_IPL4_CtrlFunct all;
+//=========================================================================
+// Module Parameters
+//=========================================================================
+
+modulepar {
+
+  // Host name where the IP Daemon listens for the testcases
+  charstring tsp_IPDD_Host := "127.0.0.1";
+
+  // Port number where the IP Daemon listens for the testcases
+  integer tsp_IPDD_Port := 1314;
+
+  charstring tsp_serverInterface := "127.0.0.1";
+  integer tsp_serverPort := 1315;
+}
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record of integer clientConnectionIds;
+
+//=========================================================================
+//Port Types
+//=========================================================================
+
+// Insert port type defintions here if applicable!
+// You can use the port_type skeleton!
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+type component MAIN_CT {
+  port IPDD_Interface_PT daemonPort;
+
+  var IPDD_Message_with_ClientId vc_daemonMessage;
+
+  var clientConnectionIds vc_clientConnIds := {};
+
+  var integer vc_tcp_client_id;
+  var integer vc_serverConnectionId := -1; 
+  var integer vc_clientConnectionId := -1;
+  var integer vc_connectedClientConnectionId := -1;
+  var boolean vc_isClientConnected := false;
+}
+
+//=========================================================================
+// Constants
+//=========================================================================
+
+// Insert constants here if applicable!
+// You can use the constant skeleton!
+
+//=========================================================================
+// Templates
+//=========================================================================
+
+// Insert templates here if applicable!
+// You can use the template skeleton!
+
+//=========================================================================
+// Altsteps
+//=========================================================================
+
+// Insert altsteps here if applicable!
+// You can use the altstep skeleton!
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_Connect_to_IPDD() runs on MAIN_CT {
+  timer t_wait;
+
+  var Result vl_result := { errorCode := omit, connId  := omit, os_error_code:=omit, os_error_text:= omit };
+
+  vl_result := IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_connect
+  ( 
+    daemonPort, 
+    tsp_IPDD_Host,
+    tsp_IPDD_Port,
+    tsp_serverInterface,
+    0,
+    connId := -1,
+    proto := { tcp := {} },
+    options := {}
+  );
+  if ((vl_result.errorCode == omit) or (vl_result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE)) { //if not error
+    log("Connected to the IP Daemon on " & tsp_IPDD_Host & ":" & int2str(tsp_IPDD_Port));
+    vc_tcp_client_id := vl_result.connId;
+
+    var f_IPL4_getMsgLen sdd_msglen := refers(f_IPDD_getMsgLen);
+    f_IPL4_setGetMsgLen(daemonPort, vc_tcp_client_id,sdd_msglen, {});
+
+  }else{
+    log("Could not connect to the IP Daemon on " & tsp_IPDD_Host & ":" & int2str(tsp_IPDD_Port));
+  }
+}
+
+// initialize a server and a client connection if they are not already present
+function f_Init_IP_Client(in charstring remoteIf, in integer remotePort, in ProtoTupleEnum proto) runs on MAIN_CT {
+  daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+  timer t_wait := 5.0; t_wait.start;
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+
+      vc_clientConnectionId := -1; 
+
+      for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+        if((vc_clientConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface)) {
+          if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.hostName == remoteIf and
+            vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.portNumber == remotePort) {
+            vc_clientConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+          }
+        }
+      }
+
+      if(vc_clientConnectionId < 0) {
+        daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+              ipdd_connect := {
+                messageType := 0, // use dummy value
+                autoReconnect := true,
+                localInterfacePresent := false, // enter always false
+                localInterface :={
+                  hostNameLength := 0, // use dummy value
+                  hostName := remoteIf,
+                  portNumber := 0
+                },
+                remoteInterface := {
+                  hostNameLength := 0, // use dummy value
+                  hostName := remoteIf,
+                  portNumber := remotePort
+                },
+                proto := proto,
+                sctpProtoAttributesPresent := false,
+                sctpProtoAttributes := omit
+              }
+            }});
+
+        t_wait.stop; t_wait.start;
+        alt {
+          [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_result := ? } }) -> value vc_daemonMessage {
+            if(not vc_daemonMessage.msg.ipdd_result.errorStatus) {
+              vc_clientConnectionId := vc_daemonMessage.msg.ipdd_result.connectionId;
+            } else {
+              log("*** ERROR: error response received for f_Init_IP_Client: " ,vc_daemonMessage.msg.ipdd_result);
+              setverdict(fail);
+            }
+            repeat;
+          }
+          [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_connected := ? } }) -> value vc_daemonMessage {
+            log("*** INFO: client connected: ", vc_daemonMessage);
+            vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connected.connectionId;
+            vc_isClientConnected := true;
+            repeat;
+          }
+          [] t_wait.timeout {
+            if((vc_clientConnectionId == -1) and (vc_connectedClientConnectionId == -1)){
+              log("*** ERROR: no response to f_Init_IP_Client!");
+              setverdict(fail);
+            }
+          }
+        }
+      } else {
+        log("*** INFO: client connection is already defined, subscribing to it...");
+        daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+              ipdd_subscribeToConnection := {
+                messageType := 0,
+                connectionId := vc_clientConnectionId
+              }
+            }
+          });
+      }
+    }
+
+    [] daemonPort.receive {
+      log("*** INFO: message ignored.");
+    }
+
+    [] t_wait.timeout {
+      log("*** ERROR: there is no response for connection list query!");
+    }
+  }
+  log("vc_clientConnectionId: ",vc_clientConnectionId);
+  log("vc_connectedClientConnectionId: ",vc_connectedClientConnectionId);
+}
+
+function f_Init_IP_Server(in charstring localIf, in integer localPort, in ProtoTupleEnum pl_proto) runs on MAIN_CT {
+  daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+  timer t_wait := 5.0; t_wait.start;
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+
+      vc_serverConnectionId := -1;
+      vc_connectedClientConnectionId := -1;
+
+      for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+        if((vc_serverConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface)) {
+          if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].serverConnection and
+            vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.hostName == localIf and
+            vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.portNumber == localPort) {
+            vc_serverConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+          }
+        }
+
+        // connected client: not server and the local interface is the same as the server's local interface
+        if((vc_connectedClientConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface)) {
+          if(not vc_daemonMessage.msg.ipdd_connections.connectionList[i].serverConnection and
+            vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.hostName == localIf and
+            vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.portNumber == localPort) {
+            vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+          }
+        }
+      }
+
+      if(vc_connectedClientConnectionId > -1) {
+        log("*** INFO: server's connected client connection is already present, subscribing to it...");
+        daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+              ipdd_subscribeToConnection := {
+                messageType := 0,
+                connectionId := vc_connectedClientConnectionId
+              }
+            }
+          });
+      }
+
+      if(vc_serverConnectionId < 0) {
+        daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+              ipdd_listen := {
+                messageType := 0, // use dummy value
+                localInterface := {
+                  hostNameLength := 0, // use dummy value
+                  hostName := localIf,
+                  portNumber := localPort
+                },
+                proto := pl_proto,
+                sctpProtoAttributesPresent := false,
+                sctpProtoAttributes := omit
+              }
+            } });
+
+        t_wait.stop; t_wait.start;
+        alt {
+          [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_result := ? } }) -> value vc_daemonMessage {
+            log("*** INFO: received result message: ",vc_daemonMessage);
+            if(not vc_daemonMessage.msg.ipdd_result.errorStatus) {
+              vc_serverConnectionId := vc_daemonMessage.msg.ipdd_result.connectionId;
+            } else {
+              log("*** ERROR: error response received for f_Init_IP_Server: ", vc_daemonMessage.msg.ipdd_result);
+              setverdict(fail);
+            }
+          }
+          [] daemonPort.receive(IPDD_Message_with_ClientId : ?) {
+            log("*** INFO: message ignored.");
+            repeat;
+          }
+          [] t_wait.timeout {
+            log("*** ERROR: no response to f_Init_IP_Server!");
+            setverdict(fail);
+          }
+        }
+      } else {
+        log("*** INFO: server connection is already defined, subscribing to it...");
+        daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+              ipdd_subscribeToConnection := {
+                messageType := 0,
+                connectionId := vc_serverConnectionId
+              }
+            }
+          });
+      }
+    }
+
+    [] daemonPort.receive {
+      log("*** INFO: message ignored.");
+      repeat;
+    }
+
+    [] t_wait.timeout {
+      log("*** ERROR: there is no response for connection list query!");
+    }
+  }
+  log("vc_serverConnectionId: ",vc_serverConnectionId);
+  log("vc_connectedClientConnectionId: ",vc_connectedClientConnectionId);
+}
+
+function f_StopServer() runs on MAIN_CT {
+  if(vc_connectedClientConnectionId > 0) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_close := { messageType := 0, connectionId := vc_connectedClientConnectionId }
+        }});
+  }
+
+  daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+        ipdd_close := { messageType := 0, connectionId := vc_serverConnectionId }
+      }});
+}
+
+function f_StopClient() runs on MAIN_CT {
+  daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+        ipdd_close := { messageType := 0, connectionId := vc_clientConnectionId }
+      }});
+}
+
+function f_StopMultipleClients() runs on MAIN_CT {
+  for(var integer i := 0; i < sizeof(vc_clientConnIds); i := i + 1) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_close := { messageType := 0, connectionId := vc_clientConnIds[i] }
+        }});
+  }
+
+  vc_clientConnIds := {};
+}
+
+// initialize a server and a client connection if they are not already present
+function f_StopMyConnections() runs on MAIN_CT {
+  daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+  timer t_wait := 5.0; t_wait.start;
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+      log("*** INFO: current ipdd_connections: ", vc_daemonMessage.msg.ipdd_connections.connectionList);
+      vc_clientConnectionId := -1; 
+      for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+        if(ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface)) {
+          if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].localInterface.hostName == tsp_serverInterface) {
+            daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+                  ipdd_close := { messageType := 0, connectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId }
+                }});
+          }
+        }
+
+        if(ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface)) {
+          if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.hostName == tsp_serverInterface) {
+            daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+                  ipdd_close := { messageType := 0, connectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId }
+                }});
+          }
+        }
+      }
+    }
+
+    [] t_wait.timeout {
+      log("*** ERROR: there is no response for connection list query!");
+    }
+  }
+}
+
+function f_CheckClientConnection_Gets(in SAC_STATE pl_state) runs on MAIN_CT {
+  timer t_wait := 55.0; t_wait.start;
+
+  log("*** INFO: waiting client connection #", vc_clientConnectionId, " to report state: ", pl_state, ".");
+
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_connectionChanged := {
+            messageType := ?,
+            connectionId := vc_clientConnectionId,
+            eventPresent := false,
+            event := omit,
+            sctpStatePresent := true,
+            sctpState := pl_state
+          }
+        }
+      }) {
+      log("*** PASS: connectionChanged ", pl_state, " received!");
+      setverdict(pass);
+    }
+    [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_connected := ? } }) -> value vc_daemonMessage {
+      log("*** INFO: client connected: ", vc_daemonMessage);
+      vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connected.connectionId;
+      repeat;
+    }
+    [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+      log("*** INFO: message ignored.");
+      repeat;
+    }
+    [] t_wait.timeout {
+      log("*** FAIL: no connectionChanged ", pl_state," received!");
+      setverdict(fail);
+    }
+  }
+}
+
+function f_serverWaitForConnection() runs on MAIN_CT {
+  timer t_wait := 55.0; t_wait.start;
+  log("*** INFO: waiting for client connection...");
+  var IPDD_Message_with_ClientId vl_msg;
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_connected := ?
+        }
+      }) -> value vl_msg
+    {
+      log("*** PASS: Connected! ");
+      vc_serverConnectionId := vl_msg.msg.ipdd_connected.connectionId;
+      setverdict(pass);
+    }
+    [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+      log("*** INFO: message ignored.");
+      repeat;
+    }
+    [] t_wait.timeout {
+      log("*** FAIL: no connection was received!");
+      setverdict(fail);
+    }
+  }
+}
+
+function f_sendDataFromClient(in octetstring dataToSend, in ProtoTupleEnum proto) runs on MAIN_CT {
+  if(proto == sctp) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_data := {
+            messageType := 0, // encoder will replace
+            connectionId := vc_clientConnectionId,
+            sctpAttributesPresent := true,
+            sctpAttributes := {
+              sinfo_stream := 11,
+              sinfo_ppid := 22  
+            },
+            dataLength := 0, // encoder will replace
+            data := dataToSend
+          }
+        }});
+  }
+  if(proto == tcp or proto == udp) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_data := {
+            messageType := 0, // encoder will replace
+            connectionId := vc_clientConnectionId,
+            sctpAttributesPresent := false,
+            sctpAttributes := omit,
+            dataLength := 0, // encoder will replace
+            data := dataToSend
+          }
+        }});
+  }
+}
+
+function f_sendDataFromServer(in octetstring dataToSend, in ProtoTupleEnum proto) runs on MAIN_CT {
+  if(proto == sctp) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_data := {
+            messageType := 0, // encoder will replace
+            connectionId := vc_serverConnectionId,
+            sctpAttributesPresent := true,
+            sctpAttributes := {
+              sinfo_stream := 11,
+              sinfo_ppid := 22  
+            },
+            dataLength := 0, // encoder will replace
+            data := dataToSend
+          }
+        }});
+  }
+  if(proto == tcp or proto == udp) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_data := {
+            messageType := 0, // encoder will replace
+            connectionId := vc_serverConnectionId,
+            sctpAttributesPresent := false,
+            sctpAttributes := omit,
+            dataLength := 0, // encoder will replace
+            data := dataToSend
+          }
+        }});
+  }
+}
+
+function f_sendData(in integer connId, in octetstring dataToSend, in ProtoTupleEnum proto) runs on MAIN_CT {
+  if(proto == sctp) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_data := {
+            messageType := 0, // encoder will replace
+            connectionId := connId,
+            sctpAttributesPresent := true,
+            sctpAttributes := {
+              sinfo_stream := 11,
+              sinfo_ppid := 22  
+            },
+            dataLength := 0, // encoder will replace
+            data := dataToSend
+          }
+        }});
+  }
+  if(proto == tcp or proto == udp) {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+          ipdd_data := {
+            messageType := 0, // encoder will replace
+            connectionId := connId,
+            sctpAttributesPresent := false,
+            sctpAttributes := omit,
+            dataLength := 0, // encoder will replace
+            data := dataToSend
+          }
+        }});
+  }
+}
+
+function f_CheckDataReceive(in integer connectionId, in octetstring dataToReceive) runs on MAIN_CT {
+  timer t_wait := 5.0; t_wait.start;
+
+  log("*** INFO: waiting for incoming data: ", dataToReceive, "...");
+
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_data := {
+            messageType := ?,
+            connectionId := connectionId,
+            sctpAttributesPresent := true,
+            sctpAttributes := {
+              sinfo_stream := 11,
+              sinfo_ppid := ?  //22
+            },
+            dataLength := ?,
+            data := dataToReceive
+          }
+        }
+      }) {
+      log("*** PASS: ipdd_data ", dataToReceive, " received!");
+      setverdict(pass);
+    }
+
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_data := {
+            messageType := ?,
+            connectionId := connectionId,
+            sctpAttributesPresent := false,
+            sctpAttributes := omit,
+            dataLength := ?,
+            data := dataToReceive
+          }
+        }
+      }) {
+      log("*** PASS: ipdd_data ", dataToReceive, " received!");
+      setverdict(pass);
+    }
+
+    [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+      log("*** INFO: message ignored.");
+      repeat;
+    }
+
+    [] t_wait.timeout {
+      log("*** FAIL: no ipdd_data ", dataToReceive, " received!");
+      setverdict(fail);
+    }
+  }
+}
+
+function f_CheckDataReceive_noOtherData(in template integer connectionId, in template octetstring dataToReceive) runs on MAIN_CT {
+  timer t_wait := 5.0; t_wait.start;
+
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_data := {
+            messageType := ?,
+            connectionId := connectionId,
+            sctpAttributesPresent := true,
+            sctpAttributes := {
+              sinfo_stream := 11,
+              sinfo_ppid := ?  //22
+            },
+            dataLength := ?,
+            data := dataToReceive
+          }
+        }
+      }) {
+      log("*** PASS: ipdd_data ", dataToReceive, " received!");
+      setverdict(pass);
+    }
+    
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_data := {
+            messageType := ?,
+            connectionId := connectionId,
+            sctpAttributesPresent := true,
+            sctpAttributes := {
+              sinfo_stream := 11,
+              sinfo_ppid := ?  //22
+            },
+            dataLength := ?,
+            data := ?
+          }
+        }
+      }) {
+      log("*** FAIL: invalid ipdd_data received!");
+      setverdict(fail);
+      repeat;
+    }
+    
+    [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+      log("*** INFO: message ignored.");
+      repeat;
+    }
+    
+    [] t_wait.timeout {
+      log("*** FAIL: no ipdd_data ", dataToReceive, " received!");
+      setverdict(fail);
+    }
+  }
+}
+
+function f_ServerEchoBack(in float p_serviceTime := 5.0) runs on MAIN_CT {
+  timer t_wait := p_serviceTime; t_wait.start;
+
+  var IPDD_Message_with_ClientId vl_inc;
+
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_data := {
+            messageType := ?,
+            connectionId := ?,
+            sctpAttributesPresent := true,
+            sctpAttributes := {
+              sinfo_stream := 11,
+              sinfo_ppid := ?  //22
+            },
+            dataLength := ?,
+            data := ?
+          }
+        }
+      }) -> value vl_inc
+    {
+      daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+            ipdd_data := {
+              messageType := 0, // encoder will replace
+              connectionId := vc_serverConnectionId,
+              sctpAttributesPresent := true,
+              sctpAttributes := {
+                sinfo_stream := 11,
+                sinfo_ppid := 22  
+              },
+              dataLength := 0, // encoder will replace
+              data := vl_inc.msg.ipdd_data.data
+            }
+          }});
+      repeat;
+    }
+    
+    [] daemonPort.receive(IPDD_Message_with_ClientId:?) {
+      log("*** INFO: message ignored in Echo mode.");
+      repeat;
+    }
+    
+    [] t_wait.timeout {
+      log("*** INFO: exiting from echo service.");
+    }
+  }
+}
+
+function f_Check_ConnClosed_Received(in integer pl_connId) runs on MAIN_CT {
+  timer t := 5.0; t.start;
+
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : {
+        client_id := vc_tcp_client_id,
+        msg := {
+          ipdd_closed := {
+            messageType := ?,
+            connectionId := pl_connId
+          }
+        }
+      }) {
+      log("*** PASS: ipdd_closed message from IPDD received for connectionId: ", pl_connId, "!");
+      setverdict(pass);
+      t.stop; t.start;
+      repeat;
+    }
+
+    [] daemonPort.receive {
+      log("*** INFO: message ignored.");
+      repeat;
+    }
+
+    [] t.timeout {
+      log("*** INFO: no more relevant messages received.");
+    }
+  }
+}
+
+function f_Init_IP_Client_with_localInterface(
+  in charstring localIf, in integer localPort, in charstring remoteIf, in integer remotePort, in ProtoTupleEnum proto) runs on MAIN_CT {
+
+  daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_queryConnections := { 0 } } });
+
+  timer t_wait := 5.0; t_wait.start;
+  alt {
+    [] daemonPort.receive(IPDD_Message_with_ClientId : { ?, { ipdd_connections := ? } }) -> value vc_daemonMessage {
+
+      vc_clientConnectionId := -1; 
+
+      for(var integer i := 0; i < sizeof(vc_daemonMessage.msg.ipdd_connections.connectionList); i := i + 1) {
+        if((vc_clientConnectionId < 0) and ispresent(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface)) {
+          if(vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.hostName == remoteIf and
+            vc_daemonMessage.msg.ipdd_connections.connectionList[i].remoteInterface.portNumber == remotePort) {
+            vc_clientConnectionId := vc_daemonMessage.msg.ipdd_connections.connectionList[i].connectionId;
+          }
+        }
+      }
+
+      if(vc_clientConnectionId < 0) {
+        daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+              ipdd_connect := {
+                messageType := 0, // use dummy value
+                autoReconnect := true,
+                localInterfacePresent := true,
+                localInterface :={
+                  hostNameLength := 0, // use dummy value
+                  hostName := localIf,
+                  portNumber := localPort
+                },
+                remoteInterface := {
+                  hostNameLength := 0, // use dummy value
+                  hostName := remoteIf,
+                  portNumber := remotePort
+                },
+                proto := proto,
+                sctpProtoAttributesPresent := false,
+                sctpProtoAttributes := omit
+              }
+            }});
+
+        t_wait.stop; t_wait.start;
+        alt {
+          [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_result := ? } }) -> value vc_daemonMessage {
+            if(not vc_daemonMessage.msg.ipdd_result.errorStatus) {
+              vc_clientConnectionId := vc_daemonMessage.msg.ipdd_result.connectionId;
+              vc_clientConnIds[sizeof(vc_clientConnIds)] := vc_clientConnectionId;
+            } else {
+              log("*** ERROR: error response received for ipdd_connect: " ,vc_daemonMessage.msg.ipdd_result);
+              setverdict(fail);
+            }
+            repeat;
+          }
+          [] daemonPort.receive(IPDD_Message_with_ClientId : { vc_tcp_client_id, { ipdd_connected := ? } }) -> value vc_daemonMessage {
+            log("*** INFO: client connected: ", vc_daemonMessage);
+            vc_connectedClientConnectionId := vc_daemonMessage.msg.ipdd_connected.connectionId;
+            vc_isClientConnected := true;
+            repeat;
+          }
+          [] t_wait.timeout {
+            if((vc_clientConnectionId == -1) and (vc_connectedClientConnectionId == -1)){
+              log("*** ERROR: no response to ipdd_connect!");
+              setverdict(fail);
+            }
+          }
+        }
+      } else {
+        log("*** INFO: client connection is already defined, subscribing to it...");
+        daemonPort.send(IPDD_Message_with_ClientId : { vc_tcp_client_id, {
+              ipdd_subscribeToConnection := {
+                messageType := 0,
+                connectionId := vc_clientConnectionId
+              }
+            }
+          });
+      }
+    }
+
+    [] daemonPort.receive {
+      log("*** INFO: message ignored.");
+    }
+
+    [] t_wait.timeout {
+      log("*** ERROR: there is no response for connection list query!");
+    }
+  }
+  log("vc_clientConnectionId: ",vc_clientConnectionId);
+  log("vc_connectedClientConnectionId: ",vc_connectedClientConnectionId);
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_Init_2_UDP_Clients_sendData_checkDataReceived() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort, tsp_serverInterface, tsp_serverPort + 1, udp);
+  f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort + 1, tsp_serverInterface, tsp_serverPort, udp);
+
+  f_sendData(vc_clientConnIds[0], '0123456789ABCDEF'O, udp);
+
+  f_CheckDataReceive(vc_clientConnIds[1], '0123456789ABCDEF'O);
+
+  f_StopMultipleClients();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_TCP_ClientServer_StopServer_CheckClientConnClosed() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+  f_StopServer();
+
+  f_Check_ConnClosed_Received(vc_clientConnectionId);
+
+  f_StopClient();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_SCTP_ClientServer_StopServer_CheckClientConnChange() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+  f_StopServer();
+
+  f_CheckClientConnection_Gets(SCTP_COMM_LOST);
+
+  f_StopClient();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_SCTP_ClientServer_CheckClientConnChange_StopServer_CheckClientConnChange_StartServer_CheckClientConnChange() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+  f_CheckClientConnection_Gets(SCTP_COMM_UP);
+
+  f_StopServer();
+  f_CheckClientConnection_Gets(SCTP_COMM_LOST);
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_CheckClientConnection_Gets(SCTP_COMM_UP);
+
+  f_StopClient();
+  f_StopServer();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_TCP_CLientServer_SendDataFromClient_CheckDataReceiveOnServer() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+  f_sendDataFromClient('DB4720FFCA'O, sctp);
+
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'DB4720FFCA'O);
+
+  f_StopClient();
+  f_StopServer();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_SCTP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+  // could be sending ASP_TCP_Close too
+  unmap(mtc:daemonPort, system:daemonPort);
+
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+  f_sendDataFromClient('EEDDAADD'O, sctp);
+
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD'O);
+
+  f_StopServer();
+  f_StopClient();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_Init_TCP_ClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+  // could be sending ASP_TCP_Close too
+  unmap(mtc:daemonPort, system:daemonPort);
+
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+  f_sendDataFromClient('DF07A9FB'O, tcp);
+
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'DF07A9FB'O);
+
+  f_StopServer();
+  f_StopClient();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_3_SCTP_Servers_and_3_SCTP_Clients() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  vc_connectedClientConnectionId := -1;
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort + 2, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort + 2, sctp);
+  f_sendDataFromClient('EEDDAADD00'O, sctp);
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD00'O);
+
+  vc_connectedClientConnectionId := -1;
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort + 1, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort + 1, sctp);
+  f_sendDataFromClient('EEDDAADD11'O, sctp);
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD11'O);
+
+  vc_connectedClientConnectionId := -1;
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+  f_sendDataFromClient('EEDDAADD22'O, sctp);
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'EEDDAADD22'O);
+
+  f_StopMyConnections();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_2_TCP_Servers_and_2_TCP_Clients() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  vc_connectedClientConnectionId := -1;
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort + 1, tcp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort + 1, tcp);
+  f_sendDataFromClient('BC579C4D00'O, tcp);
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'BC579C4D00'O);
+
+  vc_connectedClientConnectionId := -1;
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+  f_sendDataFromClient('BC579C4D11'O, tcp);
+  f_CheckDataReceive(vc_connectedClientConnectionId, 'BC579C4D11'O);
+
+  f_StopMyConnections();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_SCTP_AutoReplyDeviceWatchdog() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, sctp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, sctp);
+
+  // 4th byte/bit1: request == 0
+  // 5-7th byte: 280 == hex 118
+  f_sendDataFromClient('00112200000118778899AABBCCDDEEFF'O, sctp);
+
+  // 4th byte/bit1: reply == 1
+  f_CheckDataReceive(vc_clientConnectionId, '00112280000118778899AABBCCDDEEFF'O);
+
+  f_StopServer();
+  f_StopClient();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_TCP_AutoReplyDeviceWatchdog() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Server(tsp_serverInterface, tsp_serverPort, tcp);
+  f_Init_IP_Client(tsp_serverInterface, tsp_serverPort, tcp);
+
+  // 4th byte/bit1: request == 0
+  // 5-7th byte: 280 == hex 118
+  f_sendDataFromClient('EE81F300000118C98B6FF4'O, tcp);
+
+  // 4th byte/bit1: reply == 1
+  f_CheckDataReceive(vc_clientConnectionId, 'EE81F380000118C98B6FF4'O);
+
+  f_StopServer();
+  f_StopClient();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+testcase tc_UDP_CheckStartupCallback() runs on MAIN_CT {
+  map(mtc:daemonPort, system:daemonPort);
+
+  f_Connect_to_IPDD();
+
+  f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort, tsp_serverInterface, tsp_serverPort + 1, udp);
+  var integer vl_firstConnectionId := vc_clientConnectionId;
+  f_Init_IP_Client_with_localInterface(tsp_serverInterface, tsp_serverPort + 1, tsp_serverInterface, tsp_serverPort, udp);
+  f_CheckDataReceive(vl_firstConnectionId, 'BBCCDDEE'O);
+
+  f_StopClient();
+
+  unmap(mtc:daemonPort, system:daemonPort);
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+  //execute(tc_InitClientServer_StopServer_CheckClientConnChange());
+  //execute(tc_InitClientServer_StopServer_StartServer_CheckClientConnChange());
+  //execute(tc_InitClientServer_Disconnect_Connect_InitClientServer_SendDataFromClient_CheckDataReceiveOnServer());
+  //execute(tc_AutoReplyDeviceWatchdog());
+}
+
+}  // end of module
diff --git a/demo/IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn b/demo/IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
new file mode 100644
index 0000000..4ed2061
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:           IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn
+//  Description:    IPDD behaviour with Diameter Auto Replies
+//  Rev:            <RnXnn>
+//  Prodnr:         CNL 113 739
+//  Updated:        2012-02-28
+//  Contact:        http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_with_DiameterAutoReplies
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic all;
+import from IP_Daemon_Dynamic_Types all;
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+
+type record of boolean BooleanList;
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+//type component DIAMETER_IPDD_CT extends IPDD_CT {
+//  var BooleanList vc_userStates := {};
+//}
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_HandleDeviceWatchdog(in integer associationIndex, in ASP_RecvFrom sctpReceived, out ASP_Send sctpReply)
+runs on IPDD_CT
+return boolean {
+  if(lengthof(sctpReceived.msg) > 6) {
+    // Device Watchdog: bytes #4-6 of the Diameter message
+    if(sctpReceived.msg[4] == '00'O and sctpReceived.msg[5] == '01'O and sctpReceived.msg[6] == '18'O) {
+      // bit #1 of the 3rd byte indicates whether the message is reply(1) or request(0)
+      var bitstring thirdByte := oct2bit(sctpReceived.msg[3]);
+      // we only send reply to the incoming request
+      if(thirdByte[0] == '0'B) {
+        thirdByte[0] := '1'B;
+        
+        sctpReply.connId := sctpReceived.connId;
+        sctpReply.proto := sctpReceived.proto;
+        sctpReply.msg := sctpReceived.msg;
+        sctpReply.msg[3] := bit2oct(thirdByte);
+        return true;
+      }
+    }
+  }
+  
+  return false;
+}
+
+function f_SendAutoSetup(in integer associationIndex, in SAC_STATE newState, out ASP_Send sctpMsg)
+runs on IPDD_CT 
+return boolean {
+  if(newState == SCTP_COMM_UP) {
+    if(vc_connectionRuntimeAttributesList[associationIndex].userState == "") {
+      sctpMsg := {
+        vc_connectionRuntimeAttributesList[associationIndex].socket,
+        {sctp:={0,0,omit,omit}},
+        'AABBCCDDEEFF'O
+      }
+      return true;
+    }
+  } else if(vc_connectionRuntimeAttributesList[associationIndex].userState == "INITIALIZED") {
+    // do something different
+  } else {
+    log("ERROR: unhandled user state ", vc_connectionRuntimeAttributesList[associationIndex].userState);
+  }
+  
+  
+  return false;
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_IPDD_with_DiameterAutoReplies() runs on IPDD_CT {
+  
+  // register my Device Watchdog detector & answerer
+  f_RegisterAutoReplyFunction(refers(f_HandleDeviceWatchdog));
+  
+  // register my auto setup sending function
+  f_RegisterAutoStateChangeHandlerFunction(refers(f_SendAutoSetup));
+  
+  // run the IP Daemon's main function
+  f_IPDD();
+  
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+  execute(tc_IPDD_with_DiameterAutoReplies());
+}
+
+}
diff --git a/demo/IP_Daemon_Dynamic_with_StartupCallback.ttcn b/demo/IP_Daemon_Dynamic_with_StartupCallback.ttcn
new file mode 100644
index 0000000..e7153b0
--- /dev/null
+++ b/demo/IP_Daemon_Dynamic_with_StartupCallback.ttcn
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:           IP_Daemon_Dynamic_with_StartupCallback.ttcn
+//  Description:    IPDD behaviour with Startup callback
+//  Rev:            <RnXnn>
+//  Prodnr:         CNL 113 739
+//  Updated:        2012-05-04
+//  Contact:        http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_with_StartupCallback
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic all;
+import from IP_Daemon_Dynamic_Types all;
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function f_SendAutoStartup(in integer connectionIndex, out ASP_Send ipMsg)
+runs on IPDD_CT 
+return boolean {
+  log("connectionIndex: ", connectionIndex);
+  ipMsg := {
+    vc_connectionRuntimeAttributesList[connectionIndex].socket,
+    { udp:={} },
+    'BBCCDDEE'O
+  }
+
+  return true;
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_IPDD_with_StartupCallback() runs on IPDD_CT {
+
+  // register my auto startup function
+  f_RegisterAutoStartupFunction(refers(f_SendAutoStartup));
+
+  // run the IP Daemon's main function
+  f_IPDD();
+
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+  execute(tc_IPDD_with_StartupCallback());
+}
+
+}
+
diff --git a/src/IP_Daemon_Dynamic.ttcn b/src/IP_Daemon_Dynamic.ttcn
new file mode 100644
index 0000000..a0becd6
--- /dev/null
+++ b/src/IP_Daemon_Dynamic.ttcn
@@ -0,0 +1,1053 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:           IP_Daemon_Dynamic.ttcn
+//  Description:    IPDD behaviour
+//  Rev:            <RnXnn>
+//  Prodnr:         CNL 113 630
+//  Updated:        2012-05-07
+//  Contact:        http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic_Types all;
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from TCCInterface_Functions all;
+import from TCCConversion_Functions all;
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+import from IP_Daemon_Dynamic_IPL4_CtrlFunct all;
+
+//=========================================================================
+// Module Parameters
+//=========================================================================
+
+modulepar {
+
+  // Host name where the IP Daemon listens for the testcases
+  charstring tsp_IPDD_TCP_ListenInterface := "127.0.0.1";
+
+  // Port number where the IP Daemon listens for the testcases
+  integer tsp_IPDD_TCP_ListenPort := 1314;
+
+  // Default set of IP connections which the IP Daemon initializes on startup
+  // for connections with autoReconnect == true and server connections
+  IPDD_ConnectionConfigList tsp_IPDD_ConnectionList := {};
+
+  float tsp_IPDD_ReconnectTimer := 2.0;
+
+  // inactivity timer -> client connections get closed
+  float tsp_IPDD_InactivityTimer := 60.0;
+
+  boolean tsp_debug := false;
+}
+
+//=========================================================================
+// Altsteps
+//=========================================================================
+
+altstep as_Handle_IP_Events() runs on IPDD_CT {
+  [] IP_PCO.receive(ASP_RecvFrom : ?) -> value vc_asp_IP_ReceivedMessage {
+    debuglog("INFO: ASP_IP");
+
+    f_RestartInactivityTimer();
+
+    var boolean vl_autoReplied := false;
+    var ASP_Send vl_ipReply;
+    var integer index := 0;
+
+    for(index := 0; index < sizeof(vc_connectionRuntimeAttributesList); index := index + 1) {
+      if(vc_connectionRuntimeAttributesList[index].socket == vc_asp_IP_ReceivedMessage.connId) {
+        break;
+      }
+    }
+
+    for(var integer i := 0; not vl_autoReplied and (i < sizeof(vc_registeredAutoReplyFunctionList)); i := i + 1) {
+      vl_autoReplied := vc_registeredAutoReplyFunctionList[i].apply(index, vc_asp_IP_ReceivedMessage, vl_ipReply);
+      if(vl_autoReplied and vl_ipReply.connId > 0)
+      {
+        if(ischosen(vc_asp_IP_ReceivedMessage.proto.udp))
+        {
+          var ASP_SendTo vl_udpReply :=
+          {
+            connId  := vl_ipReply.connId,
+            remName := vc_asp_IP_ReceivedMessage.remName,
+            remPort := vc_asp_IP_ReceivedMessage.remPort,
+            proto   := vl_ipReply.proto,
+            msg     := vl_ipReply.msg
+          };
+          IP_PCO.send(vl_udpReply);
+        }
+        else
+        {
+          IP_PCO.send(vl_ipReply);
+        }
+      }
+    }
+
+    if(not vl_autoReplied) {
+      for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+        if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_ReceivedMessage.connId) {
+          if(ischosen(vc_asp_IP_ReceivedMessage.proto.sctp)) {
+            if(v_Connection_Lookup != null) {
+              v_TCP_connections_List:=v_Connection_Lookup.apply(vc_asp_IP_ReceivedMessage.msg);
+              for(var integer k := 0; k < sizeof(v_TCP_connections_List); k := k + 1) {
+                daemonPort.send(IPDD_Message_with_ClientId : {
+                    v_TCP_connections_List[k],
+                    {
+                      ipdd_data := {
+                        messageType := 0, // encoder will replace
+                        connectionId := vc_connectionList[i].connectionId,
+                        sctpAttributesPresent := true,
+                        sctpAttributes := {
+                          sinfo_stream := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_stream,
+                          sinfo_ppid := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_ppid
+                        },
+                        dataLength := 0, // encoder will replace
+                        data := vc_asp_IP_ReceivedMessage.msg
+                      }
+                    }
+                  });
+              }
+            }
+            else {
+              for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+                daemonPort.send(IPDD_Message_with_ClientId : {
+                    vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+                    {
+                      ipdd_data := {
+                        messageType := 0, // encoder will replace
+                        connectionId := vc_connectionList[i].connectionId,
+                        sctpAttributesPresent := true,
+                        sctpAttributes := {
+                          sinfo_stream := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_stream,
+                          sinfo_ppid := vc_asp_IP_ReceivedMessage.proto.sctp.sinfo_ppid
+                        },
+                        dataLength := 0, // encoder will replace
+                        data := vc_asp_IP_ReceivedMessage.msg
+                      }
+                    }
+                  });
+              }
+            }
+          }
+
+          if(ischosen(vc_asp_IP_ReceivedMessage.proto.tcp) or ischosen(vc_asp_IP_ReceivedMessage.proto.udp)) {
+            if(v_Connection_Lookup != null) {
+              v_TCP_connections_List:=v_Connection_Lookup.apply(vc_asp_IP_ReceivedMessage.msg);
+              for(var integer k := 0; k < sizeof(v_TCP_connections_List); k := k + 1) {
+                daemonPort.send(IPDD_Message_with_ClientId : {
+                    v_TCP_connections_List[k],
+                    {
+                      ipdd_data := {
+                        messageType := 0, // encoder will replace
+                        connectionId := vc_connectionList[i].connectionId,
+                        sctpAttributesPresent := false,
+                        sctpAttributes := omit,
+                        dataLength := 0, // encoder will replace
+                        data := vc_asp_IP_ReceivedMessage.msg
+                      }
+                    }
+                  });
+              }
+            }
+            else {
+              for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+                daemonPort.send(IPDD_Message_with_ClientId : {
+                    vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+                    {
+                      ipdd_data := {
+                        messageType := 0, // encoder will replace
+                        connectionId := vc_connectionList[i].connectionId,
+                        sctpAttributesPresent := false,
+                        sctpAttributes := omit,
+                        dataLength := 0, // encoder will replace
+                        data := vc_asp_IP_ReceivedMessage.msg
+                      }
+                    }
+                  });
+              }
+            }
+          }
+          if(ischosen(vc_asp_IP_ReceivedMessage.proto.udp))
+          {
+            vc_connectionList[i].remoteInterface := 
+            {
+              hostNameLength  := 0,
+              hostName        := vc_asp_IP_ReceivedMessage.remName,
+              portNumber      := vc_asp_IP_ReceivedMessage.remPort
+            }
+          }
+        }
+      }
+    }
+
+    repeat;
+  }
+
+  [] IP_PCO.receive(ASP_Event : { result := ? } ) -> value vc_asp_IP_Event {
+    debuglog("INFO: ASSOC_CHANGE vc_connectionRuntimeAttributesList: " & log2str(vc_connectionRuntimeAttributesList));
+    f_RestartInactivityTimer();
+
+    for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+
+      if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.result.connId) {
+        //debuglog(log2str(vc_connectionList[i]) & " subscribedTestcases: " & log2str(vc_connectionRuntimeAttributesList[i].subscribedTestcases));
+
+        for(var integer j := 0; j < sizeof( vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+          daemonPort.send(IPDD_Message_with_ClientId : {
+              vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+              {
+                ipdd_connectionChanged := {
+                  messageType := 0,
+                  connectionId := vc_connectionList[i].connectionId,
+                  eventPresent := true,
+                  event := {
+                    errorCodePresent := true,
+                    errorCode := vc_asp_IP_Event.result.errorCode,
+                    os_error_codePresent := true,
+                    os_error_code := vc_asp_IP_Event.result.os_error_code,
+                    os_error_textLength := 0,
+                    os_error_text := vc_asp_IP_Event.result.os_error_text
+                  },
+                  sctpStatePresent := false,
+                  sctpState := omit
+                }
+              }
+            });
+        }
+      }
+    }
+    repeat;
+  }
+
+  [] IP_PCO.receive(tr_sctpEvent(?, ?)) -> value vc_asp_IP_Event {
+    debuglog("INFO: ASSOC_CHANGE vc_connectionRuntimeAttributesList: " & log2str(vc_connectionRuntimeAttributesList));
+    f_RestartInactivityTimer();
+
+    var boolean vl_autoHandled := false;
+    var ASP_Send vl_ipMsg;
+
+    for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+
+      if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.sctpEvent.sctpAssocChange.clientId) {
+        //debuglog(log2str(vc_connectionList[i]) & " subscribedTestcases: " & log2str(vc_connectionRuntimeAttributesList[i].subscribedTestcases));
+
+        vl_autoHandled := false;
+
+        for(var integer j := 0; not vl_autoHandled and (j < sizeof(vc_registeredAutoStateChangeHandlerFunctionList)); j := j + 1) {
+          vl_autoHandled := vc_registeredAutoStateChangeHandlerFunctionList[j].apply(i, vc_asp_IP_Event.sctpEvent.sctpAssocChange.sac_state, vl_ipMsg);
+          if(vl_autoHandled) {
+            IP_PCO.send(vl_ipMsg);
+          }
+        }
+
+        if(not vl_autoHandled) {
+
+          for(var integer j := 0; j < sizeof( vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+            daemonPort.send(IPDD_Message_with_ClientId : {
+                vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+                {
+                  ipdd_connectionChanged := {
+                    messageType := 0,
+                    connectionId := vc_connectionList[i].connectionId,
+                    eventPresent := false,
+                    event := omit,
+                    sctpStatePresent := true,
+                    sctpState := vc_asp_IP_Event.sctpEvent.sctpAssocChange.sac_state
+                  }
+                }
+              });
+          }
+        }
+        vc_connectionRuntimeAttributesList[i].sctpState := vc_asp_IP_Event.sctpEvent.sctpAssocChange.sac_state;
+        if(vc_connectionRuntimeAttributesList[i].sctpState == SCTP_COMM_LOST) {
+          if(vc_connectionList[i].serverConnection) {
+            vc_connectionRuntimeAttributesList[i].socket := -1;
+            // initiate reconnect
+            f_ScheduleReconnect();
+          }
+          else{
+            f_removeConnection(vc_connectionList[i].connectionId);
+          }          
+        }
+      }
+    }
+    repeat;
+  }
+
+  [] IP_PCO.receive(tr_S_SCTP_ShutdownEvent) -> value vc_asp_IP_Event {
+    debuglog("INFO: SHUTDOWN");
+    for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+      if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.sctpEvent.sctpShutDownEvent.clientId) {
+        vc_connectionRuntimeAttributesList[i].sctpState := SCTP_COMM_LOST;
+
+        for(var integer j := 0; j < sizeof( vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+          daemonPort.send(IPDD_Message_with_ClientId : {
+              vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+              {
+                ipdd_connectionChanged := {
+                  messageType := 0,
+                  connectionId := vc_connectionList[i].connectionId,
+                  eventPresent := false,
+                  event := omit,
+                  sctpStatePresent := true,
+                  sctpState := vc_connectionRuntimeAttributesList[i].sctpState
+                }
+              }
+            });
+        }
+        f_ScheduleReconnect();
+      }
+    }
+    f_RestartInactivityTimer();
+    repeat;
+  }
+
+  [] IP_PCO.receive(tr_ASP_IP_Connected) -> value vc_asp_IP_Event {
+    if(tsp_debug) {
+      log("@before ASP_IP_Connected vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+    }
+
+    f_RestartInactivityTimer();
+
+    for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+      if(ispresent(vc_connectionList[i].localInterface)) {
+        if(vc_connectionList[i].serverConnection and
+          vc_asp_IP_Event.connOpened.locName == vc_connectionList[i].localInterface.hostName and
+          vc_asp_IP_Event.connOpened.locPort == vc_connectionList[i].localInterface.portNumber and
+          f_IPDD_ProtoMatches(vc_asp_IP_Event.connOpened.proto, vc_connectionList[i].proto)) {
+
+          // book the new connection into the database 
+          var integer newIndex := sizeof(vc_connectionList);
+
+          vc_connectionList[newIndex] := c_emptyConnection;
+          vc_connectionRuntimeAttributesList[newIndex] := c_emptyConnectionRuntimeAttribute;
+          vc_connectionRuntimeAttributesList[newIndex].socket := vc_asp_IP_Event.connOpened.connId;
+          vc_connectionRuntimeAttributesList[newIndex].endpointIndex := i;
+
+          vc_connectionList[newIndex].connectionId := f_getNextUniqueConnectionId();
+
+          vc_connectionList[newIndex].localInterface.hostNameLength := 0;
+          vc_connectionList[newIndex].localInterface.hostName := vc_asp_IP_Event.connOpened.locName;
+          vc_connectionList[newIndex].localInterface.portNumber := vc_asp_IP_Event.connOpened.locPort;
+
+          vc_connectionList[newIndex].remoteInterface.hostNameLength := 0;
+          vc_connectionList[newIndex].remoteInterface.hostName := vc_asp_IP_Event.connOpened.remName;
+          vc_connectionList[newIndex].remoteInterface.portNumber := vc_asp_IP_Event.connOpened.remPort;
+
+          vc_connectionList[newIndex].autoReconnect := false;
+          vc_connectionList[newIndex].proto := vc_connectionList[i].proto;
+
+          // send notification to all subscribed testcases of the server
+          for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+            daemonPort.send(IPDD_Message_with_ClientId : {
+                vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+                {
+                  ipdd_connected := {
+                    messageType := 0,  // encoder will replace
+                    serverId := vc_connectionList[i].connectionId,
+                    connectionId := vc_connectionList[newIndex].connectionId,
+                    remoteInterface := {
+                      hostNameLength := 0, // encoder will replace
+                      hostName := vc_asp_IP_Event.connOpened.locName,
+                      portNumber := vc_asp_IP_Event.connOpened.locPort
+                    }
+                  }
+                }
+              } );
+          }
+          // subscribe the connected connection to the server's subscribed testcases
+          vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases := vc_connectionRuntimeAttributesList[i].subscribedTestcases;
+        }
+      }
+    }
+    if(tsp_debug) {
+      log("@after ASP_IP_Connected vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+    }
+    repeat;
+  }
+
+
+  [] IP_PCO.receive(tr_S_SCTP_PeerAddressChange) {
+    debuglog("INFO: ASP_IP_PEER_ADDR_CHANGE");
+    f_RestartInactivityTimer();
+    repeat;
+  }
+
+  [] IP_PCO.receive(tr_ASP_IP_Closed) -> value vc_asp_IP_Event {
+    debuglog("INFO: ASP_IP_Closed");
+
+    for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+
+      if(vc_connectionRuntimeAttributesList[i].socket == vc_asp_IP_Event.connClosed.connId) {
+
+        for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+          daemonPort.send(IPDD_Message_with_ClientId : {
+              vc_connectionRuntimeAttributesList[i].subscribedTestcases[j],
+              {
+                ipdd_closed := {
+                  messageType := 0,  // encoder will replace
+                  connectionId := vc_connectionList[i].connectionId
+                }
+              }
+            });
+        }
+        vc_connectionRuntimeAttributesList[i].socket := -1;
+
+      }
+    }
+
+    f_RestartInactivityTimer();
+
+    repeat;
+  }
+
+  [] IP_PCO.receive(tr_ASP_Result) -> value vc_ipResult {
+    debuglog("INFO: ASP_IP_RESULT");
+    f_RestartInactivityTimer();
+    repeat;
+  }
+
+  [] IP_PCO.receive {
+    log("*** WARNING: unhandled IP message received!");
+    f_RestartInactivityTimer();
+    repeat;
+  }
+}
+
+altstep as_Handle_TCP_Events() runs on IPDD_CT {
+  [] daemonPort.receive(tr_ASP_TCP_Connected)  -> value vc_asp_TCP_Event {
+    debuglog("INFO: ASP_TCP_Connected");
+    var f_IPL4_getMsgLen sdd_msglen := refers(f_IPDD_getMsgLen);
+    IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_setGetMsgLen(daemonPort,vc_asp_TCP_Event.connOpened.connId,sdd_msglen,{});
+    repeat;
+  }
+
+  [] daemonPort.receive(tr_ASP_TCP_Close) -> value vc_tcpClose {
+    debuglog("INFO: ASP_TCP_Close");
+    var IntegerList vl_newSubsribedTestcases := {};
+
+    if (v_Connection_Delete!=null)
+    {
+      v_Connection_Delete.apply(vc_tcpClose.connClosed.connId)
+    }
+    else{
+      // remove subscrition belonging to this client from the vc_connectionRuntimeAttributesList.subscribedTestcases
+      for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+        vl_newSubsribedTestcases := {};
+        for(var integer j := 0; j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases); j := j + 1) {
+          if(vc_connectionRuntimeAttributesList[i].subscribedTestcases[j] != vc_tcpClose.connClosed.connId) {
+            vl_newSubsribedTestcases[sizeof(vl_newSubsribedTestcases)] := vc_connectionRuntimeAttributesList[i].subscribedTestcases[j];
+          }
+        }
+        if(sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases) != sizeof(vl_newSubsribedTestcases)) {
+          vc_connectionRuntimeAttributesList[i].subscribedTestcases := vl_newSubsribedTestcases;
+        }
+      }
+    }
+    repeat;
+  }
+
+  [] daemonPort.receive(t_close) -> value vc_daemonMessage {
+    debuglog("INFO: t_close");
+    for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+      if(vc_connectionList[i].connectionId == vc_daemonMessage.msg.ipdd_close.connectionId) {
+        if(vc_connectionRuntimeAttributesList[i].socket >= 0) {
+
+          var Result vl_result := IPL4asp_PortType.f_IPL4_close(IP_PCO, vc_connectionRuntimeAttributesList[i].socket, f_IPDD_getIPL4_Proto(i));
+          log("*** INFO: result of closing socket: ", vl_result);
+
+          daemonPort.send(IPDD_Message_with_ClientId : {
+              vc_daemonMessage.client_id,
+              { ipdd_result := {
+                  messageType := 0, // encoder will replace
+                  connectionId := vc_connectionList[i].connectionId,
+                  errorStatus := not(vl_result.errorCode==omit),
+                  errorMessage := vl_result.os_error_text
+                }}
+            } );
+
+        } else {
+          log("*** ERROR: connection ", vc_daemonMessage.msg.ipdd_close.connectionId, " is not alive, not sending ASP_IP_Close!");
+        }
+      }
+    }
+    f_removeConnection(vc_daemonMessage.msg.ipdd_close.connectionId);
+    debuglog("INFO: ASP_IP_Close sent, returning to the main alt");
+    repeat;
+  }
+
+  [] daemonPort.receive(t_queryConnections) -> value vc_daemonMessage {
+    daemonPort.send(IPDD_Message_with_ClientId : { vc_daemonMessage.client_id, { ipdd_connections := {
+            0, // encoder will replace
+            vc_connectionList
+          } } });
+    repeat;
+  }
+
+  [] daemonPort.receive(t_connect) -> value vc_daemonMessage {
+    if(tsp_debug) {
+      log("@before ipdd_connect vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+    }
+    var integer newIndex := sizeof(vc_connectionList);
+
+    vc_connectionList[newIndex] := c_emptyConnection;
+    vc_connectionRuntimeAttributesList[newIndex] := c_emptyConnectionRuntimeAttribute;
+    vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases
+    [sizeof(vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases)] := vc_daemonMessage.client_id;
+
+    if(ispresent(vc_daemonMessage.msg.ipdd_connect.localInterface)) {
+      vc_connectionList[newIndex].localInterface := vc_daemonMessage.msg.ipdd_connect.localInterface;
+    } 
+
+    vc_connectionList[newIndex].remoteInterface := vc_daemonMessage.msg.ipdd_connect.remoteInterface;
+
+    vc_connectionList[newIndex].autoReconnect := vc_daemonMessage.msg.ipdd_connect.autoReconnect;
+
+    vc_connectionList[newIndex].proto := vc_daemonMessage.msg.ipdd_connect.proto;
+
+    f_Reconnect_IP_Connection(newIndex);
+    f_RunAutoStartupFunctions(newIndex);
+
+    if(tsp_debug) {
+      log("@after defineClientConnection vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+    }
+    repeat;
+  }
+
+  [] daemonPort.receive(t_listen) -> value vc_daemonMessage {
+    if(tsp_debug) {
+      log("@before sctpListen vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+    }
+    var integer newIndex := sizeof(vc_connectionList);
+
+    vc_connectionList[newIndex] := c_emptyConnection;
+    vc_connectionRuntimeAttributesList[newIndex] := c_emptyConnectionRuntimeAttribute;
+    vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases
+    [sizeof(vc_connectionRuntimeAttributesList[newIndex].subscribedTestcases)] := vc_daemonMessage.client_id;
+
+    vc_connectionList[newIndex].serverConnection := true;
+
+    vc_connectionList[newIndex].localInterface := {
+      hostNameLength := 0,
+      hostName := f_getIpAddr(vc_daemonMessage.msg.ipdd_listen.localInterface.hostName,f_addressType(vc_daemonMessage.msg.ipdd_listen.localInterface.hostName)),
+      portNumber := vc_daemonMessage.msg.ipdd_listen.localInterface.portNumber
+    };
+
+    vc_connectionList[newIndex].proto := vc_daemonMessage.msg.ipdd_listen.proto;
+
+    f_Init_Server_IP_Connection(newIndex);
+    f_RunAutoStartupFunctions(newIndex);
+
+    if(tsp_debug) {
+      log("@after defineServerConnection vc_connectionList: ", vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+    }
+    repeat;
+  }
+
+  [] daemonPort.receive(t_subscribeToConnection) -> value vc_daemonMessage {
+    debuglog("INFO: t_subscribeToConnection");
+    var boolean vl_subscribed := false, vl_found := false;
+    for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+      if(vc_connectionList[i].connectionId == vc_daemonMessage.msg.ipdd_subscribeToConnection.connectionId) {
+        vl_found := false;
+        for(var integer j := 0; not vl_found and (j < sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases)); j := j + 1) {
+          if(vc_connectionRuntimeAttributesList[i].subscribedTestcases[j] == vc_daemonMessage.client_id) {
+            vl_found := true
+          }
+        }
+        if(not vl_found) {
+          vc_connectionRuntimeAttributesList[i].subscribedTestcases[sizeof(vc_connectionRuntimeAttributesList[i].subscribedTestcases)] := vc_daemonMessage.client_id;
+          vl_subscribed := true;
+        } else {
+          log("*** WARNING: test case ", vc_daemonMessage.client_id, " is already subscribed to: ", vc_connectionList[i]);
+        }
+      }
+    }
+
+    if(not vl_subscribed) {
+      log("*** WARNING: test case ", vc_daemonMessage.client_id, " was not subscribed to any connection!");
+    }
+
+    repeat;
+  }
+
+  [] daemonPort.receive(t_ipData) -> value vc_daemonMessage {
+    debuglog("INFO: t_sctpData");
+    for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+      if(vc_connectionList[i].connectionId == vc_daemonMessage.msg.ipdd_data.connectionId) {
+        if (v_Connection_Insert!=null) {v_Connection_Insert.apply(vc_daemonMessage.msg.ipdd_data.data,vc_daemonMessage.client_id)}
+
+        if(vc_connectionList[i].proto != udp)
+        {
+          var ASP_Send vl_send := {
+            connId := vc_connectionRuntimeAttributesList[i].socket,
+            proto := { tcp := {} },
+            msg := vc_daemonMessage.msg.ipdd_data.data
+          }
+
+          vl_send.proto := f_IPDD_getIPL4_Proto(i);
+
+          if (vc_connectionList[i].proto == sctp and vc_daemonMessage.msg.ipdd_data.sctpAttributesPresent) {
+            vl_send.proto.sctp.sinfo_stream := vc_daemonMessage.msg.ipdd_data.sctpAttributes.sinfo_stream;
+            vl_send.proto.sctp.sinfo_ppid := vc_daemonMessage.msg.ipdd_data.sctpAttributes.sinfo_ppid;
+          }
+          IP_PCO.send(vl_send);
+        }
+        else
+        {
+          var ASP_SendTo vl_send := {
+            connId := vc_connectionRuntimeAttributesList[i].socket,
+            remName := vc_connectionList[i].remoteInterface.hostName,
+            remPort := vc_connectionList[i].remoteInterface.portNumber,
+            proto := { udp := { } },
+            msg := vc_daemonMessage.msg.ipdd_data.data
+          }
+
+          IP_PCO.send(vl_send);
+        }
+      }
+    }
+    repeat;
+  }
+
+  [] daemonPort.receive(PortEvent : { result := ? }) -> value vc_asp_TCP_Event {
+    log("*** INFO: ignoring result.");
+    repeat;
+  }
+
+}
+
+altstep as_Handle_Reconnect() runs on IPDD_CT {
+  [] vc_reconnectTimer.timeout {
+    if(tsp_debug) {
+      log("On vc_reconnectTimer.timeout vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList, " vc_connectionList: ", vc_connectionList);
+    }
+    for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList); i := i + 1) {
+      if(vc_connectionRuntimeAttributesList[i].socket < 0 and vc_connectionList[i].autoReconnect) {
+        f_Reconnect_IP_Connection(i);
+        f_RunAutoStartupFunctions(i);
+      }
+    }
+    repeat;
+  }
+}
+
+altstep as_Handle_Inactivity() runs on IPDD_CT {
+  [] vc_inactivityTimer.timeout {
+    if(tsp_debug) {
+      log("On vc_inactivityTimer.timeout vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList, " vc_connectionList: ", vc_connectionList);
+    }
+
+    log("*** IPDD QUIT due to ", tsp_IPDD_InactivityTimer, " seconds of inactivity.");
+    log("*** Please restart IPDD if you need it again.");
+  }
+}
+
+//=========================================================================
+// Functions
+//=========================================================================
+
+function debuglog(in charstring str) {
+  if(tsp_debug) {
+    log(str);
+  }
+}
+
+function f_IPDD_ProtoMatches(in ProtoTuple pl_protoTuple, in ProtoTupleEnum pl_protoTupleEnum) return boolean {
+  select (pl_protoTupleEnum) {
+    case (udp) {
+      if(ischosen(pl_protoTuple.udp)) {
+        return true;
+      }
+    }
+    case (tcp) {
+      if(ischosen(pl_protoTuple.tcp)) {
+        return true;
+      }
+    }
+    case (sctp) {
+      if(ischosen(pl_protoTuple.sctp)) {
+        return true;
+      }
+    }
+    case (ssl) {
+      if(ischosen(pl_protoTuple.ssl)) {
+        return true;
+      }
+    }
+    case (unspecified) {
+      if(ischosen(pl_protoTuple.unspecified)) {
+        return true;
+      }
+    }
+    case else {
+      log("*** WARNING: unhandled protoTuple type!");
+    }
+  }
+
+  return false;
+}
+
+function f_IPDD_getIPL4_Proto(in integer pl_idx) runs on IPDD_CT return ProtoTuple {
+  var ProtoTuple vl_ret := { sctp := { omit, omit, omit, omit} };
+
+  select (vc_connectionList[pl_idx].proto) {
+    case (sctp) {
+      vl_ret := { sctp := { omit, omit, omit, omit} }
+    }
+    case (tcp) {
+      vl_ret := { tcp := { } };
+    }
+    case (udp) {
+      vl_ret := { udp := { } };
+    }
+    case (ssl) {
+      vl_ret := { ssl := { } };
+    }
+    case (unspecified) {
+      vl_ret := { unspecified := { } };
+    }
+    case else {
+      log("*** WARNING: unhandled protoTuple type!!!");
+    }
+  }
+
+  return vl_ret;
+}
+
+function f_addressType(charstring ip_address) return TCCInterface_IPAddressType {
+  var integer v_index := f_strstr(ip_address, ":");
+
+  if(v_index == -1) {
+    return IPv4;
+  }
+
+  return IPv6;
+}
+
+function f_getNextUniqueConnectionId() runs on IPDD_CT return integer {
+  var integer newId := 0;
+  var boolean found := false;
+  var boolean exit := false;
+
+  while(not exit) {
+    found := false;
+
+    for(var integer i := 0; i < sizeof(vc_connectionList) and (not found); i := i + 1) {
+      if(vc_connectionList[i].connectionId == newId) {
+        found := true;
+      }
+    }
+
+    if(not found) {
+      exit := true;
+    } else {
+      newId := newId + 1;
+    }
+  }
+
+  debuglog("returning new connection id: " & int2str(newId));
+  return newId;
+}
+
+function f_InitTCPServer() runs on IPDD_CT {
+  var Result vl_result := { errorCode := omit, connId  := omit, os_error_code:=omit, os_error_text:= omit };
+  vl_result := IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_listen(daemonPort, tsp_IPDD_TCP_ListenInterface, tsp_IPDD_TCP_ListenPort, {tcp := {}});
+
+  if ((vl_result.errorCode == omit) or (vl_result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE)) {
+    log("*** INFO: listening on port (TCP): ", tsp_IPDD_TCP_ListenPort, "; result: ", vl_result);
+    var f_IPL4_getMsgLen ipdd_msglen := refers(f_IPDD_getMsgLen);
+    IP_Daemon_Dynamic_IPL4_CtrlFunct.f_IPL4_setGetMsgLen(daemonPort,vl_result.connId,ipdd_msglen,{});
+  } else {
+    log("*** ERROR: error during initialization of the TCP port: ",vl_result);
+    setverdict(fail);
+    stop;
+  }
+}
+
+function f_Init_Server_IP_Connection(in integer conn_idx) runs on IPDD_CT {
+  if(vc_connectionList[conn_idx].serverConnection) {
+    if(ispresent(vc_connectionList[conn_idx].localInterface)) {
+      if(vc_connectionRuntimeAttributesList[conn_idx].socket < 0) {
+        log("init server: #", conn_idx);
+        vc_connectionRuntimeAttributesList[conn_idx].endpointIndex := f_GetEndpointIndex(vc_connectionList[conn_idx].localInterface);
+        var Result vl_result := { errorCode := omit, connId  := omit, os_error_code := omit, os_error_text := omit };
+
+        vl_result := IPL4asp_PortType.f_IPL4_listen(
+          IP_PCO,
+          vc_connectionList[conn_idx].localInterface.hostName,
+          vc_connectionList[conn_idx].localInterface.portNumber,
+          f_IPDD_getIPL4_Proto(conn_idx)
+        );
+
+        if(vc_connectionList[conn_idx].connectionId < 0) {
+          vc_connectionList[conn_idx].connectionId := f_getNextUniqueConnectionId();
+        }
+
+        vc_connectionRuntimeAttributesList[conn_idx].socket := vl_result.connId;
+        for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases); i := i + 1) {
+          daemonPort.send(IPDD_Message_with_ClientId : {
+              vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases[i],
+              { ipdd_result := {
+                  messageType := 0, // encoder will replace
+                  connectionId := vc_connectionList[conn_idx].connectionId,
+                  errorStatus := not(vl_result.errorCode==omit),
+                  errorMessage := vl_result.os_error_text
+                }}
+            } );
+        }
+      } else {
+        log("*** WARNING: IP server connection ", vc_connectionList[conn_idx].localInterface, " is already listening!");
+      }
+    } else {
+      log("*** ERROR: IP server connection #", conn_idx, " is declared as server, but has no localInterface defined!");
+    }
+  } else {
+    if(tsp_debug) {
+      log("*** INFO: IP connection ", vc_connectionList[conn_idx], " is not server.");
+    }
+  }
+}
+
+function f_Reconnect_IP_Connection(in integer conn_idx) runs on IPDD_CT {
+  if(vc_connectionRuntimeAttributesList[conn_idx].socket < 0) {
+    if(ispresent(vc_connectionList[conn_idx].remoteInterface)) {
+
+      if(ispresent(vc_connectionList[conn_idx].localInterface)) {
+        if(not vc_connectionList[conn_idx].serverConnection) {
+
+          vc_connectionRuntimeAttributesList[conn_idx].endpointIndex := f_GetEndpointIndex(vc_connectionList[conn_idx].localInterface);
+
+          var Result vl_result := { errorCode := omit, connId  := omit, os_error_code:=omit, os_error_text:= omit };
+
+          vl_result := IPL4asp_PortType.f_IPL4_connect
+          (
+            IP_PCO, 
+            vc_connectionList[conn_idx].remoteInterface.hostName,
+            vc_connectionList[conn_idx].remoteInterface.portNumber,
+            vc_connectionList[conn_idx].localInterface.hostName,
+            vc_connectionList[conn_idx].localInterface.portNumber,
+            connId := -1,
+            proto := f_IPDD_getIPL4_Proto(conn_idx),
+            options := {}
+          );
+
+          if ((vl_result.errorCode == omit) or (vl_result.errorCode == IPL4_ERROR_TEMPORARILY_UNAVAILABLE)) //if not error
+          {
+            vc_connectionRuntimeAttributesList[conn_idx].socket := vl_result.connId;
+            log("**** INFO: New client socket: ", vc_connectionRuntimeAttributesList[conn_idx].socket);
+            if(vc_connectionList[conn_idx].connectionId < 0) {
+              vc_connectionList[conn_idx].connectionId := f_getNextUniqueConnectionId();
+            }
+          }
+          else
+          {
+            f_ScheduleReconnect();
+          }
+
+          for(var integer i := 0; i < sizeof(vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases); i := i + 1) {
+            daemonPort.send(IPDD_Message_with_ClientId : {
+                vc_connectionRuntimeAttributesList[conn_idx].subscribedTestcases[i],
+                { ipdd_result := {
+                    messageType := 0, // encoder will replace
+                    connectionId := vc_connectionList[conn_idx].connectionId,
+                    errorStatus := not(vl_result.errorCode==omit),
+                    errorMessage := vl_result.os_error_text
+                  }}
+              } );
+          }
+
+        } else {
+          if(vc_connectionList[conn_idx].serverConnection) {
+            log("*** WARNING: connection ", vc_connectionList[conn_idx].localInterface,
+              " is declared as server connection, but also initiates client connection to ",
+              vc_connectionList[conn_idx].remoteInterface, ".");}
+        }
+      } 
+      else {
+        log("*** WARNING: connection ", vc_connectionList[conn_idx].remoteInterface, " localInterface is missing.");
+      }
+
+      if(tsp_debug) {
+        log("@after ASP_IP_RESULT vc_connectionList: ",vc_connectionList, ", vc_connectionRuntimeAttributesList: ", vc_connectionRuntimeAttributesList);
+      }
+
+    } else {
+      if(vc_connectionList[conn_idx].serverConnection) {
+        if(tsp_debug) {
+          log("*** INFO: IP connection ", vc_connectionList[conn_idx].localInterface, " is server only.");
+        }
+      } else {
+        log("*** ERROR: IP connection ", vc_connectionList[conn_idx].localInterface, " is not a server connection!");
+      }
+    }
+  } else if(ispresent(vc_connectionList[conn_idx].remoteInterface)) {
+    log("*** WARNING: IP connection to " & log2str(vc_connectionList[conn_idx].remoteInterface) & " is already active!");
+  }
+}
+
+function f_removeConnection(in integer pl_connectionId) runs on IPDD_CT {
+  var IPDD_ConnectionList newConnectionList := {};
+  var ConnectionRuntimeAttributesList newConnectionRuntimeAttributesList := {};
+
+  for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+    if(vc_connectionList[i].connectionId != pl_connectionId) {
+      newConnectionList[sizeof(newConnectionList)] := vc_connectionList[i];
+      newConnectionRuntimeAttributesList[sizeof(newConnectionRuntimeAttributesList)] := vc_connectionRuntimeAttributesList[i];
+    }
+  }
+
+  if(sizeof(newConnectionList) != sizeof(vc_connectionList)) {
+    vc_connectionList := newConnectionList;
+    vc_connectionRuntimeAttributesList := newConnectionRuntimeAttributesList;
+  } else {
+    log("*** WARNING: IP connection to delete: ", pl_connectionId, " was not found in the database.");
+  }
+}
+
+function f_GetEndpointIndex(in IPDD_Interface pl_interface) runs on IPDD_CT return integer {
+
+  for(var integer vl_i := 0; vl_i < sizeof(v_localEndpointList); vl_i := vl_i + 1) {
+    if((v_localEndpointList[vl_i].hostName == pl_interface.hostName) and (v_localEndpointList[vl_i].portNumber == pl_interface.portNumber)) {
+      return vl_i;
+    }
+  }
+
+  v_localEndpointList[sizeof(v_localEndpointList)] := pl_interface;
+
+  return sizeof(v_localEndpointList) - 1;
+}
+
+function f_RunAutoStartupFunctions(in integer conn_idx) runs on IPDD_CT {
+
+  var boolean vl_send;
+  var ASP_Send vl_ipMsg;
+
+  for(var integer i := 0; i < sizeof(vc_registeredAutoStartupFunctionList); i := i + 1) {
+    vl_send := vc_registeredAutoStartupFunctionList[i].apply(conn_idx, vl_ipMsg);
+    if(vl_send and vl_ipMsg.connId > 0) {
+      if(ischosen(vl_ipMsg.proto.udp)) {
+        var ASP_SendTo vl_udpMsg :=
+        {
+          connId  := vl_ipMsg.connId,
+          remName := vc_connectionList[conn_idx].remoteInterface.hostName,
+          remPort := vc_connectionList[conn_idx].remoteInterface.portNumber,
+          proto   := vl_ipMsg.proto,
+          msg     := vl_ipMsg.msg
+        };
+        IP_PCO.send(vl_udpMsg);
+      }
+      else
+      {
+        IP_PCO.send(vl_ipMsg);
+      }
+    }
+  }
+}
+
+function f_ScheduleReconnect() runs on IPDD_CT {
+  if(not vc_reconnectTimer.running) {
+    vc_reconnectTimer.start(tsp_IPDD_ReconnectTimer);
+  }
+}
+
+function f_RestartInactivityTimer() runs on IPDD_CT {
+  if(tsp_IPDD_InactivityTimer > 0.0) {
+    if(vc_inactivityTimer.running) {
+      vc_inactivityTimer.stop;
+    };
+
+    vc_inactivityTimer.start(tsp_IPDD_InactivityTimer);
+    debuglog("*** INFO: Inactivity timer restarted.");
+  }
+}
+
+function f_RegisterAutoReplyFunction(in f_IPDD_AutoReplyFunction autoReplyFunction) runs on IPDD_CT {
+  vc_registeredAutoReplyFunctionList[sizeof(vc_registeredAutoReplyFunctionList)] := autoReplyFunction;
+}
+
+function f_RegisterAutoStateChangeHandlerFunction(in f_IPDD_AutoStateChangeHandlerFunction autoStateChangeHandlerFunction) runs on IPDD_CT {
+  vc_registeredAutoStateChangeHandlerFunctionList[sizeof(vc_registeredAutoStateChangeHandlerFunctionList)] := autoStateChangeHandlerFunction;
+}
+
+function f_RegisterAutoStartupFunction(in f_IPDD_AutoStartupFunction autoStartupFunction) runs on IPDD_CT {
+  vc_registeredAutoStartupFunctionList[sizeof(vc_registeredAutoStartupFunctionList)] := autoStartupFunction;
+}
+
+function f_IPDD() runs on IPDD_CT {
+  map(mtc:daemonPort, system:daemonPort);
+  map(mtc:IP_PCO, system:IP_PCO);
+
+  f_InitTCPServer();
+
+  for(var integer i := 0; i < sizeof(tsp_IPDD_ConnectionList); i := i + 1) {
+    vc_connectionList[i] := {
+      connectionId := -1,
+      serverConnection:= tsp_IPDD_ConnectionList[i].serverConnection,
+      autoReconnect := tsp_IPDD_ConnectionList[i].autoReconnect,
+      localInterfacePresent := false, // enter always false
+      localInterface := {
+        hostNameLength := 0,
+        hostName := f_getIpAddr(tsp_IPDD_ConnectionList[i].localInterface.hostName, f_addressType(tsp_IPDD_ConnectionList[i].localInterface.hostName)),
+        portNumber := tsp_IPDD_ConnectionList[i].localInterface.portNumber
+      },
+      remoteInterfacePresent := false, // enter always false
+      remoteInterface := tsp_IPDD_ConnectionList[i].remoteInterface,
+      proto := tsp_IPDD_ConnectionList[i].proto,
+      sctpProtoAttributesPresent := false,
+      sctpProtoAttributes := omit
+    };
+    // clientIds: empty, sctpState: SCTP_COMM_LOST
+    vc_connectionRuntimeAttributesList[i] := c_emptyConnectionRuntimeAttribute;
+  }
+
+  log("*** INFO: initial config: ", vc_connectionList);
+
+  for(var integer i := 0; i < sizeof(vc_connectionList); i := i + 1) {
+    f_Init_Server_IP_Connection(i);
+    f_Reconnect_IP_Connection(i);
+    f_RunAutoStartupFunctions(i);
+  }
+
+  alt {
+    [] as_Handle_TCP_Events()
+    [] as_Handle_Reconnect()
+    [] as_Handle_IP_Events()
+    [] as_Handle_Inactivity()
+  }
+
+  unmap(mtc:daemonPort, system:daemonPort);
+  unmap(mtc:IP_PCO, system:IP_PCO);
+}
+
+//=========================================================================
+// Testcases
+//=========================================================================
+
+testcase tc_IPDD() runs on IPDD_CT {
+  f_IPDD();
+}
+
+//=========================================================================
+// Control
+//=========================================================================
+
+control {
+  execute(tc_IPDD());
+}
+
+} //end of module
diff --git a/src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc b/src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc
new file mode 100644
index 0000000..92c1cda
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:               IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 630
+//  Updated:            2010-11-24
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          
+
+
+#include "IPL4asp_PortType.hh"
+#include "IPL4asp_PT.hh"
+#include "IP_Daemon_Dynamic_Interface_Definitions.hh"
+
+namespace IP__Daemon__Dynamic__IPL4__CtrlFunct {
+
+  IPL4asp__Types::Result f__IPL4__listen(
+    IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+    const IPL4asp__Types::HostName& locName,
+    const IPL4asp__Types::PortNumber& locPort,
+    const IPL4asp__Types::ProtoTuple& proto,
+    const IPL4asp__Types::OptionList& options)
+  {
+    return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options);
+  }
+  
+  IPL4asp__Types::Result f__IPL4__connect(
+    IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+    const IPL4asp__Types::HostName& remName,
+    const IPL4asp__Types::PortNumber& remPort,
+    const IPL4asp__Types::HostName& locName,
+    const IPL4asp__Types::PortNumber& locPort,
+    const IPL4asp__Types::ConnectionId& connId,
+    const IPL4asp__Types::ProtoTuple& proto,
+    const IPL4asp__Types::OptionList& options)
+  {
+    return f__IPL4__PROVIDER__connect(portRef, remName, remPort,
+                                      locName, locPort, connId, proto, options);
+  }
+
+  IPL4asp__Types::Result f__IPL4__close(
+    IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef, 
+    const IPL4asp__Types::ConnectionId& connId, 
+    const IPL4asp__Types::ProtoTuple& proto)
+  {
+      return f__IPL4__PROVIDER__close(portRef, connId, proto);
+  }
+
+  IPL4asp__Types::Result f__IPL4__setUserData(
+    IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+    const IPL4asp__Types::ConnectionId& connId,
+    const IPL4asp__Types::UserData& userData)
+  {
+    return f__IPL4__PROVIDER__setUserData(portRef, connId, userData);
+  }
+  
+  IPL4asp__Types::Result f__IPL4__getUserData(
+    IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+    const IPL4asp__Types::ConnectionId& connId,
+    IPL4asp__Types::UserData& userData)
+  {
+    return f__IPL4__PROVIDER__getUserData(portRef, connId, userData);
+  }
+
+  void f__IPL4__setGetMsgLen(
+    IP__Daemon__Dynamic__Interface__Definitions::IPDD__Interface__PT& portRef,
+    const IPL4asp__Types::ConnectionId& connId,
+    IPL4asp__Types::f__getMsgLen& f,
+    const IPL4asp__Types::ro__integer& msgLenArgs)
+  {
+    f__IPL4__PROVIDER__setGetMsgLen(portRef, connId, f, msgLenArgs);
+  }
+  
+} // namespace IPL4__user__CtrlFunct
+
diff --git a/src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn b/src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn
new file mode 100644
index 0000000..e5ff2ea
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:               SCTP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 630
+//  Updated:            2010-11-24
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          
+//
+
+module IP_Daemon_Dynamic_IPL4_CtrlFunct {
+
+  import from IP_Daemon_Dynamic_Interface_Definitions all;
+  import from IPL4asp_Types all;
+  
+  external function f_IPL4_listen(
+    inout IPDD_Interface_PT portRef, 
+    in HostName locName,
+    in PortNumber locPort,
+    in ProtoTuple proto,
+    in OptionList options := {}
+  ) return Result; 
+
+  external function f_IPL4_connect(
+    inout IPDD_Interface_PT portRef,
+    in HostName remName,
+    in PortNumber remPort,
+    in HostName locName,
+    in PortNumber locPort,
+    in ConnectionId connId,
+    in ProtoTuple proto,
+    in OptionList options := {}
+  ) return Result;
+
+  external function f_IPL4_close(
+    inout IPDD_Interface_PT portRef,
+    in ConnectionId id,
+    in ProtoTuple proto := { unspecified := {} }
+  ) return Result;
+
+  external function f_IPL4_setUserData(
+    inout IPDD_Interface_PT portRef,
+    in ConnectionId id,
+    in UserData userData
+  ) return Result;
+
+  external function f_IPL4_getUserData(
+    inout IPDD_Interface_PT portRef,
+    in ConnectionId id,
+    out UserData userData
+  ) return Result;
+
+  external function f_IPL4_setGetMsgLen(
+    inout IPDD_Interface_PT portRef,
+    in ConnectionId id := -1,
+    inout f_getMsgLen f,
+    in ro_integer msgLenArgs
+  );
+  
+} // module SCTP_Daemon_Dynamic_IPL4_CtrlFunct
+
diff --git a/src/IP_Daemon_Dynamic_Interface_Definitions.ttcn b/src/IP_Daemon_Dynamic_Interface_Definitions.ttcn
new file mode 100644
index 0000000..ea1d2a7
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_Interface_Definitions.ttcn
@@ -0,0 +1,315 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:           SCTP_Daemon_Dynamic_Interface_Definitions.ttcn
+//  Description:    IPDD <-> Testcase interface data and port types
+//  Rev:            <RnXnn>
+//  Prodnr:         CNL 113 630
+//  Updated:        2012-11-10
+//  Contact:        http://ttcn.ericsson.se
+
+
+module IP_Daemon_Dynamic_Interface_Definitions
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record IPDD_Message_with_ClientId {
+  integer       client_id optional,
+  IPDD_Message  msg
+}
+
+type union IPDD_Message {
+
+  // Both-way traffic
+  IPDD_Data                     ipdd_data,                  // send data
+
+  // Requests
+  IPDD_QueryConnections         ipdd_queryConnections,      // query the state of the active connections
+  IPDD_Listen                   ipdd_listen,                // define a new server connection
+  IPDD_Connect                  ipdd_connect,               // define a new client connection
+  IPDD_Close                    ipdd_close,                 // close a connection
+  IPDD_SubscribeToConnection    ipdd_subscribeToConnection, // subscribe to an connection's events
+
+  // Indications
+  IPDD_Result                   ipdd_result,                // result comes in response to Listen and Connect, and contains the new connectionId
+  IPDD_Connections              ipdd_connections,           // response to queryConnections
+  IPDD_ConnectionChanged        ipdd_connectionChanged,     // indicates the change of the state of a connection 
+  IPDD_Connected                ipdd_connected,             // indicates that a client has been connected to one of our IP server
+  IPDD_Closed                   ipdd_closed                 // indicates that a connection has been closed
+
+} with {
+  variant "TAG(
+  ipdd_data,                  messageType = 0;
+  ipdd_queryConnections,      messageType = 1;
+  ipdd_listen,                messageType = 2;
+  ipdd_connect,               messageType = 3;
+  ipdd_close,                 messageType = 4;
+  ipdd_subscribeToConnection, messageType = 5;
+
+  ipdd_result,               messageType = 100;
+  ipdd_connections,          messageType = 101;
+  ipdd_connectionChanged,    messageType = 102;
+  ipdd_connected,            messageType = 103;
+  ipdd_closed,               messageType = 104)"
+}
+
+group MainMessageTypes {
+
+  type record IPDD_Data {
+    integer              messageType,
+    IPDD_INT32           connectionId,
+    boolean              sctpAttributesPresent,
+    IPDD_SctpAttributes  sctpAttributes optional,
+    integer              dataLength (0..65526),
+    octetstring          data
+  } with {
+    variant (sctpAttributesPresent) "FIELDLENGTH(8)"
+    variant (sctpAttributes) "PRESENCE (sctpAttributesPresent=true)" 
+    variant (dataLength) "FIELDLENGTH(16)"
+    variant (dataLength) "LENGTHTO(data)"
+  }
+
+  type record IPDD_QueryConnections {
+    integer         messageType
+  }
+
+  type record IPDD_Listen {
+    integer                   messageType,
+    IPDD_Interface            localInterface,
+    ProtoTupleEnum            proto,
+    boolean                   sctpProtoAttributesPresent,
+    IPDD_SctpProtoAttributes  sctpProtoAttributes optional
+  } with {
+    variant (sctpProtoAttributesPresent) "FIELDLENGTH(8)"
+    variant (sctpProtoAttributes) "PRESENCE (sctpProtoAttributesPresent=true)" 
+  }
+
+  type record IPDD_Connect {
+    integer                   messageType,
+    boolean                   autoReconnect,
+    boolean                   localInterfacePresent,
+    IPDD_Interface            localInterface optional,
+    IPDD_Interface            remoteInterface,
+    ProtoTupleEnum            proto,
+    boolean                   sctpProtoAttributesPresent,
+    IPDD_SctpProtoAttributes  sctpProtoAttributes optional
+  } with {
+    variant (autoReconnect, localInterfacePresent, sctpProtoAttributesPresent) "FIELDLENGTH(8)"
+    variant (localInterface) "PRESENCE (localInterfacePresent=true)" 
+    variant (sctpProtoAttributes) "PRESENCE (sctpProtoAttributesPresent=true)" 
+  }
+
+  type record IPDD_Close {
+    integer     messageType,
+    IPDD_INT32  connectionId
+  }
+
+  type record IPDD_SubscribeToConnection {
+    integer     messageType,
+    IPDD_INT32  connectionId
+  }
+
+  type record IPDD_Result {
+    integer     messageType,
+    IPDD_INT32  connectionId,
+    boolean     errorStatus,
+    charstring  errorMessage optional
+  } with {
+    variant (errorStatus) "FIELDLENGTH(8)"
+    variant (errorMessage) "PRESENCE (errorStatus=true)" 
+  }
+
+  type record IPDD_Connections {
+    integer              messageType,
+    IPDD_ConnectionList  connectionList
+  }
+
+  type record IPDD_ConnectionChanged {
+    integer     messageType,
+    IPDD_INT32  connectionId,
+    boolean     eventPresent,
+    IPDD_Event  event optional,
+    boolean     sctpStatePresent,
+    SAC_STATE   sctpState optional
+  } with {
+    variant (eventPresent, sctpStatePresent, sctpState) "FIELDLENGTH(8)"
+    variant (event) "PRESENCE (eventPresent=true)" 
+    variant (sctpState) "PRESENCE (sctpStatePresent=true)" 
+  }
+
+  type record IPDD_Connected {
+    integer         messageType,
+    IPDD_INT32      serverId,
+    IPDD_INT32      connectionId,
+    IPDD_Interface  remoteInterface
+  }
+  
+  type record IPDD_Closed {
+     integer     messageType,
+     IPDD_INT32  connectionId
+  }
+}
+
+group SubTypes {
+
+  type integer IPDD_INT32 with {
+    variant "FIELDLENGTH(32), COMP(signbit)"
+  }
+
+  type integer IPDD_ULONG with {
+    variant "FIELDLENGTH(32), COMP(nosign)"
+  }
+
+  type record IPDD_SctpAttributes {
+    IPDD_ULONG  sinfo_stream,
+    IPDD_ULONG  sinfo_ppid
+  }
+
+  type enumerated ProtoTupleEnum {
+    udp,
+    tcp,
+    sctp,
+    ssl,
+    unspecified
+  } with {
+    variant "FIELDLENGTH(8)"
+  }
+
+  type record IPDD_SctpProtoAttributes {
+    boolean             sinfo_streamAttributesPresent,
+    IPDD_ULONG          sinfo_stream optional,
+    boolean             sinfo_ppidPresent,
+    IPDD_ULONG          sinfo_ppid optional,
+    boolean             remSocksPresent,
+    IPDD_InterfaceList  remSocks optional,
+    boolean             assocIdPresent,
+    IPDD_ULONG          assocId optional
+  } with { 
+    variant (sinfo_streamAttributesPresent, sinfo_ppidPresent, remSocksPresent, assocIdPresent) "FIELDLENGTH(8)"
+    variant (sinfo_stream) "PRESENCE (sinfo_streamAttributesPresent=true)" 
+    variant (sinfo_ppid) "PRESENCE (sinfo_ppidPresent=true)" 
+    variant (remSocks) "PRESENCE (remSocksPresent=true)" 
+    variant (assocId) "PRESENCE (assocIdPresent=true)" 
+  }
+
+  type record IPDD_Event {
+    boolean      errorCodePresent,
+    PortError     errorCode optional,
+    boolean     os_error_codePresent,
+    integer       os_error_code optional,
+    integer       os_error_textLength,
+    charstring  os_error_text optional
+  } with { 
+    variant (errorCodePresent, os_error_codePresent, os_error_textLength) "FIELDLENGTH(8)"
+    variant (errorCode) "PRESENCE (errorCodePresent=true)" 
+    variant (os_error_code) "PRESENCE (os_error_codePresent=true)" 
+    variant (os_error_textLength) "LENGTHTO (os_error_text)" 
+  }
+
+  type record IPDD_Interface {
+    integer     hostNameLength,
+    charstring  hostName,
+    integer     portNumber (0..65535) optional
+  } with {
+    variant (hostNameLength) "LENGTHTO(hostName)";
+    variant (portNumber) "FIELDLENGTH(16)";  
+  }
+
+  type record of IPDD_Interface IPDD_InterfaceList;
+
+  type record IPDD_Connection {
+    IPDD_INT32      connectionId,
+    boolean         serverConnection, // true := server, false: client
+    boolean         autoReconnect,
+    boolean                   localInterfacePresent,
+    IPDD_Interface            localInterface optional,
+    boolean                   remoteInterfacePresent,
+    IPDD_Interface            remoteInterface optional,
+    ProtoTupleEnum            proto,
+    boolean                   sctpProtoAttributesPresent,
+    IPDD_SctpProtoAttributes  sctpProtoAttributes optional
+  } with {
+    variant (localInterface) "PRESENCE (localInterfacePresent=true)"
+    variant (remoteInterface) "PRESENCE (remoteInterfacePresent=true)"
+    variant (sctpProtoAttributes) "PRESENCE (sctpProtoAttributesPresent=true)"
+    variant (serverConnection, autoReconnect, localInterfacePresent, remoteInterfacePresent, sctpProtoAttributesPresent) "FIELDLENGTH(8)"; // take a byte to make debugging a little easier
+  }
+
+  type record of IPDD_Connection IPDD_ConnectionList;
+
+  type record IPDD_ConnectionConfig {
+    boolean         serverConnection, // true := server, false: client
+    boolean         autoReconnect,
+    IPDD_Interface    localInterface optional,
+    IPDD_Interface    remoteInterface optional
+  }
+}
+
+//=========================================================================
+//Port Types
+//=========================================================================
+
+type port IPDD_Interface_PT message {
+  in	ASP_Event;
+  inout IPDD_Message_with_ClientId
+} with { extension "user IPL4asp_PT
+  in( ASP_Event		  -> ASP_Event: simple;
+  ASP_RecvFrom            -> IPDD_Message_with_ClientId: function(f_dec_IPDD_Message))
+  out(IPDD_Message_with_ClientId    -> ASP_Send: function(f_enc_IPDD_Message))"
+}
+
+//=========================================================================
+// Encoder and Decoder Functions
+//=========================================================================
+function f_IPDD_getMsgLen(in octetstring stream, inout ro_integer args) return integer {
+  var integer stream_length := lengthof(stream);
+  
+  if (stream_length >=4) {
+    return oct2int(substr(stream,2,2));
+  }
+  
+  return -1;
+}
+
+function f_dec_IPDD_Message(in ASP_RecvFrom aspTCP, out IPDD_Message_with_ClientId daemonMsg) return integer {
+  daemonMsg.client_id := aspTCP.connId;
+  daemonMsg.msg := dec_IPDD_Message(substr(aspTCP.msg, 4, lengthof(aspTCP.msg)-4));
+  return 0;
+} with { extension "prototype(backtrack)" }
+
+function f_enc_IPDD_Message(in IPDD_Message_with_ClientId sctpMsg, out ASP_Send aspTCP) return integer {
+  aspTCP.connId := sctpMsg.client_id;
+  var octetstring vl_encoded := enc_IPDD_Message(sctpMsg.msg);
+  // assemble TPKT here; TPKT:
+  // 1st octet: version
+  // 2nd octet: '00'O
+  // 3rd-4th octet: message length; used to separate the messages travelling on TCP
+  aspTCP.msg := '0300'O & int2oct((lengthof(vl_encoded) + 4), 2) & vl_encoded;
+  aspTCP.proto := {tcp:={}};
+  return 0; 
+} with { extension "prototype(backtrack)" }
+
+// created automatically by compiler's RAW Encoder/Decoder code generator
+external function enc_IPDD_Message(in IPDD_Message pdu) return octetstring
+with { extension "prototype(convert) encode(RAW)" }
+
+// created automatically by compiler's RAW Encoder/Decoder code generator
+external function dec_IPDD_Message(in octetstring stream) return IPDD_Message
+with { extension "prototype(convert) decode(RAW)" }
+
+} with {encode "RAW"} // end of module
diff --git a/src/IP_Daemon_Dynamic_Types.ttcn b/src/IP_Daemon_Dynamic_Types.ttcn
new file mode 100644
index 0000000..3ce19f7
--- /dev/null
+++ b/src/IP_Daemon_Dynamic_Types.ttcn
@@ -0,0 +1,304 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:           SCTP_Daemon_Dynamic_Types.ttcn
+//  Description:    IPDD types
+//  Rev:            <RnXnn>
+//  Prodnr:         CNL 113 630
+//  Updated:        2012-05-07
+//  Contact:        http://ttcn.ericsson.se
+
+module IP_Daemon_Dynamic_Types
+{
+
+//=========================================================================
+// Import Part
+//=========================================================================
+
+import from IP_Daemon_Dynamic_Interface_Definitions all;
+
+import from IPL4asp_Types all;
+import from IPL4asp_PortType all;
+
+//=========================================================================
+// Data Types
+//=========================================================================
+
+type record of integer IntegerList;
+
+type record ConnectionRuntimeAttributes {
+  IntegerList    subscribedTestcases,
+  integer        socket,
+  integer        endpointIndex,
+  SAC_STATE      sctpState,
+  charstring     userState
+}
+
+type record of ConnectionRuntimeAttributes ConnectionRuntimeAttributesList;
+
+type record IPDD_ConnectionConfig {
+  boolean         serverConnection, // true := server, false: client
+  boolean         autoReconnect,
+  IPDD_Interface  localInterface optional,
+  IPDD_Interface  remoteInterface optional,
+  ProtoTupleEnum  proto
+}
+
+type record of IPDD_ConnectionConfig IPDD_ConnectionConfigList;
+
+type record of integer TCP_connections_List;                                                    //xxx for added SGsAP functionality
+
+type function Connection_Insert(octetstring pl_data, integer pl_id) runs on self;               //xxx
+type function Connection_Lookup(octetstring pl_data) runs on self return TCP_connections_List;  //xxx
+type function Connection_Delete(integer pl_id) runs on self;                                    //xxx
+
+//=========================================================================
+//Component Types
+//=========================================================================
+
+type component IPDD_CT {
+  port IPDD_Interface_PT daemonPort;
+  port IPL4asp_PT IP_PCO;
+
+  var IPDD_ConnectionList vc_connectionList := {};
+  var ConnectionRuntimeAttributesList vc_connectionRuntimeAttributesList := {};
+  var IPDD_InterfaceList v_localEndpointList := {};
+
+  //var ASP_TCP_Connected vc_connected;
+  var IPDD_Message_with_ClientId vc_daemonMessage;
+
+  timer vc_reconnectTimer;
+  timer vc_inactivityTimer;
+
+  var ASP_RecvFrom       vc_asp_IP_ReceivedMessage;
+  var ASP_Event          vc_asp_IP_Event;
+  var ASP_Event          vc_asp_TCP_Event;
+  var ASP_Event          vc_ipResult;
+
+  var ASP_Event vc_tcpClose;
+
+  var RegisteredAutoReplyFunctionList vc_registeredAutoReplyFunctionList := {};
+  var RegisteredAutoStateChangeHandlerFunctionList vc_registeredAutoStateChangeHandlerFunctionList := {};
+  var RegisteredAutoStartupFunctionList vc_registeredAutoStartupFunctionList := {};
+
+  var Connection_Insert v_Connection_Insert:=null;
+  var Connection_Lookup v_Connection_Lookup:=null;
+  var Connection_Delete v_Connection_Delete:=null;
+  var TCP_connections_List v_TCP_connections_List;
+}
+
+//=========================================================================
+// Signatures
+//=========================================================================
+
+// return true if the message should not be passed to TTCN but replied with the ipReply
+type function f_IPDD_AutoReplyFunction(in integer connectionIndex, in ASP_RecvFrom ipReceived, out ASP_Send ipReply)
+runs on self return boolean;
+
+type record of f_IPDD_AutoReplyFunction RegisteredAutoReplyFunctionList;
+
+// return true if the state should not be passed to TTCN, but ipMsg has to be automatically sent on the connection
+type function f_IPDD_AutoStateChangeHandlerFunction(in integer connectionIndex, in SAC_STATE newState, out ASP_Send ipMsg)
+runs on self return boolean;
+
+type record of f_IPDD_AutoStateChangeHandlerFunction RegisteredAutoStateChangeHandlerFunctionList;
+
+// return true if the message should be sent to SUT and put the message in the ipMsg
+type function f_IPDD_AutoStartupFunction(in integer connectionIndex, out ASP_Send ipMsg)
+runs on self return boolean;
+
+type record of f_IPDD_AutoStartupFunction RegisteredAutoStartupFunctionList;
+
+//=========================================================================
+// Constants
+//=========================================================================
+
+const IPDD_Connection c_emptyConnection := {
+  connectionId := -1,
+  serverConnection := false, // true := server, false: client
+  autoReconnect := true,
+  localInterfacePresent := false,
+  localInterface := omit,
+  remoteInterfacePresent := false,
+  remoteInterface := omit,
+  sctpProtoAttributesPresent := false,
+  sctpProtoAttributes := omit
+}
+
+const ConnectionRuntimeAttributes c_emptyConnectionRuntimeAttribute := {
+  subscribedTestcases := {},
+  socket := -1,
+  endpointIndex := -1,
+  sctpState := SCTP_COMM_LOST,
+  userState := ""
+}
+
+//=========================================================================
+// Templates
+//=========================================================================
+
+template IPDD_Message_with_ClientId t_IPDD_Message_with_ClientId := {
+  client_id := ?,
+  msg := ?
+}
+
+template IPDD_Message_with_ClientId t_queryConnections modifies t_IPDD_Message_with_ClientId := {
+  msg := {
+    ipdd_queryConnections := ?
+  }
+}
+
+template IPDD_Message_with_ClientId t_connect modifies t_IPDD_Message_with_ClientId := {
+  msg := {
+    ipdd_connect := ?
+  }
+}
+
+template IPDD_Message_with_ClientId t_listen modifies t_IPDD_Message_with_ClientId := {
+  msg := {
+    ipdd_listen := ?
+  }
+}
+
+template IPDD_Message_with_ClientId t_close modifies t_IPDD_Message_with_ClientId := {
+  msg := {
+    ipdd_close := ?
+  }
+}
+
+template IPDD_Message_with_ClientId t_ipData modifies t_IPDD_Message_with_ClientId := {
+  msg := {
+    ipdd_data := ?
+  }
+}
+
+template IPDD_Message_with_ClientId t_subscribeToConnection modifies t_IPDD_Message_with_ClientId := {
+  msg := {
+    ipdd_subscribeToConnection := ?
+  }
+}
+
+//SCTP Assoc Change
+template ASP_Event tr_sctpEvent
+( template integer    pl_connectionID,
+  template SAC_STATE  pl_state
+) :=
+{
+  sctpEvent :=
+  {
+    sctpAssocChange :=
+    {
+      clientId := pl_connectionID,
+      proto :=
+      {
+        sctp := ?
+      },
+      sac_state := pl_state
+    }
+  }
+}
+
+//SCTP ShutdownEvent
+template ASP_Event tr_S_SCTP_ShutdownEvent:=
+{
+  sctpEvent :=
+  {
+    sctpShutDownEvent :=
+    {
+      clientId := ?
+    }
+  }
+}
+
+//Result
+template ASP_Event tr_ASP_Result :=
+{
+  result :=
+  {
+    errorCode := *,
+    connId := *,
+    os_error_code := *,
+    os_error_text := *
+  }
+}
+
+//IP Connected
+template ASP_Event tr_ASP_IP_Connected:=
+{
+  connOpened :=
+  {
+    connId := ?,
+    remName := ?,
+    remPort := ?,
+    locName := ?,
+    locPort := ?,
+    proto := ?,
+    userData := ?
+  }
+}
+
+//IP Closed
+template ASP_Event tr_ASP_IP_Closed :=
+{
+  connClosed :=
+  {
+    connId := ?,
+    remName := ?,
+    remPort := ?,
+    locName := ?,
+    locPort := ?,
+    proto := ?,
+    userData := ?
+  }
+}
+
+//SCTP Peer Address Change
+template ASP_Event tr_S_SCTP_PeerAddressChange:=
+{
+  sctpEvent :=
+  {
+    sctpPeerAddrChange :=
+    {
+      clientId :=?,
+      spc_state := ?
+    }
+  }
+}
+
+//TCP Connection Openned
+template ASP_Event tr_ASP_TCP_Connected :=
+{
+  connOpened :=
+  {
+    connId := ?,
+    remName := ?,
+    remPort := ?,
+    locName := ?,
+    locPort := ?,
+    proto :={tcp:={}},
+    userData := ?
+  }
+}
+
+
+//TCP Close Connection
+template ASP_Event tr_ASP_TCP_Close:=
+{
+  connClosed :=
+  {
+    connId := ?,
+    remName := ?,
+    remPort := ?,
+    locName := ?,
+    locPort := ?,
+    proto :={tcp:={}},
+    userData := ?
+  }
+}
+
+}  // end of module