First code commit
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3534f2f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0

+

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

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

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

+

+1. DEFINITIONS

+

+"Contribution" means:

+

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

+     Distributed under this Agreement, and

+

+  b) in the case of each subsequent Contributor:

+     i) changes to the Program, and

+     ii) additions to the Program;

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

+  and are Distributed by that particular Contributor. A Contribution

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

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

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

+  are not Modified Works.

+

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

+

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

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

+or when combined with the Program.

+

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

+Agreement.

+

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

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

+

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

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

+editorial revisions, annotations, elaborations, or other modifications

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

+

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

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

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

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

+Works shall not include works that contain only declarations,

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

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

+or Modified Works thereof.

+

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

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

+

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

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

+documentation source, and configuration files.

+

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

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

+exceptions or additional permissions as identified by the initial

+Contributor.

+

+2. GRANT OF RIGHTS

+

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

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

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

+  publicly perform, Distribute and sublicense the Contribution of such

+  Contributor, if any, and such Derivative Works.

+

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

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

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

+  import and otherwise transfer the Contribution of such Contributor,

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

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

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

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

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

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

+  licensed hereunder.

+

+  c) Recipient understands that although each Contributor grants the

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

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

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

+  Each Contributor disclaims any liability to Recipient for claims

+  brought by any other entity based on infringement of intellectual

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

+  rights and licenses granted hereunder, each Recipient hereby

+  assumes sole responsibility to secure any other intellectual

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

+  patent license is required to allow Recipient to Distribute the

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

+  before distributing the Program.

+

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

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

+  the copyright license set forth in this Agreement.

+

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

+  Contributor makes additional grants to any Recipient (other than

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

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

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

+

+3. REQUIREMENTS

+

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

+

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

+  accordance with section 3.2, and the Contributor must accompany

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

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

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

+  used for software exchange; and

+

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

+  different than this Agreement, provided that such license:

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

+     warranties and conditions, express and implied, including

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

+     implied warranties or conditions of merchantability and fitness

+     for a particular purpose;

+

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

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

+     incidental and consequential damages, such as lost profits;

+

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

+     in the Source Code under section 3.2; and

+

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

+     party to be under a license that satisfies the requirements

+     of this section 3.

+

+3.2 When the Program is Distributed as Source Code:

+

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

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

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

+  Contributor attached to the Source Code the notice described in

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

+  under the terms of such Secondary Licenses, and

+

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

+  the Program.

+

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

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

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

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

+their own appropriate notices.

+

+4. COMMERCIAL DISTRIBUTION

+

+Commercial distributors of software may accept certain responsibilities

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

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

+the Contributor who includes the Program in a commercial product

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

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

+the Program in a commercial product offering, such Contributor

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

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

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

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

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

+Commercial Contributor in connection with its distribution of the Program

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

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

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

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

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

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

+related settlement negotiations. The Indemnified Contributor may

+participate in any such claim at its own expense.

+

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

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

+Contributor. If that Commercial Contributor then makes performance

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

+claims and warranties are such Commercial Contributor's responsibility

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

+defend claims against the other Contributors related to those performance

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

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

+those damages.

+

+5. NO WARRANTY

+

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

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

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

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

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

+PURPOSE. Each Recipient is solely responsible for determining the

+appropriateness of using and distributing the Program and assumes all

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

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

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

+or equipment, and unavailability or interruption of operations.

+

+6. DISCLAIMER OF LIABILITY

+

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

+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS

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

+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST

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

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

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

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

+POSSIBILITY OF SUCH DAMAGES.

+

+7. GENERAL

+

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

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

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

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

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

+

+If Recipient institutes patent litigation against any entity

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

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

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

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

+litigation is filed.

+

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

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

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

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

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

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

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

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

+

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

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

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

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

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

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

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

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

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

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

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

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

+Contributor may elect to Distribute the Program (including its

+Contributions) under the new version.

+

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

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

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

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

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

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

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

+

+Exhibit A - Form of Secondary Licenses Notice

+

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

+Secondary Licenses when the conditions for such availability set forth 

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

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

+

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

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

+

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

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

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

+  look for such a notice.

+

+  You may add additional accurate notices of copyright ownership.
\ No newline at end of file
diff --git a/STUN_CNL113644.tpd b/STUN_CNL113644.tpd
new file mode 100644
index 0000000..250d61b
--- /dev/null
+++ b/STUN_CNL113644.tpd
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TITAN_Project_File_Information version="1.0">
+  <ProjectName>STUN_CNL113644</ProjectName>
+  <ReferencedProjects>
+    <ReferencedProject name="ProtocolModules_Common" projectLocationURI="../COMMON/ProtocolModules_Common.tpd"/>
+  </ReferencedProjects>
+  <Folders>
+    <FolderResource projectRelativePath="src" relativeURI="src"/>
+  </Folders>
+  <Files>
+    <FileResource projectRelativePath="src/STUN_EncDec.cc" relativeURI="src/STUN_EncDec.cc"/>
+    <FileResource projectRelativePath="src/STUN_Functions.ttcn" relativeURI="src/STUN_Functions.ttcn"/>
+    <FileResource projectRelativePath="src/STUN_Types.ttcn" relativeURI="src/STUN_Types.ttcn"/>
+  </Files>
+  <ActiveConfiguration>Default</ActiveConfiguration>
+  <Configurations>
+    <Configuration name="Default">
+      <ProjectProperties>
+        <MakefileSettings>
+          <targetExecutable>bin/STUN_CNL113644</targetExecutable>
+        </MakefileSettings>
+        <LocalBuildSettings>
+          <workingDirectory>bin</workingDirectory>
+        </LocalBuildSettings>
+      </ProjectProperties>
+    </Configuration>
+  </Configurations>
+</TITAN_Project_File_Information>
diff --git a/demo/STUN_Demo.cfg b/demo/STUN_Demo.cfg
new file mode 100644
index 0000000..da1aeae
--- /dev/null
+++ b/demo/STUN_Demo.cfg
@@ -0,0 +1,53 @@
+# This section shall contain the values of all parameters that are defined in your TTCN-3 modules.
+
+[MODULE_PARAMETERS]
+
+tsp_STUN_ip_address := "127.0.0.1"
+
+# In this section you can specify the name of the log file and the classes of events
+# you want to log into the file or display on console (standard error).
+
+[LOGGING]
+LogFile := "%e.%h-%t%r.%s"
+FileMask := TTCN_ACTION | TTCN_DEFAULTOP | TTCN_ERROR | TTCN_EXECUTOR | TTCN_PARALLEL | TTCN_TESTCASE | TTCN_PORTEVENT | TTCN_STATISTICS | TTCN_TIMEROP |TTCN_VERDICTOP | TTCN_WARNING | TTCN_USER | TTCN_DEBUG 
+ConsoleMask := TTCN_ACTION | TTCN_ERROR | TTCN_EXECUTOR | TTCN_STATISTICS | TTCN_VERDICTOP | TTCN_WARNING |TTCN_PORTEVENT
+SourceInfoFormat := Single#Stack
+TimeStampFormat := DateTime
+LogEventTypes := Yes
+LogEntityName := Yes
+
+[TESTPORT_PARAMETERS]
+
+# In this section you can specify parameters that are passed to Test Ports.
+[DEFINE]
+
+# In this section you can create macro definitions,
+# that can be used in other configuration file sections except [INCLUDE].
+[INCLUDE]
+
+# To use configuration settings given in other configuration files,
+# the configuration files just need to be listed in this section, with their full or relative pathnames.
+[EXTERNAL_COMMANDS]
+
+# This section can define external commands (shell scripts) to be executed by the ETS
+# whenever a control part or test case is started or terminated.
+#BeginTestCase := ""
+#EndTestCase := ""
+#BeginControlPart := ""
+#EndControlPart := ""
+[EXECUTE]
+# In this section you can specify what parts of your test suite you want to execute.
+STUN_Demo.control
+
+# In this section you can specify groups of hosts. These groups can be used inside the
+# [COMPONENTS] section to restrict the creation of certain PTCs to a given set of hosts.
+[COMPONENTS]
+
+# This section consists of rules restricting the location of created PTCs.
+[MAIN_CONTROLLER]
+# The options herein control the behaviour of MC.
+TCPPort := 9995
+KillTimer := 10.0
+# NumHCs := 1
+
+//saved by GUI
diff --git a/demo/STUN_Demo.ttcn b/demo/STUN_Demo.ttcn
new file mode 100644
index 0000000..ea9ba3e
--- /dev/null
+++ b/demo/STUN_Demo.ttcn
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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:               STUN_Demo.ttcn
+//  Description:        Demo for STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-05-21
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          RFC 3489
+///////////////////////////////////////////////
+module STUN_Demo {
+
+import from STUN_Types all;
+import from STUN_Functions all;
+
+modulepar charstring tsp_STUN_ip_address := "127.0.0.1"
+
+type port STUN_PT message {
+  inout octetstring;
+}
+with 
+{ extension "internal"}
+
+type component STUN_CT {
+  port STUN_PT STUN_PCO
+  var octetstring v_temp_msg;
+  var PDU_STUN v_msg_lasd_decoded, v_msg_to_send;
+}
+
+function f_STUN_sendMsg(PDU_STUN pl_msg, in octetstring pl_password := ''O) runs on STUN_CT {
+  v_temp_msg := f_STUN_Enc(pl_msg,pl_password);
+  log("f_STUN_sendMsg");
+  STUN_PCO.send(v_temp_msg);
+}
+
+function f_STUN_Demo_Orig_behavior() runs on STUN_CT 
+{
+ f_STUN_createMsgHeader(v_msg_to_send, Binding_Request);
+ f_STUN_appendResponseAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+ f_STUN_appendChangeRequest(v_msg_to_send, NO_CHANGE);
+ f_STUN_appendUsername(v_msg_to_send, "demo");
+ //f_STUN_appendMessageIntegrity(v_msg_to_send);
+
+ f_STUN_sendMsg(v_msg_to_send, '1234'O);
+ as_STUN_msgHandler();
+ log("v_msg_lasd_decoded", v_msg_lasd_decoded);
+ 
+ setverdict(pass);
+ self.stop;
+}
+
+function f_STUN_Demo_Term_behavior() runs on STUN_CT 
+{
+	as_STUN_msgHandler();
+	log("v_msg_lasd_decoded", v_msg_lasd_decoded);
+	f_STUN_createMsgHeader(v_msg_to_send, Binding_Response, v_msg_lasd_decoded.header.trans_id);
+	f_STUN_appendMappedAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+	f_STUN_appendSourceAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+	f_STUN_appendChangedAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+	f_STUN_appendMessageIntegrity(v_msg_to_send);
+	f_STUN_sendMsg(v_msg_to_send, '1234'O);
+	setverdict(pass);
+	self.stop;
+}
+
+altstep as_STUN_msgHandler() runs on STUN_CT {
+  
+
+   [] STUN_PCO.receive(octetstring:?) -> value v_temp_msg
+    {
+      if (f_STUN_checkMessageIntegrity(v_temp_msg,'1234'O)) {
+	  		log("Good HMAC");
+			} else {
+	  		log("Bad HMAC");
+			}
+    
+      v_msg_lasd_decoded := f_STUN_Dec(v_temp_msg);
+    }
+}
+
+testcase t_STUN_demo() runs on STUN_CT {
+
+var STUN_CT c_STUN_orig;
+var STUN_CT c_STUN_term;
+  
+  c_STUN_orig := STUN_CT.create;
+  c_STUN_term := STUN_CT.create;
+  
+  connect(c_STUN_orig:STUN_PCO,c_STUN_term:STUN_PCO);
+  
+  c_STUN_term.start(f_STUN_Demo_Term_behavior());
+  c_STUN_orig.start(f_STUN_Demo_Orig_behavior());
+  
+  all component.done
+  disconnect(c_STUN_orig:STUN_PCO,c_STUN_term:STUN_PCO);
+  
+  mtc.kill;
+}
+control {
+  execute(t_STUN_demo());
+}
+}
diff --git a/doc/STUN_CNL113644_PRI.doc b/doc/STUN_CNL113644_PRI.doc
new file mode 100644
index 0000000..a56eb40
--- /dev/null
+++ b/doc/STUN_CNL113644_PRI.doc
Binary files differ
diff --git a/src/STUN_EncDec.cc b/src/STUN_EncDec.cc
new file mode 100644
index 0000000..7387068
--- /dev/null
+++ b/src/STUN_EncDec.cc
@@ -0,0 +1,248 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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:               STUN_EncDec.cc
+//  Description:	Encoder/Decoder functions for STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-09-19
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////
+
+#include "STUN_Types.hh"
+#include <sys/timeb.h>
+#include <arpa/inet.h>
+#include <openssl/hmac.h>
+
+#define MESSAGE_INTEGRITY_LENGTH 24
+#define MESSAGE_INTEGRITY_VALUE_LENGTH 20
+#define MESSAGE_INTEGRITY_TYPE 8
+
+namespace STUN__Types{
+static const unsigned char os_tr_id_octets[] = { 0, 0, 0, 0,
+						 0, 0, 0, 0,
+						 0, 0, 0, 0,
+					         0, 0, 0, 0};
+																								 
+static const unsigned char os_ip_octets[] = {0,0,0,0};
+
+static const unsigned char os_integerity_octets[] = { 0, 0, 0, 0,
+						      0, 0, 0, 0,
+						      0, 0, 0, 0,
+						      0, 0, 0, 0,
+						      0, 0, 0, 0};
+
+static const OCTETSTRING os_dummy_oct(0,os_ip_octets);																								 
+static const OCTETSTRING os_tr_id_oct(16, os_tr_id_octets);
+static const OCTETSTRING os_ip_oct(4, os_ip_octets);
+
+const unsigned char * convertInt2char(unsigned int in)
+{
+   static unsigned char out[4] ;
+   out[0] = (unsigned char)((in & 0xFF000000) >> 24);
+   out[1] = (unsigned char)((in & 0x00FF0000) >> 16);
+   out[2] = (unsigned char)((in & 0x0000FF00) >> 8);
+   out[3] = (unsigned char)(in & 0x000000FF);
+   return out;
+}  
+
+unsigned int convertChar2int(const unsigned char * in)
+{
+   return (((unsigned int)in[0]) << 24) + (((unsigned int)in[1]) << 16) + (((unsigned int)in[2]) << 8) + (((unsigned int)in[3]));
+} 
+
+BOOLEAN f__STUN__checkMessageIntegrity(const OCTETSTRING& pl__msg, const OCTETSTRING& pl__key)
+{
+	int offset2type = pl__msg.lengthof() - MESSAGE_INTEGRITY_LENGTH + 1;
+	
+	if(*((const unsigned char *)pl__msg + offset2type) != MESSAGE_INTEGRITY_TYPE) {
+		TTCN_warning("Last attribute is not Message Integrity");
+		return true;
+	}
+	else {
+	//getMAC stores Messgage-Integerity attribute value from incomming STUN msg
+	int offset2value = pl__msg.lengthof() - MESSAGE_INTEGRITY_VALUE_LENGTH;
+	OCTETSTRING getMAC(MESSAGE_INTEGRITY_VALUE_LENGTH, ((const unsigned char *)pl__msg)+ offset2value);
+	
+	//calcMAC stores the calculated MAC from incoming STUN msg
+	OCTETSTRING calcMAC = f__STUN__HMAC(pl__msg, pl__key);
+	
+	TTCN_Logger::begin_event(TTCN_DEBUG);
+	TTCN_Logger::log_event("\nget MAC \t\t\t\t= ");
+	getMAC.log();
+	TTCN_Logger::log_event("\ncalculated MAC \t= ");
+	calcMAC.log();
+	TTCN_Logger::end_event();
+	if(getMAC == calcMAC)
+  	return true;
+  else
+  	return false;
+  }
+}
+
+OCTETSTRING f__STUN__HMAC(const OCTETSTRING& pl__string, const OCTETSTRING& pl__key) 
+{
+	int size_t = pl__string.lengthof() - MESSAGE_INTEGRITY_LENGTH;
+	
+	if (size_t < 0) {
+		TTCN_warning("Message length too short");
+		return OCTETSTRING(MESSAGE_INTEGRITY_VALUE_LENGTH, os_integerity_octets);;
+	}
+	else {
+	//store pl__string without Message-Integerity attribute
+	OCTETSTRING temp(size_t,(const unsigned char *)pl__string);
+	
+	if (temp.lengthof() % 64 != 0) {
+		//padding temp with zerros up to multiple of 64
+		int paddingSize = 64 - (temp.lengthof() % 64);
+		unsigned char padding[paddingSize];
+		for (int i = 0; i < paddingSize; i++) {
+			padding[i] = 0;
+		}
+		temp+=OCTETSTRING(paddingSize, padding);
+	}
+	
+	unsigned char md[MESSAGE_INTEGRITY_VALUE_LENGTH];
+  unsigned int md_len;
+  TTCN_Logger::begin_event(TTCN_DEBUG);
+  TTCN_Logger::log_event("Calculating MAC (user initiated from TTCN-3):\nkey = ");
+  pl__key.log();
+  TTCN_Logger::log_event("\nInput = ");
+  temp.log();
+  HMAC(EVP_sha1(), (const unsigned char*)pl__key, pl__key.lengthof(), (const unsigned char *)temp, temp.lengthof(), md, &md_len);
+  TTCN_Logger::log_event("\nOutput = %s", md);
+  TTCN_Logger::end_event();
+  return OCTETSTRING(MESSAGE_INTEGRITY_VALUE_LENGTH, md);
+  }
+}
+
+OCTETSTRING f__STUN__IP2oct(const CHARSTRING& pl__ip) {
+
+int temp;
+
+temp = ntohl(inet_addr(pl__ip));
+if (temp == -1) {
+	TTCN_warning("Wrong IP address added, f_STUN_IP2oct() returns with \'00000000\'O");
+	return os_ip_oct;
+	} else {
+		return OCTETSTRING(4,convertInt2char(temp));
+	}
+}
+
+CHARSTRING f__STUN__oct2IP(const OCTETSTRING& pl__ip) {
+
+	struct in_addr temp;
+
+	temp.s_addr = htonl(convertChar2int((const unsigned char *)pl__ip));
+	
+	return inet_ntoa(temp);
+}
+
+OCTETSTRING f__STUN__genTrasId()
+{
+  OCTETSTRING ret = os_tr_id_oct;
+  timeb precise;                        // requires <sys/timeb.h>
+    
+  if ( ftime(&precise) != -1 ) {
+    srand48(precise.time + precise.millitm);
+    ret = int2oct(lrand48(),4) + int2oct(lrand48(),4) + int2oct(lrand48(),4) + int2oct(lrand48(),4);
+  }
+  else TTCN_warning("f_STUN_genTrasId() returns with \'00000000000000000000000000000000\'O");
+  return ret;
+}
+
+static const unsigned char stun_magicCookie_octets[] = { 33, 18, 164, 66 }; // '2112A442'O
+
+OCTETSTRING f__STUN__genTrasId__withMagicCookie()
+{
+  OCTETSTRING ret = os_tr_id_oct;
+  timeb precise;                        // requires <sys/timeb.h>
+    
+  if ( ftime(&precise) != -1 ) {
+    srand48(precise.time + precise.millitm);
+    ret = OCTETSTRING(4, stun_magicCookie_octets) + int2oct(lrand48(),4) + int2oct(lrand48(),4) + int2oct(lrand48(),4);
+  }
+  else TTCN_warning("f_STUN_genTrasId() returns with \'00000000000000000000000000000000\'O");
+  return ret;
+}
+
+INTEGER f__STUN__getMessageLength(const OCTETSTRING& stream)
+{
+int stream_length = stream.lengthof();
+int pdu_length = 0;
+unsigned char * stream_ptr = (unsigned char *)(const unsigned char *)stream;
+if (stream_length >= 20){
+stream_ptr = stream_ptr + 2;
+pdu_length = oct2int(OCTETSTRING(2,(const unsigned char *)stream_ptr));
+if ((pdu_length + 20)<= stream_length){
+pdu_length = pdu_length + 20;
+return pdu_length;}
+else {return 0;}
+}
+else {return 0;}
+}
+
+OCTETSTRING f__STUN__Enc(const PDU__STUN& pl__pdu, const OCTETSTRING& pl__password = os_dummy_oct)
+{
+  PDU__STUN* par=NULL;
+  
+  if (pl__pdu.header().trans__id() == os_tr_id_oct){
+    par = new PDU__STUN(pl__pdu);
+    par->header().trans__id() = f__STUN__genTrasId();
+  }
+    
+  TTCN_Buffer buf;
+  TTCN_EncDec::error_type_t err;
+  buf.clear();
+  TTCN_EncDec::clear_error();
+  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
+  
+  if(par)
+    par->encode(PDU__STUN_descr_, buf, TTCN_EncDec::CT_RAW);
+  else 
+    pl__pdu.encode(PDU__STUN_descr_, buf, TTCN_EncDec::CT_RAW);
+  err = TTCN_EncDec::get_last_error_type();
+  if(err != TTCN_EncDec::ET_NONE)
+    TTCN_warning("Encoding error: %s\n", TTCN_EncDec::get_error_str());
+  if (par)
+    delete par;
+  
+  if(pl__password.lengthof() != 0) {
+  	int offset2type = buf.get_len() - MESSAGE_INTEGRITY_LENGTH + 1;
+	//check  the last attribute
+	if(*(buf.get_data() + offset2type) != MESSAGE_INTEGRITY_TYPE) {
+	  TTCN_warning("Last attribute is not Message Integrity");
+	} else {
+	  OCTETSTRING temp(MESSAGE_INTEGRITY_VALUE_LENGTH, os_integerity_octets);
+	  temp = f__STUN__HMAC(OCTETSTRING(buf.get_len(), buf.get_data()),pl__password);
+ 	  //replace the dunny Message-Integerity value with calculated MAC value
+ 	  buf.set_pos(buf.get_len() - MESSAGE_INTEGRITY_VALUE_LENGTH);
+ 	  buf.cut_end();
+ 	  buf.put_os(temp);
+ 	}
+  }
+  return OCTETSTRING(buf.get_len(), buf.get_data());
+}
+
+PDU__STUN f__STUN__Dec(const OCTETSTRING& pl__oct) 
+{
+  PDU__STUN pdu;
+  TTCN_Buffer buf;
+  TTCN_EncDec::error_type_t err;
+  TTCN_EncDec::clear_error();
+  buf.clear();
+  buf.put_os(pl__oct);
+  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
+  pdu.decode(PDU__STUN_descr_, buf, TTCN_EncDec::CT_RAW);
+  err = TTCN_EncDec::get_last_error_type();
+  if(err != TTCN_EncDec::ET_NONE)
+    TTCN_warning("Decoding error: %s\n", TTCN_EncDec::get_error_str());
+  return pdu;
+}
+} 
+TTCN_Module STUN_EncDec("STUN_EncDec", __DATE__, __TIME__);
diff --git a/src/STUN_Functions.ttcn b/src/STUN_Functions.ttcn
new file mode 100644
index 0000000..c2fc825
--- /dev/null
+++ b/src/STUN_Functions.ttcn
@@ -0,0 +1,182 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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:               STUN_Functions.ttcn
+//  Description:        Functions for STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-05-21
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          RFC 3489
+///////////////////////////////////////////////
+module STUN_Functions {
+
+import from STUN_Types all;
+
+function f_STUN_appendMappedAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := MAPPED_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Mapped_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendResponseAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := RESPONSE_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Response_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendChangedAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := CHANGED_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Changed_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendSourceAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := SOURCE_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Source_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendReflectedForm(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := REFLECTED_FROM,
+		attr_length := 0,
+		attr_data := {
+			attr_Reflected_From := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendChangeRequest(
+inout PDU_STUN pl_msg, 
+in Stun_Change_Request pl_request) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := CHANGE_REQUEST,
+		attr_length := 0,
+		attr_data := {
+			attr_Change_Request := pl_request
+				}
+	}  
+}
+
+function f_STUN_appendUsername(
+inout PDU_STUN pl_msg, 
+in Stun_Username pl_username) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := USERNAME,
+		attr_length := 0,
+		attr_data := {
+			attr_Username := pl_username
+				}
+	}  
+}
+
+function f_STUN_appendPassword(
+inout PDU_STUN pl_msg, 
+in Stun_Password pl_password) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := PASSWORD,
+		attr_length := 0,
+		attr_data := {
+			attr_Password := pl_password
+				}
+	}  
+}
+
+function f_STUN_appendMessageIntegrity(
+inout PDU_STUN pl_msg, 
+in Stun_Message_Integrity pl_integrity := '0000000000000000000000000000000000000000'O) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := MESSAGE_INTEGRITY,
+		attr_length := 0,
+		attr_data := {
+			attr_Message_Integrity := pl_integrity
+				}
+	}  
+}
+
+function f_STUN_appendErrorCode(
+inout PDU_STUN pl_msg, 
+in Stun_Error_Code pl_error) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := ERROR_CODE,
+		attr_length := 0,
+		attr_data := {
+			attr_Error_Code := pl_error
+				}
+	}  
+}
+
+function f_STUN_appendUnkonwnAttrs(
+inout PDU_STUN pl_msg, 
+in Stun_Unknown_Attributes pl_unknown) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := UNKNOWN_ATTRIBUTES,
+		attr_length := 0,
+		attr_data := {
+			attr_Unknown_Attributes := pl_unknown
+				}
+	}  
+}
+function f_STUN_createMsgHeader(
+inout PDU_STUN pl_msg, 
+in STUN_Msg_Type pl_msgType,
+in OCT16 pl_transId := '00000000000000000000000000000000'O)
+{
+  if (pl_transId == '00000000000000000000000000000000'O) {
+    pl_transId := f_STUN_genTrasId();
+  }
+
+  pl_msg := {
+    header := {
+      msg_type := pl_msgType,
+      msg_length := 0,
+      trans_id := pl_transId
+    },
+    attr_list := {}
+  }
+  
+}
+}
diff --git a/src/STUN_Types.ttcn b/src/STUN_Types.ttcn
new file mode 100644
index 0000000..c32f17f
--- /dev/null
+++ b/src/STUN_Types.ttcn
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:               STUN_Types.ttcn
+//  Description:        STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-09-16
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          RFC 3489
+///////////////////////////////////////////////
+module STUN_Types {
+
+external function f_STUN_Enc(in PDU_STUN pl_pdu, in octetstring pl_password := ''O) return octetstring;
+external function f_STUN_Dec(in octetstring pl_oct) return PDU_STUN;
+external function f_STUN_genTrasId() return octetstring;
+external function f_STUN_genTrasId_withMagicCookie() return octetstring;
+external function f_STUN_IP2oct(in charstring pl_ip) return octetstring;
+external function f_STUN_oct2IP(in octetstring pl_ip) return charstring;
+external function f_STUN_HMAC(in octetstring pl_string, in octetstring pl_key) return octetstring;
+external function f_STUN_checkMessageIntegrity(in octetstring pl_msg, in octetstring pl_key) return boolean;
+external function f_STUN_getMessageLength(in octetstring stream) return integer;
+
+// STUN: RFC3489
+type octetstring OCT4 length(4) with {
+variant "FIELDLENGTH(4)"
+}
+
+type octetstring OCT1 length(1) with {
+variant "FIELDLENGTH(1)"
+}
+
+type octetstring OCT2 length(2) with {
+variant "FIELDLENGTH(2)"
+}
+
+type octetstring OCT16 length(16) with {
+variant "FIELDLENGTH(16)"
+}
+
+type octetstring OCT20 length(20) with {
+variant "FIELDLENGTH(20)"
+}
+
+type integer UINT16 (0..65535) with {
+variant "FIELDLENGTH(16)"
+variant "BYTEORDER(last)"
+}
+
+type OCT20 Attr_Oct160
+
+type OCT4 Attr_Oct32
+
+type OCT1 Attr_Oct8
+
+type OCT2 Attr_Oct16
+
+type enumerated STUN_Family 
+{
+  IP4 (1)
+} with {
+  variant "FIELDLENGTH(8)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+//
+// 11.2 STUN Message Attributes
+//
+
+// RFC 3489 11.2.1
+// Attr: MAPPED-ADDRESS (1)
+// RFC 3489 11.2.2
+// Attr: RESPONSE-ADDRESS (2)
+// RFC 3489 11.2.3
+// Attr: CHANGED-ADDRESS (3)
+// RFC 3489 11.2.5
+// Attr: SOURCE-ADDRESS (5)
+// RFC 3489 11.2.11
+// Attr: REFLECTED-FROM (11)
+type record Stun_Address 
+{
+  STUN_Family   family,
+  UINT16	port_id,
+  Attr_Oct32	ip_address
+} with { variant (family) "FIELDLENGTH(16)"
+  	 variant (family) "ALIGN(right)"
+}
+
+
+// RFC 3489 11.2.4
+// Attr: CHANGE-REQUEST (4)
+type enumerated Stun_Change_Request 
+{
+  NO_CHANGE   (0),
+  CHANGE_PORT (2),
+  CHANGE_IP   (4),
+  CHANGE_BOTH (6)
+} with {
+  variant "FIELDLENGTH(32)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+// RFC 3489 11.2.6
+// Attr: USERNAME (6)
+type charstring Stun_Username 
+with { variant "PADDING(dword32)"}
+
+// RFC 3489 11.2.7
+// Attr: PASSWORD (7)
+type octetstring Stun_Password 
+with { variant "PADDING(dword32)"}
+
+// RFC 3489 11.2.8
+// Attr: MESSAGE-INTEGRITY (8)
+type Attr_Oct160 Stun_Message_Integrity
+
+// RFC 3489bis-13 14.7
+// Attr: REALM (20)
+type charstring Stun_Realm
+with { variant "PADDING(dword32)"}
+
+// RFC 3489bis-13 14.8
+// Attr: NONCE (21)
+type octetstring Stun_Nonce
+with { variant "PADDING(dword32)"}
+
+type enumerated Stun_Error_Code_Type
+{
+  BAD_REQUEST 		  (1024),
+  UNAUTHORIZED		  (1025),
+  UNKNOWN_ATTRIBUTE	  (1044),
+  STALE_CREDENTIALS	  (1054),
+  INTEGRITY_CHECK_FAILURE (1055),
+  MISSING_USERNAME	  (1056),
+  USE_TLS		  (1057),
+  SERVER_ERROR		  (1280),
+  GLOBAL_FAILURE	  (1536)
+} with {
+  variant "FIELDLENGTH(32)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+// RFC 3489 11.2.9
+// Attr: ERROR-CODE (9)
+type record Stun_Error_Code {
+  Stun_Error_Code_Type	error_code_tpye,
+  charstring		reason_phrase
+}
+with { variant (reason_phrase) "PADDING(dword32)"}
+
+type Attr_Oct16 STUN_Unknown_Attr_Data;
+
+// RFC 3489 11.2.10
+// Attr: UNKNOWN-ATTRIBUTES (10)
+type set of STUN_Unknown_Attr_Data Stun_Unknown_Attributes
+with { variant "PADDING(dword32)"}
+
+type union STUN_Attr_data
+{
+  Stun_Address 			attr_Mapped_Address,
+  Stun_Address			attr_Response_Address,
+  Stun_Address			attr_Changed_Address,
+  Stun_Change_Request		attr_Change_Request,
+  Stun_Address			attr_Source_Address,
+  Stun_Username			attr_Username,
+  Stun_Password			attr_Password,
+  Stun_Message_Integrity	attr_Message_Integrity,
+  Stun_Error_Code		attr_Error_Code,
+  Stun_Unknown_Attributes	attr_Unknown_Attributes,
+  Stun_Address			attr_Reflected_From,
+  Stun_Address                  attr_Xor_Mapped_Address,
+  Stun_Realm                    attr_Realm,
+  Stun_Nonce                    attr_Nonce
+}
+
+type enumerated STUN_Attr_type {
+  MAPPED_ADDRESS      (1),
+  RESPONSE_ADDRESS    (2),
+  CHANGE_REQUEST      (3),
+  SOURCE_ADDRESS      (4),
+  CHANGED_ADDRESS     (5),
+  USERNAME            (6),
+  PASSWORD            (7),
+  MESSAGE_INTEGRITY   (8),
+  ERROR_CODE          (9),
+  UNKNOWN_ATTRIBUTES (10),
+  REFLECTED_FROM     (11),
+  REALM              (20), //RFC 3489bis-13
+  NONCE              (21), //RFC 3489bis-13
+  XOR_MAPPED_ADDRESS (32)  //RFC 3489bis-13
+} with {
+  variant "FIELDLENGTH(16)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+type record STUN_Attr {
+  STUN_Attr_type	attr_type,
+  UINT16		attr_length,
+  STUN_Attr_data	attr_data 
+} with {
+  variant "PADDING(dword32)"
+  variant (attr_length) "LENGTHTO(attr_data)"
+  variant (attr_data) "CROSSTAG(
+    attr_Mapped_Address, 	attr_type = MAPPED_ADDRESS;
+    attr_Response_Address,	attr_type = RESPONSE_ADDRESS;
+    attr_Changed_Address, 	attr_type = CHANGED_ADDRESS;
+    attr_Change_Request,	attr_type = CHANGE_REQUEST;
+    attr_Source_Address,	attr_type = SOURCE_ADDRESS;
+    attr_Username,		attr_type = USERNAME;
+    attr_Password,		attr_type = PASSWORD;
+    attr_Message_Integrity,	attr_type = MESSAGE_INTEGRITY;
+    attr_Error_Code,		attr_type = ERROR_CODE;
+    attr_Unknown_Attributes,	attr_type = UNKNOWN_ATTRIBUTES;
+    attr_Reflected_From,        attr_type = REFLECTED_FROM
+  )"
+}
+
+type set of STUN_Attr Attr_List
+
+type enumerated STUN_Msg_Type {
+ Binding_Request                (1),
+ Binding_Response             (257),
+ Binding_Error_Response       (273),
+ Shared_Secret_Request          (2),
+ Shared_Secret_Response       (258),
+ Shared_Secret_Error_Response (274)
+} with {
+  variant "FIELDLENGTH(16)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+type record STUN_Header {
+  STUN_Msg_Type   msg_type,
+  UINT16	  msg_length,
+  OCT16		  trans_id
+}
+
+type record PDU_STUN {
+ 	 STUN_Header 	header,
+ 	 Attr_List	attr_list
+} with {
+  variant "PADDING(dword32)"
+  variant (header) "LENGTHTO(attr_list)"
+  variant (header) "LENGTHINDEX(msg_length)"
+}
+ 
+} with { encode "RAW" } // End module
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..48bf537
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,154 @@
+# This Makefile was generated by the Makefile Generator
+# of the TTCN-3 Test Executor version 1.8.pre0 build 3
+# for Timea Moder (etmemod@ehubuux110) on Tue May 19 10:01:38 2009
+
+# Copyright Ericsson Telecom AB 2000-2018
+
+# The following make commands are available:
+# - make, make all     Builds the executable test suite.
+# - make archive       Archives all source files.
+# - make check         Checks the semantics of TTCN-3 and ASN.1 modules.
+# - make clean         Removes all generated files.
+# - make compile       Translates TTCN-3 and ASN.1 modules to C++.
+# - make dep           Creates/updates dependency list.
+# - make objects       Builds the object files without linking the executable.
+# - make tags          Creates/updates tags file using ctags.
+
+#
+# Set these variables...
+#
+
+# The path of your TTCN-3 Test Executor installation:
+# Uncomment this line to override the environment variable.
+# TTCN3_DIR =
+
+# Your platform: (SOLARIS, SOLARIS8, LINUX, FREEBSD or WIN32)
+PLATFORM = SOLARIS8
+
+# Your C++ compiler:
+CXX = g++
+
+# Flags for the C++ preprocessor (and makedepend as well):
+CPPFLAGS = -D$(PLATFORM) -I$(OPENSSL_DIR)/include -I$(TTCN3_DIR)/include -DNO_IPV6
+
+# Flags for the C++ compiler:
+CXXFLAGS = -Wall -g
+
+# Flags for the linker:
+LDFLAGS = -g 
+
+# Flags for the TTCN-3 and ASN.1 compiler:
+COMPILER_FLAGS = -L
+
+# Execution mode: (either ttcn3 or ttcn3-parallel)
+TTCN3_LIB = ttcn3-parallel
+
+# The path of your OpenSSL installation:
+# If you do not have your own one, leave it unchanged.
+OPENSSL_DIR = /mnt/TTCN/Tools/openssl-0.9.8e
+
+# The path of your libxml2 installation:
+# If you do not have your own one, leave it unchanged.
+XMLDIR = $(TTCN3_DIR)
+
+# Directory to store the archived source files:
+# Note: you can set any directory except ./archive
+ARCHIVE_DIR = backup
+
+#
+# You may change these variables. Add your files if necessary...
+#
+
+# TTCN-3 modules of this project:
+TTCN3_MODULES = STUN_Demo.ttcn STUN_Functions.ttcn STUN_Types.ttcn
+
+# ASN.1 modules of this project:
+ASN1_MODULES =
+
+# C++ source & header files generated from the TTCN-3 & ASN.1 modules of
+# this project:
+GENERATED_SOURCES = STUN_Demo.cc STUN_Functions.cc STUN_Types.cc
+GENERATED_HEADERS = STUN_Demo.hh STUN_Functions.hh STUN_Types.hh
+
+# C/C++ Source & header files of Test Ports, external functions and
+# other modules:
+USER_SOURCES = STUN_EncDec.cc
+USER_HEADERS =
+
+# Object files of this project that are needed for the executable test suite:
+OBJECTS = STUN_Demo.o STUN_Functions.o STUN_Types.o STUN_EncDec.o
+
+# Other files of the project (Makefile, configuration files, etc.)
+# that will be added to the archived source files:
+OTHER_FILES = STUN_Demo.cfg Makefile
+
+# The name of the executable test suite:
+TARGET = STUN_Demo
+
+#
+# Do not modify these unless you know what you are doing...
+# Platform specific additional libraries:
+#
+SOLARIS_LIBS = -lsocket -lnsl -lresolv -lxnet -lxml2 
+SOLARIS8_LIBS = -lsocket -lnsl -lresolv -lxnet -lxml2 
+LINUX_LIBS = -lxml2 
+FREEBSD_LIBS = -lxml2 
+WIN32_LIBS = -lxml2 
+
+#
+# Rules for building the executable...
+#
+
+all: $(TARGET) ;
+
+objects: $(OBJECTS) ;
+
+$(TARGET): $(OBJECTS)
+	$(CXX) $(LDFLAGS) -o $@ $(OBJECTS) \
+	-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \
+	-L$(OPENSSL_DIR)/lib -lcrypto \
+	-L$(XMLDIR)/lib $($(PLATFORM)_LIBS)
+
+.cc.o .c.o:
+	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
+
+$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile
+	@if [ ! -f $@ ]; then rm -f compile; $(MAKE) compile; fi
+
+check: $(TTCN3_MODULES) $(ASN1_MODULES)
+	$(TTCN3_DIR)/bin/compiler -s $(COMPILER_FLAGS) \
+	$(TTCN3_MODULES) $(PREPROCESSED_TTCN3_MODULES) $(ASN1_MODULES)
+
+compile: $(TTCN3_MODULES) $(ASN1_MODULES)
+	$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) \
+	$(TTCN3_MODULES) $(ASN1_MODULES) - $?
+	touch $@
+
+browserdata.dat: $(TTCN3_MODULES) $(ASN1_MODULES)
+	$(TTCN3_DIR)/bin/compiler -B -s $(COMPILER_FLAGS) \
+	$(TTCN3_MODULES) $(ASN1_MODULES)
+
+tags: $(TTCN3_MODULES) $(ASN1_MODULES) \
+$(USER_HEADERS) $(USER_SOURCES)
+	$(TTCN3_DIR)/bin/ctags_ttcn3 --line-directives=yes \
+	$(TTCN3_MODULES) $(ASN1_MODULES) \
+	$(USER_HEADERS) $(USER_SOURCES)
+
+clean:
+	-rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+	$(GENERATED_SOURCES) compile \
+	browserdata.dat tags *.log
+
+dep: $(GENERATED_SOURCES) $(USER_SOURCES)
+	makedepend $(CPPFLAGS) $(GENERATED_SOURCES) $(USER_SOURCES)
+
+archive:
+	mkdir -p $(ARCHIVE_DIR)
+	tar -cvhf - $(TTCN3_MODULES) $(ASN1_MODULES) \
+	$(USER_HEADERS) $(USER_SOURCES) $(OTHER_FILES) \
+	| gzip >$(ARCHIVE_DIR)/`basename $(TARGET) .exe`-`date '+%y%m%d-%H%M'`.tgz
+
+#
+# Add your rules here if necessary...
+#
+
diff --git a/test/Makefile_patch.sh b/test/Makefile_patch.sh
new file mode 100644
index 0000000..8bbd39c
--- /dev/null
+++ b/test/Makefile_patch.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+sed -e '
+s/OPENSSL_DIR = $(TTCN3_DIR)/#OPENSSL_DIR = $(TTCN3_DIR)/g
+s/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include -I$(OPENSSL_DIR)\/include/g
+' <$1 >$2
diff --git a/test/STUN_Demo.cfg b/test/STUN_Demo.cfg
new file mode 100644
index 0000000..da1aeae
--- /dev/null
+++ b/test/STUN_Demo.cfg
@@ -0,0 +1,53 @@
+# This section shall contain the values of all parameters that are defined in your TTCN-3 modules.
+
+[MODULE_PARAMETERS]
+
+tsp_STUN_ip_address := "127.0.0.1"
+
+# In this section you can specify the name of the log file and the classes of events
+# you want to log into the file or display on console (standard error).
+
+[LOGGING]
+LogFile := "%e.%h-%t%r.%s"
+FileMask := TTCN_ACTION | TTCN_DEFAULTOP | TTCN_ERROR | TTCN_EXECUTOR | TTCN_PARALLEL | TTCN_TESTCASE | TTCN_PORTEVENT | TTCN_STATISTICS | TTCN_TIMEROP |TTCN_VERDICTOP | TTCN_WARNING | TTCN_USER | TTCN_DEBUG 
+ConsoleMask := TTCN_ACTION | TTCN_ERROR | TTCN_EXECUTOR | TTCN_STATISTICS | TTCN_VERDICTOP | TTCN_WARNING |TTCN_PORTEVENT
+SourceInfoFormat := Single#Stack
+TimeStampFormat := DateTime
+LogEventTypes := Yes
+LogEntityName := Yes
+
+[TESTPORT_PARAMETERS]
+
+# In this section you can specify parameters that are passed to Test Ports.
+[DEFINE]
+
+# In this section you can create macro definitions,
+# that can be used in other configuration file sections except [INCLUDE].
+[INCLUDE]
+
+# To use configuration settings given in other configuration files,
+# the configuration files just need to be listed in this section, with their full or relative pathnames.
+[EXTERNAL_COMMANDS]
+
+# This section can define external commands (shell scripts) to be executed by the ETS
+# whenever a control part or test case is started or terminated.
+#BeginTestCase := ""
+#EndTestCase := ""
+#BeginControlPart := ""
+#EndControlPart := ""
+[EXECUTE]
+# In this section you can specify what parts of your test suite you want to execute.
+STUN_Demo.control
+
+# In this section you can specify groups of hosts. These groups can be used inside the
+# [COMPONENTS] section to restrict the creation of certain PTCs to a given set of hosts.
+[COMPONENTS]
+
+# This section consists of rules restricting the location of created PTCs.
+[MAIN_CONTROLLER]
+# The options herein control the behaviour of MC.
+TCPPort := 9995
+KillTimer := 10.0
+# NumHCs := 1
+
+//saved by GUI
diff --git a/test/STUN_Demo.ttcn b/test/STUN_Demo.ttcn
new file mode 100644
index 0000000..ea9ba3e
--- /dev/null
+++ b/test/STUN_Demo.ttcn
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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:               STUN_Demo.ttcn
+//  Description:        Demo for STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-05-21
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          RFC 3489
+///////////////////////////////////////////////
+module STUN_Demo {
+
+import from STUN_Types all;
+import from STUN_Functions all;
+
+modulepar charstring tsp_STUN_ip_address := "127.0.0.1"
+
+type port STUN_PT message {
+  inout octetstring;
+}
+with 
+{ extension "internal"}
+
+type component STUN_CT {
+  port STUN_PT STUN_PCO
+  var octetstring v_temp_msg;
+  var PDU_STUN v_msg_lasd_decoded, v_msg_to_send;
+}
+
+function f_STUN_sendMsg(PDU_STUN pl_msg, in octetstring pl_password := ''O) runs on STUN_CT {
+  v_temp_msg := f_STUN_Enc(pl_msg,pl_password);
+  log("f_STUN_sendMsg");
+  STUN_PCO.send(v_temp_msg);
+}
+
+function f_STUN_Demo_Orig_behavior() runs on STUN_CT 
+{
+ f_STUN_createMsgHeader(v_msg_to_send, Binding_Request);
+ f_STUN_appendResponseAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+ f_STUN_appendChangeRequest(v_msg_to_send, NO_CHANGE);
+ f_STUN_appendUsername(v_msg_to_send, "demo");
+ //f_STUN_appendMessageIntegrity(v_msg_to_send);
+
+ f_STUN_sendMsg(v_msg_to_send, '1234'O);
+ as_STUN_msgHandler();
+ log("v_msg_lasd_decoded", v_msg_lasd_decoded);
+ 
+ setverdict(pass);
+ self.stop;
+}
+
+function f_STUN_Demo_Term_behavior() runs on STUN_CT 
+{
+	as_STUN_msgHandler();
+	log("v_msg_lasd_decoded", v_msg_lasd_decoded);
+	f_STUN_createMsgHeader(v_msg_to_send, Binding_Response, v_msg_lasd_decoded.header.trans_id);
+	f_STUN_appendMappedAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+	f_STUN_appendSourceAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+	f_STUN_appendChangedAddress(v_msg_to_send, {IP4, 1234,f_STUN_IP2oct("127.0.0.1")});
+	f_STUN_appendMessageIntegrity(v_msg_to_send);
+	f_STUN_sendMsg(v_msg_to_send, '1234'O);
+	setverdict(pass);
+	self.stop;
+}
+
+altstep as_STUN_msgHandler() runs on STUN_CT {
+  
+
+   [] STUN_PCO.receive(octetstring:?) -> value v_temp_msg
+    {
+      if (f_STUN_checkMessageIntegrity(v_temp_msg,'1234'O)) {
+	  		log("Good HMAC");
+			} else {
+	  		log("Bad HMAC");
+			}
+    
+      v_msg_lasd_decoded := f_STUN_Dec(v_temp_msg);
+    }
+}
+
+testcase t_STUN_demo() runs on STUN_CT {
+
+var STUN_CT c_STUN_orig;
+var STUN_CT c_STUN_term;
+  
+  c_STUN_orig := STUN_CT.create;
+  c_STUN_term := STUN_CT.create;
+  
+  connect(c_STUN_orig:STUN_PCO,c_STUN_term:STUN_PCO);
+  
+  c_STUN_term.start(f_STUN_Demo_Term_behavior());
+  c_STUN_orig.start(f_STUN_Demo_Orig_behavior());
+  
+  all component.done
+  disconnect(c_STUN_orig:STUN_PCO,c_STUN_term:STUN_PCO);
+  
+  mtc.kill;
+}
+control {
+  execute(t_STUN_demo());
+}
+}
diff --git a/test/STUN_EncDec.cc b/test/STUN_EncDec.cc
new file mode 100644
index 0000000..7387068
--- /dev/null
+++ b/test/STUN_EncDec.cc
@@ -0,0 +1,248 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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:               STUN_EncDec.cc
+//  Description:	Encoder/Decoder functions for STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-09-19
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////
+
+#include "STUN_Types.hh"
+#include <sys/timeb.h>
+#include <arpa/inet.h>
+#include <openssl/hmac.h>
+
+#define MESSAGE_INTEGRITY_LENGTH 24
+#define MESSAGE_INTEGRITY_VALUE_LENGTH 20
+#define MESSAGE_INTEGRITY_TYPE 8
+
+namespace STUN__Types{
+static const unsigned char os_tr_id_octets[] = { 0, 0, 0, 0,
+						 0, 0, 0, 0,
+						 0, 0, 0, 0,
+					         0, 0, 0, 0};
+																								 
+static const unsigned char os_ip_octets[] = {0,0,0,0};
+
+static const unsigned char os_integerity_octets[] = { 0, 0, 0, 0,
+						      0, 0, 0, 0,
+						      0, 0, 0, 0,
+						      0, 0, 0, 0,
+						      0, 0, 0, 0};
+
+static const OCTETSTRING os_dummy_oct(0,os_ip_octets);																								 
+static const OCTETSTRING os_tr_id_oct(16, os_tr_id_octets);
+static const OCTETSTRING os_ip_oct(4, os_ip_octets);
+
+const unsigned char * convertInt2char(unsigned int in)
+{
+   static unsigned char out[4] ;
+   out[0] = (unsigned char)((in & 0xFF000000) >> 24);
+   out[1] = (unsigned char)((in & 0x00FF0000) >> 16);
+   out[2] = (unsigned char)((in & 0x0000FF00) >> 8);
+   out[3] = (unsigned char)(in & 0x000000FF);
+   return out;
+}  
+
+unsigned int convertChar2int(const unsigned char * in)
+{
+   return (((unsigned int)in[0]) << 24) + (((unsigned int)in[1]) << 16) + (((unsigned int)in[2]) << 8) + (((unsigned int)in[3]));
+} 
+
+BOOLEAN f__STUN__checkMessageIntegrity(const OCTETSTRING& pl__msg, const OCTETSTRING& pl__key)
+{
+	int offset2type = pl__msg.lengthof() - MESSAGE_INTEGRITY_LENGTH + 1;
+	
+	if(*((const unsigned char *)pl__msg + offset2type) != MESSAGE_INTEGRITY_TYPE) {
+		TTCN_warning("Last attribute is not Message Integrity");
+		return true;
+	}
+	else {
+	//getMAC stores Messgage-Integerity attribute value from incomming STUN msg
+	int offset2value = pl__msg.lengthof() - MESSAGE_INTEGRITY_VALUE_LENGTH;
+	OCTETSTRING getMAC(MESSAGE_INTEGRITY_VALUE_LENGTH, ((const unsigned char *)pl__msg)+ offset2value);
+	
+	//calcMAC stores the calculated MAC from incoming STUN msg
+	OCTETSTRING calcMAC = f__STUN__HMAC(pl__msg, pl__key);
+	
+	TTCN_Logger::begin_event(TTCN_DEBUG);
+	TTCN_Logger::log_event("\nget MAC \t\t\t\t= ");
+	getMAC.log();
+	TTCN_Logger::log_event("\ncalculated MAC \t= ");
+	calcMAC.log();
+	TTCN_Logger::end_event();
+	if(getMAC == calcMAC)
+  	return true;
+  else
+  	return false;
+  }
+}
+
+OCTETSTRING f__STUN__HMAC(const OCTETSTRING& pl__string, const OCTETSTRING& pl__key) 
+{
+	int size_t = pl__string.lengthof() - MESSAGE_INTEGRITY_LENGTH;
+	
+	if (size_t < 0) {
+		TTCN_warning("Message length too short");
+		return OCTETSTRING(MESSAGE_INTEGRITY_VALUE_LENGTH, os_integerity_octets);;
+	}
+	else {
+	//store pl__string without Message-Integerity attribute
+	OCTETSTRING temp(size_t,(const unsigned char *)pl__string);
+	
+	if (temp.lengthof() % 64 != 0) {
+		//padding temp with zerros up to multiple of 64
+		int paddingSize = 64 - (temp.lengthof() % 64);
+		unsigned char padding[paddingSize];
+		for (int i = 0; i < paddingSize; i++) {
+			padding[i] = 0;
+		}
+		temp+=OCTETSTRING(paddingSize, padding);
+	}
+	
+	unsigned char md[MESSAGE_INTEGRITY_VALUE_LENGTH];
+  unsigned int md_len;
+  TTCN_Logger::begin_event(TTCN_DEBUG);
+  TTCN_Logger::log_event("Calculating MAC (user initiated from TTCN-3):\nkey = ");
+  pl__key.log();
+  TTCN_Logger::log_event("\nInput = ");
+  temp.log();
+  HMAC(EVP_sha1(), (const unsigned char*)pl__key, pl__key.lengthof(), (const unsigned char *)temp, temp.lengthof(), md, &md_len);
+  TTCN_Logger::log_event("\nOutput = %s", md);
+  TTCN_Logger::end_event();
+  return OCTETSTRING(MESSAGE_INTEGRITY_VALUE_LENGTH, md);
+  }
+}
+
+OCTETSTRING f__STUN__IP2oct(const CHARSTRING& pl__ip) {
+
+int temp;
+
+temp = ntohl(inet_addr(pl__ip));
+if (temp == -1) {
+	TTCN_warning("Wrong IP address added, f_STUN_IP2oct() returns with \'00000000\'O");
+	return os_ip_oct;
+	} else {
+		return OCTETSTRING(4,convertInt2char(temp));
+	}
+}
+
+CHARSTRING f__STUN__oct2IP(const OCTETSTRING& pl__ip) {
+
+	struct in_addr temp;
+
+	temp.s_addr = htonl(convertChar2int((const unsigned char *)pl__ip));
+	
+	return inet_ntoa(temp);
+}
+
+OCTETSTRING f__STUN__genTrasId()
+{
+  OCTETSTRING ret = os_tr_id_oct;
+  timeb precise;                        // requires <sys/timeb.h>
+    
+  if ( ftime(&precise) != -1 ) {
+    srand48(precise.time + precise.millitm);
+    ret = int2oct(lrand48(),4) + int2oct(lrand48(),4) + int2oct(lrand48(),4) + int2oct(lrand48(),4);
+  }
+  else TTCN_warning("f_STUN_genTrasId() returns with \'00000000000000000000000000000000\'O");
+  return ret;
+}
+
+static const unsigned char stun_magicCookie_octets[] = { 33, 18, 164, 66 }; // '2112A442'O
+
+OCTETSTRING f__STUN__genTrasId__withMagicCookie()
+{
+  OCTETSTRING ret = os_tr_id_oct;
+  timeb precise;                        // requires <sys/timeb.h>
+    
+  if ( ftime(&precise) != -1 ) {
+    srand48(precise.time + precise.millitm);
+    ret = OCTETSTRING(4, stun_magicCookie_octets) + int2oct(lrand48(),4) + int2oct(lrand48(),4) + int2oct(lrand48(),4);
+  }
+  else TTCN_warning("f_STUN_genTrasId() returns with \'00000000000000000000000000000000\'O");
+  return ret;
+}
+
+INTEGER f__STUN__getMessageLength(const OCTETSTRING& stream)
+{
+int stream_length = stream.lengthof();
+int pdu_length = 0;
+unsigned char * stream_ptr = (unsigned char *)(const unsigned char *)stream;
+if (stream_length >= 20){
+stream_ptr = stream_ptr + 2;
+pdu_length = oct2int(OCTETSTRING(2,(const unsigned char *)stream_ptr));
+if ((pdu_length + 20)<= stream_length){
+pdu_length = pdu_length + 20;
+return pdu_length;}
+else {return 0;}
+}
+else {return 0;}
+}
+
+OCTETSTRING f__STUN__Enc(const PDU__STUN& pl__pdu, const OCTETSTRING& pl__password = os_dummy_oct)
+{
+  PDU__STUN* par=NULL;
+  
+  if (pl__pdu.header().trans__id() == os_tr_id_oct){
+    par = new PDU__STUN(pl__pdu);
+    par->header().trans__id() = f__STUN__genTrasId();
+  }
+    
+  TTCN_Buffer buf;
+  TTCN_EncDec::error_type_t err;
+  buf.clear();
+  TTCN_EncDec::clear_error();
+  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
+  
+  if(par)
+    par->encode(PDU__STUN_descr_, buf, TTCN_EncDec::CT_RAW);
+  else 
+    pl__pdu.encode(PDU__STUN_descr_, buf, TTCN_EncDec::CT_RAW);
+  err = TTCN_EncDec::get_last_error_type();
+  if(err != TTCN_EncDec::ET_NONE)
+    TTCN_warning("Encoding error: %s\n", TTCN_EncDec::get_error_str());
+  if (par)
+    delete par;
+  
+  if(pl__password.lengthof() != 0) {
+  	int offset2type = buf.get_len() - MESSAGE_INTEGRITY_LENGTH + 1;
+	//check  the last attribute
+	if(*(buf.get_data() + offset2type) != MESSAGE_INTEGRITY_TYPE) {
+	  TTCN_warning("Last attribute is not Message Integrity");
+	} else {
+	  OCTETSTRING temp(MESSAGE_INTEGRITY_VALUE_LENGTH, os_integerity_octets);
+	  temp = f__STUN__HMAC(OCTETSTRING(buf.get_len(), buf.get_data()),pl__password);
+ 	  //replace the dunny Message-Integerity value with calculated MAC value
+ 	  buf.set_pos(buf.get_len() - MESSAGE_INTEGRITY_VALUE_LENGTH);
+ 	  buf.cut_end();
+ 	  buf.put_os(temp);
+ 	}
+  }
+  return OCTETSTRING(buf.get_len(), buf.get_data());
+}
+
+PDU__STUN f__STUN__Dec(const OCTETSTRING& pl__oct) 
+{
+  PDU__STUN pdu;
+  TTCN_Buffer buf;
+  TTCN_EncDec::error_type_t err;
+  TTCN_EncDec::clear_error();
+  buf.clear();
+  buf.put_os(pl__oct);
+  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
+  pdu.decode(PDU__STUN_descr_, buf, TTCN_EncDec::CT_RAW);
+  err = TTCN_EncDec::get_last_error_type();
+  if(err != TTCN_EncDec::ET_NONE)
+    TTCN_warning("Decoding error: %s\n", TTCN_EncDec::get_error_str());
+  return pdu;
+}
+} 
+TTCN_Module STUN_EncDec("STUN_EncDec", __DATE__, __TIME__);
diff --git a/test/STUN_Functions.ttcn b/test/STUN_Functions.ttcn
new file mode 100644
index 0000000..c2fc825
--- /dev/null
+++ b/test/STUN_Functions.ttcn
@@ -0,0 +1,182 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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:               STUN_Functions.ttcn
+//  Description:        Functions for STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-05-21
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          RFC 3489
+///////////////////////////////////////////////
+module STUN_Functions {
+
+import from STUN_Types all;
+
+function f_STUN_appendMappedAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := MAPPED_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Mapped_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendResponseAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := RESPONSE_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Response_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendChangedAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := CHANGED_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Changed_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendSourceAddress(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := SOURCE_ADDRESS,
+		attr_length := 0,
+		attr_data := {
+			attr_Source_Address := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendReflectedForm(
+inout PDU_STUN pl_msg, 
+in Stun_Address pl_values) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := REFLECTED_FROM,
+		attr_length := 0,
+		attr_data := {
+			attr_Reflected_From := pl_values
+				}
+	}  
+}
+
+function f_STUN_appendChangeRequest(
+inout PDU_STUN pl_msg, 
+in Stun_Change_Request pl_request) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := CHANGE_REQUEST,
+		attr_length := 0,
+		attr_data := {
+			attr_Change_Request := pl_request
+				}
+	}  
+}
+
+function f_STUN_appendUsername(
+inout PDU_STUN pl_msg, 
+in Stun_Username pl_username) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := USERNAME,
+		attr_length := 0,
+		attr_data := {
+			attr_Username := pl_username
+				}
+	}  
+}
+
+function f_STUN_appendPassword(
+inout PDU_STUN pl_msg, 
+in Stun_Password pl_password) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := PASSWORD,
+		attr_length := 0,
+		attr_data := {
+			attr_Password := pl_password
+				}
+	}  
+}
+
+function f_STUN_appendMessageIntegrity(
+inout PDU_STUN pl_msg, 
+in Stun_Message_Integrity pl_integrity := '0000000000000000000000000000000000000000'O) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := MESSAGE_INTEGRITY,
+		attr_length := 0,
+		attr_data := {
+			attr_Message_Integrity := pl_integrity
+				}
+	}  
+}
+
+function f_STUN_appendErrorCode(
+inout PDU_STUN pl_msg, 
+in Stun_Error_Code pl_error) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := ERROR_CODE,
+		attr_length := 0,
+		attr_data := {
+			attr_Error_Code := pl_error
+				}
+	}  
+}
+
+function f_STUN_appendUnkonwnAttrs(
+inout PDU_STUN pl_msg, 
+in Stun_Unknown_Attributes pl_unknown) 
+{
+	pl_msg.attr_list[sizeof(pl_msg.attr_list)] := {
+	  attr_type := UNKNOWN_ATTRIBUTES,
+		attr_length := 0,
+		attr_data := {
+			attr_Unknown_Attributes := pl_unknown
+				}
+	}  
+}
+function f_STUN_createMsgHeader(
+inout PDU_STUN pl_msg, 
+in STUN_Msg_Type pl_msgType,
+in OCT16 pl_transId := '00000000000000000000000000000000'O)
+{
+  if (pl_transId == '00000000000000000000000000000000'O) {
+    pl_transId := f_STUN_genTrasId();
+  }
+
+  pl_msg := {
+    header := {
+      msg_type := pl_msgType,
+      msg_length := 0,
+      trans_id := pl_transId
+    },
+    attr_list := {}
+  }
+  
+}
+}
diff --git a/test/STUN_Test.prj b/test/STUN_Test.prj
new file mode 100644
index 0000000..171f129
--- /dev/null
+++ b/test/STUN_Test.prj
@@ -0,0 +1,39 @@
+<!DOCTYPE TITAN_GUI_project_file>
+<Project TITAN_version="1.8.pl2" >
+    <General>
+        <Project_Name>STUN_Test</Project_Name>
+        <Executable_Path>bin/STUN_Test</Executable_Path>
+        <Working_Dir>bin</Working_Dir>
+        <Build_Host>alpha</Build_Host>
+        <Execution_Mode>Parallel</Execution_Mode>
+        <Code_Splitting_Mode>None</Code_Splitting_Mode>
+        <ScriptFile_AfterMake>Makefile_patch.sh</ScriptFile_AfterMake>
+        <Log_Format>yes</Log_Format>
+        <Update_Symlinks>yes</Update_Symlinks>
+        <Create_Absolute_Symlinks>no</Create_Absolute_Symlinks>
+        <Update_Makefile>yes</Update_Makefile>
+        <Localhost_Execute>yes</Localhost_Execute>
+        <Execute_Command>rsh %host &quot;cd %project_working_dir ; &quot;%executable&quot; %localhost %mctr_port&quot;</Execute_Command>
+        <Execute_Hosts>alfa, beta, gamma</Execute_Hosts>
+        <UnUsed_List></UnUsed_List>
+    </General>
+    <Configs>
+        <Config>STUN_Demo.cfg</Config>
+    </Configs>
+    <Test_Cases>
+        <Test_Case>STUN_Demo.control</Test_Case>
+        <Test_Case>STUN_Demo.t_STUN_demo</Test_Case>
+    </Test_Cases>
+    <File_Group name="MainFileGroup" >
+        <File_Groups>
+            <File_Group name="STUN_PM" >
+                <File path="../src/STUN_EncDec.cc" />
+                <File path="../src/STUN_Functions.ttcn" />
+                <File path="../src/STUN_Types.ttcn" />
+            </File_Group>
+            <File_Group name="STUN_Test" >
+                <File path="STUN_Demo.ttcn" />
+            </File_Group>
+        </File_Groups>
+    </File_Group>
+</Project>
diff --git a/test/STUN_Types.ttcn b/test/STUN_Types.ttcn
new file mode 100644
index 0000000..c32f17f
--- /dev/null
+++ b/test/STUN_Types.ttcn
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+//
+//  File:               STUN_Types.ttcn
+//  Description:        STUN Protocol module
+//  Rev:                <RnXnn>
+//  Prodnr:             CNL 113 644
+//  Updated:            2009-09-16
+//  Contact:            http://ttcn.ericsson.se
+//  Reference:          RFC 3489
+///////////////////////////////////////////////
+module STUN_Types {
+
+external function f_STUN_Enc(in PDU_STUN pl_pdu, in octetstring pl_password := ''O) return octetstring;
+external function f_STUN_Dec(in octetstring pl_oct) return PDU_STUN;
+external function f_STUN_genTrasId() return octetstring;
+external function f_STUN_genTrasId_withMagicCookie() return octetstring;
+external function f_STUN_IP2oct(in charstring pl_ip) return octetstring;
+external function f_STUN_oct2IP(in octetstring pl_ip) return charstring;
+external function f_STUN_HMAC(in octetstring pl_string, in octetstring pl_key) return octetstring;
+external function f_STUN_checkMessageIntegrity(in octetstring pl_msg, in octetstring pl_key) return boolean;
+external function f_STUN_getMessageLength(in octetstring stream) return integer;
+
+// STUN: RFC3489
+type octetstring OCT4 length(4) with {
+variant "FIELDLENGTH(4)"
+}
+
+type octetstring OCT1 length(1) with {
+variant "FIELDLENGTH(1)"
+}
+
+type octetstring OCT2 length(2) with {
+variant "FIELDLENGTH(2)"
+}
+
+type octetstring OCT16 length(16) with {
+variant "FIELDLENGTH(16)"
+}
+
+type octetstring OCT20 length(20) with {
+variant "FIELDLENGTH(20)"
+}
+
+type integer UINT16 (0..65535) with {
+variant "FIELDLENGTH(16)"
+variant "BYTEORDER(last)"
+}
+
+type OCT20 Attr_Oct160
+
+type OCT4 Attr_Oct32
+
+type OCT1 Attr_Oct8
+
+type OCT2 Attr_Oct16
+
+type enumerated STUN_Family 
+{
+  IP4 (1)
+} with {
+  variant "FIELDLENGTH(8)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+//
+// 11.2 STUN Message Attributes
+//
+
+// RFC 3489 11.2.1
+// Attr: MAPPED-ADDRESS (1)
+// RFC 3489 11.2.2
+// Attr: RESPONSE-ADDRESS (2)
+// RFC 3489 11.2.3
+// Attr: CHANGED-ADDRESS (3)
+// RFC 3489 11.2.5
+// Attr: SOURCE-ADDRESS (5)
+// RFC 3489 11.2.11
+// Attr: REFLECTED-FROM (11)
+type record Stun_Address 
+{
+  STUN_Family   family,
+  UINT16	port_id,
+  Attr_Oct32	ip_address
+} with { variant (family) "FIELDLENGTH(16)"
+  	 variant (family) "ALIGN(right)"
+}
+
+
+// RFC 3489 11.2.4
+// Attr: CHANGE-REQUEST (4)
+type enumerated Stun_Change_Request 
+{
+  NO_CHANGE   (0),
+  CHANGE_PORT (2),
+  CHANGE_IP   (4),
+  CHANGE_BOTH (6)
+} with {
+  variant "FIELDLENGTH(32)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+// RFC 3489 11.2.6
+// Attr: USERNAME (6)
+type charstring Stun_Username 
+with { variant "PADDING(dword32)"}
+
+// RFC 3489 11.2.7
+// Attr: PASSWORD (7)
+type octetstring Stun_Password 
+with { variant "PADDING(dword32)"}
+
+// RFC 3489 11.2.8
+// Attr: MESSAGE-INTEGRITY (8)
+type Attr_Oct160 Stun_Message_Integrity
+
+// RFC 3489bis-13 14.7
+// Attr: REALM (20)
+type charstring Stun_Realm
+with { variant "PADDING(dword32)"}
+
+// RFC 3489bis-13 14.8
+// Attr: NONCE (21)
+type octetstring Stun_Nonce
+with { variant "PADDING(dword32)"}
+
+type enumerated Stun_Error_Code_Type
+{
+  BAD_REQUEST 		  (1024),
+  UNAUTHORIZED		  (1025),
+  UNKNOWN_ATTRIBUTE	  (1044),
+  STALE_CREDENTIALS	  (1054),
+  INTEGRITY_CHECK_FAILURE (1055),
+  MISSING_USERNAME	  (1056),
+  USE_TLS		  (1057),
+  SERVER_ERROR		  (1280),
+  GLOBAL_FAILURE	  (1536)
+} with {
+  variant "FIELDLENGTH(32)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+// RFC 3489 11.2.9
+// Attr: ERROR-CODE (9)
+type record Stun_Error_Code {
+  Stun_Error_Code_Type	error_code_tpye,
+  charstring		reason_phrase
+}
+with { variant (reason_phrase) "PADDING(dword32)"}
+
+type Attr_Oct16 STUN_Unknown_Attr_Data;
+
+// RFC 3489 11.2.10
+// Attr: UNKNOWN-ATTRIBUTES (10)
+type set of STUN_Unknown_Attr_Data Stun_Unknown_Attributes
+with { variant "PADDING(dword32)"}
+
+type union STUN_Attr_data
+{
+  Stun_Address 			attr_Mapped_Address,
+  Stun_Address			attr_Response_Address,
+  Stun_Address			attr_Changed_Address,
+  Stun_Change_Request		attr_Change_Request,
+  Stun_Address			attr_Source_Address,
+  Stun_Username			attr_Username,
+  Stun_Password			attr_Password,
+  Stun_Message_Integrity	attr_Message_Integrity,
+  Stun_Error_Code		attr_Error_Code,
+  Stun_Unknown_Attributes	attr_Unknown_Attributes,
+  Stun_Address			attr_Reflected_From,
+  Stun_Address                  attr_Xor_Mapped_Address,
+  Stun_Realm                    attr_Realm,
+  Stun_Nonce                    attr_Nonce
+}
+
+type enumerated STUN_Attr_type {
+  MAPPED_ADDRESS      (1),
+  RESPONSE_ADDRESS    (2),
+  CHANGE_REQUEST      (3),
+  SOURCE_ADDRESS      (4),
+  CHANGED_ADDRESS     (5),
+  USERNAME            (6),
+  PASSWORD            (7),
+  MESSAGE_INTEGRITY   (8),
+  ERROR_CODE          (9),
+  UNKNOWN_ATTRIBUTES (10),
+  REFLECTED_FROM     (11),
+  REALM              (20), //RFC 3489bis-13
+  NONCE              (21), //RFC 3489bis-13
+  XOR_MAPPED_ADDRESS (32)  //RFC 3489bis-13
+} with {
+  variant "FIELDLENGTH(16)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+type record STUN_Attr {
+  STUN_Attr_type	attr_type,
+  UINT16		attr_length,
+  STUN_Attr_data	attr_data 
+} with {
+  variant "PADDING(dword32)"
+  variant (attr_length) "LENGTHTO(attr_data)"
+  variant (attr_data) "CROSSTAG(
+    attr_Mapped_Address, 	attr_type = MAPPED_ADDRESS;
+    attr_Response_Address,	attr_type = RESPONSE_ADDRESS;
+    attr_Changed_Address, 	attr_type = CHANGED_ADDRESS;
+    attr_Change_Request,	attr_type = CHANGE_REQUEST;
+    attr_Source_Address,	attr_type = SOURCE_ADDRESS;
+    attr_Username,		attr_type = USERNAME;
+    attr_Password,		attr_type = PASSWORD;
+    attr_Message_Integrity,	attr_type = MESSAGE_INTEGRITY;
+    attr_Error_Code,		attr_type = ERROR_CODE;
+    attr_Unknown_Attributes,	attr_type = UNKNOWN_ATTRIBUTES;
+    attr_Reflected_From,        attr_type = REFLECTED_FROM
+  )"
+}
+
+type set of STUN_Attr Attr_List
+
+type enumerated STUN_Msg_Type {
+ Binding_Request                (1),
+ Binding_Response             (257),
+ Binding_Error_Response       (273),
+ Shared_Secret_Request          (2),
+ Shared_Secret_Response       (258),
+ Shared_Secret_Error_Response (274)
+} with {
+  variant "FIELDLENGTH(16)"
+  variant "BYTEORDER(last)"
+  variant "COMP(2scompl)"
+}
+
+type record STUN_Header {
+  STUN_Msg_Type   msg_type,
+  UINT16	  msg_length,
+  OCT16		  trans_id
+}
+
+type record PDU_STUN {
+ 	 STUN_Header 	header,
+ 	 Attr_List	attr_list
+} with {
+  variant "PADDING(dword32)"
+  variant (header) "LENGTHTO(attr_list)"
+  variant (header) "LENGTHINDEX(msg_length)"
+}
+ 
+} with { encode "RAW" } // End module