blob: 71f99298b1a11bd2ba0b32b28471c71e5c25e451 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// 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
}
}