blob: 9cb11a22a4562f7a54cd099822cccf84a01abb8e [file] [log] [blame]
= IP Daemon Dynamic for TTCN-3 Toolset with TITAN, Description
:author: Eduard Czimbalmos
:toc: left
== Introduction
=== References
[[_1]][1] ETSI ES 201 873-1 v.3.1.1 (2005-06) +
The Testing and Test Control Nota¬tion version 3. Part 1: Core Language
[[_2]][2] 1/198 17-CRL 113 200 Uen +
TITAN Installation Guide
[[_3]][3] 1/198 17-CRL 113 200 Uen +
TITAN Users Guide
[[_4]][4] 2/198 17-CRL 113 200 Uen +
Programmers Technical Reference for TITAN
=== Abbreviations
RTE:: Run-Time Environment
SCTP:: Stream Control Transmission Protocol
UDP:: User Datagram Protocol
IPDD:: IP Daemon Dynamic
SUT:: System Under Test
TCP:: Transmission Control Protocol
TTCN-3:: Testing and Test Control Notation version 3
=== System Requirements
In order to operate IPDD, the following system requirements must be satisfied:
* TITAN TTCN-3 Test Executor version R7A (1.7.pl0) or higher installed. For installation guide see <<_2, [2]>>.
* IPL4asp Test Port for TITAN.
* TCCUsefulFunctions for TITAN.
== The IP Daemon Dynamic
=== Overview
IPDD provides the following features to a testcase:
* defining server and client connections
* SCTP, TCP or UDP payload relaying from the SUT via TCP connections between IPDD and the testcases
* keeping connections alive between testcases
* reconnect disconnected client connections
* dynamically create new SCTP client and server associations from the testcase
* close client and server connections from the testcase
* subscribe to connection events, if the connections are already present
* API to allow automatic handling of incoming messages (i.e. heartbeat messages) and events
* API to allow sending messages when a connection initiates (auto-startup functions)
* function callbacks that allow the user to extend the daemon so that routing can be implemented based on upper layer protocols
* automatic shutdown after an inactivity period
The outline of the IPDDs architecture can be seen in <<figure-1, Figure 1>>. The IPDD is a standalone application, which is executed independently of the TTCN-3 testcases. This results that the SCTP, TCP and UDP connections remain active between the executions of testcases.
When the IPDD is started, it connects the configured client IP connections to the SUT, opens the configured server IP connections, and starts listening on a TCP port for incoming connection requests from the users (testcases). After the daemon accepted a TCP connection request, the IP messages sent by the testcase are forwarded to the selected IP connection.
Naturally, the answers coming from the SUT are relayed back to the user as well. Thus, IPDD provides an interface to access SCTP, TCP or UDP communication ports via TCP connections.
The daemon tries to re-establish client IP connections that were interrupted and in case of SCTP, the testcases are notified if the corresponding SCTP connection is lost or becomes active again.
[[figure-1]]
image::images/architecture.png[title="IP Daemon Dynamic architecture"]
=== Functional specification
The outline of the IPDDs architecture can be seen in <<figure-1, Figure 1>>. IPDD is a standalone application, which is executed independently of the TTCN-3 testcases. This results that the SCTP, TCP and UDP connections remain active between the executions of testcases.
When the IPDD is started, it connects the configured client IP connections to the SUT, opens the configured server IP connections, and starts listening on a TCP port for incoming connection requests from the users (testcases). After the daemon accepted a TCP connection request, the IP messages sent by the testcase are forwarded to the selected IP connection.
Naturally, the answers coming from the SUT are relayed back to the user as well. Thus, IPDD provides an interface to access SCTP, TCP or UDP communication ports via TCP connections.
The daemon tries to re-establish client IP connections that were interrupted and in case of SCTP, the testcases are notified if the corresponding SCTP connection is lost or becomes active again. In case of TCP, connection opened and connection closed messages are sent.
[[figure-1]]
image::images/architecture.png[title="IP Daemon Dynamic architecture"]
==== TCP Interface
The messages between IPDD and the daemon users are sent over one or more TCP connections, which are handled by IPL4 test port. The IPDD source code contains a dual-faced port definition `IPDD_Interface_P`T, which is used by the testcase and the IPDD to communicate with each other.
==== IP interface
To handle IP connections, IPDD relies on the IPL4asp test port, thus the supported SCTP, TCP and UDP specifications also apply here. The user can control the SCTP, TCP or UDP connection Id, and in case of SCTP, the stream Id and PPID. The testcase can also assign a specific local address for each IP connection.
=== Installation
IPDD is used as part of the TTCN-3 test environment. This means that the TTCN-3 Test Executor must be installed before any operation of IPDD. For more details on the installation of TTCN-3 Test Executor see <<_2, [2]>>.
Furthermore, IPDD uses the IPL4 test ports and interface functions from TCCUsefulFunctions, therefore their installation is also inevitable.
=== Compilation
IPDD sources have to be compiled in order to get the IP Daemon Dynamic executable. The compilation has to be done in single mode (`TTCN3_LIB=ttcn3` in the Makefile), not in parallel mode. The following IPDD specific source files are needed:
* _IP_Daemon_Dynamic.ttcn_
* _IP_Daemon_Dynamic_Interface_Definitions.ttcn_
* _IP_Daemon_Dynamic_Types.ttcn_
* _IP_Daemon_Dynamic_IPL4_CtrlFunct.ttcn_
* _IP_Daemon_Dynamic_IPL4_CtrlFuncDef.cc_
The following source files are needed from other products:
* *IPL4asp Test Port for TITAN*
** _IPL4asp_PT.hh_
** _IPL4asp_PT.cc_
** _IPL4asp_PortType.ttcn_
** _IPL4asp_Types.ttcn_
** _IPL4asp_Functions.ttcn_
** _IPL4asp_protocol_L234.hh_
** _IPL4asp_discovery.cc_
* *Socket API Common Component*
* *TCCUsefulFunctions for TITAN*
** _TCCInterface.cc_
** _TCCInterface_Functions.ttcn_
** _TCCInterface_ip.h_
`CPPFLAGS` are needed to be add in the Makefile:
* SCTP support need to be enabled by adding `-DUSE_SCTP`
For details on the compilation with TTCN-3 Test Executor see the relevant section of <<_3, [3]>>.
=== Start procedure
IPDD can be started as a stand-alone TTCN-3 program in single mode: __IP_Daemon_Dynamic <config file>.cfg__
Multiple instances of IPDD can be executed in a single host.
If a fatal error occurs during initialization, IPDD does not start. Fatal error means: the configuration file cannot be found or there is error in the RTE configuration file.
=== Stop procedure
IPDD can be stopped by pressing `CTRL-C`. IP connections should gracefully terminate when IPDD terminates.
=== Configuration
IPDD can be configured using the RTE configuration file, see ‎<<_3, [3]>>. This file is read by IPDD at start-up and it sets its internal parameters. Any name can be chosen as RTE configuration file name, but it is recommended to have _.cfg_ as its extension.
[[ipdd-parameters]]
==== IPDD parameters
IPDDs own parameters have to be specified in the `[MODULE_PARAMETERS]` section of the RTE configuration file:
* `tsp_IPDD_TCP_ListenInterface`
+
Optional
+
Type: charstring
+
Default value: `_"127.0.0.1"_`
+
This module parameter specifies the TCP interface where IPDD is waiting for the clients to connect.
* `tsp_IPDD_TCP_ListenPort`
+
Optional
+
Type: integer
+
Default value: `_1314_`
+
Specifies the TCP port where IPDD is waiting for the clients to connect.
* `tsp_IPDD_ConnectionList`
+
Optional
+
Type: IPDD_ConnectionConfigList
+
Default value: empty
+
Specifies the list of connections to be initiated on the start-up of IPDD.
+
Fields of a single `IPDD_ConnectionConfig`:
** `serverConnection`
+
`_true_` means server, `_false_` means client.
** `autoReconnect`
+
`_true_` means reconnect connection if it gets broken.
** `localInterface`
+
Local interface and port of the connection. This field has to be filled if server connection is created.
** `remoteInterface`
+
Remote interface and port of the connection. This field has to be filled if client connection is created.
** `proto`
+
The used protocol of the connection.
* `tsp_IPDD_ReconnectTimer`
+
Optional
+
Type: float
+
Default value: `_2.0_`
+
Specifies the interval (seconds) the daemon tries to re-establish a broken client connection, if the connection is configured to be auto-reconnected.
* `tsp_IPDD_InactivityTimer`
+
Optional
+
Type: float
+
Default value: `_60.0_`
+
Specifies the timeframe (seconds) IPDD is alive after an IP event. IPDD exits to the shell if no event happens within this timeframe. +
The feature can be switched off by setting the parameter to `_0.0_` or a negative float value.
* [[tsp_debug]]`tsp_debug`
+
Optional
+
Type: boolean
+
Default value: `_false_`
+
A boolean parameter, which turns on/off the verbose output to the logfile. +
A sample module parameter setting can be examined <<rte-configuration-file, here>>, where a complete configuration file is presented.
=== Logging
The logging mechanism logs information either to the log file or to the output console. The user can set the amount and type of logging in the RTE configuration file. The Titan parameters `ConsoleMask` and `FileMask` control the overall logging. These logging options are described in <<_3, [3]>>.
IPDD log messages can be received by using the `TTCN_USER` log mask. The module parameter <<tsp_debug, `tsp_debug`>> enables/disables verbose logging. If `tsp_debug` is selected most internal events are logged textually.
Since there is only an MTC and no PTCs within IPDD, there is only one log file that includes logging from IPDD and the IPL4 Test Port.
=== Error handling
Erroneous behaviour detected during runtime is directed into the RTE log file. The following two types of messages are taken care of:
* Errors: information about the detected errors is provided. If an error occurs the execution of IPDD will stop immediately. The test ports will be unmapped. These log messages are starting with: `\*** ERROR`.
* Warnings: information about the detected warnings is provided. The execution continues after the warning is shown. These log messages are starting with: `\*** WARNING`.
The following sections give detailed descriptions of IPDDs error and warning messages.
NOTE: Besides these, error and warning messages of the IPL4asp test ports may also appear, since the daemon uses these components.
==== Error messages
* *`ERROR: IP server connection #<connIdx> is declared as a server, but has no localInterface defined!`*
+
Occurs if the connection is server connection, but it has no local interface defined.
* *`ERROR: error during initialization of the TCP port: <result>`*
+
An error occurred during the initialization of the TCP server.
* *`ERROR: connection <connectionId> is not alive, not sending ASP_IP_Close!`*
+
Occurs if the connection about to be closed is not present.
==== Warning messages
* *`WARNING: IP connection to delete: <connectionId> was not found in the database!`*
+
Attempting to delete a connection which is not in the database.
* *`WARNING: unhandled protoTuple type!`*
+
Pops up when trying to use a protocol which is unhandled in IPL4 Test Port.
* *`WARNING: unhandled IP message received!`*
+
Receiving a message that is unimplemented in IPDD.
* *`WARNING: test case <id> is already subscribed to: <connection>`*
+
The test case issuing the `subscribeToConnection` message is already subscribed to the given connections events.
* *`WARNING: test case <id> was not subscribed to any connection!`*
+
Either the test case was already subscribed to the connection (and the previous warning is also in the log), or the given connection was not found in the database.
* *`WARNING: IP server connection <interface, port> is already listening!`*
+
The server connection sent in the listen message is already in listening state, the server is active.
* *`WARNING: IP connection to <interface, port> is already active!`*
+
The reconnected connection is already connected.
== Dynamic behaviour
This section describes the communication between a testcase and the SUT through the IP Daemon Dynamic.
The __IP_Daemon_Dynamic_Test.ttcn__ in the demo directory of IPDD contains example testcases for the usage of the daemon.
=== Daemon messages and port definition
The `IP_Daemon_Dynamic_Interface_Definitions` module contains the required message types and port definition needed to communicate with IPDD. The `IPDD_Interface_PT` port type is a TCP port, which is responsible to establish the connection between the testcase and IPDD.
The port is based on the TCP port, and automatically encodes/decodes the `IPDD_Message_with_ClientId` type. The `IPDD_Message_with_ClientId` types msg field is defined as a union, and contains all the possible interface messages which can be exchanged by the testcase and IPDD.
[cols="m,s,",options="header"]
|===
|Message type |Direction |Effect
|IPDD_Data |TestcaseIPDD |SCTP, TCP or UDP data coming from the SUT is forwarded to the testcase, message coming from the testcase is forwarded to the SUT.
|IPDD_QueryAssociations |TestcaseIPDD |The testcase queries the current IP connections allocated in IPDD.
|IPDD_Listen |TestcaseIPDD |IPDD opens a new IP server socket, and subscribes the testcase to receive events from the server socket and the connected clients.
|IPDD_Connect |TestcaseIPDD |IPDD initiates a client connection to the SUT, and subscribes the testcase to the events of the connection.
|IPDD_Close |TestcaseIPDD |If the requested connection is client, IPDD closes it. If server, then IPDD shuts it down.
|IPDD_SubscribeToAssociation |TestcaseIPDD |IPDD subscribes the testcase to the specified connection's events.
|IPDD_Result |Testcase←IPDD |Returns the result of a listen/connect request. The result will contain the allocated connection's ID, which is `_-1_` if failure happened.
|IPDD_Connections |TestcaseIPDD |Returns the current connections allocated in IPDD in response to the `queryAssociations` request.
|IPDD_ConnectionChanged |TestcaseIPDD |Reports about the state change of an SCTP connection to the subscribed testcases.
|IPDD_Connected |TestcaseIPDD |Reports that the SUT has initiated a client connection to a server which the testcase is subscribed to.
|IPDD_Closed |TestcaseIPDD |Reports that a connection is closed in response to the close request.
|===
=== Signalling procedures between the testcase and IPDD
The signalling procedures are presented in this section in the recommended order as they should be performed in testcases.
[[connecting-the-testcase-to-ipdd]]
==== Connecting the testcase to IPDD
The `f_IPL4_connect` function can be used to create a connection. The connection ID is returned in the `Result` record.
As only the upper protocol may know how to find message boundaries in the stream of bytes. In order to perform this task a callback function may be registered for each connection in the test port. This way the user will receive complete messages.
To achieve this functionality, separate function(s) have to be written, which is needed to be called with the connection ID from the `Result` record.
[source]
f_IPL4_setGetMsgLen(inout IPDD_Interface_PT portRef, in ConnectionId id := -1,inout f_getMsgLen f,in ro_integer msgLenArgs);
In the demo directory there is an example of usage.
==== Initiating server connection
The purpose of the procedure is to ensure that a server connection is active in IPDD, and the testcase is subscribed to the servers events.
After successfully performing the procedure, the testcase knows the connection ID of the server.
The procedure assumes that <<connecting-the-testcase-to-ipdd, Connecting the testcase to IPDD>> is performed successfully already.
image::images/Initiating_server_connections.png[title="Initiating server connections"]
==== Initiating client connection
The purpose of the procedure is to ensure that a client connection is active in IPDD, and the testcase is subscribed to the clients events.
After successfully performing the procedure, the testcase knows the connection ID of the client.
The procedure assumes that <<connecting-the-testcase-to-ipdd, Connecting the testcase to IPDD>> is performed successfully already.
image::images/Initiating_client_connections.png[title="Initiating client connections"]
==== Querying the servers connected client connections
The purpose of the procedure is to get the connection IDs of the clients which are connected to servers active in IPDD, and subscribe to their events.
After successfully performing the procedure, the testcase knows the connection IDs of the connections connected to the servers.
The procedure assumes that <<connecting-the-testcase-to-ipdd, Connecting the testcase to IPDD>> is performed successfully already.
image::images/Querying_connected_client_connections.png[title="Querying connected client connections"]
=== Sending data through IPDD
Sending SCTP, TCP or UDP payload through IPDD is performed by using the `IPDD_Data` message. IPDD forwards the data to the connections socket to the SUT.
image::images/Sending_SCTP_TCP_or_UDP_payload.png[title="Sending SCTP, TCP or UDP payload"]
=== Receiving data through IPDD
Receiving SCTP, TCP or UDP payload through IPDD is performed by handling the incoming `IPDD_Data` message in an altstep. IPDD forwards the data coming on the connections socket to the testcase.
image::images/Receiving_SCTP_TCP_or_UDP_payload.png[title="Receiving SCTP, TCP or UDP payload"]
=== Receiving SCTP connection events
SCTP connection state change events are sent to the testcase with the `IPDD_ConnectionChanged` message.
image::images/Receiving_SCTP_connection_events.png[title="Receiving SCTP connection events"]
=== Notification of incoming SCTP or TCP client connection
When a SCTP or a TCP client connects to the server allocated in IPDD, IPDD sends the `IPDD_Connected` message to the testcase, which includes the association ID of the accepted client connection.
image::images/Incoming_client_connection.png[title="Incoming client connection"]
=== Closing SCTP or TCP connections
The testcase can close any SCTP or TCP connection by sending the `IPDD_Close` message.
image::images/Closing_a_connection.png[title="Closing a connection"]
=== Notification of a closed connection
The IPDD notifies the testcase if an SCTP or a TCP connection has been closed via an `IPDD_Closed` message.
[[automatic-message-handling]]
== Automatic message handling
IPDD provides a method for automatically handling incoming messages (like protocol heartbeat messages) and answer them without relaying them to the testcase.
To achieve this functionality, separate function(s) have to be written, which will be executed when data arrives from the SUT.
The `IP_Daemon_Dynamic_Types` module defines the function prototype:
[source]
----
type function f_IPDD_AutoReplyFunction(in integer connectionIndex, in ASP_RecvFrom ipReceived, out ASP_Send ipReply) runs on self return boolean.
----
The `f_RegisterAutoReplyFunction(in f_IPDD_AutoReplyFunction autoReplyFunction)` function of the `IP_Daemon_Dynamic` module has to be used to register auto-reply function(s) of type `f_IPDD_AutoReplyFunction`.
The logic displayed in <<flowchart-of-automatic-reply-logic, Figure 10>> is to be applied if any SCTP or TCP data is received from the SUT.
[[flowchart-of-automatic-reply-logic]]
image::images/Flowchart_of_automatic_reply_logic.png[title="Flowchart of automatic reply logic"]
The user-written auto-reply function runs on the IPDDs component. The parameter `connectionIndex` can be used as an index to the IPDDs internal connection databases.
The function has to examine the incoming message, and if it decides to answer it, it sets the answer in the `ipReply` parameter, and returns `_true_`. The returned `_true_` value means that the incoming message is processed, and the IPDD should not forward it to the testcase but send the `ipReply` to the SUT.
If the auto-reply function decides that the message should be relayed to the testcase, it has to return `_false_` on exit.
To make the functionality working, the user has to write a module with a separate testcase, which registers the auto-reply function(s), and executes the IPDDs `f_IPDD()` function.
For a working example, see the __IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn__ source file in the demo directory of IPDD.
== Automatic event handling
IPDD provides a method for automatically handling incoming events and send a message on them without relaying them to the testcase.
The API can be used to implement automatic sending of upper layer messages when the state of the connection changes.
To achieve this functionality, separate function(s) have to be written, which will be executed when the connection event happens.
The `IP_Daemon_Dynamic_Types` module defines the function prototype:
[source]
----
type function f_IPDD_AutoStateChangeHandlerFunction(in integer connectionIndex, in SAC_STATE newState, out ASP_Send ipMsg) runs on self return boolean;
----
The `f_RegisterAutoStateChangeHandlerFunction (in f_IPDD_AutoStateChangeHandlerFunction autoStateChangeHandlerFunction)` function of the `IP_Daemon_Dynamic module` has to be used to register auto-event function(s) of type `f_IP_AutoStateChangeHandlerFunction`.
The logic and the required implementation is the same as in <<automatic-message-handling, Automatic message handling>>. Example implementation can be found in the __IP_Daemon_Dynamic_with_DiameterAutoReplies.ttcn__ source file in the demo directory of IPDD.
== Automatic sending of messages on connection initiation
Outgoing messages can be sent automatically if a client connection is established from the IPDD. Functionality is available through the AutoStartup functions.
The `IP_Daemon_Dynamic_Types` module defines the function prototype:
[source]
----
type function f_IPDD_AutoStartupFunction(in integer connectionIndex, out ASP_Send ipMsg)
runs on self return boolean;
----
The function `f_RegisterAutoStartupFunction(in f_IPDD_AutoStartupFunction autoStartupFunction)` function of the `IP_Daemon_Dynamic` module has to be used to register auto-startup function(s) of type `f_IPDD_AutoStartupFunction`.
== Examples
[[rte-configuration-file]]
=== RTE Configuration file
[source]
----
[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]
LogFile := "ip_daemon.log"
SourceInfoFormat := Stack
[TESTPORT_PARAMETERS]
*.IP_PCO.pureNonBlocking := "NO"
*.IP_PCO.debug := "YES"
[EXECUTE]
IP_Daemon_Dynamic.tc_IPDD
----