Initial commit
diff --git a/EPTF_Applib_COAP_CNL113858.tpd b/EPTF_Applib_COAP_CNL113858.tpd
new file mode 100644
index 0000000..11a0cba
--- /dev/null
+++ b/EPTF_Applib_COAP_CNL113858.tpd
@@ -0,0 +1,43 @@
+<!--
+Copyright (c) 2000-2017 Ericsson Telecom AB
+
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+
+    File:               COAP_CNL113858.tpd
+    Description:        tpd project file
+    Rev:                R1A
+    Prodnr:             CNL 113 858
+    Updated:            2017-09-01
+    Contact:            http://ttcn.ericsson.se
+
+-->
+<TITAN_Project_File_Information version="1.0">
+<ProjectName>EPTF_Applib_COAP_CNL113858</ProjectName>
+<Files>
+    <FileResource projectRelativePath="EPTF_COAP_LGen_Definitions.ttcn" relativeURI="./src/EPTF_COAP_LGen_Definitions.ttcn"/>
+    <FileResource projectRelativePath="EPTF_COAP_LGen_Functions.ttcn" relativeURI="./src/EPTF_COAP_LGen_Functions.ttcn"/>
+    <FileResource projectRelativePath="EPTF_COAP_LocalTransport_Definitions.ttcn" relativeURI="./src/EPTF_COAP_LocalTransport_Definitions.ttcn"/>
+    <FileResource projectRelativePath="EPTF_COAP_LocalTransport_Functions.ttcn" relativeURI="./src/EPTF_COAP_LocalTransport_Functions.ttcn"/>
+    <FileResource projectRelativePath="EPTF_COAP_Transport_Definitions.ttcn" relativeURI="./src/EPTF_COAP_Transport_Definitions.ttcn"/>
+  </Files>
+  <ActiveConfiguration>Default</ActiveConfiguration>
+  <Configurations>
+    <Configuration name="Default">
+      <ProjectProperties>
+        <MakefileSettings>
+          <generateInternalMakefile>true</generateInternalMakefile>
+          <GNUMake>true</GNUMake>
+          <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+          <targetExecutable>bin/COAP_CNL113858</targetExecutable>
+          <buildLevel>Level 3 - Creating object files with dependency update</buildLevel>
+        </MakefileSettings>
+        <LocalBuildSettings>
+          <workingDirectory>bin</workingDirectory>
+        </LocalBuildSettings>
+      </ProjectProperties>
+    </Configuration>
+  </Configurations>
+</TITAN_Project_File_Information>
diff --git a/src/EPTF_COAP_LGen_Definitions.ttcn b/src/EPTF_COAP_LGen_Definitions.ttcn
new file mode 100644
index 0000000..502421a
--- /dev/null
+++ b/src/EPTF_COAP_LGen_Definitions.ttcn
@@ -0,0 +1,363 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+//  File:               EPTF_COAP_LGen_Definitions.ttcn
+//  Description:
+//  Rev:                R1A
+//  Prodnr:             CNL 113 858
+//  Updated:            2017-09-01
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_COAP_LGen_Definitions
+{
+  import from EPTF_COAP_Transport_Definitions all;
+  import from EPTF_CLL_LGenBase_Definitions all;
+  import from EPTF_CLL_Logging_Definitions all;
+  import from EPTF_CLL_FBQ_Definitions all;
+  import from Socket_API_Definitions all;
+  import from CoAP_Types all;
+
+  modulepar boolean tsp_EPTF_COAP_LGen_debug := false;
+  modulepar boolean tsp_EPTF_COAP_LGen_debugVerbose := false;
+  modulepar integer tsp_EPTF_COAP_LGen_maxBindableCtx := -1;
+
+  modulepar CoAP_Template_List tsp_EPTF_COAP_LGen_templates := {};
+
+  const integer c_COAP_LGen_Logging_WARNING := 0;
+  const integer c_COAP_LGen_Logging_DEBUG := 1;
+  const integer c_COAP_LGen_Logging_DEBUGV := 2;
+  const integer c_COAP_LGen_Logging_ERROR := 3;
+
+  const charstring c_COAP_behaviorType := "COAP Behavior";
+
+  type record COAP_EntityCtx
+  {
+    integer eIdx,
+    integer localAddressIdx,
+    integer nextMID,
+    integer nextToken,
+    boolean reportCoapEvent
+  }
+
+  const COAP_EntityCtx c_COAP_EntityCtx_init :=
+  {
+    eIdx := -1,
+    localAddressIdx := -1,
+    nextMID := -1,
+    nextToken := -1,
+    reportCoapEvent := true
+  }
+
+  type record of COAP_EntityCtx COAP_EntityCtx_List;
+
+  type record COAP_EntityCtx_DB
+  {
+    EPTF_FreeBusyQueue  queue,
+    COAP_EntityCtx_List data,
+    integer             hashRef
+  }
+
+  type record COAP_FsmCtx
+  {
+    integer eIdx,
+    integer remoteAddressIdx,
+    integer rrIdx
+  }
+
+  const COAP_FsmCtx c_COAP_FsmCtx_init :=
+  {
+    eIdx := -1,
+    remoteAddressIdx := -1,
+    rrIdx := -1
+  }
+
+  type record of COAP_FsmCtx COAP_FsmCtx_List;
+
+  type record COAP_FsmCtx_DB
+  {
+    EPTF_FreeBusyQueue  queue,
+    COAP_FsmCtx_List    data,
+    integer             hashRef
+  }
+
+  type enumerated COAP_Transaction_State
+  {
+    CLOSED,
+    RELIABLE_TX,
+    ACK_PENDING,
+    REMOVING
+  }
+
+  type enumerated COAP_Transaction_Direction
+  {
+    OUTGOING,
+    INCOMING
+  }
+
+  type record COAP_Transaction
+  {
+    integer mid,
+    integer eIdx,
+    integer addrIdx,
+    integer rrIdx,
+    integer retransmitTimer,
+    float	retransmitTimerValue,
+    integer lifetimeTimer,
+    EPTF_COAP_PDU cache optional,
+    COAP_Transaction_State state,
+    COAP_Transaction_Direction direction
+  }
+
+  const COAP_Transaction c_COAP_Transaction_init :=
+  {
+    mid := -1,
+    eIdx := -1,
+    addrIdx := -1,
+    rrIdx := -1,
+    retransmitTimer := -1,
+    retransmitTimerValue := 1.0,
+    lifetimeTimer := -1,
+    cache := omit,
+    state := CLOSED,
+    direction := OUTGOING
+  }
+
+  type record of COAP_Transaction COAP_Transaction_List;
+
+  type record COAP_Transaction_DB
+  {
+    EPTF_FreeBusyQueue    queue,
+    COAP_Transaction_List data,
+    integer               hashRefOutgoing,
+    integer               hashRefIncoming
+  }
+
+  type enumerated COAP_RR_Client_State
+  {
+    IDLE,
+    WAITING,
+    REMOVING
+  }
+
+  type enumerated COAP_RR_Server_State
+  {
+    IDLE,
+    SEPARATE,
+    SERVING,
+    REMOVING
+  }
+
+  type union COAP_RR_State
+  {
+    COAP_RR_Client_State client,
+    COAP_RR_Server_State server
+  }
+
+  type record COAP_RR
+  {
+    integer eIdx,
+    integer fsmIdx,
+    integer fsmCtxIdx,
+    integer addrIdx,
+    octetstring token,
+    integer trIdx,
+    Socket  remoteAddress optional,
+    EPTF_COAP_PDU request optional,
+    EPTF_COAP_PDU response optional,
+    COAP_RR_State state
+  }
+
+  const COAP_RR c_COAP_RR_init :=
+  {
+    eIdx := -1,
+    fsmIdx := -1,
+    fsmCtxIdx := -1,
+    addrIdx := -1,
+    token := ''O,
+    trIdx := -1,
+    remoteAddress := omit,
+    request := omit,
+    response := omit,
+    state := { client := IDLE }
+  }
+
+  type record of COAP_RR COAP_RR_List;
+
+  type record COAP_RR_DB
+  {
+    EPTF_FreeBusyQueue    queue,
+    COAP_RR_List          data,
+    integer               hashRef
+  }
+
+  type record CoAP_Template
+  {
+    charstring id,
+    CoAP_ReqResp msg
+  }
+
+  type record of CoAP_Template CoAP_Template_List;
+
+  type record COAP_Template_DB
+  {
+    CoAP_Template_List data,
+    integer hashRef
+  }
+
+  type record COAP_StepCtx
+  {
+    integer eIdx,
+    integer fsmIdx,
+    integer eCtxIdx,
+    integer fsmCtxIdx
+  }
+
+  const COAP_StepCtx c_COAP_StepCtx_empty :=
+  {
+    eIdx := -1,
+    fsmIdx := -1,
+    eCtxIdx := -1,
+    fsmCtxIdx := -1
+  }
+
+  type record of Socket COAP_Address_List;
+
+  type record COAP_AddressDB
+  {
+    EPTF_FreeBusyQueue queue,
+    COAP_Address_List data,
+    integer hashRef
+  }
+
+  type function fcb_EPTF_COAP_messageReceived(in EPTF_COAP_PDU pl_message, in boolean p_duplicate) runs on self;
+
+  type component EPTF_COAP_LGen_CT extends EPTF_COAP_Transport_User_CT, EPTF_LGenBase_CT, EPTF_Logging_CT
+  {
+    var boolean v_COAP_initialized := false;
+
+    var integer v_COAP_bIdx;
+
+    var integer v_COAP_loggingMaskId := -1;
+
+    var COAP_EntityCtx_DB   v_COAP_EntityCtxDB;
+    var COAP_FsmCtx_DB      v_COAP_FsmCtxDB;
+    var COAP_AddressDB      v_COAP_addressDB;
+    var COAP_Transaction_DB v_COAP_trDB;
+    var COAP_RR_DB          v_COAP_rrDB;
+    var COAP_Template_DB    v_COAP_templateDB := {};
+
+    var COAP_StepCtx v_COAP_ctx := c_COAP_StepCtx_empty;
+
+    var EPTF_COAP_PDU v_COAP_msgToProcess;
+    var EPTF_COAP_PDU v_COAP_msgToSend;
+
+    var fcb_EPTF_COAP_messageReceived vf_COAP_msgReceived := null;
+  }
+
+  const integer c_COAP_AppData_fsmCtxIdx := 0;
+
+  // Events
+
+  const integer c_COAP_eventIdx_EMPTY := 0;
+  const charstring c_COAP_eventName_EMPTY := "COAP req: EMPTY";
+
+  const integer c_COAP_eventIdx_GET := 1;
+  const charstring c_COAP_eventName_GET := "COAP req: GET";
+
+  const integer c_COAP_eventIdx_POST := 2;
+  const charstring c_COAP_eventName_POST := "COAP req: POST";
+
+  const integer c_COAP_eventIdx_PUT := 3;
+  const charstring c_COAP_eventName_PUT := "COAP req: PUT";
+
+  const integer c_COAP_eventIdx_DELETE := 4;
+  const charstring c_COAP_eventName_DELETE := "COAP req: DELETE";
+
+  template charstring c_COAP_eventName(in integer p_code) := "COAP rsp: "&int2str(p_code);
+
+  const integer c_COAP_eventIdx_1xx := 700;
+  const charstring c_COAP_eventName_1xx := "COAP rsp: 1xx";
+
+  const integer c_COAP_eventIdx_2xx := 701;
+  const charstring c_COAP_eventName_2xx := "COAP rsp: 2xx";
+
+  const integer c_COAP_eventIdx_3xx := 702;
+  const charstring c_COAP_eventName_3xx := "COAP rsp: 3xx";
+
+  const integer c_COAP_eventIdx_4xx := 703;
+  const charstring c_COAP_eventName_4xx := "COAP rsp: 4xx";
+
+  const integer c_COAP_eventIdx_5xx := 704;
+  const charstring c_COAP_eventName_5xx := "COAP rsp: 5xx";
+
+  const integer c_COAP_eventIdx_6xx := 705;
+  const charstring c_COAP_eventName_6xx := "COAP rsp: 6xx";
+
+  const integer c_COAP_eventIdx_3xxto6xx := 706;
+  const charstring c_COAP_eventName_3xxto6xx := "COAP rsp: 3xxto6xx";
+
+  const integer c_COAP_eventIdx_transportSucc := 707;
+  const charstring c_COAP_eventName_transportSucc := "COAP transport: succ rsp";
+
+  const integer c_COAP_eventIdx_transportFail := 708;
+  const charstring c_COAP_eventName_transportFail := "COAP transport: fail rsp";
+
+  const integer c_COAP_eventIdx_trRST := 709;
+  const charstring c_COAP_eventName_trRST := "COAP transaction: reset";
+
+  const integer c_COAP_eventIdx_trTimeout := 710;
+  const charstring c_COAP_eventName_trTimeout := "COAP transaction: timeout";
+
+  // Steps
+
+  const integer c_COAP_stepIdx_init := 0;
+  const charstring c_COAP_stepName_init := "COAP Applib: init";
+
+  const integer c_COAP_stepIdx_cleanUp := 1;
+  const charstring c_COAP_stepName_cleanUp := "COAP Applib: cleanUp";
+
+  const integer c_COAP_stepIdx_setLocalAddress := 2;
+  const charstring c_COAP_stepName_setLocalAddress := "COAP Applib: setLocalAddress";
+
+  const integer c_COAP_stepIdx_setRemoteAddress_byIntIdx := 3;
+  const charstring c_COAP_stepName_setRemoteAddress_byIntIdx := "COAP Applib: setRemoteAddress_byIntIdx";
+
+  const integer c_COAP_stepIdx_send := 4;
+  const charstring c_COAP_stepName_send := "COAP Applib: send";
+
+  const integer c_COAP_stepIdx_loadTemplate_byIntIdx := 5;
+  const charstring c_COAP_stepName_loadTemplate_byIntIdx := "COAP Applib: loadTemplate_byIntIdx";
+
+  const integer c_COAP_stepIdx_handleRequest := 6;
+  const charstring c_COAP_stepName_handleRequest := "COAP Applib: handleRequest";
+
+  const integer c_COAP_stepIdx_sendResponse := 7;
+  const charstring c_COAP_stepName_sendResponse := "COAP Applib: sendResponse";
+
+  const integer c_COAP_stepIdx_sendAccept := 8;
+  const charstring c_COAP_stepName_sendAccept := "COAP Applib: sendAccept";
+
+  const integer c_COAP_stepIdx_startListening := 9;
+  const charstring c_COAP_stepName_startListening := "COAP Applib: startListening";
+
+  const integer c_COAP_stepIdx_reportCoapEventForEntity := 10;
+  const charstring c_COAP_stepName_reportCoapEventForEntity := "COAP Applib: reportCoapEventForEntity";
+
+  const integer c_COAP_stepIdx_loadTemplate_byStringId := 11;
+  const charstring c_COAP_stepName_loadTemplate_byStringId := "COAP Applib: loadTemplate_byStringId";
+
+  const integer c_COAP_stepIdx_setRemoteAddress_byVars := 12;
+  const charstring c_COAP_stepName_setRemoteAddress_byVars := "COAP Applib: setRemoteAddress_byVars";
+
+  // Step parameters:
+
+  const integer c_COAP_stepParam_true := 1;
+  const integer c_COAP_stepParam_false := 0;
+
+}
diff --git a/src/EPTF_COAP_LGen_Functions.ttcn b/src/EPTF_COAP_LGen_Functions.ttcn
new file mode 100644
index 0000000..71f9929
--- /dev/null
+++ b/src/EPTF_COAP_LGen_Functions.ttcn
@@ -0,0 +1,1922 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+//  File:               EPTF_COAP_LGen_Functions.ttcn
+//  Description:
+//  Rev:                R1A
+//  Prodnr:             CNL 113 858
+//  Updated:            2017-09-01
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_COAP_LGen_Functions
+{
+  import from EPTF_COAP_LGen_Definitions all;
+  import from EPTF_COAP_Transport_Definitions all;
+
+  import from EPTF_CLL_Base_Functions all;
+  import from EPTF_CLL_Common_Definitions all;
+  import from EPTF_CLL_Variable_Definitions all;
+  import from EPTF_CLL_Variable_Functions all;
+  import from EPTF_CLL_LGenBase_Definitions all;
+  import from EPTF_CLL_LGenBase_ConfigFunctions all;
+  import from EPTF_CLL_LGenBase_Functions all;
+  import from EPTF_CLL_LGenBase_EventHandlingFunctions all;
+  import from EPTF_CLL_Logging_Definitions all;
+  import from EPTF_CLL_Logging_Functions all;
+  import from EPTF_CLL_FBQ_Functions all;
+  import from EPTF_CLL_HashMapStr2Int_Functions all;
+  import from EPTF_CLL_Scheduler_Definitions all;
+  import from EPTF_CLL_RBTScheduler_Functions all;
+
+  import from CoAP_Types all;
+  import from IPL4asp_Types all;
+
+  modulepar integer tsp_EPTF_COAP_maxToken := 65535;
+  modulepar float tsp_EPTF_COAP_NON_LIFETIME := 145.0;
+  modulepar float tsp_EPTF_COAP_EXCHANGE_LIFETIME := 247.0;
+
+  function f_EPTF_COAP_LGen_init(in charstring pl_name)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (v_COAP_initialized){return;}
+
+    f_EPTF_LGenBase_init(pl_name, 0, pl_name);
+    f_EPTF_Logging_init_CT(pl_name);
+    f_EPTF_str2int_HashMap_Init();
+
+    v_COAP_bIdx := f_EPTF_LGenBase_declareBehaviorType(
+      c_COAP_behaviorType,
+      tsp_EPTF_COAP_LGen_maxBindableCtx,
+      refers(f_COAP_eCtxReset),
+      refers(f_COAP_eCtxBind),
+      refers(f_COAP_eCtxUnbind)
+      );
+
+    v_COAP_loggingMaskId :=
+      f_EPTF_Logging_registerComponentMasks(
+        "COAP_Logging",
+        {"WARNING", "DEBUG", "DEBUGV", "ERROR" },
+        EPTF_Logging_CLL);
+
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId,": my behavior idx is ", v_COAP_bIdx));
+
+    f_EPTF_COAP_EntityCtxDB_init();
+    f_EPTF_COAP_FsmCtxDB_init();
+    f_EPTF_COAP_addressDB_init();
+    f_EPTF_COAP_trDB_init();
+    f_EPTF_COAP_rrDB_init();
+    f_EPTF_COAP_templateDB_init();
+
+    f_EPTF_COAP_declareSteps();
+    f_EPTF_COAP_declareEvents();
+
+    f_EPTF_Base_registerCleanup(refers(f_COAP_cleanUp));
+
+    v_COAP_initialized := true;
+  }
+
+  function f_EPTF_COAP_LGen_initLogging()
+  runs on EPTF_COAP_LGen_CT
+  {
+	f_EPTF_Logging_init_CT("COAP_LGen");
+    v_COAP_loggingMaskId :=
+    	f_EPTF_Logging_registerComponentMasks(
+    		"COAP_LGen_Logging",
+    		{"WARNING", "DEBUG", "DEBUGV", "ERROR"},
+    		EPTF_Logging_CLL
+    	);
+
+	if(tsp_EPTF_COAP_LGen_debug){
+	  f_EPTF_Logging_enableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_DEBUG);
+	}
+	else {
+	  f_EPTF_Logging_disableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_DEBUG);
+	}
+
+	if(tsp_EPTF_COAP_LGen_debugVerbose) {
+	  f_EPTF_Logging_enableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_DEBUGV);
+	}
+	else {
+	  f_EPTF_Logging_disableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_DEBUGV);
+	}
+  }
+
+  function f_COAP_cleanUp()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_EntityCtxDB_cleanUp();
+    f_EPTF_COAP_FsmCtxDB_cleanUp();
+    f_EPTF_COAP_addressDB_cleanUp();
+    f_EPTF_COAP_trDB_cleanUp();
+    f_EPTF_COAP_rrDB_cleanUp();
+    f_EPTF_COAP_templateDB_cleanUp();
+    vf_COAP_msgReceived := null;
+
+    v_COAP_initialized := false;
+  }
+
+  function f_COAP_eCtxBind(in integer pl_eIdx)
+  runs on EPTF_COAP_LGen_CT
+  return EPTF_IntegerList
+  {
+    var integer vl_eCtxIdx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_EntityCtxDB.queue);
+    f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_EntityCtxDB.queue);
+
+    v_COAP_EntityCtxDB.data[vl_eCtxIdx] := c_COAP_EntityCtx_init;
+    v_COAP_EntityCtxDB.data[vl_eCtxIdx].eIdx := pl_eIdx;
+    v_COAP_EntityCtxDB.data[vl_eCtxIdx].nextToken := float2int(int2float(tsp_EPTF_COAP_maxToken)*rnd());
+    v_COAP_EntityCtxDB.data[vl_eCtxIdx].nextMID := float2int(int2float(65535)*rnd());
+
+    return {vl_eCtxIdx};
+  }
+
+  function f_COAP_eCtxUnbind(in integer pl_eIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (not v_COAP_initialized) {return;}
+
+    var integer vl_eCtxIdx:= f_EPTF_LGenBase_getBehaviorCtxItem(pl_eIdx, v_COAP_bIdx, 0);
+
+    f_EPTF_FBQ_moveFromBusyToFreeTail(vl_eCtxIdx, v_COAP_EntityCtxDB.queue);
+  }
+
+  function f_COAP_eCtxReset(in integer pl_eIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    var integer vl_eCtxIdx:= f_EPTF_LGenBase_getBehaviorCtxItem(pl_eIdx, v_COAP_bIdx, 0);
+
+    v_COAP_EntityCtxDB.data[vl_eCtxIdx] := c_COAP_EntityCtx_init;
+  }
+
+  function f_EPTF_COAP_EntityCtxDB_init()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_EntityCtxDB.queue);
+    v_COAP_EntityCtxDB.data := {};
+    v_COAP_EntityCtxDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_COAP_EnityCtxDB_Hash");
+  }
+
+  function f_EPTF_COAP_EntityCtxDB_cleanUp()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_EntityCtxDB.queue);
+    v_COAP_EntityCtxDB.data :={}
+    f_EPTF_str2int_HashMap_Delete("EPTF_COAP_EnityCtxDB_Hash");
+  }
+
+  function f_EPTF_COAP_FsmCtxDB_init()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_FsmCtxDB.queue);
+    v_COAP_FsmCtxDB.data := {};
+    v_COAP_FsmCtxDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_COAP_FsmCtxDB_Hash");
+  }
+
+  function f_EPTF_COAP_FsmCtxDB_cleanUp()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_FsmCtxDB.queue);
+    v_COAP_FsmCtxDB.data :={}
+    f_EPTF_str2int_HashMap_Delete("EPTF_COAP_FsmCtxDB_Hash");
+  }
+
+  function f_EPTF_COAP_addressDB_init()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_addressDB.queue);
+    v_COAP_addressDB.data := {};
+    v_COAP_addressDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_COAP_addressDB_Hash");
+  }
+
+  function f_EPTF_COAP_addressDB_cleanUp()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_addressDB.queue);
+    v_COAP_addressDB.data := {};
+    f_EPTF_str2int_HashMap_Delete("EPTF_COAP_addressDB_Hash");
+  }
+
+  function f_EPTF_COAP_addressDB_add(in Socket p_addr, inout integer p_idx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    p_idx := f_EPTF_COAP_addressDB_lookUp(p_addr);
+
+    if (p_idx == -1)
+    {
+      p_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_addressDB.queue);
+      f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_addressDB.queue);
+      f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding target address ", p_idx, " ", p_addr));
+      f_EPTF_str2int_HashMap_Insert(v_COAP_addressDB.hashRef, f_EPTF_COAP_addressDB_Socket2String(p_addr), p_idx);
+      v_COAP_addressDB.data[p_idx] := p_addr;
+    }
+  }
+
+  function f_EPTF_COAP_addressDB_get(inout Socket p_addr, in integer p_idx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (p_idx < sizeof(v_COAP_addressDB.data))
+    {
+      p_addr := v_COAP_addressDB.data[p_idx];
+    }
+  }
+
+  function f_EPTF_COAP_addressDB_lookUp(in Socket p_sock)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    var integer vl_idx := -1;
+    f_EPTF_str2int_HashMap_Find(v_COAP_addressDB.hashRef, f_EPTF_COAP_addressDB_Socket2String(p_sock), vl_idx);
+    return vl_idx;
+  }
+
+  function f_EPTF_COAP_addressDB_Socket2String(Socket p_sock)
+  return charstring
+  {
+    return p_sock.hostName&":"&int2str(p_sock.portNumber);
+  }
+
+  function f_EPTF_COAP_rrDB_init()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_rrDB.queue);
+    v_COAP_rrDB.data := {};
+    v_COAP_rrDB.hashRef := f_EPTF_str2int_HashMap_New("v_COAP_rrDB");
+  }
+
+  function f_EPTF_COAP_rrDB_add(in COAP_RR p_rr)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    var Socket v_addr;
+    f_EPTF_COAP_addressDB_get(v_addr, p_rr.addrIdx);
+
+    var integer v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_rrDB.queue);
+    f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_rrDB.queue);
+    f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding rr ", v_idx, " ", p_rr));
+    f_EPTF_str2int_HashMap_Insert(v_COAP_rrDB.hashRef, f_EPTF_COAP_rrDB_tokenHash(v_addr, p_rr.token), v_idx);
+
+    v_COAP_rrDB.data[v_idx] := p_rr;
+
+    return v_idx;
+  }
+
+  function f_EPTF_COAP_rrDB_lookUp(in Socket p_sock, in octetstring p_token)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    var integer    vl_idx := -1;
+    f_EPTF_str2int_HashMap_Find(v_COAP_rrDB.hashRef, f_EPTF_COAP_rrDB_tokenHash(p_sock, p_token), vl_idx);
+    return vl_idx;
+  }
+
+  function f_EPTF_COAP_rrDB_get(in integer p_idx, inout COAP_RR p_rr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (p_idx < sizeof(v_COAP_rrDB.data))
+    {
+      p_rr := v_COAP_rrDB.data[p_idx];
+    }
+  }
+
+  function f_EPTF_COAP_rrDB_remove(in integer p_idx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    var Socket v_addr;
+    f_EPTF_COAP_addressDB_get(v_addr, v_COAP_rrDB.data[p_idx].addrIdx);
+    f_EPTF_str2int_HashMap_Erase(v_COAP_rrDB.hashRef, f_EPTF_COAP_rrDB_tokenHash(v_addr, v_COAP_rrDB.data[p_idx].token));
+    v_COAP_rrDB.data[p_idx] := c_COAP_RR_init;
+    f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_COAP_rrDB.queue);
+  }
+
+  function f_EPTF_COAP_rrDB_cleanUp()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_rrDB.queue);
+    v_COAP_rrDB.data := {};
+    f_EPTF_str2int_HashMap_Delete("v_COAP_rrDB");
+  }
+
+  function f_EPTF_COAP_rrDB_tokenHash(in Socket p_sock, in octetstring p_token)
+  return charstring
+  {
+    return oct2str(p_token)&":"&p_sock.hostName&":"&int2str(p_sock.portNumber);
+  }
+
+  function f_EPTF_COAP_trDB_init()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_trDB.queue);
+    v_COAP_trDB.data := {};
+    v_COAP_trDB.hashRefOutgoing := f_EPTF_str2int_HashMap_New("v_COAP_outTrDB");
+    v_COAP_trDB.hashRefIncoming := f_EPTF_str2int_HashMap_New("v_COAP_incTrDB");
+  }
+
+  function f_EPTF_COAP_trDB_add(in COAP_Transaction p_tr)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    var Socket v_addr;
+    f_EPTF_COAP_addressDB_get(v_addr, p_tr.addrIdx);
+    var integer v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_trDB.queue);
+    f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_trDB.queue);
+    f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding tr ", v_idx, " ", p_tr));
+    if (p_tr.direction == OUTGOING)
+    {
+      f_EPTF_str2int_HashMap_Insert(v_COAP_trDB.hashRefOutgoing, f_EPTF_COAP_trDB_midHash(v_addr, p_tr.mid), v_idx);
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_DEBUG(log2str("adding tr ", v_idx, " ", f_EPTF_COAP_trDB_midHash(v_addr, p_tr.mid)));
+      f_EPTF_str2int_HashMap_Insert(v_COAP_trDB.hashRefIncoming, f_EPTF_COAP_trDB_midHash(v_addr, p_tr.mid), v_idx);
+    }
+    v_COAP_trDB.data[v_idx] := p_tr;
+
+    return v_idx;
+  }
+
+  function f_EPTF_COAP_trDB_lookUp(in Socket p_sock, in integer p_mid, COAP_Transaction_Direction p_dir)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    var integer    vl_idx := -1;
+    if (p_dir == OUTGOING)
+    {
+      f_EPTF_str2int_HashMap_Find(v_COAP_trDB.hashRefOutgoing, f_EPTF_COAP_trDB_midHash(p_sock, p_mid), vl_idx);
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_VERBOSE(log2str("look up tr ", f_EPTF_COAP_trDB_midHash(p_sock, p_mid)));
+      f_EPTF_str2int_HashMap_Find(v_COAP_trDB.hashRefIncoming, f_EPTF_COAP_trDB_midHash(p_sock, p_mid), vl_idx);
+    }
+
+    return vl_idx;
+  }
+
+  function f_EPTF_COAP_trDB_get(in integer p_idx, inout COAP_Transaction p_tr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (p_idx < sizeof(v_COAP_trDB.data))
+    {
+      p_tr := v_COAP_trDB.data[p_idx];
+    }
+  }
+
+  function f_EPTF_COAP_trDB_remove(in integer p_idx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    var Socket v_addr;
+    f_EPTF_COAP_addressDB_get(v_addr, v_COAP_trDB.data[p_idx].addrIdx);
+    if (v_COAP_trDB.data[p_idx].direction == OUTGOING)
+    {
+      f_EPTF_str2int_HashMap_Erase(v_COAP_trDB.hashRefOutgoing, f_EPTF_COAP_trDB_midHash(v_addr, v_COAP_trDB.data[p_idx].mid));
+    }
+    else
+    {
+      f_EPTF_str2int_HashMap_Erase(v_COAP_trDB.hashRefIncoming, f_EPTF_COAP_trDB_midHash(v_addr, v_COAP_trDB.data[p_idx].mid));
+    }
+    v_COAP_trDB.data[p_idx] := c_COAP_Transaction_init;
+    f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_COAP_trDB.queue);
+  }
+
+  function f_EPTF_COAP_trDB_cleanUp()
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_trDB.queue);
+    v_COAP_trDB.data := {};
+    f_EPTF_str2int_HashMap_Delete("v_COAP_outTrDB");
+    f_EPTF_str2int_HashMap_Delete("v_COAP_incTrDB");
+  }
+
+  function f_EPTF_COAP_trDB_midHash(in Socket p_sock, in integer p_mid)
+  return charstring
+  {
+    return int2str(p_mid)&":"&p_sock.hostName&":"&int2str(p_sock.portNumber);
+  }
+
+  function f_EPTF_COAP_templateDB_init()
+  runs on EPTF_COAP_LGen_CT
+  {
+    v_COAP_templateDB.data := {};
+    v_COAP_templateDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_COAP_templateDB_Hash");
+
+    for (var integer i:=0; i<sizeof(tsp_EPTF_COAP_LGen_templates); i:=i+1) {
+      f_EPTF_COAP_templateDB_add(tsp_EPTF_COAP_LGen_templates[i]);
+    }
+  }
+
+  function f_EPTF_COAP_templateDB_add(in CoAP_Template p_template)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    if (f_EPTF_COAP_templateDB_lookUp(p_template.id)!=-1)
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " template is already added with id: ", p_template.id));
+      return -1;
+    }
+
+    var integer v_idx := sizeof(v_COAP_templateDB.data);
+    v_COAP_templateDB.data[v_idx] := p_template;
+    f_EPTF_str2int_HashMap_Insert(v_COAP_templateDB.hashRef, p_template.id, v_idx);
+
+    f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " template was added with id: ", p_template.id, " at idx: ",v_idx));
+
+    return v_idx;
+  }
+
+  function f_EPTF_COAP_templateDB_lookUp(in charstring p_id)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    var integer    vl_idx := -1;
+    if (not f_EPTF_str2int_HashMap_Find(v_COAP_templateDB.hashRef, p_id, vl_idx))
+    {
+      vl_idx := -1;
+    }
+
+    return vl_idx;
+  }
+
+  function f_EPTF_COAP_templateDB_get(in integer p_idx, inout CoAP_ReqResp p_pdu)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (p_idx < sizeof(v_COAP_templateDB.data) and p_idx >= 0)
+    {
+      f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " template is fetched with idx: ", p_idx));
+      p_pdu := v_COAP_templateDB.data[p_idx].msg;
+    }
+  }
+
+  function f_EPTF_COAP_templateDB_cleanUp()
+  runs on EPTF_COAP_LGen_CT
+  {
+    v_COAP_templateDB.data := {};
+    f_EPTF_str2int_HashMap_Delete("EPTF_COAP_templateDB_Hash");
+  }
+
+  function f_EPTF_COAP_getNextMID(in COAP_StepCtx p_ctx)
+  runs on EPTF_COAP_LGen_CT
+  return integer
+  {
+    if (v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextMID < 65535)
+    {
+      v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextMID := v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextMID + 1;
+    }
+    else
+    {
+      v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextMID := 0;
+    }
+    return v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextMID;
+  }
+
+  function f_EPTF_COAP_getNextToken(in COAP_StepCtx p_ctx)
+  runs on EPTF_COAP_LGen_CT
+  return octetstring
+  {
+    if (v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextToken < tsp_EPTF_COAP_maxToken)
+    {
+      v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextToken := v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextToken + 1;
+    }
+    else
+    {
+      v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextToken := 0;
+    }
+    return int2oct(v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].nextToken, 4);
+  }
+
+  function f_EPTF_COAP_LGen_receiveMessage(in EPTF_COAP_PDU pl_message)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " ", pl_message));
+
+    v_COAP_msgToProcess := pl_message;
+
+    var boolean v_duplicate := not f_EPTF_COAP_stack_fromEnv(v_COAP_msgToProcess);
+
+    if (vf_COAP_msgReceived != null)
+    {
+      vf_COAP_msgReceived.apply(v_COAP_msgToProcess, v_duplicate);
+    }
+  }
+
+  function f_EPTF_COAP_LGen_receiveEvent(in ASP_Event p_event)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " ", p_event));
+  }
+
+  function f_EPTF_COAP_LGen_transportApiResponse(in EPTF_COAP_Transport_Response pl_rsp)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_VERBOSE(log2str("api response: ", pl_rsp));
+    if (pl_rsp.succ)
+    {
+      f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_transportSucc, pl_rsp.eIdx, pl_rsp.fsmIdx, {});
+    }
+    else
+    {
+      f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_transportFail, pl_rsp.eIdx, pl_rsp.fsmIdx, {});
+    }
+  }
+
+  function f_EPTF_COAP_stack_fromApp(inout EPTF_COAP_PDU p_msg, in COAP_StepCtx p_ctx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    // New Req-Resp
+    if (v_COAP_FsmCtxDB.data[p_ctx.fsmCtxIdx].rrIdx == -1)
+    {
+      f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " new request response"));
+
+      var COAP_RR vl_rr := c_COAP_RR_init;
+      vl_rr.eIdx := p_ctx.eIdx;
+      vl_rr.fsmIdx := p_ctx.fsmIdx;
+      vl_rr.fsmCtxIdx := p_ctx.fsmCtxIdx;
+      vl_rr.addrIdx := v_COAP_EntityCtxDB.data[p_ctx.eCtxIdx].localAddressIdx;
+      vl_rr.token := f_EPTF_COAP_getNextToken(p_ctx);
+      vl_rr.state.client := IDLE;
+      p_msg.pdu.token := vl_rr.token;
+      var integer vl_rrIdx := f_EPTF_COAP_rrDB_add(vl_rr);
+      f_EPTF_COAP_rr_setState(vl_rrIdx, {client := IDLE});
+
+      v_COAP_FsmCtxDB.data[p_ctx.fsmCtxIdx].rrIdx := vl_rrIdx;
+
+      f_EPTF_COAP_rr_handleMsg(p_msg, v_COAP_FsmCtxDB.data[p_ctx.fsmCtxIdx].rrIdx);
+    }
+    // Ongoing Req-Resp
+    else
+    {
+      f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " ongoing request response"));
+      f_EPTF_COAP_rr_handleMsg(p_msg, v_COAP_FsmCtxDB.data[p_ctx.fsmCtxIdx].rrIdx);
+    }
+  }
+
+  function f_EPTF_COAP_stack_fromEnv(inout EPTF_COAP_PDU p_msg)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    // Answer for an ongoing tr
+    var integer vl_trIdx := f_EPTF_COAP_trDB_lookUp(p_msg.transportParams.localAddress, p_msg.pdu.header.message_id, OUTGOING);
+    if (vl_trIdx >= 0)
+    {
+      f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " answer for ongoing tr"));
+      f_EPTF_COAP_tr_fromEnv(p_msg, vl_trIdx);
+      return true;
+    }
+    else
+    {
+      vl_trIdx := f_EPTF_COAP_trDB_lookUp(p_msg.transportParams.localAddress, p_msg.pdu.header.message_id, INCOMING);
+
+      // Deduplication. Already ongoing tr for a request
+      if (vl_trIdx != -1 and (p_msg.pdu.header.msg_type == CONFIRMABLE or p_msg.pdu.header.msg_type == NON_CONFIRMABLE))
+      {
+        f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " duplicate received ", p_msg));
+        if (ispresent(v_COAP_trDB.data[vl_trIdx].cache))
+        {
+          f_EPTF_COAP_tr_send(v_COAP_trDB.data[vl_trIdx].cache, vl_trIdx);
+        }
+        return false;
+      }
+      // New incoming request
+      else
+      {
+        f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " new incoming request ", p_msg));
+
+        // Create new tr
+        var integer vl_eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(p_msg.eIdx, v_COAP_bIdx, 0);
+        var COAP_Transaction vl_tr := c_COAP_Transaction_init;
+        vl_tr.mid := p_msg.pdu.header.message_id;
+        vl_tr.eIdx := p_msg.eIdx;
+        vl_tr.addrIdx := v_COAP_EntityCtxDB.data[vl_eCtxIdx].localAddressIdx;
+        vl_tr.state := CLOSED;
+        vl_tr.direction := INCOMING;
+
+        vl_trIdx := f_EPTF_COAP_trDB_add(vl_tr);
+        f_EPTF_COAP_tr_setState(vl_trIdx, CLOSED);
+
+        f_EPTF_COAP_tr_fromEnv(v_COAP_msgToProcess, vl_trIdx);
+        return true;
+      }
+    }
+  }
+
+  function f_EPTF_COAP_rr_handleMsg(inout EPTF_COAP_PDU p_msg, in integer p_rrIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " rr [",v_COAP_rrDB.data[p_rrIdx].token,"] current state: ",v_COAP_rrDB.data[p_rrIdx].state));
+
+    f_EPTF_COAP_setCtx(v_COAP_rrDB.data[p_rrIdx].eIdx, v_COAP_rrDB.data[p_rrIdx].fsmIdx, v_COAP_ctx);
+
+    // RR: Client
+    if (ischosen(v_COAP_rrDB.data[p_rrIdx].state.client))
+    {
+      // State: IDLE
+      if (v_COAP_rrDB.data[p_rrIdx].state.client == IDLE)
+      {
+        // appIn: request
+        if (f_EPTF_COAP_isRequest(p_msg.pdu))
+        {
+          // Create new TR
+          var COAP_Transaction vl_tr := c_COAP_Transaction_init;
+          vl_tr.mid := f_EPTF_COAP_getNextMID(v_COAP_ctx);
+          vl_tr.eIdx := v_COAP_ctx.eIdx;
+          vl_tr.rrIdx := p_rrIdx;
+          vl_tr.addrIdx := v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx;
+          vl_tr.state := CLOSED;
+          vl_tr.direction := OUTGOING;
+          p_msg.pdu.header.message_id := vl_tr.mid;
+          var integer vl_trIdx := f_EPTF_COAP_trDB_add(vl_tr);
+          f_EPTF_COAP_tr_setState(vl_trIdx, CLOSED);
+
+          v_COAP_rrDB.data[p_rrIdx].trIdx := vl_trIdx;
+
+          // trOut.send
+          v_COAP_rrDB.data[p_rrIdx].request := p_msg;
+          f_EPTF_COAP_tr_fromRR(p_msg, v_COAP_ctx, p_rrIdx, v_COAP_rrDB.data[p_rrIdx].trIdx);
+
+          // next state: WAITING
+          f_EPTF_COAP_rr_setState(p_rrIdx, {client := WAITING});
+        }
+        else
+        {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " only request can be handled in rr::client::IDLE. Ignoring:", p_msg));
+        }
+      }
+      // State: WAITING
+      else if (v_COAP_rrDB.data[p_rrIdx].state.client == WAITING)
+      {
+        // trIn: response
+        if (f_EPTF_COAP_isResponse(p_msg.pdu))
+        {
+          v_COAP_rrDB.data[p_rrIdx].response := p_msg;
+
+          // If response is CON then immediatelly answer with empty ack
+          if (p_msg.pdu.header.msg_type == CONFIRMABLE and
+              v_COAP_rrDB.data[p_rrIdx].trIdx != -1 and
+              ispresent(v_COAP_rrDB.data[p_rrIdx].request)
+          ) {
+            var EPTF_COAP_PDU vl_empty_ack := v_COAP_rrDB.data[p_rrIdx].request;
+            vl_empty_ack.pdu := valueof(t_CoAP_EmptyAck);
+            //vl_empty_ack.pdu.token := int2oct(v_COAP_rrDB.data[p_rrIdx].token, 4);
+
+            f_EPTF_COAP_tr_fromRR(vl_empty_ack, v_COAP_ctx, p_rrIdx, v_COAP_rrDB.data[p_rrIdx].trIdx);
+          }
+
+          // report to app
+          f_EPTF_COAP_dispatchEventsForCode(
+            p_msg.pdu.header.code,
+            v_COAP_rrDB.data[p_rrIdx].eIdx,
+            v_COAP_rrDB.data[p_rrIdx].fsmIdx,
+            {}
+          );
+          p_msg.fsmIdx := v_COAP_rrDB.data[p_rrIdx].fsmIdx;
+          // finish
+          f_EPTF_COAP_rr_remove(p_rrIdx);
+        }
+        else
+        {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId," only response can be handled in rr::client::WAITING. Ignoring: ", p_msg));
+        }
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId," rr: unknown client state ", v_COAP_rrDB.data[p_rrIdx].state.client));
+      }
+    }
+    // RR: Server
+    else
+    {
+      // State: IDLE
+      if (v_COAP_rrDB.data[p_rrIdx].state.server == IDLE)
+      {
+        v_COAP_rrDB.data[p_rrIdx].remoteAddress := p_msg.transportParams.remoteAddress;
+        v_COAP_rrDB.data[p_rrIdx].request := p_msg;
+
+        // appIn: request && CON
+        if (p_msg.pdu.header.msg_type == CONFIRMABLE)
+        {
+          // next state: SERVING
+          f_EPTF_COAP_rr_setState(p_rrIdx, {server := SERVING});
+        }
+        // appIn: request && NON
+        else if (p_msg.pdu.header.msg_type == NON_CONFIRMABLE)
+        {
+          // next state: SEPARATE
+          f_EPTF_COAP_rr_setState(p_rrIdx, {server := SEPARATE});
+        }
+        else
+        {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " message type not handled in rr:server::IDLE ", p_msg));
+        }
+      }
+      // State: SEPARATE
+      else if (v_COAP_rrDB.data[p_rrIdx].state.server == SEPARATE)
+      {
+        // appIn: response
+        if (f_EPTF_COAP_isResponse(p_msg.pdu))
+        {
+          p_msg.pdu.token := v_COAP_rrDB.data[p_rrIdx].token;
+
+          // create new TR
+          var COAP_Transaction vl_tr := c_COAP_Transaction_init;
+          vl_tr.mid := f_EPTF_COAP_getNextMID(v_COAP_ctx);
+          vl_tr.eIdx := v_COAP_ctx.eIdx;
+          vl_tr.rrIdx := p_rrIdx;
+          vl_tr.addrIdx := v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx;
+          vl_tr.state := CLOSED;
+          vl_tr.direction := OUTGOING;
+          p_msg.pdu.header.message_id := vl_tr.mid;
+          var integer vl_trIdx := f_EPTF_COAP_trDB_add(vl_tr);
+          f_EPTF_COAP_tr_setState(vl_trIdx, CLOSED);
+
+          v_COAP_rrDB.data[p_rrIdx].trIdx := vl_trIdx;
+
+          if (ispresent(v_COAP_rrDB.data[p_rrIdx].remoteAddress))
+          {
+            p_msg.transportParams.remoteAddress := v_COAP_rrDB.data[p_rrIdx].remoteAddress;
+          }
+
+          // trOut.send
+          v_COAP_rrDB.data[p_rrIdx].response := p_msg;
+          f_EPTF_COAP_tr_fromRR(p_msg, v_COAP_ctx, p_rrIdx, v_COAP_rrDB.data[p_rrIdx].trIdx);
+
+          // finish
+          f_EPTF_COAP_rr_remove(p_rrIdx);
+        }
+        else
+        {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId," only response can be handled in rr::server::SEPARATE. Ignoring: ", p_msg));
+        }
+      }
+      // State: SERVING
+      else if (v_COAP_rrDB.data[p_rrIdx].state.server == SERVING)
+      {
+        // appIn: response
+        if (f_EPTF_COAP_isResponse(p_msg.pdu) and p_msg.pdu.header.msg_type == ACKNOWLEDGEMENT)
+        {
+          // Get the TR
+          if (v_COAP_rrDB.data[p_rrIdx].trIdx != -1)
+          {
+            p_msg.pdu.token := v_COAP_rrDB.data[p_rrIdx].token;
+
+            if (ispresent(v_COAP_rrDB.data[p_rrIdx].remoteAddress))
+            {
+              p_msg.transportParams.remoteAddress := v_COAP_rrDB.data[p_rrIdx].remoteAddress;
+            }
+
+            // trOut.send
+            v_COAP_rrDB.data[p_rrIdx].response := p_msg;
+            f_EPTF_COAP_tr_fromRR(p_msg, v_COAP_ctx, p_rrIdx, v_COAP_rrDB.data[p_rrIdx].trIdx);
+
+            f_EPTF_COAP_rr_remove(p_rrIdx);
+          }
+          else
+          {
+            f_EPTF_COAP_Logging_WARNING(log2str(%definitionId," couldn't find ongoing transaction in rr::server::SERVING. Ignoring: ", p_msg));
+          }
+        }
+        // appIn: empty ACK
+        else if (f_EPTF_COAP_isEmpty(p_msg.pdu) and p_msg.pdu.header.msg_type == ACKNOWLEDGEMENT)
+        {
+          // Get the TR
+          if (v_COAP_rrDB.data[p_rrIdx].trIdx != -1)
+          {
+            // Empty ACK has no token
+            //p_msg.pdu.token := int2oct(v_COAP_rrDB.data[p_rrIdx].token, 4);
+
+            if (ispresent(v_COAP_rrDB.data[p_rrIdx].remoteAddress))
+            {
+              p_msg.transportParams.remoteAddress := v_COAP_rrDB.data[p_rrIdx].remoteAddress;
+            }
+
+            // trOut.send
+            f_EPTF_COAP_tr_fromRR(p_msg, v_COAP_ctx, p_rrIdx, v_COAP_rrDB.data[p_rrIdx].trIdx);
+
+			f_EPTF_COAP_rr_setState(p_rrIdx, {server := SEPARATE});
+          }
+          else
+          {
+            f_EPTF_COAP_Logging_WARNING(log2str(%definitionId," couldn't find ongoing transaction in rr::server::SERVING. Ignoring: ", p_msg));
+          }
+        }
+        else
+        {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId," response must be an ACK, message cannot be handled in rr::server::SERVING. Ignoring: ", p_msg));
+        }
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, "unknown server state ", v_COAP_rrDB.data[p_rrIdx].state.server));
+      }
+    }
+  }
+
+  function f_EPTF_COAP_rr_reset(in integer p_rrIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    // RR: Client
+    if (ischosen(v_COAP_rrDB.data[p_rrIdx].state.client))
+    {
+      // State: WAITING
+      if (v_COAP_rrDB.data[p_rrIdx].state.client == WAITING)
+      {
+        f_EPTF_COAP_dispatchEvent(
+          c_COAP_eventIdx_trRST,
+          v_COAP_rrDB.data[p_rrIdx].eIdx,
+          v_COAP_rrDB.data[p_rrIdx].fsmIdx,
+          {}
+        );
+        f_EPTF_COAP_rr_remove(p_rrIdx);
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " reset only handled rr:client::WAITING"));
+      }
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " reset not handled in rr:server"));
+    }
+  }
+
+  function f_EPTF_COAP_rr_timeout(in integer p_rrIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    // RR: Client
+    if (ischosen(v_COAP_rrDB.data[p_rrIdx].state.client))
+    {
+      // State: WAITING
+      if (v_COAP_rrDB.data[p_rrIdx].state.client == WAITING)
+      {
+        f_EPTF_COAP_dispatchEvent(
+          c_COAP_eventIdx_trTimeout,
+          v_COAP_rrDB.data[p_rrIdx].eIdx,
+          v_COAP_rrDB.data[p_rrIdx].fsmIdx,
+          {}
+        );
+        f_EPTF_COAP_rr_remove(p_rrIdx);
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " reset only handled rr:client::WAITING"));
+      }
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " reset not handled in rr:server"));
+    }
+  }
+
+  function f_EPTF_COAP_rr_cancel(in integer p_rrIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    // RR: Client
+    if (ischosen(v_COAP_rrDB.data[p_rrIdx].state.client))
+    {
+      // State: WAITING
+      if (v_COAP_rrDB.data[p_rrIdx].state.client == WAITING)
+      {
+        if (v_COAP_rrDB.data[p_rrIdx].trIdx != -1)
+        {
+          f_EPTF_COAP_tr_cancel(v_COAP_rrDB.data[p_rrIdx].trIdx);
+
+          f_EPTF_COAP_rr_remove(p_rrIdx);
+        }
+        else
+        {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " there is no ongoing transaction to handle cancel"));
+        }
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " cancel only handled rr:client::WAITING"));
+      }
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " cance; not handled in rr:server"));
+    }
+  }
+
+  function f_EPTF_COAP_rr_remove(in integer p_rrIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (ischosen(v_COAP_rrDB.data[p_rrIdx].state.client))
+    {
+      f_EPTF_COAP_rr_setState(p_rrIdx, {client := REMOVING});
+    }
+    else
+    {
+      f_EPTF_COAP_rr_setState(p_rrIdx, {server := REMOVING});
+    }
+    //action(%definitionId, " rr: (rrIdx: ",p_rrIdx,") ",v_COAP_rrDB.data[p_rrIdx]);
+
+    if (v_COAP_rrDB.data[p_rrIdx].trIdx != -1)
+    {
+      if (v_COAP_trDB.data[v_COAP_rrDB.data[p_rrIdx].trIdx].rrIdx == p_rrIdx)
+      {
+        v_COAP_trDB.data[v_COAP_rrDB.data[p_rrIdx].trIdx].rrIdx := -1;
+      }
+    }
+
+    if (v_COAP_rrDB.data[p_rrIdx].fsmCtxIdx != -1)
+    {
+      //action(%definitionId, " fsm: ",v_COAP_FsmCtxDB.data[v_COAP_rrDB.data[p_rrIdx].fsmCtxIdx]);
+      if (v_COAP_FsmCtxDB.data[v_COAP_rrDB.data[p_rrIdx].fsmCtxIdx].rrIdx == p_rrIdx)
+      {
+        v_COAP_FsmCtxDB.data[v_COAP_rrDB.data[p_rrIdx].fsmCtxIdx].rrIdx := -1;
+      }
+    }
+
+    f_EPTF_COAP_rrDB_remove(p_rrIdx);
+  }
+
+  function f_EPTF_COAP_rr_setState(in integer p_rrIdx, in COAP_RR_State p_nextState)
+  runs on EPTF_COAP_LGen_CT
+  {
+    v_COAP_rrDB.data[p_rrIdx].state := p_nextState;
+	f_EPTF_COAP_Logging_VERBOSE(log2str("rr [", v_COAP_rrDB.data[p_rrIdx].token,"] next state: ", v_COAP_rrDB.data[p_rrIdx].state));
+  }
+
+  function f_EPTF_COAP_tr_fromRR(inout EPTF_COAP_PDU p_msg, in COAP_StepCtx p_ctx, in integer p_rrIdx, in integer p_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str("current state: ", v_COAP_trDB.data[p_trIdx].state));
+    // State: CLOSED
+    if (v_COAP_trDB.data[p_trIdx].state == CLOSED)
+    {
+      // rrIn: CON
+      if (p_msg.pdu.header.msg_type == CONFIRMABLE)
+      {
+        f_EPTF_COAP_tr_startT_retransmit(p_trIdx);
+        // start EXCHANGE_LIFETIME
+        f_EPTF_COAP_tr_startT_lifetime(p_trIdx, tsp_EPTF_COAP_EXCHANGE_LIFETIME);
+        // send to env
+        f_EPTF_COAP_tr_send(p_msg, p_trIdx);
+        // next state: RELIABLE_TX
+        f_EPTF_COAP_tr_setState(p_trIdx, RELIABLE_TX);
+      }
+      // rrIn: NON
+      else if (p_msg.pdu.header.msg_type == NON_CONFIRMABLE)
+      {
+        // out.send
+        f_EPTF_COAP_tr_send(p_msg, p_trIdx);
+        // finish
+        f_EPTF_COAP_tr_remove(p_trIdx);
+      }
+      // rrIn: ACK
+      else if (p_msg.pdu.header.msg_type == ACKNOWLEDGEMENT)
+      {
+        // out.send
+        f_EPTF_COAP_tr_send(p_msg, p_trIdx);
+        // finish
+        f_EPTF_COAP_tr_remove(p_trIdx);
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, "cannot handle msg type ",p_msg.pdu.header.msg_type," in state ",v_COAP_trDB.data[p_trIdx].state));
+      }
+    }
+    // State: ACK_PENDING
+    else if (v_COAP_trDB.data[p_trIdx].state == ACK_PENDING)
+    {
+      // rrIn: ACK
+      if (p_msg.pdu.header.msg_type == ACKNOWLEDGEMENT)
+      {
+        p_msg.pdu.header.message_id := v_COAP_trDB.data[p_trIdx].mid;
+        // store in cache
+        v_COAP_trDB.data[p_trIdx].cache := p_msg;
+        // out.send
+        f_EPTF_COAP_tr_send(p_msg, p_trIdx);
+        // next state: CLOSED
+        f_EPTF_COAP_tr_setState(p_trIdx, CLOSED);
+      }
+      // rrIn: RST
+      else if (p_msg.pdu.header.msg_type == RESET)
+      {
+        p_msg.pdu.header.message_id := v_COAP_trDB.data[p_trIdx].mid;
+        // store in cache
+        v_COAP_trDB.data[p_trIdx].cache := p_msg;
+        // out.send
+        f_EPTF_COAP_tr_send(p_msg, p_trIdx);
+        // next state: CLOSED
+        f_EPTF_COAP_tr_setState(p_trIdx, CLOSED);
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, "cannot handle msg type ",p_msg.pdu.header.msg_type," in state ",v_COAP_trDB.data[p_trIdx].state));
+      }
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_ERROR(log2str(%definitionId, "unknown state ", p_msg));
+    }
+  }
+
+  function f_EPTF_COAP_tr_fromEnv(inout EPTF_COAP_PDU p_msg, in integer p_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, "current state: ", v_COAP_trDB.data[p_trIdx].state));
+    // State: CLOSED
+    if (v_COAP_trDB.data[p_trIdx].state == CLOSED)
+    {
+      // envIn: NON
+      if (p_msg.pdu.header.msg_type == NON_CONFIRMABLE)
+      {
+        // start NON_LIFETIME
+        f_EPTF_COAP_tr_startT_lifetime(p_trIdx, tsp_EPTF_COAP_NON_LIFETIME);
+        // next state: CLOSED
+        f_EPTF_COAP_tr_setState(p_trIdx, CLOSED);
+        // rrOut.send
+        if (v_COAP_trDB.data[p_trIdx].rrIdx == -1)
+        {
+          //
+          var integer vl_rrIdx := f_EPTF_COAP_rrDB_lookUp(p_msg.transportParams.localAddress, p_msg.pdu.token);
+          if (vl_rrIdx >= 0)
+          {
+            v_COAP_trDB.data[p_trIdx].rrIdx := vl_rrIdx;
+            v_COAP_rrDB.data[vl_rrIdx].trIdx := p_trIdx;
+            f_EPTF_COAP_rr_handleMsg(p_msg, vl_rrIdx);
+          }
+          else
+          {
+            f_EPTF_COAP_dispatchEventsForCode(
+              p_msg.pdu.header.code,
+              p_msg.eIdx,
+              -1,
+              {}
+            );
+          }
+        }
+        else
+        {
+          f_EPTF_COAP_rr_handleMsg(p_msg, v_COAP_trDB.data[p_trIdx].rrIdx);
+        }
+      }
+      // envIn: CON
+      else if (p_msg.pdu.header.msg_type == CONFIRMABLE)
+      {
+        // start EXCHANGE_LIFETIME
+        f_EPTF_COAP_tr_startT_lifetime(p_trIdx, tsp_EPTF_COAP_EXCHANGE_LIFETIME);
+        // next state: ACK_PENDING
+        f_EPTF_COAP_tr_setState(p_trIdx, ACK_PENDING);
+        // rrOut.send
+        if (v_COAP_trDB.data[p_trIdx].rrIdx == -1)
+        {
+          //
+          var integer vl_rrIdx := f_EPTF_COAP_rrDB_lookUp(p_msg.transportParams.localAddress, p_msg.pdu.token);
+          if (vl_rrIdx >= 0)
+          {
+            v_COAP_trDB.data[p_trIdx].rrIdx := vl_rrIdx;
+            v_COAP_rrDB.data[vl_rrIdx].trIdx := p_trIdx;
+            f_EPTF_COAP_rr_handleMsg(p_msg, vl_rrIdx);
+          }
+          else
+          {
+            f_EPTF_COAP_dispatchEventsForCode(
+              p_msg.pdu.header.code,
+              p_msg.eIdx,
+              -1,
+              {}
+            );
+          }
+        }
+        else
+        {
+          f_EPTF_COAP_rr_handleMsg(p_msg, v_COAP_trDB.data[p_trIdx].rrIdx);
+        }
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, "cannot handle msg type ",p_msg.pdu.header.msg_type," in state ",v_COAP_trDB.data[p_trIdx].state));
+      }
+    }
+    // State: RELIABLE_TX
+    else if (v_COAP_trDB.data[p_trIdx].state == RELIABLE_TX)
+    {
+      if (p_msg.pdu.header.msg_type == ACKNOWLEDGEMENT)
+      {
+        // cancel T retransmission
+        f_EPTF_COAP_tr_cancelT_retransmit(p_trIdx);
+        if (not f_EPTF_COAP_isEmpty(p_msg.pdu))
+        {
+          f_EPTF_COAP_rr_handleMsg(p_msg, v_COAP_trDB.data[p_trIdx].rrIdx);
+        }
+        // next state: CLOSED
+        f_EPTF_COAP_tr_setState(p_trIdx, CLOSED);
+      }
+      else if (p_msg.pdu.header.msg_type == RESET)
+      {
+        // cancel T retransmission
+        f_EPTF_COAP_tr_cancelT_retransmit(p_trIdx);
+        // report reset
+        f_EPTF_COAP_rr_reset(v_COAP_trDB.data[p_trIdx].rrIdx);
+        // next state: CLOSED
+        f_EPTF_COAP_tr_setState(p_trIdx, CLOSED);
+      }
+      else
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, "cannot handle msg type ",p_msg.pdu.header.msg_type," in state ",v_COAP_trDB.data[p_trIdx].state));
+      }
+    }
+    else if (v_COAP_trDB.data[p_trIdx].state == ACK_PENDING)
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " messages from environment in ACK_PENDING are not expected"));
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_ERROR(log2str(%definitionId, " unknown state"));
+    }
+  }
+
+  function f_EPTF_COAP_tr_cancel(in integer p_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (v_COAP_trDB.data[p_trIdx].state == RELIABLE_TX)
+    {
+        // cancel T retransmission
+        f_EPTF_COAP_tr_cancelT_retransmit(p_trIdx);
+        // next state: CLOSED
+        f_EPTF_COAP_tr_setState(p_trIdx, CLOSED);
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " cancel only handled in RELIABLE_ACK state"));
+    }
+  }
+
+  function f_EPTF_COAP_tr_lifetime(in EPTF_ScheduledAction pl_action, in integer pl_eventIndex)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    var integer vl_trIdx := pl_action.actionId[0];
+    v_COAP_trDB.data[vl_trIdx].lifetimeTimer := -1;
+
+    if (v_COAP_trDB.data[vl_trIdx].state == RELIABLE_TX)
+    {
+      // cancel T retransmission
+      f_EPTF_COAP_tr_cancelT_retransmit(vl_trIdx);
+      // report trTimeout event
+      f_EPTF_COAP_rr_timeout(v_COAP_trDB.data[vl_trIdx].rrIdx);
+      // next state: CLOSED
+      f_EPTF_COAP_tr_setState(vl_trIdx, CLOSED);
+    }
+
+    f_EPTF_COAP_tr_remove(vl_trIdx);
+
+    return true;
+  }
+
+  function f_EPTF_COAP_tr_retransmit(in EPTF_ScheduledAction pl_action, in integer pl_eventIndex)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    var integer vl_trIdx := pl_action.actionId[0];
+    v_COAP_trDB.data[vl_trIdx].retransmitTimer := -1;
+
+    if (ispresent(v_COAP_trDB.data[vl_trIdx].cache))
+    {
+      f_EPTF_COAP_tr_startT_retransmit(vl_trIdx);
+      f_EPTF_COAP_tr_send(v_COAP_trDB.data[vl_trIdx].cache, vl_trIdx);
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " cannot retransmit empty cache"));
+    }
+
+    return true;
+  }
+
+  function f_EPTF_COAP_tr_startT_retransmit(in integer pl_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    var boolean retval;
+    var EPTF_ActionId vl_actionId;
+    var float vl_time := v_COAP_trDB.data[pl_trIdx].retransmitTimerValue;
+
+    vl_actionId[0] := pl_trIdx;
+
+    retval := f_EPTF_SchedulerComp_scheduleAction(
+      f_EPTF_SchedulerComp_snapshotTime() + vl_time,
+      refers(f_EPTF_COAP_tr_retransmit),
+      vl_actionId,
+      v_COAP_trDB.data[pl_trIdx].retransmitTimer
+    );
+
+    // start retransTimeout (TODO calculate next rentransmission)
+    v_COAP_trDB.data[pl_trIdx].retransmitTimerValue := v_COAP_trDB.data[pl_trIdx].retransmitTimerValue * 2.0;
+
+    return retval;
+  }
+
+  function f_EPTF_COAP_tr_cancelT_retransmit(in integer pl_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (v_COAP_trDB.data[pl_trIdx].retransmitTimer >= 0)
+    {
+      if(not f_EPTF_SchedulerComp_CancelEvent(v_COAP_trDB.data[pl_trIdx].retransmitTimer))
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId,": could not cancel timer"));
+      }
+      v_COAP_trDB.data[pl_trIdx].retransmitTimer := -1;
+    }
+  }
+
+  function f_EPTF_COAP_tr_startT_lifetime(in integer pl_trIdx, in float pl_time)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    var boolean retval;
+    var EPTF_ActionId vl_actionId;
+
+    vl_actionId[0] := pl_trIdx;
+
+    retval := f_EPTF_SchedulerComp_scheduleAction(
+      f_EPTF_SchedulerComp_snapshotTime() + pl_time,
+      refers(f_EPTF_COAP_tr_lifetime),
+      vl_actionId,
+      v_COAP_trDB.data[pl_trIdx].lifetimeTimer
+    );
+
+    return retval;
+  }
+
+  function f_EPTF_COAP_tr_cancelT_lifetime(in integer pl_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (v_COAP_trDB.data[pl_trIdx].lifetimeTimer >= 0)
+    {
+      if(not f_EPTF_SchedulerComp_CancelEvent(v_COAP_trDB.data[pl_trIdx].lifetimeTimer))
+      {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId,": could not cancel timer"));
+      }
+      v_COAP_trDB.data[pl_trIdx].lifetimeTimer := -1;
+    }
+  }
+
+  function f_EPTF_COAP_tr_send(inout EPTF_COAP_PDU p_msg, in integer p_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    v_COAP_trDB.data[p_trIdx].cache := p_msg;
+    vf_EPTF_COAP_Transport_send.apply(p_msg);
+  }
+
+  function f_EPTF_COAP_tr_remove(in integer p_trIdx)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_tr_setState(p_trIdx, REMOVING);
+
+    f_EPTF_COAP_tr_cancelT_lifetime(p_trIdx);
+    f_EPTF_COAP_tr_cancelT_retransmit(p_trIdx);
+
+    if (v_COAP_trDB.data[p_trIdx].rrIdx != -1)
+    {
+      if (v_COAP_rrDB.data[v_COAP_trDB.data[p_trIdx].rrIdx].trIdx == p_trIdx)
+      {
+        v_COAP_rrDB.data[v_COAP_trDB.data[p_trIdx].rrIdx].trIdx := -1;
+      }
+    }
+    f_EPTF_COAP_trDB_remove(p_trIdx);
+  }
+
+  function f_EPTF_COAP_tr_setState(in integer p_trIdx, in COAP_Transaction_State p_nextState)
+  runs on EPTF_COAP_LGen_CT
+  {
+    v_COAP_trDB.data[p_trIdx].state := p_nextState;
+	f_EPTF_COAP_Logging_VERBOSE(log2str("tr [", v_COAP_trDB.data[p_trIdx].mid,"] next state: ", v_COAP_trDB.data[p_trIdx].state));
+  }
+
+  function f_EPTF_COAP_Logging_VERBOSE(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+    	f_EPTF_Logging_debugV2(pl_message, v_COAP_loggingMaskId, {c_COAP_LGen_Logging_DEBUGV});
+	}
+  }
+
+  function f_EPTF_COAP_Logging_DEBUG(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+	    f_EPTF_Logging_debugV2(pl_message, v_COAP_loggingMaskId, {c_COAP_LGen_Logging_DEBUG});
+	}
+  }
+
+  function f_EPTF_COAP_Logging_WARNING(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+	    f_EPTF_Logging_debugV2(pl_message, v_COAP_loggingMaskId, {c_COAP_LGen_Logging_WARNING});
+	}
+  }
+
+  function f_EPTF_COAP_Logging_ERROR(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+    	f_EPTF_Logging_debugV2(pl_message, v_COAP_loggingMaskId, {c_COAP_LGen_Logging_ERROR});
+	}
+  }
+
+  function f_EPTF_COAP_declareEvents()
+  runs on EPTF_COAP_LGen_CT
+  {
+    var integer vl_dummy;
+
+    if (
+      c_COAP_eventIdx_EMPTY != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_EMPTY) or
+      c_COAP_eventIdx_GET != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_GET) or
+      c_COAP_eventIdx_POST != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_POST) or
+      c_COAP_eventIdx_PUT != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_PUT) or
+      c_COAP_eventIdx_DELETE != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_DELETE)
+    ){
+      f_EPTF_LGenBase_log();
+      log("error"); mtc.stop
+    }
+
+    for (var integer i:=5; i<700; i:=i+1)
+    {
+      vl_dummy := f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, "COAP rsp: "&int2str(i));
+    }
+
+    if (
+      c_COAP_eventIdx_1xx != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_1xx) or
+      c_COAP_eventIdx_2xx != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_2xx) or
+      c_COAP_eventIdx_3xx != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_3xx) or
+      c_COAP_eventIdx_4xx != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_4xx) or
+      c_COAP_eventIdx_5xx != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_5xx) or
+      c_COAP_eventIdx_6xx != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_6xx) or
+      c_COAP_eventIdx_3xxto6xx != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_3xxto6xx) or
+      c_COAP_eventIdx_transportSucc != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_transportSucc) or
+      c_COAP_eventIdx_transportFail != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_transportFail) or
+      c_COAP_eventIdx_trRST != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_trRST) or
+      c_COAP_eventIdx_trTimeout != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_trTimeout)
+    ){
+      f_EPTF_LGenBase_log();
+      log("error"); mtc.stop
+    }
+  }
+
+  function f_EPTF_COAP_declareSteps()
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (
+      c_COAP_stepIdx_init != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_init, refers(f_COAP_step_init)}) or
+      c_COAP_stepIdx_cleanUp != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_cleanUp, refers(f_COAP_step_cleanUp) }) or
+      c_COAP_stepIdx_setLocalAddress != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_setLocalAddress, refers(f_COAP_step_setLocalAddress)}) or
+      c_COAP_stepIdx_setRemoteAddress_byIntIdx != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_setRemoteAddress_byIntIdx, refers(f_COAP_step_setRemoteAddress_byIntIdx)}) or
+      c_COAP_stepIdx_send != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_send, refers(f_COAP_step_send)}) or
+      c_COAP_stepIdx_loadTemplate_byIntIdx != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_loadTemplate_byIntIdx, refers(f_COAP_step_loadTemplate_byIntIdx)}) or
+      c_COAP_stepIdx_handleRequest != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_handleRequest, refers(f_COAP_step_handleRequest)}) or
+      c_COAP_stepIdx_sendResponse != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_sendResponse, refers(f_COAP_step_sendResponse)}) or
+      c_COAP_stepIdx_sendAccept != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_sendAccept, refers(f_COAP_step_sendAccept)}) or
+      c_COAP_stepIdx_startListening != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_startListening, refers(f_COAP_step_startListening)}) or
+      c_COAP_stepIdx_reportCoapEventForEntity != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_reportCoapEventForEntity, refers(f_COAP_step_reportCoapEventForEntity)}) or
+      c_COAP_stepIdx_loadTemplate_byStringId != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_loadTemplate_byStringId, refers(f_COAP_step_loadTemplate_byStringId)}) or
+      c_COAP_stepIdx_setRemoteAddress_byVars != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_setRemoteAddress_byVars, refers(f_COAP_step_setRemoteAddress_byVars)})
+    )
+    {
+      f_EPTF_LGenBase_log();
+      log("EPTF_COAP_LGen declaration error"); mtc.stop
+    }
+  }
+
+  function f_COAP_step_init(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    var integer vl_eIdx := pl_ptr.eIdx;
+    var integer vl_fsmIdx := pl_ptr.refContext.fCtxIdx;
+    var integer vl_newFsmCtxIdx := -1;
+
+    if (f_EPTF_COAP_isFsmInitialized(vl_eIdx, vl_fsmIdx, vl_newFsmCtxIdx)) { return }
+
+    vl_newFsmCtxIdx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_FsmCtxDB.queue);
+    f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_FsmCtxDB.queue);
+
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId, ":  initializing fsm ", vl_fsmIdx, " for entity ",vl_eIdx));
+
+    f_EPTF_LGenBase_setAppDataItemOfFsmCtx(vl_eIdx, vl_fsmIdx, v_COAP_bIdx, c_COAP_AppData_fsmCtxIdx, vl_newFsmCtxIdx);
+
+    v_COAP_FsmCtxDB.data[vl_newFsmCtxIdx] := c_COAP_FsmCtx_init;
+    v_COAP_FsmCtxDB.data[vl_newFsmCtxIdx].eIdx := vl_eIdx;
+  }
+
+  function f_COAP_step_cleanUp(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+     f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    var integer vl_eIdx:=pl_ptr.eIdx;
+    var integer vl_fsmIdx := pl_ptr.refContext.fCtxIdx;
+    var integer vl_fsmCtxIdx := -1;
+
+    if (not f_EPTF_COAP_isFsmInitialized(vl_eIdx, vl_fsmIdx, vl_fsmCtxIdx))
+    {
+      f_EPTF_COAP_Logging_DEBUG(%definitionId&": FSM has not been initialized");
+      return;
+    }
+
+    var integer vl_eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(vl_eIdx, v_COAP_bIdx, 0);
+
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId,": FSM database: ",v_COAP_FsmCtxDB.data[vl_fsmCtxIdx]));
+
+    //f_EPTF_SIP_CancelAllTimers_FSM(vl_userIdx, vl_FSMIdx);
+
+    v_COAP_FsmCtxDB.data[vl_fsmCtxIdx] := c_COAP_FsmCtx_init;
+
+    f_EPTF_FBQ_moveFromBusyToFreeTail(vl_fsmCtxIdx, v_COAP_FsmCtxDB.queue);
+
+    f_EPTF_LGenBase_setAppDataItemOfFsmCtx(vl_eIdx, vl_fsmIdx, v_COAP_bIdx, c_COAP_AppData_fsmCtxIdx, -1);
+  }
+
+  function f_COAP_step_setLocalAddress(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx);
+  }
+
+  function f_COAP_step_setRemoteAddress_byIntIdx(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].remoteAddressIdx);
+  }
+
+  function f_COAP_step_loadTemplate_byIntIdx(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    var integer vl_templateIdx := -1;
+    f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_templateIdx);
+
+    f_EPTF_COAP_templateDB_get(vl_templateIdx, v_COAP_msgToSend.pdu);
+  }
+
+  function f_COAP_step_loadTemplate_byStringId(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+	var charstring vl_templateId := f_EPTF_LGenBase_charstringValOfStep(pl_ptr);
+	var integer vl_templateIdx := f_EPTF_COAP_templateDB_lookUp(vl_templateId);
+
+	if (vl_templateIdx >= 0)
+	{
+      f_EPTF_COAP_templateDB_get(vl_templateIdx, v_COAP_msgToSend.pdu);
+    }
+    else
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId," Couldn't find template with id: ", vl_templateId));
+    }
+  }
+
+  function f_COAP_step_send(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId," ",pl_ptr));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    f_EPTF_COAP_addressDB_get(v_COAP_msgToSend.transportParams.localAddress, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx);
+    if (v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].rrIdx == -1)
+    {
+      // If there is no ongoing RR, we will send to the remote address
+      f_EPTF_COAP_addressDB_get(v_COAP_msgToSend.transportParams.remoteAddress, v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].remoteAddressIdx);
+    }
+    v_COAP_msgToSend.transportParams.proto := {udp := {}};
+    v_COAP_msgToSend.eIdx := v_COAP_ctx.eIdx;
+
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId," msg to send: ",v_COAP_msgToSend));
+
+    f_EPTF_COAP_stack_fromApp(v_COAP_msgToSend, v_COAP_ctx);
+
+    f_EPTF_SchedulerComp_refreshSnapshotTime();
+  }
+
+  function f_COAP_step_handleRequest(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    // New RR
+    var COAP_RR vl_rr := c_COAP_RR_init;
+    vl_rr.eIdx := v_COAP_ctx.eIdx;
+    vl_rr.fsmIdx := v_COAP_ctx.fsmIdx;
+    vl_rr.fsmCtxIdx := v_COAP_ctx.fsmCtxIdx;
+    vl_rr.addrIdx := v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx;
+    vl_rr.token := v_COAP_msgToProcess.pdu.token;
+    vl_rr.state.server := IDLE;
+
+    var integer vl_rrIdx := f_EPTF_COAP_rrDB_add(vl_rr);
+    v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].rrIdx := vl_rrIdx;
+
+    // Get TR
+    var integer vl_trIdx := f_EPTF_COAP_trDB_lookUp(v_COAP_msgToProcess.transportParams.localAddress, v_COAP_msgToProcess.pdu.header.message_id, INCOMING);
+    if (vl_trIdx < 0)
+    {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " couldn't find incoming transaction"));
+    }
+    v_COAP_trDB.data[vl_trIdx].rrIdx := vl_rrIdx;
+    v_COAP_rrDB.data[vl_rrIdx].trIdx := vl_trIdx;
+
+    f_EPTF_COAP_rr_handleMsg(v_COAP_msgToProcess, vl_rrIdx);
+  }
+
+  // Matches the msg_Type of response to the incoming request and the current state
+  // That is:
+  // - req.NON -> rsp.NON
+  // - req.CON && state.SERVING -> rsp.ACK
+  // - req.CON && state.SEPARATE -> rsp.CON
+  function f_COAP_step_sendResponse(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    // We need an ongoing RR!
+    if (v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].rrIdx != -1)
+    {
+      var integer vl_rrIdx := v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].rrIdx;
+      if (ischosen(v_COAP_rrDB.data[vl_rrIdx].state.server))
+      {
+        if (ispresent(v_COAP_rrDB.data[vl_rrIdx].request))
+        {
+          if (v_COAP_rrDB.data[vl_rrIdx].request.pdu.header.msg_type == NON_CONFIRMABLE) {
+            v_COAP_msgToSend.pdu.header.msg_type := NON_CONFIRMABLE;
+          }
+          else //if (v_COAP_rrDB.data[vl_rrIdx].request.pdu.header.msg_type == CONFIRMABLE)
+          {
+            if (v_COAP_rrDB.data[vl_rrIdx].state.server == SERVING) {
+              v_COAP_msgToSend.pdu.header.msg_type := ACKNOWLEDGEMENT;
+            }
+            else if (v_COAP_rrDB.data[vl_rrIdx].state.server == SEPARATE) {
+              v_COAP_msgToSend.pdu.header.msg_type := CONFIRMABLE;
+            }
+            else {
+              f_EPTF_COAP_Logging_ERROR(log2str(%definitionId, " unrecognized state"));
+            }
+          }
+          f_EPTF_COAP_addressDB_get(v_COAP_msgToSend.transportParams.localAddress, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx);
+          v_COAP_msgToSend.transportParams.proto := {udp := {}};
+          v_COAP_msgToSend.eIdx := v_COAP_ctx.eIdx;
+
+          f_EPTF_COAP_stack_fromApp(v_COAP_msgToSend, v_COAP_ctx);
+        }
+        else {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " there is no request received, therefore response cannot be sent!"));
+        }
+      }
+      else {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " ongoing rr must be a server, in a client rr no response can be sent!"));
+      }
+    }
+    else {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " there is no ongoing RR, therefore response cannot be sent!"));
+    }
+
+    f_EPTF_SchedulerComp_refreshSnapshotTime();
+  }
+
+  function f_COAP_step_sendAccept(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    // We need an ongoing RR!
+    if (v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].rrIdx != -1)
+    {
+      var integer vl_rrIdx := v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].rrIdx;
+      if (ischosen(v_COAP_rrDB.data[vl_rrIdx].state.server) and v_COAP_rrDB.data[vl_rrIdx].state.server == SERVING)
+      {
+        if (ispresent(v_COAP_rrDB.data[vl_rrIdx].request))
+        {
+          v_COAP_msgToSend.pdu := valueof(t_CoAP_EmptyAck);
+
+          f_EPTF_COAP_addressDB_get(v_COAP_msgToSend.transportParams.localAddress, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx);
+          v_COAP_msgToSend.transportParams.proto := {udp := {}};
+          v_COAP_msgToSend.eIdx := v_COAP_ctx.eIdx;
+
+          f_EPTF_COAP_stack_fromApp(v_COAP_msgToSend, v_COAP_ctx);
+        }
+        else {
+          f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " there is no request received, therefore empty ack response cannot be sent!"));
+        }
+      }
+      else {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " ongoing rr must be a server, and the rr must be in SERVING state!"));
+      }
+    }
+    else {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " there is no ongoing RR, therefore empty ack response cannot be sent!"));
+    }
+
+    f_EPTF_SchedulerComp_refreshSnapshotTime();
+  }
+
+  function f_COAP_step_startListening(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    var EPTF_COAP_Transport_Request vl_req := c_EPTF_COAP_Transport_Request_init;
+    vl_req.eIdx := v_COAP_ctx.eIdx;
+    vl_req.fsmIdx := v_COAP_ctx.fsmIdx;
+
+    f_EPTF_COAP_addressDB_get(vl_req.params.startListening.localAddress, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx);
+
+    vf_EPTF_COAP_Transport_apiRequest.apply(vl_req);
+  }
+
+
+  // 1st param: remoteHost: charstring
+  // 2nd param: remotePort: integer
+  function f_COAP_step_setRemoteAddress_byVars(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    var EPTF_IntegerList vl_varIds := {};
+    f_EPTF_LGenBase_fsmVarIdListFromStep(pl_ptr, vl_varIds);
+
+    if (sizeof(vl_varIds)==2)
+    {
+      var EPTF_Var_DirectContent vl_host, vl_port;
+      f_EPTF_Var_getContent(vl_varIds[0], vl_host);
+      f_EPTF_Var_getContent(vl_varIds[1], vl_port);
+
+      if (not ischosen(vl_host.charstringVal)) {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " first param is not charstring variable!"));
+        return;
+      }
+      if (not ischosen(vl_port.intVal)) {
+        f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " second param is not integer variable!"));
+        return;
+      }
+
+      f_EPTF_COAP_addressDB_add(
+        {
+          hostName := vl_host.charstringVal,
+          portNumber := vl_port.intVal
+        },
+        v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].remoteAddressIdx
+      );
+    }
+    else {
+      f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " two variables are needed as params!"));
+    }
+  }
+
+  function f_COAP_step_reportCoapEventForEntity(in EPTF_LGenBase_TestStepArgs pl_ptr)
+  runs on EPTF_COAP_LGen_CT
+  {
+    f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId));
+
+    if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; }
+
+    var integer vl_paramValue := -1;
+    f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_paramValue);
+
+	if (vl_paramValue == c_COAP_stepParam_true) {
+		v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].reportCoapEvent := true;
+	}
+	else {
+	  v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].reportCoapEvent := false;
+	}
+  }
+
+  function f_EPTF_COAP_setStepCtx(in EPTF_LGenBase_TestStepArgs pl_ptr, inout COAP_StepCtx p_ctx)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    if (not f_EPTF_COAP_isFsmInitialized(pl_ptr.eIdx, pl_ptr.refContext.fCtxIdx, p_ctx.fsmCtxIdx))
+    {
+      f_EPTF_COAP_Logging_WARNING(%definitionId &
+        ": FSM has not been initialized. The f_COAP_step_init function must be called as first step in the FSMs using COAP.");
+      return false;
+    }
+
+    p_ctx.eIdx := pl_ptr.eIdx;
+    p_ctx.fsmIdx := pl_ptr.refContext.fCtxIdx;
+    p_ctx.eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(pl_ptr.eIdx, v_COAP_bIdx, 0);
+
+    return true;
+  }
+
+  function f_EPTF_COAP_setCtx(in integer p_eIdx, in integer p_fsmIdx, inout COAP_StepCtx p_ctx)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    if (not f_EPTF_COAP_isFsmInitialized(p_eIdx, p_fsmIdx, p_ctx.fsmCtxIdx))
+    {
+      f_EPTF_COAP_Logging_WARNING(%definitionId &
+        ": FSM has not been initialized. The f_COAP_step_init function must be called as first step in the FSMs using COAP.");
+      return false;
+    }
+
+    p_ctx.eIdx := p_eIdx;
+    p_ctx.fsmIdx := p_fsmIdx;
+    p_ctx.eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(p_eIdx, v_COAP_bIdx, 0);
+
+    return true;
+  }
+
+  function f_EPTF_COAP_isFsmInitialized(in integer pl_eIdx, in integer pl_fsmIdx, inout integer pl_fsmCtxIdx)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    pl_fsmCtxIdx := -1;
+
+    var EPTF_IntegerList vl_appData := f_EPTF_LGenBase_getAppDataListOfFsmCtx(pl_eIdx, pl_fsmIdx, v_COAP_bIdx);
+
+    if (c_COAP_AppData_fsmCtxIdx < sizeof(vl_appData))
+    {
+      pl_fsmCtxIdx := vl_appData[c_COAP_AppData_fsmCtxIdx];
+    }
+
+    return -1 < pl_fsmCtxIdx and sizeof(v_COAP_FsmCtxDB.data) > pl_fsmCtxIdx;
+  }
+
+  function f_EPTF_COAP_getIntValue(
+    in EPTF_IntegerList pl_intList,
+    in integer pl_number,
+    inout integer pl_value)
+  return boolean
+  {
+    if (sizeof(pl_intList) > pl_number)
+    {
+      pl_value := pl_intList[pl_number];
+      return true;
+    }
+    return false;
+  }
+
+  function f_EPTF_COAP_CodeToEventIdx(in Code p_code)
+  return integer
+  {
+    return p_code.class*100+p_code.detail;
+  }
+
+  function f_EPTF_COAP_isCoapReportEnabledForEntity(in integer pl_eIdx)
+  runs on EPTF_COAP_LGen_CT
+  return boolean
+  {
+    var integer vl_eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(pl_eIdx, v_COAP_bIdx, 0);
+
+    return v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].reportCoapEvent;
+  }
+
+  function f_EPTF_COAP_dispatchEventsForCode(in Code pl_code, in integer pl_eIdx, in integer pl_fsmCtx, in EPTF_IntegerList pl_reportedArgs)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (not f_EPTF_COAP_isCoapReportEnabledForEntity(pl_eIdx) ) { return; }
+
+    var integer vl_eventIdx := f_EPTF_COAP_CodeToEventIdx(pl_code);
+
+    f_EPTF_COAP_dispatchEvent(vl_eventIdx, pl_eIdx, pl_fsmCtx, {});
+
+    if (100 <= vl_eventIdx and vl_eventIdx <= 199)
+    {
+      f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_1xx, pl_eIdx, pl_fsmCtx, {});
+    }
+    else if (200 <= vl_eventIdx and vl_eventIdx <= 299)
+    {
+      f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_2xx, pl_eIdx, pl_fsmCtx, {});
+    }
+    else if (300 <= vl_eventIdx and vl_eventIdx <= 699)
+    {
+      if (300 <= vl_eventIdx and vl_eventIdx <= 399)
+      {
+        f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_3xx, pl_eIdx, pl_fsmCtx, {});
+      }
+      else if (400 <= vl_eventIdx and vl_eventIdx <= 499)
+      {
+        f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_4xx, pl_eIdx, pl_fsmCtx, {});
+      }
+      else if (500 <= vl_eventIdx and vl_eventIdx <= 599)
+      {
+        f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_4xx, pl_eIdx, pl_fsmCtx, {});
+      }
+      f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_3xxto6xx, pl_eIdx, pl_fsmCtx, {});
+    }
+  }
+
+  function f_EPTF_COAP_dispatchEvent(in integer pl_eventIdx, in integer pl_eIdx, in integer pl_fsmCtx, in EPTF_IntegerList pl_reportedArgs)
+  runs on EPTF_COAP_LGen_CT
+  {
+    if (pl_eIdx < 0)
+    {
+      f_EPTF_LGenBase_postEvent(
+        {
+          {
+            v_COAP_bIdx,
+            pl_eventIdx,
+            omit,
+            omit
+          },
+          pl_reportedArgs
+      });
+    }
+    else
+    {
+      if (pl_fsmCtx < 0)
+      {
+        f_EPTF_LGenBase_postEvent(
+          {
+            {
+              v_COAP_bIdx,
+              pl_eventIdx,
+              {
+                pl_eIdx,
+                omit
+              }, omit
+            },
+            pl_reportedArgs
+        });
+      }
+      else
+      {
+        f_EPTF_LGenBase_postEvent(
+          {
+            {
+              v_COAP_bIdx,
+              pl_eventIdx,
+              {
+                pl_eIdx,
+                pl_fsmCtx
+              }, omit
+            },
+            pl_reportedArgs
+        });
+      }
+    }
+  }
+
+  function f_EPTF_COAP_isEmpty(in CoAP_ReqResp p_pdu)
+  return boolean
+  {
+    if (p_pdu.header.code.class == 0 and
+      p_pdu.header.code.detail == 0) {
+      return true;
+    }
+    return false;
+  }
+
+  function f_EPTF_COAP_isRequest(in CoAP_ReqResp p_pdu)
+  return boolean
+  {
+    if (p_pdu.header.code.class == 0 and
+      p_pdu.header.code.detail > 0) {
+      return true;
+    }
+    return false;
+  }
+
+  function f_EPTF_COAP_isResponse(in CoAP_ReqResp p_pdu)
+  return boolean
+  {
+    if (p_pdu.header.code.class > 0) {
+      return true;
+    }
+    return false;
+  }
+
+  template CoAP_ReqResp t_CoAP_EmptyAck :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := ACKNOWLEDGEMENT,
+      code := EMPTY_MESSAGE,
+      message_id := 0
+    },
+    token := ''O,
+    options := omit,
+    payload := omit
+  }
+}
diff --git a/src/EPTF_COAP_LocalTransport_Definitions.ttcn b/src/EPTF_COAP_LocalTransport_Definitions.ttcn
new file mode 100644
index 0000000..0c0cfef
--- /dev/null
+++ b/src/EPTF_COAP_LocalTransport_Definitions.ttcn
@@ -0,0 +1,107 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+//  File:               EPTF_COAP_LocalTransport_Definitions.ttcn
+//  Description:
+//  Rev:                R1A
+//  Prodnr:             CNL 113 858
+//  Updated:            2017-09-01
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_COAP_LocalTransport_Definitions
+{
+  import from EPTF_COAP_Transport_Definitions all;
+  import from EPTF_CLL_Base_Definitions all;
+  import from EPTF_CLL_Logging_Definitions all;
+  import from EPTF_CLL_FBQ_Definitions all;
+  import from EPTF_CLL_TransportCommPortIPL4_Definitions all;
+  import from EPTF_CLL_RBTScheduler_Definitions all;
+  import from IPL4asp_Types all;
+
+  modulepar boolean tsp_EPTF_COAP_LocalTransport_debug := false;
+  modulepar boolean tsp_EPTF_COAP_LocalTransport_debugVerbose := false;
+
+  const charstring c_COAP_Transport_LGenType := "COAP_Transport";
+
+  const integer c_COAP_LocalTransport_Logging_WARNING := 0;
+  const integer c_COAP_LocalTransport_Logging_DEBUG := 1;
+  const integer c_COAP_LocalTransport_Logging_DEBUGV := 2;
+  const integer c_COAP_LocalTransport_Logging_ERROR := 3;
+
+  type component EPTF_COAP_LocalTransport_CT extends EPTF_COAP_Transport_Provider_CT, EPTF_Base_CT, EPTF_Logging_CT, EPTF_CommPort_IPL4_CT, EPTF_Scheduler_CT
+  {
+    var boolean                         v_EPTF_COAP_LocalTransport_initialized := false;
+   	var integer 						v_EPTF_COAP_LocalTransport_loggingMaskId;
+
+    var SocketEntry   					v_COAP_LocalTransport_currentSocket;
+
+    // database:
+    var SocketDB                        v_COAP_LocalTransport_localSocketDB;
+
+    // statistics:
+    var EPTF_COAP_Transport_Statistics  v_EPTF_COAP_Transport_stats;
+  }
+
+  type record SocketEntry
+  {
+    Socket          addr,
+    ConnectionId    connId,
+    SocketState     state,
+    integer         eIdx
+  }
+
+  type enumerated SocketState
+  {
+    UNUSED,
+    CLOSED,
+    OPENED,
+    TEMPORARY_UNAVAILABLE
+  }
+
+  const SocketEntry c_SocketEntry_init :=
+  {
+    addr := {
+      hostName := "",
+      portNumber := -1
+    },
+    connId := -1,
+    state := UNUSED,
+    eIdx := -1
+  }
+
+  type record of SocketEntry SocketEntry_List;
+
+  type record SocketDB
+  {
+    EPTF_FreeBusyQueue queue,
+    SocketEntry_List data,
+    integer hashRef
+  }
+  const charstring c_EPTF_COAP_LocalTransport_SocketDB := "EPTF_COAP_LocalTransport_SocketDB";
+
+  type record EPTF_COAP_Transport_Statistics
+  {
+    integer   nofOpenConnections,
+    integer   nofTransportWarnings,
+    float     nofReceivedMessages,
+    float     nofSentMessages,
+    float     nofReceivedBytes,
+    float     nofSentBytes
+  }
+
+  const EPTF_COAP_Transport_Statistics c_EPTF_COAP_Transport_Statistics_empty :=
+  {
+    nofOpenConnections := 0,
+    nofTransportWarnings := 0,
+    nofReceivedMessages := 0.0,
+    nofSentMessages := 0.0,
+    nofReceivedBytes := 0.0,
+    nofSentBytes := 0.0
+  }
+}
diff --git a/src/EPTF_COAP_LocalTransport_Functions.ttcn b/src/EPTF_COAP_LocalTransport_Functions.ttcn
new file mode 100644
index 0000000..e5aa9d2
--- /dev/null
+++ b/src/EPTF_COAP_LocalTransport_Functions.ttcn
@@ -0,0 +1,404 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+//  File:               EPTF_COAP_LocalTransport_Functions.ttcn
+//  Description:
+//  Rev:                R1A
+//  Prodnr:             CNL 113 858
+//  Updated:            2017-09-01
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_COAP_LocalTransport_Functions
+{
+  import from IPL4asp_Types all;
+
+  import from EPTF_CLL_Base_Functions all;
+  import from EPTF_CLL_Common_Definitions all;
+  import from EPTF_CLL_Logging_Definitions all;
+  import from EPTF_CLL_Logging_Functions all;
+  import from EPTF_CLL_HashMapStr2Int_Functions all;
+  import from EPTF_CLL_FBQ_Functions all;
+  import from EPTF_CLL_TransportCommPortIPL4_Functions all;
+  import from EPTF_CLL_RBTScheduler_Functions all;
+
+  import from EPTF_COAP_LocalTransport_Definitions all;
+  import from EPTF_COAP_Transport_Definitions all;
+
+  import from CoAP_Types all;
+
+  function f_EPTF_COAP_LocalTransport_init()
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    if (v_EPTF_COAP_LocalTransport_initialized) {return;}
+
+    f_EPTF_COAP_LocalTransport_initLogging();
+
+    f_EPTF_CommPort_IPL4_init();
+
+    v_EPTF_COAP_Transport_stats := c_EPTF_COAP_Transport_Statistics_empty;
+
+    f_EPTF_COAP_LocalTransport_socketDB_init();
+
+    var f_IPL4_getMsgLen fcb_msglen := refers(f_EPTF_COAP_IPL4asp_getMsgLen);
+    f_EPTF_CommPort_IPL4_setMsgLen4LGenType(fcb_msglen, {}, c_COAP_Transport_LGenType);
+
+    f_EPTF_CommPort_IPL4_setReceive({asp_Event := ?},refers(f_EPTF_COAP_IPL4asp_handleEvent), c_COAP_Transport_LGenType);
+    f_EPTF_CommPort_IPL4_setReceive({asp_RecvFrom := ?},refers(f_EPTF_COAP_IPL4asp_handleMessage), c_COAP_Transport_LGenType);
+
+    f_EPTF_Base_registerCleanup(refers(f_EPTF_COAP_LocalTransport_cleanup));
+
+    v_EPTF_COAP_LocalTransport_initialized := true;
+  }
+
+  function f_EPTF_COAP_LocalTransport_initLogging()
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+	f_EPTF_Logging_init_CT("COAP_Transport");
+    v_EPTF_COAP_LocalTransport_loggingMaskId :=
+    	f_EPTF_Logging_registerComponentMasks(
+    		"COAP_LocalTransport_Logging",
+    		{"WARNING", "DEBUG", "DEBUGV", "ERROR"},
+    		EPTF_Logging_CLL
+    	);
+
+	if(tsp_EPTF_COAP_LocalTransport_debug){
+	  f_EPTF_Logging_enableLocalMask(v_EPTF_COAP_LocalTransport_loggingMaskId, c_COAP_LocalTransport_Logging_DEBUG);
+	}
+	else {
+	  f_EPTF_Logging_disableLocalMask(v_EPTF_COAP_LocalTransport_loggingMaskId, c_COAP_LocalTransport_Logging_DEBUG);
+	}
+
+	if(tsp_EPTF_COAP_LocalTransport_debugVerbose) {
+	  f_EPTF_Logging_enableLocalMask(v_EPTF_COAP_LocalTransport_loggingMaskId, c_COAP_LocalTransport_Logging_DEBUGV);
+	}
+	else {
+	  f_EPTF_Logging_disableLocalMask(v_EPTF_COAP_LocalTransport_loggingMaskId, c_COAP_LocalTransport_Logging_DEBUGV);
+	}
+  }
+
+  function f_EPTF_COAP_LocalTransport_cleanup()
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    // Reset DBs, close connections
+
+    f_EPTF_COAP_LocalTransport_socketDB_cleanUp();
+
+    vf_EPTF_COAP_Transport_receiveMessage := null;
+    vf_EPTF_COAP_Transport_receiveEvent := null;
+
+    v_EPTF_COAP_LocalTransport_initialized := false;
+  }
+
+  function f_EPTF_COAP_IPL4asp_getMsgLen
+  (
+    in octetstring stream,
+    inout ro_integer args
+  )
+  return integer
+  {
+    return lengthof(stream);
+  }
+
+  function f_EPTF_COAP_IPL4asp_handleEvent() runs on EPTF_COAP_LocalTransport_CT
+  {
+    f_COAP_Transport_Logging_DEBUG(log2str(": incoming event: ", v_EPTF_CommPort_IPL4_incomingMessage));
+
+    if (vf_EPTF_COAP_Transport_receiveEvent != null) {
+      vf_EPTF_COAP_Transport_receiveEvent.apply(v_EPTF_CommPort_IPL4_incomingMessage.asp_Event);
+    }
+  }
+
+  function f_EPTF_COAP_IPL4asp_handleMessage() runs on EPTF_COAP_LocalTransport_CT
+  {
+    var CoAP_Message   vl_COAP_MSG;
+    var EPTF_COAP_PDU  vl_EPTF_COAP_PDU;
+
+    f_EPTF_SchedulerComp_refreshSnapshotTime();
+
+    f_CoAP_dec(v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.msg, vl_COAP_MSG);
+
+    if (tsp_EPTF_COAP_LocalTransport_debug) { action("COAP transport receiving: \n", vl_COAP_MSG); }
+
+    if (ischosen(vl_COAP_MSG.msg))
+    {
+      vl_EPTF_COAP_PDU.pdu := vl_COAP_MSG.msg;
+      vl_EPTF_COAP_PDU.transportParams.localAddress.hostName := v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.locName;
+      vl_EPTF_COAP_PDU.transportParams.localAddress.portNumber := v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.locPort;
+      vl_EPTF_COAP_PDU.transportParams.remoteAddress.hostName := v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.remName;
+      vl_EPTF_COAP_PDU.transportParams.remoteAddress.portNumber := v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.remPort;
+      vl_EPTF_COAP_PDU.transportParams.proto := v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.proto;
+
+      var SocketEntry vl_entry := c_SocketEntry_init;
+      var integer vl_sockIdx := f_EPTF_COAP_LocalTransport_socketDB_lookUp({
+        v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.locName,
+        v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.locPort
+      });
+      f_EPTF_COAP_LocalTransport_socketDB_get(vl_sockIdx, vl_entry);
+      vl_EPTF_COAP_PDU.eIdx := vl_entry.eIdx;
+      vl_EPTF_COAP_PDU.fsmIdx := -1;
+      if (tsp_EPTF_COAP_LocalTransport_debug) { action("COAP transport receiving: eIdx: ", vl_EPTF_COAP_PDU.eIdx); }
+
+      v_EPTF_COAP_Transport_stats.nofReceivedMessages :=
+        v_EPTF_COAP_Transport_stats.nofReceivedMessages + 1.0;
+      v_EPTF_COAP_Transport_stats.nofReceivedBytes :=
+        v_EPTF_COAP_Transport_stats.nofReceivedBytes + int2float(lengthof(v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.msg));
+
+      if (vf_EPTF_COAP_Transport_receiveMessage != null) {
+        vf_EPTF_COAP_Transport_receiveMessage.apply(vl_EPTF_COAP_PDU);
+      }
+    }
+    else
+    {
+      f_COAP_Transport_Logging_WARNING(
+      	log2str(%definitionId, " Couldn't decode msg: ",v_EPTF_CommPort_IPL4_incomingMessage.asp_RecvFrom.msg, " decoded: ", vl_COAP_MSG)
+      );
+    }
+  }
+
+  function f_EPTF_COAP_LocalTransport_send(in EPTF_COAP_PDU pl_msg)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    f_COAP_Transport_Logging_VERBOSE(log2str(%definitionId, " ", pl_msg));
+
+    var integer vl_sockIdx := f_EPTF_COAP_LocalTransport_socketDB_lookUp(pl_msg.transportParams.localAddress);
+
+    if (vl_sockIdx < 0)
+    {
+      if (not f_EPTF_COAP_LocalTransport_startSocket(pl_msg.transportParams.localAddress, pl_msg.eIdx, vl_sockIdx))
+      {
+        f_COAP_Transport_Logging_WARNING(log2str(": couldn't create socket: ", pl_msg.transportParams.localAddress));
+        return;
+      }
+    }
+    f_EPTF_COAP_LocalTransport_socketDB_get(vl_sockIdx, v_COAP_LocalTransport_currentSocket);
+
+    if (tsp_EPTF_COAP_LocalTransport_debug) { action("COAP transport sending: \n", pl_msg.pdu); }
+
+    var octetstring v_encoded;
+    f_CoAP_enc(CoAP_Message: {msg := pl_msg.pdu}, v_encoded);
+
+    f_EPTF_COAP_LocalTransport_IPL4_send
+    (
+      v_COAP_LocalTransport_currentSocket.connId,
+      pl_msg.transportParams.remoteAddress.hostName,
+      pl_msg.transportParams.remoteAddress.portNumber,
+      pl_msg.transportParams.proto,
+      v_encoded
+    );
+  }
+
+  function f_EPTF_COAP_LocalTransport_transportApiRequest(EPTF_COAP_Transport_Request pl_req)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    if (ischosen(pl_req.params.startListening))
+    {
+      var EPTF_COAP_Transport_Response vl_rsp := c_EPTF_COAP_Transport_Response_init;
+      vl_rsp.eIdx := pl_req.eIdx;
+      vl_rsp.fsmIdx := pl_req.fsmIdx;
+
+      var integer vl_sockIdx := f_EPTF_COAP_LocalTransport_socketDB_lookUp(pl_req.params.startListening.localAddress);
+      if (vl_sockIdx < 0)
+      {
+        if (not f_EPTF_COAP_LocalTransport_startSocket(pl_req.params.startListening.localAddress, pl_req.eIdx, vl_sockIdx))
+        {
+          f_COAP_Transport_Logging_WARNING(log2str(": couldn't create socket: ", pl_req.params.startListening.localAddress));
+        }
+        else { vl_rsp.succ := true; }
+      }
+      else { vl_rsp.succ := false; }
+      vf_EPTF_COAP_Transport_apiResponse.apply(vl_rsp);
+    }
+  }
+
+  function f_EPTF_COAP_LocalTransport_startSocket(in Socket p_sock, in integer p_eIdx, inout integer p_idx)
+  runs on EPTF_COAP_LocalTransport_CT
+  return boolean
+  {
+    var Result vl_result;
+    var SocketEntry vl_socketEntry := c_SocketEntry_init;
+
+    vl_result :=
+      f_EPTF_CommPort_IPL4_send(
+        {asp_Listen :=
+          {
+            locName := p_sock.hostName,
+            locPort := p_sock.portNumber,
+            proto := { udp := {} }
+          }
+        },
+        null,
+        false,
+        false,
+        c_COAP_Transport_LGenType);
+
+    if (f_EPTF_COAP_IPL4asp_handleResult(vl_result)) // Everything went OK
+    {
+      vl_socketEntry.addr := p_sock;
+      vl_socketEntry.connId := vl_result.connId;
+      vl_socketEntry.eIdx := p_eIdx;
+      vl_socketEntry.state := OPENED;
+    }
+    else
+    { return false;}
+
+    p_idx := f_EPTF_COAP_LocalTransport_socketDB_add(vl_socketEntry);
+
+    return true;
+  }
+
+  function f_EPTF_COAP_LocalTransport_IPL4_send(
+    in integer pl_connId,
+    in charstring pl_remName,
+    in integer pl_remPort,
+    in ProtoTuple  pl_proto,
+    in octetstring pl_msg)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    var Result v_res;
+
+    v_res := f_EPTF_CommPort_IPL4_send(
+      {
+        asp_SendTo :=
+        {
+          connId := pl_connId,
+          remName := pl_remName,
+          remPort := pl_remPort,
+          proto := pl_proto,
+          msg := pl_msg
+        }
+      },
+      null,
+      false,
+      false,
+      c_COAP_Transport_LGenType
+    );
+
+    if (ispresent(v_res.errorCode))
+    {
+      f_COAP_Transport_Logging_WARNING(log2str(": message could not be sent."));
+    }
+
+    v_EPTF_COAP_Transport_stats.nofSentMessages := v_EPTF_COAP_Transport_stats.nofSentMessages + 1.0;
+    v_EPTF_COAP_Transport_stats.nofSentBytes := v_EPTF_COAP_Transport_stats.nofSentBytes + int2float(lengthof(pl_msg));
+  }
+
+  function f_EPTF_COAP_LocalTransport_socketDB_init()
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_LocalTransport_localSocketDB.queue);
+    v_COAP_LocalTransport_localSocketDB.data := {};
+    v_COAP_LocalTransport_localSocketDB.hashRef := f_EPTF_str2int_HashMap_New(c_EPTF_COAP_LocalTransport_SocketDB);
+  }
+
+  function f_EPTF_COAP_LocalTransport_socketDB_cleanUp()
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    f_EPTF_FBQ_initFreeBusyQueue(v_COAP_LocalTransport_localSocketDB.queue);
+    v_COAP_LocalTransport_localSocketDB.data := {};
+    f_EPTF_str2int_HashMap_Delete(c_EPTF_COAP_LocalTransport_SocketDB);
+  }
+
+  function f_EPTF_COAP_LocalTransport_socketDB_add(in SocketEntry p_sock)
+  runs on EPTF_COAP_LocalTransport_CT
+  return integer
+  {
+    var integer v_idx := f_EPTF_COAP_LocalTransport_socketDB_lookUp(p_sock.addr);
+
+    if (v_idx == -1)
+    {
+      v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_LocalTransport_localSocketDB.queue);
+      f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_LocalTransport_localSocketDB.queue);
+
+      f_COAP_Transport_Logging_DEBUG(log2str(": "," adding socket ", v_idx, " ", p_sock));
+
+      f_EPTF_str2int_HashMap_Insert(v_COAP_LocalTransport_localSocketDB.hashRef, f_EPTF_COAP_Socket2String(p_sock.addr), v_idx);
+
+      v_COAP_LocalTransport_localSocketDB.data[v_idx] := p_sock;
+    }
+
+    return v_idx;
+  }
+
+  function f_EPTF_COAP_LocalTransport_socketDB_lookUp(in Socket p_sock)
+  runs on EPTF_COAP_LocalTransport_CT
+  return integer
+  {
+    var integer    vl_idx := -1;
+    f_EPTF_str2int_HashMap_Find(v_COAP_LocalTransport_localSocketDB.hashRef, f_EPTF_COAP_Socket2String(p_sock), vl_idx);
+    return vl_idx;
+  }
+
+  function f_EPTF_COAP_LocalTransport_socketDB_get(in integer p_idx, inout SocketEntry p_sock)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    if (p_idx < sizeof(v_COAP_LocalTransport_localSocketDB.data))
+    {
+      p_sock := v_COAP_LocalTransport_localSocketDB.data[p_idx];
+    }
+  }
+
+  function f_EPTF_COAP_LocalTransport_socketDB_remove(in integer p_idx)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    v_COAP_LocalTransport_localSocketDB.data[p_idx] := c_SocketEntry_init;
+    f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_COAP_LocalTransport_localSocketDB.queue);
+  }
+
+  function f_EPTF_COAP_Socket2String(Socket p_sock)
+  return charstring
+  {
+    return p_sock.hostName&":"&int2str(p_sock.portNumber);
+  }
+
+  function f_COAP_Transport_Logging_VERBOSE(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+    	f_EPTF_Logging_debugV2(pl_message, v_EPTF_COAP_LocalTransport_loggingMaskId, {c_COAP_LocalTransport_Logging_DEBUGV});
+	}
+  }
+
+  function f_COAP_Transport_Logging_DEBUG(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+	    f_EPTF_Logging_debugV2(pl_message, v_EPTF_COAP_LocalTransport_loggingMaskId, {c_COAP_LocalTransport_Logging_DEBUG});
+	}
+  }
+
+  function f_COAP_Transport_Logging_WARNING(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+	    f_EPTF_Logging_debugV2(pl_message, v_EPTF_COAP_LocalTransport_loggingMaskId, {c_COAP_LocalTransport_Logging_WARNING});
+	}
+  }
+
+  function f_COAP_Transport_Logging_ERROR(in @lazy charstring pl_message)
+  runs on EPTF_COAP_LocalTransport_CT
+  {
+    if (c_EPTF_Common_debugSwitch) {
+    	f_EPTF_Logging_debugV2(pl_message, v_EPTF_COAP_LocalTransport_loggingMaskId, {c_COAP_LocalTransport_Logging_ERROR});
+	}
+  }
+
+  function f_EPTF_COAP_IPL4asp_handleResult(inout Result p_res)
+  runs on EPTF_COAP_LocalTransport_CT
+  return boolean
+  {
+    if (ispresent(p_res.errorCode) and (p_res.errorCode != IPL4_ERROR_TEMPORARILY_UNAVAILABLE))
+    {
+      f_COAP_Transport_Logging_WARNING(log2str("Warning: f_EPTF_COAP_IPL4asp_handleResult: IPL4 error: ", p_res));
+      v_EPTF_COAP_Transport_stats.nofTransportWarnings := v_EPTF_COAP_Transport_stats.nofTransportWarnings + 1;
+      return false;
+    }
+    return true;
+  }
+
+}
diff --git a/src/EPTF_COAP_Transport_Definitions.ttcn b/src/EPTF_COAP_Transport_Definitions.ttcn
new file mode 100644
index 0000000..4ebb5d8
--- /dev/null
+++ b/src/EPTF_COAP_Transport_Definitions.ttcn
@@ -0,0 +1,100 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+//  File:               EPTF_COAP_Transport_Definitions.ttcn
+//  Description:
+//  Rev:                R1A
+//  Prodnr:             CNL 113 858
+//  Updated:            2017-09-01
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_COAP_Transport_Definitions
+{
+  import from CoAP_Types all;
+  import from IPL4asp_Types all;
+
+  type function fcb_EPTF_COAP_Transport_receiveMessage(in EPTF_COAP_PDU pl_message) runs on self;
+  type function fcb_EPTF_COAP_Transport_receiveEvent(in ASP_Event p_event) runs on self;
+  type function fcb_EPTF_COAP_Transport_sendMessage(in EPTF_COAP_PDU pl_msg) runs on self;
+  type function fcb_EPTF_COAP_Transport_apiRequest(in EPTF_COAP_Transport_Request pl_req) runs on self;
+  type function fcb_EPTF_COAP_Transport_apiResponse(in EPTF_COAP_Transport_Response pl_rsp) runs on self;
+
+  type record EPTF_COAP_PDU
+  {
+    CoAP_ReqResp                  pdu,
+    EPTF_COAP_TransportParameters transportParams,
+    integer                       eIdx,
+    integer						  fsmIdx
+  }
+
+  type record EPTF_COAP_TransportParameters
+  {
+    Socket      localAddress,
+    Socket      remoteAddress,
+    ProtoTuple  proto
+  }
+
+  type record EPTF_COAP_Transport_Request
+  {
+    integer eIdx,
+    integer fsmIdx,
+    EPTF_COAP_Transport_RequestParams params optional
+  }
+
+  const EPTF_COAP_Transport_Request c_EPTF_COAP_Transport_Request_init :=
+  {
+    eIdx := -1,
+    fsmIdx := -1,
+    params := omit
+  }
+
+  type union EPTF_COAP_Transport_RequestParams
+  {
+    EPTF_COAP_Transport_startListening startListening
+  }
+
+  type record EPTF_COAP_Transport_startListening
+  {
+    Socket localAddress
+  }
+
+  type record EPTF_COAP_Transport_Response
+  {
+    boolean succ,
+    integer eIdx,
+    integer fsmIdx,
+    EPTF_COAP_Transport_ResponseParams params optional
+  }
+
+  const EPTF_COAP_Transport_Response c_EPTF_COAP_Transport_Response_init :=
+  {
+    succ := false,
+    eIdx := -1,
+    fsmIdx := -1,
+    params := omit
+  }
+
+  type union EPTF_COAP_Transport_ResponseParams
+  {
+    boolean listening
+  }
+
+  type component EPTF_COAP_Transport_Provider_CT
+  {
+    var fcb_EPTF_COAP_Transport_receiveMessage  vf_EPTF_COAP_Transport_receiveMessage := null;
+    var fcb_EPTF_COAP_Transport_receiveEvent    vf_EPTF_COAP_Transport_receiveEvent := null;
+    var fcb_EPTF_COAP_Transport_apiResponse     vf_EPTF_COAP_Transport_apiResponse := null;
+  }
+
+  type component EPTF_COAP_Transport_User_CT
+  {
+    var fcb_EPTF_COAP_Transport_sendMessage     vf_EPTF_COAP_Transport_send := null;
+    var fcb_EPTF_COAP_Transport_apiRequest      vf_EPTF_COAP_Transport_apiRequest := null;
+  }
+}
diff --git a/test/EPTF_COAP_Tests.ttcn b/test/EPTF_COAP_Tests.ttcn
new file mode 100644
index 0000000..2f420bb
--- /dev/null
+++ b/test/EPTF_COAP_Tests.ttcn
@@ -0,0 +1,1076 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+//  File:               EPTF_COAP_Tests.ttcn
+//  Description:
+//  Rev:                R1A
+//  Prodnr:             CNL 113 858
+//  Updated:            2017-09-01
+//  Contact:            http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_COAP_Tests
+{
+  import from EPTF_MBT_LGen_Definitions all;
+  import from EPTF_MBT_LGen_Functions all;
+  import from EPTF_COAP_LGen_Definitions all;
+  import from EPTF_COAP_LGen_Functions all;
+  import from EPTF_COAP_LocalTransport_Definitions all;
+  import from EPTF_COAP_LocalTransport_Functions all;
+  import from EPTF_CLL_Base_Functions all;
+  import from CoAP_Types all;
+  import from IoT_FT_Framework all;
+
+  modulepar charstring tsp_SUT_localHost := "127.0.0.1";
+  modulepar integer    tsp_SUT_localPort := 31111;
+  modulepar charstring tsp_SUT_remoteHost := "127.0.0.1";
+  modulepar integer    tsp_SUT_remotePort := 5683;
+
+  // SUT: Coap LGen
+  type component SUT_CT extends EPTF_MBT_LGen_CT, EPTF_COAP_LGen_CT, EPTF_COAP_LocalTransport_CT {}
+
+  // Tester_CT
+  type component Tester_CT extends EPTF_MBT_Tester_CT, IFW_MAIN_CT {}
+
+  function f_COAP_Tests_begin() runs on Tester_CT
+  {
+    log(%definitionId, " started");
+    setverdict(pass);
+
+    f_EPTF_Base_init_CT("mtc");
+
+    log(%definitionId, " Creating SUT");
+
+    var SUT_CT vc_sut := SUT_CT.create;
+    connect(self:EPTF_MBT_TESTER_PCO, vc_sut:EPTF_MBT_PCO);
+    vc_sut.start(f_SUT_behavior());
+    EPTF_MBT_TESTER_PCO.receive(EPTF_MBT_CommandResponse:?) from vc_sut;
+
+    EPTF_MBT_TESTER_PCO.send(EPTF_MBT_ConfigRequest:
+      {
+        entityGroupName := "SUT_EntityType",
+        noEntities := 1,
+        behaviors := {c_EPTF_MBT_myBName, c_COAP_behaviorType},
+        fsmName := "FSM_MBT"
+      }
+    ) to vc_sut;
+    EPTF_MBT_TESTER_PCO.receive(EPTF_MBT_ConfigResponse:?) from vc_sut;
+
+    log(%definitionId, " SUT ready");
+
+    log(%definitionId, " finished");
+  }
+
+  function f_COAP_Tests_end() runs on Tester_CT
+  {
+    log("### MAIN: END TESTCASE started");
+
+    f_EPTF_Base_stopAll(none, true);
+
+    log("### MAIN: END TESTCASE finished");
+  }
+
+  function f_handleVerdict(in boolean p_verdict)
+  {
+    if (p_verdict) { setverdict(pass) }
+    else { setverdict(fail) }
+  }
+
+  function f_SUT_behavior() runs on SUT_CT
+  {
+    // Init
+    f_EPTF_MBT_init("SUT_LGen",0, "SUT_");
+
+    f_EPTF_COAP_LGen_init("SUT_LGen");
+    f_EPTF_COAP_LocalTransport_init();
+
+    vf_EPTF_COAP_Transport_send := refers(f_EPTF_COAP_LocalTransport_send);
+    vf_EPTF_COAP_Transport_receiveMessage := refers(f_EPTF_COAP_LGen_receiveMessage);
+    vf_EPTF_COAP_Transport_receiveEvent := refers(f_EPTF_COAP_LGen_receiveEvent);
+    vf_EPTF_COAP_Transport_apiRequest := refers(f_EPTF_COAP_LocalTransport_transportApiRequest);
+    vf_EPTF_COAP_Transport_apiResponse := refers(f_EPTF_COAP_LGen_transportApiResponse);
+
+    var integer vl_addrIdx;
+    f_EPTF_COAP_addressDB_add({tsp_SUT_localHost, tsp_SUT_localPort}, vl_addrIdx);
+    f_EPTF_COAP_addressDB_add({tsp_SUT_remoteHost, tsp_SUT_remotePort}, vl_addrIdx);
+
+    var integer v_tempIdx;
+    v_tempIdx := f_EPTF_COAP_templateDB_add({id:= "t_reg_NON_GET", msg:=valueof(t_reg_NON_GET)});
+    v_tempIdx := f_EPTF_COAP_templateDB_add({id:="t_reg_CON_GET", msg:=valueof(t_reg_CON_GET)});
+    v_tempIdx := f_EPTF_COAP_templateDB_add({id:="t_reg_Content", msg:=valueof(t_reg_Content)});
+
+    f_EPTF_MBT_initLGenFsm(null, null);
+    EPTF_MBT_PCO.send(EPTF_MBT_CommandResponse:{ ready := {}}) to mtc;
+
+    // Loop
+    f_EPTF_Base_wait4Shutdown();
+  }
+
+  template CoAP_ReqResp t_reg_NON_GET :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := NON_CONFIRMABLE,
+      code := METHOD_GET,
+      message_id := 0
+    },
+    token := ''O,
+    options :=
+    {
+      {
+	uri_path := "test"
+      }
+    },
+    payload := omit
+  }
+
+  template CoAP_ReqResp t_reg_CON_GET :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := CONFIRMABLE,
+      code := METHOD_GET,
+      message_id := 0
+    },
+    token := ''O,
+    options :=
+    {
+      {
+	uri_path := "test"
+      }
+    },
+    payload := omit
+  }
+
+  template CoAP_ReqResp t_reg_Content :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := NON_CONFIRMABLE,
+      code := RESPONSE_CODE_Content,
+      message_id := 0
+    },
+    token := ''O,
+    options :=
+    {
+      {
+        content_format := 0
+      }
+    },
+    payload := char2oct("Some payload")
+  }
+
+  template CoAP_ReqResp tr_NON_GET :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := NON_CONFIRMABLE,
+      code := METHOD_GET,
+      message_id := ?
+    },
+    token := ?,
+    options :=
+    {
+      {
+	uri_path := "test"
+      }
+    },
+    payload := omit
+  }
+
+  template CoAP_ReqResp tr_CON_GET :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := CONFIRMABLE,
+      code := METHOD_GET,
+      message_id := ?
+    },
+    token := ?,
+    options :=
+    {
+      {
+	uri_path := "test"
+      }
+    },
+    payload := omit
+  }
+
+  template CoAP_ReqResp t_Content(Type p_msgType) :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := p_msgType,
+      code := RESPONSE_CODE_Content,
+      message_id := 0
+    },
+    token := ''O,
+    options :=
+    {
+      {
+        content_format := 0
+      }
+    },
+    payload := char2oct("Some payload")
+  }
+
+  template CoAP_ReqResp t_ACK_Empty :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := ACKNOWLEDGEMENT,
+      code := EMPTY_MESSAGE,
+      message_id := 0
+    },
+    token := ''O,
+    options := omit,
+    payload := omit
+  }
+
+  template CoAP_ReqResp tr_ACK_Empty :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := ACKNOWLEDGEMENT,
+      code := EMPTY_MESSAGE,
+      message_id := ?
+    },
+    token := ''O,
+    options := omit,
+    payload := omit
+  }
+
+  template CoAP_ReqResp tr_Content(Type p_msgType) :=
+  {
+    header :=
+    {
+      version := 1,
+      msg_type := p_msgType,
+      code := RESPONSE_CODE_Content,
+      message_id := ?
+    },
+    token := ?,
+    options :=
+    {
+      {
+        content_format := 0
+      }
+    },
+    payload := char2oct("Some payload")
+  }
+
+  template EPTF_MBT_LGen_Definitions.FsmAddr t_addr(integer eIdx, integer fIdx := 0) :=
+  {
+    entityGroupName := "SUT_EntityType",
+    eIdx := eIdx,
+    fIdx := fIdx
+  }
+
+  function f_delay(in float p_time)
+  {
+    timer t:= p_time;
+    t.start;
+    t.timeout;
+  }
+
+  const integer c_localAddr := 0;
+  const integer c_remoteAddr := 1;
+
+  const integer c_t_NON_GET := 0;
+  const integer c_t_CON_GET := 1;
+  const integer c_t_Content := 2;
+
+  testcase tc_send_NON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(NON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_NON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- NON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_NON_GET));
+
+    // Tester -- call cleanUp --> SUT
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_send_NON_recv_NON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(NON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_NON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- NON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_NON_GET));
+
+    // Tester -- NON-205 --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_Content(NON_CONFIRMABLE)), USE_LAST_RECEIVED_MID, USE_LAST_RECEIVED_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind 205 -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName(205), valueof(t_addr(0, 0)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_send_CON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(CON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_CON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester -- call cleanUp --> SUT
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_retransmit_CON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(CON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_CON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester <-- CON-GET -- SUT (retransmission)
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester <-- CON-GET -- SUT (retransmission)
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester -- call cleanUp --> SUT
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_timeout_CON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(CON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_CON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester <-- CON-GET -- SUT (retransmission)
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester <-- ind trTimeout -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_trTimeout, valueof(t_addr(0, 0)), tsp_EPTF_COAP_EXCHANGE_LIFETIME+3.0));
+
+    // Tester -- call cleanUp --> SUT
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_send_CON_recv_ACK() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(CON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_CON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester -- ACK-205 --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_Content(ACKNOWLEDGEMENT)), USE_LAST_RECEIVED_MID, USE_LAST_RECEIVED_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind 205 -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName(205), valueof(t_addr(0, 0)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_send_CON_retransmit_CON_recv_ACK() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(CON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_CON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester <-- CON-GET -- SUT (retransmission)
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester <-- CON-GET -- SUT (retransmission)
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester -- ACK-205 --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_Content(ACKNOWLEDGEMENT)), USE_LAST_RECEIVED_MID, USE_LAST_RECEIVED_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind 205 -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName(205), valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- call cleanUp --> SUT
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_send_CON_recv_emptyACK_recv_NON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(CON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_CON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester -- ACK-empty --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_ACK_Empty), USE_LAST_RECEIVED_MID, USE_GIVEN_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester -- NON-205 --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_Content(NON_CONFIRMABLE)), GENERATE_NEW_MID, USE_LAST_RECEIVED_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind 205 -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName(205), valueof(t_addr(0, 0)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_send_CON_recv_emptyACK_recv_CON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+    f_MBT_execute(c_COAP_stepName_setRemoteAddress_byIntIdx, valueof(t_addr(0, 0)), {c_remoteAddr}, false);
+
+    // Tester -- call send(CON-GET) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_CON_GET}, false);
+    f_MBT_execute(c_COAP_stepName_send, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-GET -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_CON_GET));
+
+    // Tester -- ACK-empty --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_ACK_Empty), USE_LAST_RECEIVED_MID, USE_GIVEN_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester -- CON-205 --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_Content(CONFIRMABLE)), GENERATE_NEW_MID, USE_LAST_RECEIVED_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <- ACK-empty -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_ACK_Empty));
+
+    // Tester <-- ind 205 -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName(205), valueof(t_addr(0, 0)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_call_startListening() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_NON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- NON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_NON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_NON_send_NON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- NON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_NON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- call sendResponse(NON-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- NON-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(NON_CONFIRMABLE)));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_NON_recv_Duplicate_send_NON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- NON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_NON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- NON-GET-duplicate --> SUT
+    f_IFW_CoapPeer_send(peer);
+
+    f_delay(0.2);
+
+    // Tester -- call sendResponse(NON-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- NON-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(NON_CONFIRMABLE)));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_NON_send_NON_recv_Duplicate() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- NON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_NON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- call sendResponse(NON-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- NON-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(NON_CONFIRMABLE)));
+
+    // Tester -- NON-GET-duplicate --> SUT
+    f_IFW_CoapPeer_send(peer);
+
+    f_delay(0.2);
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_NON_send_NON_wait_lifetime_recv_no_duplicate() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- NON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_NON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- call sendResponse(NON-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- NON-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(NON_CONFIRMABLE)));
+
+    // Wait for EXCHANGE_LIFETIME
+    f_delay(tsp_EPTF_COAP_EXCHANGE_LIFETIME+1.0);
+
+    // Tester -- NON-GET-(no duplicate anymore) --> SUT
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_CON() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- CON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_CON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_CON_send_ACK() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- CON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_CON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- call sendResponse(ACK-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ACK-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(ACKNOWLEDGEMENT)));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_CON_recv_Duplicate_send_ACK() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- CON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_CON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- CON-GET-duplicate --> SUT
+    f_IFW_CoapPeer_send(peer);
+
+    f_delay(0.2);
+
+    // Tester -- call sendResponse(CON-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- NON-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(ACKNOWLEDGEMENT)));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_CON_send_ACK_recv_Duplicate_retransmit_ACK() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- CON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_CON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- call sendResponse(ACK-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ACK-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(ACKNOWLEDGEMENT)));
+
+    // Tester -- CON-GET-duplicate --> SUT
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ACK-Content-retransmit -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(ACKNOWLEDGEMENT)));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_CON_send_emptyACK() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- CON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_CON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- call sendAccept(ACK-empty) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_sendAccept, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ACK-empty -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_ACK_Empty));
+
+    f_COAP_Tests_end();
+  }
+
+  testcase tc_recv_CON_send_emptyACK_send_CON_recv_ACK() runs on Tester_CT
+  {
+    f_COAP_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    // Tester -- call init --> SUT
+    f_MBT_execute(c_COAP_stepName_init, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_setLocalAddress, valueof(t_addr(0, 0)), {c_localAddr}, false);
+
+    // Tester -- call startListening --> SUT
+    f_MBT_execute(c_COAP_stepName_startListening, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ind transportSucc -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_transportSucc, valueof(t_addr(0, 0)), 3.0));
+
+    // Tester -- CON-GET --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_reg_CON_GET), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    // Tester <-- ind GET -- SUT
+    f_handleVerdict(f_MBT_waitFor(c_COAP_behaviorType, c_COAP_eventName_GET, valueof(t_addr(0, -1)), 3.0));
+
+    // Tester -- call sendAccept(ACK-empty) --> SUT
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_COAP_stepName_sendAccept, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- ACK-empty -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_ACK_Empty));
+
+    // Tester -- call sendResponse(CON-Content) --> SUT
+    f_MBT_execute(c_COAP_stepName_loadTemplate_byIntIdx, valueof(t_addr(0, 0)), {c_t_Content}, false);
+    f_MBT_execute(c_COAP_stepName_sendResponse, valueof(t_addr(0, 0)), {}, false);
+
+    // Tester <-- CON-Content -- SUT
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_Content(CONFIRMABLE), DO_NOT_CHECK_MID));
+
+    // Tester -- ACK-empty --> SUT
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_ACK_Empty), USE_LAST_RECEIVED_MID, USE_LAST_RECEIVED_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    f_COAP_Tests_end();
+  }
+
+  control
+  {
+    // SUT: client
+    execute(tc_send_NON());
+    execute(tc_send_NON_recv_NON());
+    execute(tc_send_CON());
+    execute(tc_retransmit_CON());
+    execute(tc_timeout_CON());
+    execute(tc_send_CON_recv_ACK());
+    execute(tc_send_CON_retransmit_CON_recv_ACK());
+    execute(tc_send_CON_recv_emptyACK_recv_NON());
+    execute(tc_send_CON_recv_emptyACK_recv_CON());
+
+    // SUT: server
+    execute(tc_call_startListening());
+    execute(tc_recv_NON());
+    execute(tc_recv_NON_send_NON());
+    execute(tc_recv_NON_recv_Duplicate_send_NON());
+    execute(tc_recv_NON_send_NON_recv_Duplicate());
+    execute(tc_recv_NON_send_NON_wait_lifetime_recv_no_duplicate());
+    execute(tc_recv_CON());
+    execute(tc_recv_CON_send_ACK());
+    execute(tc_recv_CON_recv_Duplicate_send_ACK());
+    execute(tc_recv_CON_send_ACK_recv_Duplicate_retransmit_ACK());
+    execute(tc_recv_CON_send_emptyACK());
+    execute(tc_recv_CON_send_emptyACK_send_CON_recv_ACK());
+  }
+
+}