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());
+ }
+
+}