| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // Copyright (c) 2000-2020 Ericsson Telecom AB |
| // |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v2.0 |
| // which accompanies this distribution, and is available at |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html |
| /////////////////////////////////////////////////////////////////////////////// |
| // File: EPTF_COAP_LGen_Functions.ttcn |
| // Description: |
| // Rev: R1A |
| // Prodnr: CNL 113 858 |
| // Updated: 2020-03-04 |
| // Contact: http://ttcn.ericsson.se |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /////////////////////////////////////////////////////////// |
| // Module: EPTF_COAP_LGen_Functions |
| // |
| // Purpose: |
| // This module contains the functions of the COAP load generator component |
| // |
| // See also: |
| // <EPTF_COAP_LGen_Definitions> |
| /////////////////////////////////////////////////////////////// |
| module EPTF_COAP_LGen_Functions |
| { |
| import from EPTF_COAP_LGen_Definitions all; |
| import from EPTF_COAP_Transport_Definitions all; |
| import from EPTF_CLL_Base_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; |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_LGen_init |
| // |
| // Purpose: |
| // The main initialization function for the <EPTF_COAP_LGen_CT> component type |
| // |
| // Parameters: |
| // pl_name - *in* *charstring* - the name for the component instance |
| // |
| // Related Type: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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) |
| ); |
| |
| f_EPTF_COAP_LGen_initLogging(); |
| |
| 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_transportEndpointDB_init(); |
| f_EPTF_COAP_trDB_init(); |
| f_EPTF_COAP_rrDB_init(); |
| f_EPTF_COAP_templateDB_init(); |
| f_EPTF_COAP_observedResourceDB_init(); |
| f_EPTF_COAP_observationDB_init(); |
| f_EPTF_COAP_blockwiseDB_init(); |
| f_EPTF_COAP_niddDB_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 |
| // |
| // Purpose: |
| // Initializing CLL's logging feature on the <EPTF_COAP_LGen_CT> component type |
| // |
| // Related Type: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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_log_error){ |
| f_EPTF_Logging_enableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_ERROR); |
| } |
| else { |
| f_EPTF_Logging_disableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_ERROR); |
| } |
| |
| if(tsp_EPTF_COAP_LGen_log_warning){ |
| f_EPTF_Logging_enableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_WARNING); |
| } |
| else { |
| f_EPTF_Logging_disableLocalMask(v_COAP_loggingMaskId, c_COAP_LGen_Logging_WARNING); |
| } |
| |
| 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 |
| // |
| // Purpose: |
| // The main clean up function for the <EPTF_COAP_LGen_CT> component type |
| // |
| // Related Type: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_cleanUp() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_EntityCtxDB_cleanUp(); |
| f_EPTF_COAP_FsmCtxDB_cleanUp(); |
| f_EPTF_COAP_transportEndpointDB_cleanUp(); |
| f_EPTF_COAP_trDB_cleanUp(); |
| f_EPTF_COAP_rrDB_cleanUp(); |
| f_EPTF_COAP_templateDB_cleanUp(); |
| f_EPTF_COAP_observedResourceDB_cleanUp(); |
| f_EPTF_COAP_observationDB_cleanUp(); |
| f_EPTF_COAP_blockwiseDB_cleanUp(); |
| f_EPTF_COAP_niddDB_cleanUp(); |
| vf_COAP_msgReceived := null; |
| vf_COAP_eventIndication := null; |
| |
| v_COAP_initialized := false; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_eCtxBind |
| // |
| // Purpose: |
| // This function is called by the CLL for each entity instance created on a particular instace of <EPTF_COAP_LGen_CT> |
| // The function will allocate and initialize an instance of <COAP_EntityCtx> in *v_COAP_EntityCtxDB* <COAP_EntityCtx_DB> |
| // |
| // Parameters: |
| // pl_eIdx - *in* *integer* - the index of the entity instance on this load generator component instance |
| // |
| // Returns: |
| // <EPTF_IntegerList> - The list will contain the index of the <COAP_EntityCtx> instance in the *v_COAP_EntityCtxDB* |
| // |
| // Related Type: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // The reverse operation of <f_COAP_eCtxBind>. Cleans up resources reserved during <f_COAP_eCtxBind>. Called by the CLL. |
| // |
| // Parameters: |
| // pl_eIdx - *in* *integer* - the index of the entity instance on this load generator component instance |
| // |
| // Related Type: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // The resources reserved during <f_COAP_eCtxBind> are reinitalized (reset). Called by the CLL. |
| // |
| // Parameters: |
| // pl_eIdx - *in* *integer* - the index of the entity instance on this load generator component instance |
| // |
| // Related Type: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Initializes the *v_COAP_EntityCtxDB* <COAP_EntityCtx_DB> database |
| // |
| // Related Type: |
| // <COAP_EntityCtx_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_EntityCtxDB* <COAP_EntityCtx_DB> database |
| // |
| // Related Type: |
| // <COAP_EntityCtx_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Initializes the *v_COAP_FsmCtxDB* <COAP_FsmCtx_DB> database |
| // |
| // Related Type: |
| // <COAP_FsmCtx_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_FsmCtxDB* <COAP_FsmCtx_DB> database |
| // |
| // Related Type: |
| // <COAP_FsmCtx_DB> |
| /////////////////////////////////////////////////////////// |
| 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_transportEndpointDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_transportEndpointDB* <COAP_TransportEndpointDB> database |
| // |
| // Related Type: |
| // <COAP_TransportEndpointDB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_transportEndpointDB_init() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_transportEndpointDB.queue); |
| v_COAP_transportEndpointDB.data := {}; |
| v_COAP_transportEndpointDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_COAP_addressDB_Hash"); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_transportEndpointDB_cleanUp |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_transportEndpointDB* <COAP_TransportEndpointDB> database |
| // |
| // Related Type: |
| // <COAP_TransportEndpointDB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_transportEndpointDB_cleanUp() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_transportEndpointDB.queue); |
| v_COAP_transportEndpointDB.data := {}; |
| f_EPTF_str2int_HashMap_Delete("EPTF_COAP_addressDB_Hash"); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_transportEndpointDB_add |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_transportEndpointDB* <COAP_TransportEndpointDB> database |
| // |
| // Parameters: |
| // p_te - *in* <COAP_TransportEndpoint> - the element to be added |
| // |
| // Returns: |
| // p_idx - *out* *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_TransportEndpointDB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_transportEndpointDB_add(in COAP_TransportEndpoint p_te, inout integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| p_idx := f_EPTF_COAP_transportEndpointDB_lookUp(p_te); |
| |
| if (p_idx == -1) |
| { |
| p_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_transportEndpointDB.queue); |
| f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_transportEndpointDB.queue); |
| f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding target address ", p_idx, " ", p_te.socket, " ", p_te.proto)); |
| f_EPTF_str2int_HashMap_Insert(v_COAP_transportEndpointDB.hashRef, f_EPTF_COAP_transportEndpointDB_Socket2String(p_te.socket), p_idx); |
| v_COAP_transportEndpointDB.data[p_idx] := p_te; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_transportEndpointDB_get |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_transportEndpointDB* <COAP_TransportEndpointDB> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to retrieved |
| // |
| // Returns: |
| // p_te - *inout* <COAP_TransportEndpoint> - the retrieved element |
| // |
| // Related Type: |
| // <COAP_TransportEndpointDB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_transportEndpointDB_get(inout COAP_TransportEndpoint p_te, in integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_idx < sizeof(v_COAP_transportEndpointDB.data)) |
| { |
| p_te := v_COAP_transportEndpointDB.data[p_idx]; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_transportEndpointDB_lookUp |
| // |
| // Purpose: |
| // Gets the index of an <COAP_TransportEndpoint> element in *v_COAP_transportEndpointDB* <COAP_TransportEndpointDB> database |
| // based on its socket member field |
| // |
| // Parameters: |
| // p_te - *in* <COAP_TransportEndpoint> - the retrieved element |
| // |
| // Returns: |
| // *integer* - the index of the element, or -1 if not found |
| // |
| // Related Type: |
| // <COAP_TransportEndpointDB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_transportEndpointDB_lookUp(in COAP_TransportEndpoint p_te) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| var integer vl_idx := -1; |
| f_EPTF_str2int_HashMap_Find(v_COAP_transportEndpointDB.hashRef, f_EPTF_COAP_transportEndpointDB_Socket2String(p_te.socket), vl_idx); |
| return vl_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_transportEndpointDB_Socket2String |
| // |
| // Purpose: |
| // Hash function for lookups used by the *v_COAP_transportEndpointDB* <COAP_TransportEndpointDB> database |
| // |
| // Parameters: |
| // p_sock - *in* <Socket> - the address (of a <COAP_TransportEndpoint>) |
| // |
| // Returns: |
| // *charstring* - string hash unique for the <Socket> parameter |
| // |
| // Related Type: |
| // <COAP_TransportEndpointDB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_transportEndpointDB_Socket2String(Socket p_sock) |
| return charstring |
| { |
| return p_sock.hostName&":"&int2str(p_sock.portNumber); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_rrDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_rrDB* <COAP_RR_DB> database |
| // |
| // Related Type: |
| // <COAP_RR_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_rrDB* <COAP_RR_DB> database |
| // |
| // Parameters: |
| // p_rr - *in* <COAP_RR> - the element to be added |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_RR_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rrDB_add(in COAP_RR p_rr) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, 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_COAP_transportEndpoint.socket, p_rr.token), v_idx); |
| |
| v_COAP_rrDB.data[v_idx] := p_rr; |
| |
| return v_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_rrDB_lookUp |
| // |
| // Purpose: |
| // Gets the index of an <COAP_RR> element in *v_COAP_rrDB* <COAP_RR_DB> database |
| // |
| // Parameters: |
| // p_rr - *in* <Socket> - the socket (IP) address |
| // p_token - *in* *octetstring* - the token value |
| // |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database, or -1 if not found |
| // |
| // Related Type: |
| // <COAP_RR_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_rrDB* <COAP_RR> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be retrieved |
| // |
| // Returns: |
| // p_rr - *inout* <COAP_RR> - the retrieved element |
| // |
| // Related Type: |
| // <COAP_RR_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Removes an element from the *v_COAP_rrDB* <COAP_RR> database and frees up its reserved resources |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be removed |
| // |
| // Related Type: |
| // <COAP_RR_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rrDB_remove(in integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_rrDB.data[p_idx].addrIdx); |
| f_EPTF_str2int_HashMap_Erase(v_COAP_rrDB.hashRef, f_EPTF_COAP_rrDB_tokenHash(v_COAP_transportEndpoint.socket, 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 |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_rrDB* <COAP_RR_DB> database |
| // |
| // Related Type: |
| // <COAP_RR_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Hash function for lookups used by the *v_COAP_rrDB* <COAP_RR_DB> database |
| // |
| // Parameters: |
| // p_sock - *in* <Socket> - the address (of a <COAP_TransportEndpoint>) |
| // p_token - *in* *octetstring* - the token value |
| // |
| // Returns: |
| // *charstring* - string hash unique for a <COAP_RR> element |
| // |
| // Related Type: |
| // <COAP_RR_DB> |
| /////////////////////////////////////////////////////////// |
| 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_observationDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_observationDB* <COAP_Observation_DB> database |
| // |
| // Related Type: |
| // <COAP_Observation_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observationDB_init() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_observationDB.queue); |
| v_COAP_observationDB.data := {}; |
| v_COAP_observationDB.hashRef := f_EPTF_str2int_HashMap_New("v_COAP_observationDB"); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observationDB_add |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_observationDB* <COAP_Observation_DB> database |
| // |
| // Parameters: |
| // p_os - *in* <COAP_Observation_Server> - the element to be added |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_Observation_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observationDB_add(in COAP_Observation_Server p_os) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| var integer v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_observationDB.queue); |
| f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_observationDB.queue); |
| f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding observation server ", v_idx, " ", p_os)); |
| f_EPTF_str2int_HashMap_Insert( |
| v_COAP_observationDB.hashRef, |
| f_EPTF_COAP_observationDB_tokenHash(p_os.remoteAddress, p_os.remotePort, p_os.resourceId, p_os.observedResourceIdx), v_idx |
| ); |
| |
| v_COAP_observationDB.data[v_idx] := p_os; |
| |
| return v_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observationDB_lookUp |
| // |
| // Purpose: |
| // Gets the index of an <COAP_Observation_Server> element in *v_COAP_observationDB* <COAP_Observation_DB> database |
| // |
| // Parameters: |
| // p_remoteAddr - *in* *charstring* - the address (host) of the observer |
| // p_remotePort - *in* *integer* - the port of the observer |
| // p_resId - *in* *charstring* - the id of the observed resource |
| // |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database, or -1 if not found |
| // |
| // Related Type: |
| // <COAP_Observation_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observationDB_lookUp(in charstring p_remoteAddr, in integer p_remotePort, in charstring p_resId, in integer p_resIdx) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| var integer vl_idx := -1; |
| f_EPTF_str2int_HashMap_Find( |
| v_COAP_observationDB.hashRef, |
| f_EPTF_COAP_observationDB_tokenHash(p_remoteAddr, p_remotePort, p_resId, p_resIdx), vl_idx |
| ); |
| return vl_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observationDB_get |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_observationDB* <COAP_Observation_DB> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be retrieved |
| // |
| // Returns: |
| // p_os - *inout* <COAP_Observation_Server> - the retrieved element |
| // |
| // Related Type: |
| // <COAP_Observation_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observationDB_get(in integer p_idx, inout COAP_Observation_Server p_os) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_idx < sizeof(v_COAP_observationDB.data)) |
| { |
| p_os := v_COAP_observationDB.data[p_idx]; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observationDB_remove |
| // |
| // Purpose: |
| // Removes an element from the *v_COAP_observationDB* <COAP_Observation_DB> database and frees up its reserved resources |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be removed |
| // |
| // Related Type: |
| // <COAP_Observation_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observationDB_remove(in integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_str2int_HashMap_Erase( |
| v_COAP_observationDB.hashRef, |
| f_EPTF_COAP_observationDB_tokenHash( |
| v_COAP_observationDB.data[p_idx].remoteAddress, |
| v_COAP_observationDB.data[p_idx].remotePort, |
| v_COAP_observationDB.data[p_idx].resourceId, |
| v_COAP_observationDB.data[p_idx].observedResourceIdx |
| ) |
| ); |
| |
| v_COAP_observationDB.data[p_idx] := c_COAP_Observation_Server_init; |
| f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_COAP_observationDB.queue); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observationDB_cleanUp |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_observationDB* <COAP_Observation_DB> database |
| // |
| // Related Type: |
| // <COAP_Observation_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observationDB_cleanUp() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_observationDB.queue); |
| v_COAP_observationDB.data := {}; |
| f_EPTF_str2int_HashMap_Delete("v_COAP_observationDB"); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observationDB_tokenHash |
| // |
| // Purpose: |
| // Hash function for lookups used by the *v_COAP_rrDB* <COAP_Observation_DB> database |
| // |
| // Parameters: |
| // p_remoteAddr - *in* *charstring* - the address (host) of the observer |
| // p_remotePort - *in* *integer* - the port of the observer |
| // p_resId - *in* *charstring* - the id of the observed resource |
| // |
| // Returns: |
| // *charstring* - string hash unique of a <COAP_Observation_Server> element |
| // |
| // Related Type: |
| // <COAP_Observation_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observationDB_tokenHash(in charstring p_remoteAddr, in integer p_remotePort, in charstring p_resId, in integer p_resIdx) |
| return charstring |
| { |
| return int2str(p_resIdx)&":"&p_remoteAddr&":"&int2str(p_remotePort)&p_resId; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_blockwiseDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database |
| // |
| // Related Type: |
| // <COAP_Blockwise_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_blockwiseDB_init() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_blockwiseDB.queue); |
| v_COAP_blockwiseDB.data := {}; |
| v_COAP_blockwiseDB.hashRef := f_EPTF_str2int_HashMap_New("v_COAP_blockwiseDB"); |
| v_COAP_blockwiseDB.collectContent := tsp_EPTF_COAP_BlockwiseTransfer_collectContent; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_blockwiseDB_add |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database |
| // |
| // Parameters: |
| // p_bs - *in* <COAP_Blockwise_Server> - the element to be added |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_Blockwise_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_blockwiseDB_add(in COAP_Blockwise_Transfer p_bt) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| var integer v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_blockwiseDB.queue); |
| f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_blockwiseDB.queue); |
| f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding blockwise transfer ", v_idx, " ", p_bt)); |
| f_EPTF_str2int_HashMap_Insert( |
| v_COAP_blockwiseDB.hashRef, |
| f_EPTF_COAP_blockwiseDB_tokenHash(p_bt.localAddress, p_bt.localPort, p_bt.resourceId), v_idx |
| ); |
| |
| v_COAP_blockwiseDB.data[v_idx] := p_bt; |
| |
| return v_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_blockwiseDB_lookUp |
| // |
| // Purpose: |
| // Gets the index of an <COAP_Blockwise_Transfer> element in *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database |
| // |
| // Parameters: |
| // p_localAddr - *in* *charstring* - the address (host) of the observer |
| // p_localPort - *in* *integer* - the port of the observer |
| // p_resId - *in* *charstring* - the id of the observed resource |
| // |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database, or -1 if not found |
| // |
| // Related Type: |
| // <COAP_Blockwise_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_blockwiseDB_lookUp(in charstring p_localAddr, in integer p_localPort, in charstring p_resId) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| var integer vl_idx := -1; |
| f_EPTF_str2int_HashMap_Find( |
| v_COAP_blockwiseDB.hashRef, |
| f_EPTF_COAP_blockwiseDB_tokenHash(p_localAddr, p_localPort, p_resId), vl_idx |
| ); |
| return vl_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_blockwiseDB_get |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be retrieved |
| // |
| // Returns: |
| // p_bs - *inout* <COAP_Blockwise_Transfer> - the retrieved element |
| // |
| // Related Type: |
| // <COAP_Blockwise_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_blockwiseDB_get(in integer p_idx, inout COAP_Blockwise_Transfer p_bt) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_idx < sizeof(v_COAP_blockwiseDB.data)) |
| { |
| p_bt := v_COAP_blockwiseDB.data[p_idx]; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_blockwiseDB_remove |
| // |
| // Purpose: |
| // Removes an element from the *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database and frees up its reserved resources |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be removed |
| // |
| // Related Type: |
| // <COAP_Blockwise_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_blockwiseDB_remove(in integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_str2int_HashMap_Erase( |
| v_COAP_blockwiseDB.hashRef, |
| f_EPTF_COAP_blockwiseDB_tokenHash( |
| v_COAP_blockwiseDB.data[p_idx].localAddress, |
| v_COAP_blockwiseDB.data[p_idx].localPort, |
| v_COAP_blockwiseDB.data[p_idx].resourceId |
| ) |
| ); |
| |
| v_COAP_blockwiseDB.data[p_idx] := c_COAP_Blockwise_Transfer_init; |
| f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_COAP_blockwiseDB.queue); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_blockwiseDB_cleanUp |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database |
| // |
| // Related Type: |
| // <COAP_Blockwise_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_blockwiseDB_cleanUp() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_blockwiseDB.queue); |
| v_COAP_blockwiseDB.data := {}; |
| f_EPTF_str2int_HashMap_Delete("v_COAP_blockwiseDB"); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_blockwiseDB_tokenHash |
| // |
| // Purpose: |
| // Hash function for lookups used by the *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database |
| // |
| // Parameters: |
| // p_localAddr - *in* *charstring* - the address (host) of resource |
| // p_localPort - *in* *integer* - the port of the resource |
| // p_resId - *in* *charstring* - the id of the observed resource |
| // |
| // Returns: |
| // *charstring* - string hash unique of a <COAP_Blockwise_Server> element |
| // |
| // Related Type: |
| // <COAP_Blockwise_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_blockwiseDB_tokenHash(in charstring p_localAddr, in integer p_localPort, in charstring p_resId) |
| return charstring |
| { |
| return p_localAddr&":"&int2str(p_localPort)&p_resId; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_trDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_trDB* <COAP_Transaction_DB> database |
| // |
| // Related Type: |
| // <COAP_Transaction_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_trDB* <COAP_Transaction_DB> database |
| // |
| // Parameters: |
| // p_tr - *in* <COAP_Transaction> - the element to be added |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_Transaction_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_trDB_add(in COAP_Transaction p_tr) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, 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_COAP_transportEndpoint.socket, p_tr.mid), v_idx); |
| } |
| else |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str("adding tr ", v_idx, " ", f_EPTF_COAP_trDB_midHash(v_COAP_transportEndpoint.socket, p_tr.mid))); |
| f_EPTF_str2int_HashMap_Insert(v_COAP_trDB.hashRefIncoming, f_EPTF_COAP_trDB_midHash(v_COAP_transportEndpoint.socket, p_tr.mid), v_idx); |
| } |
| v_COAP_trDB.data[v_idx] := p_tr; |
| |
| return v_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_trDB_lookUp |
| // |
| // Purpose: |
| // Gets the index of an <COAP_Transaction> element in *v_COAP_trDB* <COAP_Transaction_DB> database |
| // |
| // Parameters: |
| // p_sock - *in* <Socket> - the local address of a <COAP_Transaction> |
| // p_mid - *in* *integer* - the message id of the <COAP_Transaction> |
| // p_dir - *in* <COAP_Transaction_Direction> - the direction of the <COAP_Transaction> |
| // |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database, or -1 if not found |
| // |
| // Related Type: |
| // <COAP_Transaction_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_trDB* <COAP_Transaction_DB> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be retrieved |
| // |
| // Returns: |
| // p_os - *inout* <COAP_Transaction> - the retrieved element |
| // |
| // Related Type: |
| // <COAP_Transaction_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Removes an element from the *v_COAP_trDB* <COAP_Transaction_DB> database and frees up its reserved resources |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be removed |
| // |
| // Related Type: |
| // <COAP_Transaction_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_trDB_remove(in integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, 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_COAP_transportEndpoint.socket, v_COAP_trDB.data[p_idx].mid)); |
| } |
| else |
| { |
| f_EPTF_str2int_HashMap_Erase(v_COAP_trDB.hashRefIncoming, f_EPTF_COAP_trDB_midHash(v_COAP_transportEndpoint.socket, 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 |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_trDB* <COAP_Transaction_DB> database |
| // |
| // Related Type: |
| // <COAP_Transaction_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Hash function for lookups used by the *v_COAP_trDB* <COAP_Transaction_DB> database |
| // |
| // Parameters: |
| // p_sock - *in* <Socket> - the local address of a <COAP_Transaction> |
| // p_mid - *in* *integer* - the message id of the <COAP_Transaction> |
| // |
| // Returns: |
| // *charstring* - string hash unique of a <COAP_Transaction> element |
| // |
| // Related Type: |
| // <COAP_Transaction_DB> |
| /////////////////////////////////////////////////////////// |
| 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_observedResourceDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_observedResourceDB* <COAP_ObservedResource_DB> database |
| // |
| // Related Type: |
| // <COAP_ObservedResource_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observedResourceDB_init() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_observedResourceDB.queue); |
| v_COAP_observedResourceDB.data := {}; |
| v_COAP_observedResourceDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_COAP_observedResourceDB_Hash"); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observedResourceDB_add |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_observedResourceDB* <COAP_ObservedResource_DB> database |
| // |
| // Parameters: |
| // p_or - *in* <COAP_ObservedResource> - the element to be added |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_ObservedResource_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observedResourceDB_add(in COAP_ObservedResource p_or) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| if (f_EPTF_COAP_observedResourceDB_lookUp(p_or.localAddress, p_or.localPort, p_or.resourceId)!=-1) |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " observed resource is already added with id: ", p_or.resourceId)); |
| return -1; |
| } |
| |
| var integer v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_observedResourceDB.queue); |
| f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_observedResourceDB.queue); |
| f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding observed resource ", v_idx, " ", p_or)); |
| f_EPTF_str2int_HashMap_Insert( |
| v_COAP_observedResourceDB.hashRef, |
| f_EPTF_COAP_observedResourceDB_tokenHash(p_or.localAddress, p_or.localPort, p_or.resourceId), |
| v_idx |
| ); |
| |
| v_COAP_observedResourceDB.data[v_idx] := p_or; |
| |
| f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " observed resource was added with id: ", p_or.resourceId, " at idx: ",v_idx)); |
| |
| return v_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observedResourceDB_lookUp |
| // |
| // Purpose: |
| // Gets the index of an <COAP_ObservedResource> element in *v_COAP_observedResourceDB* <COAP_ObservedResource_DB> database |
| // |
| // Parameters: |
| // p_localAddr - *in* *charstring* - the local address of a <COAP_ObservedResource> |
| // p_localPort - *in* *integer* - the local port of the <COAP_ObservedResource> |
| // p_resourceId - *in* *charstring* - the resource id of the <COAP_ObservedResource> |
| // |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database, or -1 if not found |
| // |
| // Related Type: |
| // <COAP_ObservedResource_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observedResourceDB_lookUp(in charstring p_localAddr, in integer p_localPort, in charstring p_resourceId) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| var integer vl_idx := -1; |
| if (not f_EPTF_str2int_HashMap_Find( |
| v_COAP_observedResourceDB.hashRef, |
| f_EPTF_COAP_observedResourceDB_tokenHash(p_localAddr, p_localPort, p_resourceId), |
| vl_idx) |
| ) |
| { |
| vl_idx := -1; |
| } |
| |
| return vl_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observedResourceDB_get |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_observedResourceDB* <COAP_ObservedResource_DB> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be retrieved |
| // |
| // Returns: |
| // p_or - *inout* <COAP_ObservedResource> - the retrieved element |
| // |
| // Related Type: |
| // <COAP_ObservedResource_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observedResourceDB_get(in integer p_idx, inout COAP_ObservedResource p_or) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_idx < sizeof(v_COAP_observedResourceDB.data)) |
| { |
| p_or := v_COAP_observedResourceDB.data[p_idx]; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observedResourceDB_remove |
| // |
| // Purpose: |
| // Removes an element from the *v_COAP_observedResourceDB* <COAP_ObservedResource_DB> database and frees up its reserved resources |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be removed |
| // |
| // Related Type: |
| // <COAP_ObservedResource_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observedResourceDB_remove(in integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_str2int_HashMap_Erase( |
| v_COAP_observedResourceDB.hashRef, |
| f_EPTF_COAP_observedResourceDB_tokenHash( |
| v_COAP_observedResourceDB.data[p_idx].localAddress, |
| v_COAP_observedResourceDB.data[p_idx].localPort, |
| v_COAP_observedResourceDB.data[p_idx].resourceId |
| ) |
| ); |
| |
| v_COAP_observedResourceDB.data[p_idx] := c_COAP_ObservedResource_init; |
| f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_COAP_observedResourceDB.queue); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_observedResourceDB_cleanUp |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_observedResourceDB* <COAP_ObservedResource_DB> database |
| // |
| // Related Type: |
| // <COAP_ObservedResource_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_observedResourceDB_cleanUp() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_observedResourceDB.queue); |
| v_COAP_observedResourceDB.data := {}; |
| f_EPTF_str2int_HashMap_Delete("EPTF_COAP_observedResourceDB_Hash"); |
| } |
| |
| function f_EPTF_COAP_observedResourceDB_tokenHash(in charstring p_localAddr, in integer p_localPort, in charstring p_resourceId) |
| return charstring |
| { |
| return p_localAddr&":"&int2str(p_localPort)&p_resourceId; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_templateDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_templateDB* <COAP_Template_DB> database by adding the templates given in <tsp_EPTF_COAP_LGen_templates> |
| // |
| // Related Type: |
| // <COAP_Template_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_templateDB* <COAP_Template_DB> database |
| // |
| // Parameters: |
| // p_template - *in* <CoAP_Template> - the element to be added |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_Template_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Gets the index of an <CoAP_Template> element in *v_COAP_templateDB* <COAP_Template_DB> database |
| // |
| // Parameters: |
| // p_id - *in* *charstring* - the id of the <CoAP_Template> |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database, or -1 if not found |
| // |
| // Related Type: |
| // <COAP_Template_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_templateDB* <COAP_Template_DB> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be retrieved |
| // |
| // Returns: |
| // p_or - *inout* <CoAP_ReqResp> - the retrieved element |
| // |
| // Related Type: |
| // <COAP_Template_DB> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_templateDB* <COAP_Template_DB> database |
| // |
| // Related Type: |
| // <COAP_Template_DB> |
| /////////////////////////////////////////////////////////// |
| 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_niddDB_init |
| // |
| // Purpose: |
| // Initializes the *v_COAP_niddDB* <COAP_NIDD_DB> database |
| // |
| // Related Type: |
| // <COAP_NIDD_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_niddDB_init() |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_FBQ_initFreeBusyQueue(v_COAP_niddDB.queue); |
| v_COAP_niddDB.data := {}; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_niddDB_add |
| // |
| // Purpose: |
| // Adds a new element to the *v_COAP_niddDB* <COAP_NIDD_DB> database |
| // |
| // Parameters: |
| // p_msg - *in octetstring* - the element to be added |
| // |
| // Returns: |
| // *integer* - the index of the added element in the database |
| // |
| // Related Type: |
| // <COAP_NIDD_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_niddDB_add(in octetstring p_msg) |
| runs on EPTF_COAP_LGen_CT |
| return integer |
| { |
| var integer v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_COAP_niddDB.queue); |
| f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_COAP_niddDB.queue); |
| f_EPTF_COAP_Logging_DEBUG(log2str(": "," adding nidd message at ", v_idx)); |
| |
| v_COAP_niddDB.data[v_idx] := p_msg; |
| |
| return v_idx; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_niddDB_get |
| // |
| // Purpose: |
| // Retrieves an element from the *v_COAP_niddDB* <COAP_NIDD_DB> database |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be retrieved |
| // |
| // Returns: |
| // p_msg - *inout octetstring* - the retrieved element |
| // |
| // Related Type: |
| // <COAP_NIDD_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_niddDB_get(in integer p_idx, inout octetstring p_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_idx < sizeof(v_COAP_niddDB.data) and p_idx >= 0) |
| { |
| p_msg := v_COAP_niddDB.data[p_idx]; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_niddDB_remove |
| // |
| // Purpose: |
| // Removes an element from the *v_COAP_niddDB* <COAP_NIDD_DB> database and frees up its reserved resources |
| // |
| // Parameters: |
| // p_idx - *in* *integer* - the index of the element to be removed |
| // |
| // Related Type: |
| // <COAP_NIDD_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_niddDB_remove(in integer p_idx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| v_COAP_niddDB.data[p_idx] := ''O; |
| f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_COAP_niddDB.queue); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_niddDB_cleanUp |
| // |
| // Purpose: |
| // Cleans up the reserved resources of the *v_COAP_niddDB* <COAP_NIDD_DB> database |
| // |
| // Related Type: |
| // <COAP_NIDD_DB> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_niddDB_cleanUp() |
| runs on EPTF_COAP_LGen_CT |
| { |
| v_COAP_niddDB.data := {}; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_getNextMID |
| // |
| // Purpose: |
| // Generate the next unused message id for an entity |
| // |
| // Parameters: |
| // p_ctx - *in* <COAP_StepCtx> - pointers for the instances related to a particular simulated entity |
| // |
| // Returns: |
| // *integer* - the generated message id |
| // |
| // Related Type: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Generate the next unused token for an entity |
| // |
| // Parameters: |
| // p_ctx - *in* <COAP_StepCtx> - pointers for the instances related to a particular simulated entity |
| // |
| // Returns: |
| // *octetstring* - the generated token identifier |
| // |
| // Related Type: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| 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_send |
| // |
| // Purpose: |
| // The transport layer implementation <EPTF_COAP_Transport_Provider_CT> can report received <EPTF_COAP_PDU> message |
| // to the load generator layer <EPTF_COAP_Transport_User_CT> extended by <EPTF_COAP_LGen_CT> using this function. |
| // |
| // Parameters: |
| // pl_msg - *in* <EPTF_COAP_PDU> - received message |
| // |
| // Related Types: |
| // - <EPTF_COAP_LGen_CT> |
| // - <EPTF_COAP_Transport_Provider_CT> |
| // - <EPTF_COAP_Transport_User_CT> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_LGen_send(in EPTF_COAP_PDU pl_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (ischosen(pl_msg.transportParams.transport.nidd)) |
| { |
| var integer vl_eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(pl_msg.eIdx, v_COAP_bIdx, 0); |
| f_CoAP_enc(CoAP_Message: {msg := pl_msg.pdu}, v_COAP_encoded); |
| f_EPTF_COAP_EntityCtx_addOutgoingNiddMessage(vl_eCtxIdx, v_COAP_encoded); |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_niddMessageBuffered, pl_msg.eIdx, -1, {}); |
| } |
| else |
| { |
| vf_EPTF_COAP_Transport_send.apply(pl_msg); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_LGen_receiveMessage |
| // |
| // Purpose: |
| // The transport layer implementation <EPTF_COAP_Transport_Provider_CT> can report received <EPTF_COAP_PDU> message |
| // to the load generator layer <EPTF_COAP_Transport_User_CT> extended by <EPTF_COAP_LGen_CT> using this function. |
| // |
| // Parameters: |
| // pl_message - *in* <EPTF_COAP_PDU> - received message |
| // |
| // Related Types: |
| // - <EPTF_COAP_LGen_CT> |
| // - <fcb_EPTF_COAP_Transport_receiveMessage> |
| // - <EPTF_COAP_Transport_Provider_CT> |
| // - <EPTF_COAP_Transport_User_CT> |
| /////////////////////////////////////////////////////////// |
| 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; |
| |
| f_EPTF_COAP_updateMessageStatistics(v_COAP_stats.incoming, v_COAP_msgToProcess); |
| |
| var boolean v_duplicate := not f_EPTF_COAP_stack_fromEnv(v_COAP_msgToProcess); |
| |
| if (v_duplicate) { |
| v_COAP_stats.noDuplicates := v_COAP_stats.noDuplicates + 1; |
| } |
| |
| if (vf_COAP_msgReceived != null) |
| { |
| vf_COAP_msgReceived.apply(v_COAP_msgToProcess, v_duplicate, v_COAP_Stack_autoHandled); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_LGen_receiveEvent |
| // |
| // Purpose: |
| // The transport layer implementation <EPTF_COAP_Transport_Provider_CT> can report received <ASP_Event> events |
| // to the load generator layer <EPTF_COAP_Transport_User_CT> extended by <EPTF_COAP_LGen_CT> using this function. |
| // |
| // Parameters: |
| // pl_message - *in* <ASP_Event> - received event |
| // |
| // Related Types: |
| // - <EPTF_COAP_LGen_CT> |
| // - <fcb_EPTF_COAP_Transport_receiveEvent> |
| // - <EPTF_COAP_Transport_Provider_CT> |
| // - <EPTF_COAP_Transport_User_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // The transport layer implementation <EPTF_COAP_Transport_Provider_CT> can report received <EPTF_COAP_Transport_Response> responses |
| // to the load generator layer <EPTF_COAP_Transport_User_CT> extended by <EPTF_COAP_LGen_CT> using this function. |
| // |
| // Parameters: |
| // pl_rsp - *in* <EPTF_COAP_Transport_Response> - received transport api response |
| // |
| // Related Types: |
| // - <EPTF_COAP_LGen_CT> |
| // - <fcb_EPTF_COAP_Transport_apiResponse> |
| // - <EPTF_COAP_Transport_Provider_CT> |
| // - <EPTF_COAP_Transport_User_CT> |
| /////////////////////////////////////////////////////////// |
| 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 (ispresent(pl_rsp.params)) |
| { |
| if (ischosen(pl_rsp.params.dtlsConnectionClosed)) { |
| |
| } |
| } |
| |
| 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 |
| // |
| // Purpose: |
| // This is the main entry point for the COAP stack realization of the <EPTF_COAP_LGen_CT> |
| // component that handles messages received from the application layer (e.g. FSMs) |
| // |
| // Parameters: |
| // p_msg - *inout* <EPTF_COAP_PDU> - message that enters into the stack (will be modified by the stack) |
| // p_ctx - *in* <COAP_StepCtx> - pointers for the instances related to a particular simulated entity |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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")); |
| |
| if (f_EPTF_COAP_isRequest(p_msg.pdu)) |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " replacing ongoing request response with new RR")); |
| |
| 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); |
| } |
| else |
| { |
| f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " handling ongoing request response with original RR")); |
| |
| f_EPTF_COAP_rr_handleMsg(p_msg, v_COAP_FsmCtxDB.data[p_ctx.fsmCtxIdx].rrIdx); |
| } |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_stack_fromEnv |
| // |
| // Purpose: |
| // This is the main entry point for the COAP stack realization of the <EPTF_COAP_LGen_CT> |
| // component that handles messages received from the environment layer (e.g. transport layer) |
| // |
| // Parameters: |
| // p_msg - *inout* <EPTF_COAP_PDU> - message that enters into the stack (will be modified by the stack) |
| // |
| // Returns: |
| // *boolean* - true, if the *p_msg* message was a duplicate, false if it was not |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_stack_fromEnv(inout EPTF_COAP_PDU p_msg) |
| runs on EPTF_COAP_LGen_CT |
| return boolean |
| { |
| // We clear the the flag that indicates automatic handling by the stack |
| v_COAP_Stack_autoHandled := false; |
| |
| // 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_tr.retransmitTimerValue := tsp_EPTF_COAP_LGen_retransmitTimerInitialValue; |
| |
| 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; |
| } |
| } |
| } |
| |
| /***************************************************************** |
| @startuml EPTF_COAP_LGen_Functions.COAP_RR_Server.jpg |
| [*] --> IDLE |
| IDLE --> SERVING: trIn: request CON |
| IDLE --> SEPARATE: trIn: request NON |
| SERVING --> REMOVING: appIn: response |
| SERVING --> REMOVING: appIn: empty ACK |
| SEPARATE --> REMOVING: appIn: response |
| REMOVING --> [*] |
| @enduml |
| ******************************************************************/ |
| /***************************************************************** |
| @startuml EPTF_COAP_LGen_Functions.COAP_RR_Client.jpg |
| [*] --> IDLE |
| IDLE --> WAITING: appIn: request |
| WAITING --> REMOVING: appIn: cancel |
| WAITING --> REMOVING: trIn: timeout |
| WAITING --> REMOVING: trIn: reset |
| WAITING --> REMOVING: trIn: response |
| REMOVING --> [*] |
| @enduml |
| ******************************************************************/ |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_rr_handleMsg |
| // |
| // Purpose: |
| // This function implements a COAP request-response state machine |
| // |
| // Parameters: |
| // p_msg - *inout* <EPTF_COAP_PDU> - message that enters into the stack (will be modified by the stack) |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> that will handle the message |
| // |
| // Related Types: |
| // <COAP_RR> |
| // |
| // FSM Diagram of client request-response: |
| // (see EPTF_COAP_LGen_Functions.COAP_RR_Client.jpg) |
| // |
| // FSM Diagram of server request-response: |
| // (see EPTF_COAP_LGen_Functions.COAP_RR_Server.jpg) |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_handleMsg(inout EPTF_COAP_PDU p_msg, in integer p_rrIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_rrIdx < 0 or p_rrIdx >= sizeof(v_COAP_rrDB.data)) { return } |
| |
| 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; |
| vl_tr.retransmitTimerValue := tsp_EPTF_COAP_LGen_retransmitTimerInitialValue; |
| |
| 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_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_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].remoteProtocol := p_msg.transportParams.transport; |
| 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; |
| |
| f_EPTF_COAP_rr_handle_Observe_request(p_rrIdx, p_msg); |
| |
| f_EPTF_COAP_rr_handle_BlockwiseTransfer_request(p_rrIdx, p_msg, v_COAP_ctx.eCtxIdx); |
| |
| // 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; |
| vl_tr.retransmitTimerValue := tsp_EPTF_COAP_LGen_retransmitTimerInitialValue; |
| |
| 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; |
| } |
| if (ispresent(v_COAP_rrDB.data[p_rrIdx].remoteProtocol)) |
| { |
| p_msg.transportParams.transport := v_COAP_rrDB.data[p_rrIdx].remoteProtocol; |
| } |
| |
| // trOut.send |
| v_COAP_rrDB.data[p_rrIdx].response := p_msg; |
| f_EPTF_COAP_tr_fromRR(p_msg, 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; |
| |
| f_EPTF_COAP_rr_handle_Observe_request(p_rrIdx, p_msg); |
| |
| f_EPTF_COAP_rr_handle_BlockwiseTransfer_request(p_rrIdx, p_msg, v_COAP_ctx.eCtxIdx); |
| |
| if (ispresent(v_COAP_rrDB.data[p_rrIdx].remoteAddress)) |
| { |
| p_msg.transportParams.remoteAddress := v_COAP_rrDB.data[p_rrIdx].remoteAddress; |
| } |
| if (ispresent(v_COAP_rrDB.data[p_rrIdx].remoteProtocol)) |
| { |
| p_msg.transportParams.transport := v_COAP_rrDB.data[p_rrIdx].remoteProtocol; |
| } |
| |
| // trOut.send |
| v_COAP_rrDB.data[p_rrIdx].response := p_msg; |
| f_EPTF_COAP_tr_fromRR(p_msg, 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; |
| } |
| if (ispresent(v_COAP_rrDB.data[p_rrIdx].remoteProtocol)) |
| { |
| p_msg.transportParams.transport := v_COAP_rrDB.data[p_rrIdx].remoteProtocol; |
| } |
| |
| // trOut.send |
| f_EPTF_COAP_tr_fromRR(p_msg, 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 |
| // |
| // Purpose: |
| // This function handles the *reset* event of a <COAP_RR> state machine |
| // |
| // Parameters: |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> that will handle the message |
| // |
| // Related Types: |
| // <COAP_RR> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_reset(in integer p_rrIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_rrIdx < 0 or p_rrIdx >= sizeof(v_COAP_rrDB.data)) { return } |
| |
| // 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 |
| // |
| // Purpose: |
| // This function handles the *timeout* event of a <COAP_RR> state machine |
| // |
| // Parameters: |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> that will handle the message |
| // |
| // Related Types: |
| // <COAP_RR> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_timeout(in integer p_rrIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_rrIdx < 0 or p_rrIdx >= sizeof(v_COAP_rrDB.data)) { return } |
| |
| // RR: Client |
| if (ischosen(v_COAP_rrDB.data[p_rrIdx].state.client)) |
| { |
| // State: WAITING |
| if (v_COAP_rrDB.data[p_rrIdx].state.client == WAITING) |
| { |
| v_COAP_stats.noTransactionTimeouts := v_COAP_stats.noTransactionTimeouts + 1; |
| 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 |
| // |
| // Purpose: |
| // This function handles the *cancel* event of a <COAP_RR> state machine |
| // |
| // Parameters: |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> that will handle the message |
| // |
| // Related Types: |
| // <COAP_RR> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_cancel(in integer p_rrIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_rrIdx < 0 or p_rrIdx >= sizeof(v_COAP_rrDB.data)) { return } |
| |
| // 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 |
| // |
| // Purpose: |
| // This function handles the removal and clean up of a <COAP_RR> state machine instance from the DB |
| // |
| // Parameters: |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> |
| // |
| // Related Types: |
| // <COAP_RR> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_remove(in integer p_rrIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_rrIdx < 0 or p_rrIdx >= sizeof(v_COAP_rrDB.data)) { return } |
| |
| 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 |
| // |
| // Purpose: |
| // This function sets the current state of a <COAP_RR> state machine instance |
| // |
| // Parameters: |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> that will handle the message |
| // p_nextState - *in* <COAP_RR_State> - next state of the state machine |
| // |
| // Related Types: |
| // <COAP_RR> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_setState(in integer p_rrIdx, in COAP_RR_State p_nextState) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_rrIdx < 0 or p_rrIdx >= sizeof(v_COAP_rrDB.data)) { return } |
| |
| 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_rr_handle_Observe_request |
| // |
| // Purpose: |
| // This function handles an incoming Observe request as part of a <COAP_RR> state machine instance |
| // |
| // Parameters: |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> that will handle the message |
| // p_msg - *in* <EPTF_COAP_PDU> - incoming message |
| // |
| // Related Types: |
| // <COAP_RR> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_handle_Observe_request(in integer p_rrIdx, inout EPTF_COAP_PDU p_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| // In case it's a response to an Observe request |
| var integer v_observeOptionIdx := f_EPTF_COAP_hasObserve(v_COAP_rrDB.data[p_rrIdx].request.pdu); |
| if (v_observeOptionIdx >= 0) |
| { |
| // In case the request was an observe subscribe |
| if (v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_observeOptionIdx].observe == 0) |
| { |
| // In case it is a positive (2xx) response |
| if (p_msg.pdu.header.code.class == 2) |
| { |
| // We are adding the observation to the DB |
| f_EPTF_COAP_EntityCtx_addObservation(v_COAP_ctx.eCtxIdx, v_COAP_rrDB.data[p_rrIdx].request); |
| |
| f_EPTF_COAP_addOption(p_msg.pdu, { observe := c_COAP_Observation_initSeqNum }); |
| } |
| } |
| // In case the request was an observe unsubscribe |
| else if (v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_observeOptionIdx].observe == 1) |
| { |
| // Let's fetch the uri path |
| var charstring vl_resourceId := f_EPTF_COAP_uriPathToString(v_COAP_rrDB.data[p_rrIdx].request.pdu); |
| f_EPTF_COAP_Logging_DEBUG(log2str("observe unsubscribe for ", vl_resourceId)); |
| |
| // Let's try to look up the observed resource |
| var integer vl_observedResourceIdx := f_EPTF_COAP_observedResourceDB_lookUp( |
| v_COAP_rrDB.data[p_rrIdx].request.transportParams.localAddress.hostName, |
| v_COAP_rrDB.data[p_rrIdx].request.transportParams.localAddress.portNumber, |
| vl_resourceId |
| ); |
| f_EPTF_COAP_Logging_DEBUG(log2str("observedResourceIdx: ", vl_observedResourceIdx)); |
| |
| if (vl_observedResourceIdx != -1) |
| { |
| // Let's try to look up the observation server |
| var integer vl_observationIdx := f_EPTF_COAP_observationDB_lookUp( |
| v_COAP_rrDB.data[p_rrIdx].request.transportParams.remoteAddress.hostName, |
| v_COAP_rrDB.data[p_rrIdx].request.transportParams.remoteAddress.portNumber, |
| vl_resourceId, |
| vl_observedResourceIdx |
| ); |
| f_EPTF_COAP_Logging_DEBUG(log2str("observationIdx: ", vl_observationIdx)); |
| |
| if (vl_observationIdx != -1) |
| { |
| f_EPTF_COAP_ObservationServer_cancelReceivedFromEnv(vl_observationIdx); |
| } |
| } |
| } |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_rr_handle_BlockwiseTransfer_request |
| // |
| // Purpose: |
| // This function handles an incoming blockwise transfer request as part of a <COAP_RR> state machine instance |
| // |
| // Parameters: |
| // p_rrIdx - *in* *integer* - index of the <COAP_RR> in the <COAP_RR_DB> that will handle the message |
| // p_msg - *in* <EPTF_COAP_PDU> - incoming message |
| // p_eCtxIdx - *in* *integer* - entity context index |
| // |
| // Related Types: |
| // <COAP_RR> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_rr_handle_BlockwiseTransfer_request(in integer p_rrIdx, inout EPTF_COAP_PDU p_msg, in integer p_eCtxIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| // In case it's a response to a Block1 request |
| var integer v_block1OptionIdx := f_EPTF_COAP_hasBlock1(v_COAP_rrDB.data[p_rrIdx].request.pdu); |
| if (v_block1OptionIdx >= 0) |
| { |
| // In case it is a positive (2xx) response |
| if (p_msg.pdu.header.code.class == 2) |
| { |
| // 204 response -> stateless block1 server |
| if (p_msg.pdu.header.code.detail == 4) |
| { |
| f_EPTF_COAP_addOption(p_msg.pdu, |
| { |
| block1 := { |
| num := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.num, |
| m := false, |
| szx := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.szx |
| } |
| }); |
| } |
| // 231 response -> atomic server creation |
| else if (p_msg.pdu.header.code.detail == 31) |
| { |
| // if it is an initial block we can add an atomic server |
| if (v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.num == 0) |
| { |
| f_EPTF_COAP_EntityCtx_addBlockwiseTransfer( |
| v_COAP_ctx.eIdx, v_COAP_ctx.fsmIdx, v_COAP_ctx.eCtxIdx, |
| v_block1OptionIdx, v_COAP_rrDB.data[p_rrIdx].request); |
| |
| // If we have a smaller preferred block size, we send that back |
| if ( |
| ispresent(v_COAP_EntityCtxDB.data[p_eCtxIdx].preferredBlocksize) and |
| v_COAP_EntityCtxDB.data[p_eCtxIdx].preferredBlocksize < v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.szx |
| ) |
| { |
| f_EPTF_COAP_addOption(p_msg.pdu, |
| { |
| block1 := { |
| num := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.num, |
| m := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.m, |
| szx := v_COAP_EntityCtxDB.data[p_eCtxIdx].preferredBlocksize |
| } |
| }); |
| } |
| else |
| { |
| f_EPTF_COAP_addOption(p_msg.pdu, |
| { |
| block1 := { |
| num := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.num, |
| m := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.m, |
| szx := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.szx |
| } |
| }); |
| } |
| } |
| // not an initial block |
| else |
| { |
| f_EPTF_COAP_addOption(p_msg.pdu, |
| { |
| block1 := { |
| num := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.num, |
| m := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.m, |
| szx := v_COAP_rrDB.data[p_rrIdx].request.pdu.options[v_block1OptionIdx].block1.szx |
| } |
| }); |
| } |
| } |
| } |
| } |
| } |
| |
| /***************************************************************** |
| @startuml EPTF_COAP_LGen_Functions.COAP_Transaction.jpg |
| [*] --> CLOSED |
| CLOSED --> CLOSED: envIn: NON |
| CLOSED --> CLOSED: rrIn: NON |
| CLOSED --> CLOSED: envIn: RST |
| CLOSED --> REMOVING: T_lifetime |
| CLOSED --> REMOVING: rrIn: ACK |
| CLOSED --> RELIABLE_TX: rrIn: CON |
| RELIABLE_TX --> CLOSED: envIn: ACK |
| RELIABLE_TX --> CLOSED: envIn: RST |
| RELIABLE_TX --> CLOSED: rrIn: CANCEL |
| RELIABLE_TX --> RELIABLE_TX: T_retransmit |
| RELIABLE_TX --> REMOVING: T_lifetime |
| ACK_PENDING --> CLOSED: rrIn: ACK |
| ACK_PENDING --> CLOSED: rrIn: RST |
| ACK_PENDING --> REMOVING: T_lifetime |
| REMOVING --> [*] |
| @enduml |
| ******************************************************************/ |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_tr_fromRR |
| // |
| // Purpose: |
| // This function implements a COAP request-response state machine by handling the incoming message from a <COAP_RR> |
| // |
| // Parameters: |
| // p_msg - *inout* <EPTF_COAP_PDU> - message that enters into the transaction (will be modified by the stack) |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> instance in the <COAP_Transaction_DB> that will handle the message |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| // |
| // FSM Diagram of a COAP transaction: |
| // (see EPTF_COAP_LGen_Functions.COAP_Transaction.jpg) |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_fromRR(inout EPTF_COAP_PDU p_msg, in integer p_trIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_trIdx < 0 or p_trIdx >= sizeof(v_COAP_trDB.data)) { return } |
| |
| 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); |
| f_EPTF_COAP_tr_startT_rtt(p_trIdx); |
| // 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) |
| { |
| // start EXCHANGE_LIFETIME |
| f_EPTF_COAP_tr_startT_lifetime(p_trIdx, tsp_EPTF_COAP_EXCHANGE_LIFETIME); |
| // out.send |
| f_EPTF_COAP_tr_send(p_msg, p_trIdx); |
| // next state: CLOSED |
| f_EPTF_COAP_tr_setState(p_trIdx, CLOSED); |
| // OLD: 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 |
| // |
| // Purpose: |
| // This function implements a COAP request-response state machine by handling the incoming message from a <COAP_RR> |
| // |
| // Parameters: |
| // p_msg - *inout* <EPTF_COAP_PDU> - message that enters into the transaction (will be modified by the stack) |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> instance in the <COAP_Transaction_DB> that will handle the message |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| // |
| // FSM Diagram of a COAP transaction: |
| // (see EPTF_COAP_LGen_Functions.COAP_Transaction.jpg) |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_fromEnv(inout EPTF_COAP_PDU p_msg, in integer p_trIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_trIdx < 0 or p_trIdx >= sizeof(v_COAP_trDB.data)) { return } |
| |
| 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_dispatchEventForObserve_ifExists(p_msg.pdu, p_msg.eIdx, -1); |
| if (not f_EPTF_COAP_tr_handleBlockwiseTransfer(p_trIdx, p_msg)) |
| { |
| 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_dispatchEventForObserve_ifExists(p_msg.pdu, p_msg.eIdx, -1); |
| if (not f_EPTF_COAP_tr_handleBlockwiseTransfer(p_trIdx, p_msg)) |
| { |
| 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: RST |
| else if (p_msg.pdu.header.msg_type == RESET) |
| { |
| // report reset |
| if (v_COAP_trDB.data[p_trIdx].rrIdx != -1) { |
| f_EPTF_COAP_rr_reset(v_COAP_trDB.data[p_trIdx].rrIdx); |
| } |
| // report observe cancel |
| if (v_COAP_trDB.data[p_trIdx].obsIdx != -1) { |
| f_EPTF_COAP_ObservationServer_cancelReceivedFromEnv(v_COAP_trDB.data[p_trIdx].obsIdx); |
| } |
| // 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)); |
| } |
| } |
| // 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); |
| f_EPTF_COAP_tr_stopT_rtt(p_trIdx); |
| if (not f_EPTF_COAP_isEmpty(p_msg.pdu) and v_COAP_trDB.data[p_trIdx].rrIdx != -1) |
| { |
| 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 |
| if (v_COAP_trDB.data[p_trIdx].rrIdx != -1) { |
| f_EPTF_COAP_rr_reset(v_COAP_trDB.data[p_trIdx].rrIdx); |
| } |
| // report observe cancel |
| if (v_COAP_trDB.data[p_trIdx].obsIdx != -1) { |
| f_EPTF_COAP_ObservationServer_cancelReceivedFromEnv(v_COAP_trDB.data[p_trIdx].obsIdx); |
| } |
| // 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_handleBlockwiseTransfer |
| // |
| // Purpose: |
| // This function handles incoming COAP messages in case they are blockwise transfer related. |
| // |
| // Parameters: |
| // p_msg - *inout* <EPTF_COAP_PDU> - message that enters into the transaction |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> instance in the <COAP_Transaction_DB> that will handle the message |
| // |
| // Returns: |
| // *boolean* - true if the message is blockwise transfer related |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| // |
| // FSM Diagram of a COAP transaction: |
| // (see EPTF_COAP_LGen_Functions.COAP_Transaction.jpg) |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_handleBlockwiseTransfer(in integer p_trIdx, inout EPTF_COAP_PDU p_msg) |
| runs on EPTF_COAP_LGen_CT |
| return boolean |
| { |
| var integer v_block1OptionIdx := f_EPTF_COAP_hasBlock1(p_msg.pdu); |
| // If we have a block1 option |
| if (v_block1OptionIdx >= 0) |
| { |
| v_COAP_stats.block1.noBlocks := v_COAP_stats.block1.noBlocks + 1; |
| |
| var charstring v_uriPath := f_EPTF_COAP_uriPathToString(p_msg.pdu); |
| var integer v_blockwiseIdx := f_EPTF_COAP_blockwiseDB_lookUp( |
| p_msg.transportParams.localAddress.hostName, |
| p_msg.transportParams.localAddress.portNumber, |
| v_uriPath |
| ); |
| // If we have ongoing atomic block1 transfer |
| // -> the message is handled by the BlockwiseTransfer FSM |
| if (v_blockwiseIdx >= 0) |
| { |
| f_EPTF_COAP_BlockwiseTransfer_in(v_blockwiseIdx, p_msg, v_block1OptionIdx); |
| // The stack indicates, that the request is automatically handled |
| v_COAP_Stack_autoHandled := true; |
| } |
| // If we don't have a BlockwiseTransfer FSM we dispatch an event to the entity to handle it |
| else |
| { |
| f_EPTF_COAP_dispatchEventForBlock1(p_msg.pdu.options[v_block1OptionIdx].block1, p_msg.eIdx, -1); |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_tr_cancel |
| // |
| // Purpose: |
| // This function handles the *cancel* event of a <COAP_Transaction> state machine instance |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will handle the event |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_cancel(in integer p_trIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_trIdx < 0 or p_trIdx >= sizeof(v_COAP_trDB.data)) { return } |
| |
| 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 |
| // |
| // Purpose: |
| // This function handles the *T_lifetime* timer's timeout event of a <COAP_Transaction> state machine instance |
| // |
| // Parameters: |
| // pl_action - *in* <EPTF_ScheduledAction> - contains the index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will handle the event |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| 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]; |
| |
| if (vl_trIdx < 0 or vl_trIdx >= sizeof(v_COAP_trDB.data)) { return false } |
| |
| 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 |
| // |
| // Purpose: |
| // This function handles the *T_retransmit* timer's timeout event of a <COAP_Transaction> state machine instance |
| // |
| // Parameters: |
| // pl_action - *in* <EPTF_ScheduledAction> - contains the index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will handle the event |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| 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]; |
| |
| if (vl_trIdx < 0 or vl_trIdx >= sizeof(v_COAP_trDB.data)) { return false } |
| |
| 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); |
| v_COAP_stats.noRetransmissions := v_COAP_stats.noRetransmissions + 1; |
| } |
| else |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " cannot retransmit empty cache")); |
| } |
| |
| return true; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_tr_startT_retransmit |
| // |
| // Purpose: |
| // This function starts the *T_retransmit* timer of a particular <COAP_Transaction> instance |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will start the timer |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // This function cancels the *T_retransmit* timer of a particular <COAP_Transaction> instance |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will cancel the timer |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // This function starts the *T_lifetime* timer of a particular <COAP_Transaction> instance |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will start the timer |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // This function cancels the *T_lifetime* timer of a particular <COAP_Transaction> instance |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will cancel the timer |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| 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_startT_rtt |
| // |
| // Purpose: |
| // This function starts the *T_rtt* timer to measure the round-trip time of the transaction |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will start the timer |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_startT_rtt(in integer pl_trIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| v_COAP_trDB.data[pl_trIdx].rtt := T_EPTF_componentClock.read; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_tr_stopT_rtt |
| // |
| // Purpose: |
| // This function stops the *T_rtt* timer and reports the measure round-trip time |
| // via the <vf_COAP_rttIndication> <fcb_EPTF_COAP_rttIndication> call-back function |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will measure RTT |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_stopT_rtt(in integer pl_trIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (ispresent(v_COAP_trDB.data[pl_trIdx].rtt)) |
| { |
| v_COAP_trDB.data[pl_trIdx].rtt := T_EPTF_componentClock.read - v_COAP_trDB.data[pl_trIdx].rtt; |
| |
| if (vf_COAP_rttIndication != null) { |
| vf_COAP_rttIndication.apply(v_COAP_trDB.data[pl_trIdx].rtt); |
| } |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_tr_send |
| // |
| // Purpose: |
| // This function is used to send out a message from an instance of a <COAP_Transaction> using the registered |
| // function <fcb_EPTF_COAP_Transport_sendMessage> of the underlying transport layer instance. |
| // |
| // Parameters: |
| // p_msg - *intout* <EPTF_COAP_PDU> - the message to be sent |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will cancel the timer |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_send(inout EPTF_COAP_PDU p_msg, in integer p_trIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_trIdx < 0 or p_trIdx >= sizeof(v_COAP_trDB.data)) { return } |
| |
| v_COAP_trDB.data[p_trIdx].cache := p_msg; |
| |
| f_EPTF_COAP_updateMessageStatistics(v_COAP_stats.outgoing, p_msg); |
| |
| f_EPTF_COAP_LGen_send(p_msg); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_tr_remove |
| // |
| // Purpose: |
| // This function handles the removal and clean up of a <COAP_Transaction> state machine instance from the DB |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_remove(in integer p_trIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_trIdx < 0 or p_trIdx >= sizeof(v_COAP_trDB.data)) { return } |
| |
| 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 |
| // |
| // Purpose: |
| // This function sets the current state of a <COAP_Transaction> state machine instance |
| // |
| // Parameters: |
| // p_trIdx - *in* *integer* - index of the <COAP_Transaction> in the <COAP_Transaction_DB> that will handle the message |
| // p_nextState - *in* <COAP_Transaction_State> - next state of the state machine |
| // |
| // Related Types: |
| // <COAP_Transaction> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_tr_setState(in integer p_trIdx, in COAP_Transaction_State p_nextState) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_trIdx < 0 or p_trIdx >= sizeof(v_COAP_trDB.data)) { return } |
| |
| 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_BlockwiseTransfer_in |
| // |
| // Purpose: |
| // This function implements the incoming message handling for a <COAP_Blockwise_Transfer> instance |
| // |
| // Parameters: |
| // p_blockwiseIdx - *in* *integer* - index of the <COAP_Blockwise_Transfer> in the *v_COAP_blockwiseDB* <COAP_Blockwise_DB> database |
| // p_msg - *inout* <EPTF_COAP_PDU> - the incoming message |
| // p_block1OptionIdx - *in* *integer* - the index of the block1 option in the message header |
| // |
| // Related Types: |
| // <COAP_Blockwise_Transfer> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_BlockwiseTransfer_in(in integer p_blockwiseIdx, inout EPTF_COAP_PDU p_msg, in integer p_block1OptionIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_BlockwiseTransfer_cancelT_lifetime(p_blockwiseIdx); |
| |
| // in case the incoming block is not in sequence (and we didn't ask for smaller block size) |
| if ( |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].lastBlock1Option.num + 1 != p_msg.pdu.options[p_block1OptionIdx].block1.num |
| and not v_COAP_blockwiseDB.data[p_blockwiseIdx].ongoingBlocksizeChange |
| ) |
| { |
| // Send back 4.08 |
| f_COAP_step_handleRequest(valueof(t_EPTF_COAP_stepArgs(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, v_COAP_blockwiseDB.data[p_blockwiseIdx].fsmIdx))); |
| v_COAP_msgToSend.pdu := valueof(t_EPTF_COAP_BlockwiseResponse(4,8)); |
| f_COAP_step_sendResponse(valueof(t_EPTF_COAP_stepArgs(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, v_COAP_blockwiseDB.data[p_blockwiseIdx].fsmIdx))); |
| |
| // Dispatch event: blockwise transfer fail finish |
| //if (f_EPTF_COAP_isCoapReportEnabledForEntity(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx) ) { |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_BLOCK1_atomic_fail, v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, -1, {}); |
| //} |
| |
| v_COAP_stats.block1.noAtomicUnsucc := v_COAP_stats.block1.noAtomicUnsucc + 1; |
| |
| // Remove the blockwise transfer FSM |
| f_EPTF_COAP_blockwiseDB_remove(p_blockwiseIdx); |
| return; |
| } |
| |
| // Save incoming block1 |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].lastBlock1Option := p_msg.pdu.options[p_block1OptionIdx].block1; |
| if (ispresent(p_msg.pdu.payload) and v_COAP_blockwiseDB.collectContent) |
| { |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].content := v_COAP_blockwiseDB.data[p_blockwiseIdx].content & p_msg.pdu.payload; |
| } |
| |
| // if we asked for a smaller blocksize we switch the 'ongoing' flag after the blocksize handshake |
| if (v_COAP_blockwiseDB.data[p_blockwiseIdx].ongoingBlocksizeChange) |
| { |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].ongoingBlocksizeChange := false; |
| } |
| |
| // if there are more blocks coming |
| if (v_COAP_blockwiseDB.data[p_blockwiseIdx].lastBlock1Option.m == true) |
| { |
| // Send back 2.31 |
| f_COAP_step_handleRequest(valueof(t_EPTF_COAP_stepArgs(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, v_COAP_blockwiseDB.data[p_blockwiseIdx].fsmIdx))); |
| v_COAP_msgToSend.pdu := valueof(t_EPTF_COAP_BlockwiseResponse(2,31)); |
| f_COAP_step_sendResponse(valueof(t_EPTF_COAP_stepArgs(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, v_COAP_blockwiseDB.data[p_blockwiseIdx].fsmIdx))); |
| |
| // Re-Start the lifetime timer for the blockwise transfer |
| f_EPTF_COAP_BlockwiseTransfer_startT_lifetime(p_blockwiseIdx); |
| } |
| // in case it was the last block |
| else |
| { |
| // Send back 2.04 |
| f_COAP_step_handleRequest(valueof(t_EPTF_COAP_stepArgs(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, v_COAP_blockwiseDB.data[p_blockwiseIdx].fsmIdx))); |
| v_COAP_msgToSend.pdu := valueof(t_EPTF_COAP_BlockwiseResponse(2,4)); |
| f_COAP_step_sendResponse(valueof(t_EPTF_COAP_stepArgs(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, v_COAP_blockwiseDB.data[p_blockwiseIdx].fsmIdx))); |
| |
| // Dispatch event: blockwise transfer succ finish |
| if (f_EPTF_COAP_isCoapReportEnabledForEntity(v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx) ) { |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_BLOCK1_atomic_succ, v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, -1, {}); |
| } |
| |
| v_COAP_stats.block1.noAtomicSucc := v_COAP_stats.block1.noAtomicSucc + 1; |
| |
| // Indicate event to the COAP user layer |
| if (vf_COAP_eventIndication != null) |
| { |
| vf_COAP_eventIndication.apply( |
| { |
| atomicBlock1Finished := |
| { |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].eIdx, |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].uriPath, |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].headerCode, |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].contentFormat, |
| v_COAP_blockwiseDB.data[p_blockwiseIdx].content |
| } |
| } |
| ); |
| } |
| |
| // Remove the blockwise transfer FSM |
| f_EPTF_COAP_blockwiseDB_remove(p_blockwiseIdx); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_BlockwiseTransfer_lifetime |
| // |
| // Purpose: |
| // This function handles the incoming T_lifetime timeout event for a <COAP_Blockwise_Transfer> instance |
| // |
| // Parameters: |
| // pl_action - *in* <EPTF_ScheduledAction> - the action descriptor |
| // pl_eventIndex - *in integer* - event index |
| // |
| // Related Types: |
| // <COAP_Blockwise_Transfer> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_BlockwiseTransfer_lifetime(in EPTF_ScheduledAction pl_action, in integer pl_eventIndex) |
| runs on EPTF_COAP_LGen_CT |
| return boolean |
| { |
| var integer vl_btIdx := pl_action.actionId[0]; |
| |
| if (vl_btIdx < 0 or vl_btIdx >= sizeof(v_COAP_blockwiseDB.data)) { return false } |
| |
| v_COAP_blockwiseDB.data[vl_btIdx].lifetimeTimer := -1; |
| |
| // Dispatch event: blockwise transfer fail finish |
| //if (f_EPTF_COAP_isCoapReportEnabledForEntity(v_COAP_blockwiseDB.data[vl_btIdx].eIdx) ) { |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_BLOCK1_atomic_fail, v_COAP_blockwiseDB.data[vl_btIdx].eIdx, -1, {}); |
| //} |
| |
| v_COAP_stats.block1.noAtomicTimeouts := v_COAP_stats.block1.noAtomicTimeouts + 1; |
| |
| // Remove the blockwise transfer FSM |
| f_EPTF_COAP_blockwiseDB_remove(vl_btIdx); |
| |
| return true; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_BlockwiseTransfer_startT_lifetime |
| // |
| // Purpose: |
| // This function starts the *T_lifetime* timer of a particular <COAP_Blockwise_Transfer> instance. |
| // The timer value is set to <tsp_EPTF_COAP_EXCHANGE_LIFETIME> |
| // |
| // Parameters: |
| // p_btIdx - *in* *integer* - index of the <COAP_Blockwise_Transfer> in the <COAP_Blockwise_DB> that will start the timer |
| // |
| // Related Types: |
| // <COAP_Blockwise_Transfer> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_BlockwiseTransfer_startT_lifetime(in integer pl_btIdx) |
| runs on EPTF_COAP_LGen_CT |
| return boolean |
| { |
| if (v_COAP_blockwiseDB.data[pl_btIdx].lifetimeTimer != -1) |
| { |
| f_EPTF_COAP_BlockwiseTransfer_cancelT_lifetime(pl_btIdx); |
| } |
| |
| var boolean retval; |
| var EPTF_ActionId vl_actionId; |
| |
| vl_actionId[0] := pl_btIdx; |
| |
| retval := f_EPTF_SchedulerComp_scheduleAction( |
| f_EPTF_SchedulerComp_snapshotTime() + tsp_EPTF_COAP_EXCHANGE_LIFETIME, |
| refers(f_EPTF_COAP_BlockwiseTransfer_lifetime), |
| vl_actionId, |
| v_COAP_blockwiseDB.data[pl_btIdx].lifetimeTimer |
| ); |
| |
| return retval; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_BlockwiseTransfer_cancelT_lifetime |
| // |
| // Purpose: |
| // This function cancels the *T_lifetime* timer of a particular <COAP_Blockwise_Transfer> instance |
| // |
| // Parameters: |
| // p_btIdx - *in* *integer* - index of the <COAP_Blockwise_Transfer> in the <COAP_Blockwise_DB> that will cancel the timer |
| // |
| // Related Types: |
| // <COAP_Blockwise_Transfer> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_BlockwiseTransfer_cancelT_lifetime(in integer pl_btIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (v_COAP_blockwiseDB.data[pl_btIdx].lifetimeTimer >= 0) |
| { |
| if(not f_EPTF_SchedulerComp_CancelEvent(v_COAP_blockwiseDB.data[pl_btIdx].lifetimeTimer)) |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId,": could not cancel timer")); |
| } |
| v_COAP_blockwiseDB.data[pl_btIdx].lifetimeTimer := -1; |
| } |
| } |
| |
| template EPTF_LGenBase_TestStepArgs t_EPTF_COAP_stepArgs(in integer p_eIdx, in integer p_fsmIdx) := |
| { |
| eIdx := p_eIdx, |
| refContext := |
| { |
| fCtxIdx := p_fsmIdx, |
| fRefArgs := {} |
| }, |
| stepArgs := {}, |
| reportedEvent := |
| { |
| event := { -1,-1,omit,omit }, |
| reportedArgs := {} |
| } |
| } |
| |
| template CoAP_ReqResp t_EPTF_COAP_BlockwiseResponse(in integer p_class, in integer p_detail) := |
| { |
| header := |
| { |
| version := 1, |
| msg_type := NON_CONFIRMABLE, |
| code := { class := p_class, detail := p_detail }, |
| message_id := 0 |
| }, |
| token := ''O, |
| options := {}, |
| payload := omit |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_Logging_VERBOSE |
| // |
| // Purpose: |
| // Logging functions for the VERBOSE log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Logging functions for the DEBUG log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Logging functions for the WARNING log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Logging functions for the ERROR log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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_EntityCtx_addObservation |
| // |
| // Purpose: |
| // Adds a new observation to the simulated device |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // p_msg - *in* <EPTF_COAP_PDU> - The incoming OBSERVE request |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_addObservation(in integer p_eCtxIdx, in EPTF_COAP_PDU p_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| // Fetch the URI path |
| var charstring v_uriPath := f_EPTF_COAP_uriPathToString(p_msg.pdu); |
| |
| f_EPTF_COAP_Logging_DEBUG(log2str("addObservation() for ", v_uriPath)); |
| |
| // Do we already have this resource under observation? |
| var integer v_observedResourceIdx := f_EPTF_COAP_observedResourceDB_lookUp( |
| p_msg.transportParams.localAddress.hostName, |
| p_msg.transportParams.localAddress.portNumber, |
| v_uriPath |
| ); |
| |
| // If we haven't found it, then we need to add this resource to the list of observed resources |
| if (v_observedResourceIdx < 0) |
| { |
| var COAP_ObservedResource v_observedResource := c_COAP_ObservedResource_init; |
| v_observedResource.localAddress := p_msg.transportParams.localAddress.hostName; |
| v_observedResource.localPort := p_msg.transportParams.localAddress.portNumber; |
| v_observedResource.resourceId := v_uriPath; |
| v_observedResource.uriPath := f_EPTF_COAP_fetchUriPath(p_msg.pdu); |
| v_observedResource.eCtxIdx := p_eCtxIdx; |
| |
| v_observedResourceIdx := f_EPTF_COAP_observedResourceDB_add(v_observedResource); |
| v_COAP_EntityCtxDB.data[p_eCtxIdx].observedResourceIndices[sizeof(v_COAP_EntityCtxDB.data[p_eCtxIdx].observedResourceIndices)] := v_observedResourceIdx; |
| } |
| |
| // Let's add the observer to the observed resource |
| f_EPTF_COAP_ObservedResource_addObserver(v_observedResourceIdx, p_msg, v_COAP_EntityCtxDB.data[p_eCtxIdx].confirmableNotification); |
| |
| v_COAP_stats.noObserves := v_COAP_stats.noObserves + 1; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_EntityCtx_removeObservation |
| // |
| // Purpose: |
| // Removes an existing observation from the simulated device |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // p_obsResIdx - *in* *integer* - The index of the <COAP_ObservedResource> instance in the <COAP_ObservedResource_DB> |
| // p_lastObserver - *in* *boolean* - True if this was the last observer for an observed resource (ie observed resource is not observed any more) |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_removeObservation(in integer pl_eCtxIdx, in integer p_obsResIdx, in boolean p_lastObserver) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId)); |
| |
| if (f_EPTF_COAP_isCoapReportEnabledForEntity(v_COAP_EntityCtxDB.data[pl_eCtxIdx].eIdx) ) { |
| f_EPTF_COAP_dispatchEvent( |
| c_COAP_eventIdx_observeCanceled, |
| v_COAP_EntityCtxDB.data[pl_eCtxIdx].eIdx, |
| -1, {} |
| ); |
| } |
| |
| var COAP_ObservedResourceIdx_List vl_newList := {}; |
| |
| if (p_lastObserver) |
| { |
| // Indicate event to the COAP user layer |
| if (vf_COAP_eventIndication != null) |
| { |
| vf_COAP_eventIndication.apply( |
| {resourceNotObserved := { v_COAP_EntityCtxDB.data[pl_eCtxIdx].eIdx, v_COAP_observedResourceDB.data[p_obsResIdx].uriPath } } |
| ); |
| } |
| |
| // Remove the p_obsResIdx from the stored indices |
| for (var integer i:=0; i<sizeof(v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices); i:=i+1) |
| { |
| if (v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices[i] != p_obsResIdx) { |
| vl_newList[sizeof(vl_newList)] := v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices[i]; |
| } |
| } |
| v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices := vl_newList; |
| |
| // Remove the observed resource from the DB |
| f_EPTF_COAP_observedResourceDB_remove(p_obsResIdx); |
| |
| if (f_EPTF_COAP_isCoapReportEnabledForEntity(v_COAP_EntityCtxDB.data[pl_eCtxIdx].eIdx) ) { |
| f_EPTF_COAP_dispatchEvent( |
| c_COAP_eventIdx_resourceNotObservedIndication, |
| v_COAP_EntityCtxDB.data[pl_eCtxIdx].eIdx, |
| -1, {} |
| ); |
| } |
| } |
| |
| v_COAP_stats.noObserves := v_COAP_stats.noObserves - 1; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_EntityCtx_removeObservedResource |
| // |
| // Purpose: |
| // Removes an observed resource entry from the simulated device |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // p_obsResIdx - *in* *integer* - The index of the <COAP_ObservedResource> instance in the <COAP_ObservedResource_DB> |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_removeObservedResource(in integer pl_eCtxIdx, in integer p_obsResIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| var COAP_ObservedResourceIdx_List vl_newList := {}; |
| |
| // call clean up for the observed resource to remove the observations |
| f_EPTF_COAP_ObservedResource_cleanUp(p_obsResIdx); |
| |
| // Remove the p_obsResIdx from the stored indices |
| for (var integer i:=0; i<sizeof(v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices); i:=i+1) |
| { |
| if (v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices[i] != p_obsResIdx) { |
| vl_newList[sizeof(vl_newList)] := v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices[i]; |
| } |
| } |
| v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices := vl_newList; |
| |
| // Remove the observed resource from the DB |
| f_EPTF_COAP_observedResourceDB_remove(p_obsResIdx); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_EntityCtx_addBlockwiseTransfer |
| // |
| // Purpose: |
| // Adds a new blockwise transfer FSM to the simulated device |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // p_msg - *in* <EPTF_COAP_PDU> - The incoming blockwise (num=0) request (or response) |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_addBlockwiseTransfer( |
| in integer p_eIdx, |
| in integer p_fsmIdx, |
| in integer p_eCtxIdx, |
| in integer p_block1OptionIdx, |
| in EPTF_COAP_PDU p_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| // Fetch the URI path |
| var charstring v_uriPath := f_EPTF_COAP_uriPathToString(p_msg.pdu); |
| |
| f_EPTF_COAP_Logging_DEBUG(log2str("addBlockwiseTransfer() for ", v_uriPath)); |
| |
| // Do we already have this resource under observation? |
| var integer v_blockwiseIdx := f_EPTF_COAP_blockwiseDB_lookUp( |
| p_msg.transportParams.localAddress.hostName, |
| p_msg.transportParams.localAddress.portNumber, |
| v_uriPath |
| ); |
| |
| // If we haven't found it, then we need to add this FSM to the list of blockwise FSMs |
| if (v_blockwiseIdx < 0) |
| { |
| var COAP_Blockwise_Transfer v_blockwiseTransfer := c_COAP_Blockwise_Transfer_init; |
| v_blockwiseTransfer.localAddress := p_msg.transportParams.localAddress.hostName; |
| v_blockwiseTransfer.localPort := p_msg.transportParams.localAddress.portNumber; |
| v_blockwiseTransfer.remoteAddress := p_msg.transportParams.remoteAddress.hostName; |
| v_blockwiseTransfer.remotePort := p_msg.transportParams.remoteAddress.portNumber; |
| v_blockwiseTransfer.resourceId := v_uriPath; |
| v_blockwiseTransfer.uriPath := f_EPTF_COAP_fetchUriPath(p_msg.pdu); |
| v_blockwiseTransfer.eIdx := p_eIdx; |
| v_blockwiseTransfer.fsmIdx := p_fsmIdx; |
| v_blockwiseTransfer.lastBlock1Option := p_msg.pdu.options[p_block1OptionIdx].block1; |
| v_blockwiseTransfer.headerCode := p_msg.pdu.header.code; |
| v_blockwiseTransfer.contentFormat := f_EPTF_COAP_fetchContentFormat(p_msg.pdu); |
| if (ispresent(p_msg.pdu.payload) and v_COAP_blockwiseDB.collectContent) |
| { |
| v_blockwiseTransfer.content := p_msg.pdu.payload; |
| } |
| |
| // In case the simualted device has a preferred block size and it is smaller then the offered block1 szx |
| // -> we will have a block size change |
| if ( |
| ispresent(v_COAP_EntityCtxDB.data[p_eCtxIdx].preferredBlocksize) and |
| v_COAP_EntityCtxDB.data[p_eCtxIdx].preferredBlocksize < p_msg.pdu.options[p_block1OptionIdx].block1.szx |
| ) |
| { |
| v_blockwiseTransfer.ongoingBlocksizeChange := true; |
| } |
| |
| var integer v_blockwiseTransferIdx := f_EPTF_COAP_blockwiseDB_add(v_blockwiseTransfer); |
| v_COAP_EntityCtxDB.data[p_eCtxIdx].blockwiseIndices[sizeof(v_COAP_EntityCtxDB.data[p_eCtxIdx].blockwiseIndices)] := v_blockwiseTransferIdx; |
| |
| f_EPTF_COAP_BlockwiseTransfer_startT_lifetime(v_blockwiseTransferIdx); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_EntityCtx_removeBlockwiseTransfer |
| // |
| // Purpose: |
| // Removes an existing blockwise transfer from the simulated device |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // p_BlockwiseTransferIdx - *in* *integer* - The index of the <COAP_Blockwise_Transfer> instance in the <COAP_Blockwise_DB> |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_removeBlockwiseTransfer(in integer pl_eCtxIdx, in integer p_BlockwiseTransferIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| var COAP_ObservedResourceIdx_List vl_newList := {}; |
| |
| // Remove the p_BlockwiseTransferIdx from the stored indices |
| for (var integer i:=0; i<sizeof(v_COAP_EntityCtxDB.data[pl_eCtxIdx].observedResourceIndices); i:=i+1) |
| { |
| if (v_COAP_EntityCtxDB.data[pl_eCtxIdx].blockwiseIndices[i] != p_BlockwiseTransferIdx) { |
| vl_newList[sizeof(vl_newList)] := v_COAP_EntityCtxDB.data[pl_eCtxIdx].blockwiseIndices[i]; |
| } |
| } |
| v_COAP_EntityCtxDB.data[pl_eCtxIdx].blockwiseIndices := vl_newList; |
| |
| // Remove the blockwise transfer from the DB |
| f_EPTF_COAP_blockwiseDB_remove(p_BlockwiseTransferIdx); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_EntityCtx_addOutgoingNiddMessage |
| // |
| // Purpose: |
| // Stores a new outgoing encoded NIDD message to the entity context |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // p_msg - *in octetstring* - The encoded outgoing NIDD message |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_addOutgoingNiddMessage(in integer p_eCtxIdx, in octetstring p_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str("addOutgoingNiddMessage() for eCtxIdx: ", p_eCtxIdx)); |
| |
| // If we haven't reached the buffer limit |
| if (sizeof(v_COAP_EntityCtxDB.data[p_eCtxIdx].niddOutgoingMessages) <= tsp_EPTF_COAP_maxNiddBufferSize) |
| { |
| var integer v_msgIdx := f_EPTF_COAP_niddDB_add(p_msg); |
| v_COAP_EntityCtxDB.data[p_eCtxIdx].niddOutgoingMessages[sizeof(v_COAP_EntityCtxDB.data[p_eCtxIdx].niddOutgoingMessages)] := v_msgIdx; |
| } |
| else |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str("addOutgoingNiddMessage() reached buffering limit, ignoring message! eCtxIdx: ", p_eCtxIdx)); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_EntityCtx_clearOutgoingNiddMessages |
| // |
| // Purpose: |
| // Removes all buffered NIDD messages belonging to the entity |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_clearOutgoingNiddMessages(in integer p_eCtxIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str("clearOutgoingNiddMessages() for eCtxIdx: ", p_eCtxIdx)); |
| |
| for (var integer i:=0; i<sizeof(v_COAP_EntityCtxDB.data[p_eCtxIdx].niddOutgoingMessages); i:=i+1) |
| { |
| f_EPTF_COAP_niddDB_remove(v_COAP_EntityCtxDB.data[p_eCtxIdx].niddOutgoingMessages[i]); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_EntityCtx_cleanUp |
| // |
| // Purpose: |
| // Cleans up the <COAP_EntityCtx> instance of a simulated device by deleting related instances |
| // |
| // Parameters: |
| // p_eCtxIdx - *in* *integer* - index of the <COAP_EntityCtx> instance in <COAP_EntityCtx_DB> |
| // p_obsResIdx - *in* *integer* - The index of the <COAP_ObservedResource> instance in the <COAP_ObservedResource_DB> |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_EntityCtx_cleanUp(in integer p_eCtxIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| var integer vl_obsResIdx; |
| for (var integer i:=0; i<sizeof(v_COAP_EntityCtxDB.data[p_eCtxIdx].observedResourceIndices); i:=i+1) |
| { |
| vl_obsResIdx := v_COAP_EntityCtxDB.data[p_eCtxIdx].observedResourceIndices[i]; |
| f_EPTF_COAP_ObservedResource_cleanUp(vl_obsResIdx); |
| f_EPTF_COAP_observedResourceDB_remove(vl_obsResIdx); |
| } |
| f_EPTF_COAP_EntityCtx_clearOutgoingNiddMessages(p_eCtxIdx); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_ObservedResource_addObserver |
| // |
| // Purpose: |
| // Adds an <COAP_Observation_Server> instance to the <COAP_ObservedResource> instance based on the OBSERVE message |
| // |
| // Parameters: |
| // p_obsResIdx - *in* *integer* - The index of the <COAP_ObservedResource> instance in the <COAP_ObservedResource_DB> |
| // p_msg - *in* <EPTF_COAP_PDU> - The OBSERVE message that the observer sent to observe a resource |
| // p_confirmable - *in* *boolean* - when true CON transaction is used else NON is used for notifications |
| // |
| // Related Types: |
| // <COAP_ObservedResource> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_ObservedResource_addObserver(in integer p_obsResIdx, in EPTF_COAP_PDU p_msg, in boolean p_confirmable) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_obsResIdx < 0 or p_obsResIdx >= sizeof(v_COAP_observedResourceDB.data)) { return } |
| |
| // Do we already have this observer? |
| var integer v_observationIdx := f_EPTF_COAP_observationDB_lookUp( |
| p_msg.transportParams.remoteAddress.hostName, |
| p_msg.transportParams.remoteAddress.portNumber, |
| v_COAP_observedResourceDB.data[p_obsResIdx].resourceId, |
| p_obsResIdx |
| ); |
| |
| // If we haven't found it, then we need to add this observation |
| if (v_observationIdx < 0) |
| { |
| var COAP_Observation_Server v_observationServer := c_COAP_Observation_Server_init; |
| v_observationServer.remoteAddress := p_msg.transportParams.remoteAddress.hostName; |
| v_observationServer.remotePort := p_msg.transportParams.remoteAddress.portNumber; |
| v_observationServer.protocol := p_msg.transportParams.transport; |
| v_observationServer.resourceId := v_COAP_observedResourceDB.data[p_obsResIdx].resourceId; |
| v_observationServer.token := p_msg.pdu.token; |
| v_observationServer.confirmable := p_confirmable; |
| v_observationServer.observedResourceIdx := p_obsResIdx; |
| v_observationServer.trIdx := -1; |
| |
| v_observationIdx := f_EPTF_COAP_observationDB_add(v_observationServer); |
| |
| v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices[sizeof(v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices)] := |
| v_observationIdx; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_ObservedResource_removeObserver |
| // |
| // Purpose: |
| // Removes an <COAP_Observation_Server> instance from the <COAP_ObservedResource> instance that canceled its observation |
| // |
| // Parameters: |
| // p_obsResIdx - *in* *integer* - The index of the <COAP_ObservedResource> instance in the <COAP_ObservedResource_DB> |
| // p_obsIdx - *in* *integer* - The index of the <COAP_Observation_Server> instance in the <COAP_Observation_DB> |
| // |
| // Related Types: |
| // <COAP_ObservedResource> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_ObservedResource_removeObserver(in integer p_obsResIdx, in integer p_obsIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId)); |
| |
| if (p_obsResIdx < 0 or p_obsResIdx >= sizeof(v_COAP_observedResourceDB.data)) { return } |
| |
| var ObservationServerIdx_List vl_newList := {}; |
| |
| // Remove the p_obsIdx from the stored indices |
| for (var integer i:=0; i<sizeof(v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices); i:=i+1) |
| { |
| if (v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices[i] != p_obsIdx) { |
| vl_newList[sizeof(vl_newList)] := v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices[i]; |
| } |
| } |
| v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices := vl_newList; |
| |
| // Remove the observation from the DB |
| f_EPTF_COAP_observationDB_remove(p_obsIdx); |
| |
| // Was this the last observer? |
| var boolean vl_lastObserver := false; |
| if (sizeof(v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices)==0) { vl_lastObserver := true; } |
| |
| // Notify the entity |
| f_EPTF_COAP_EntityCtx_removeObservation(v_COAP_observedResourceDB.data[p_obsResIdx].eCtxIdx, p_obsResIdx, vl_lastObserver); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_ObservedResource_sendNotification |
| // |
| // Purpose: |
| // Sends notificiations to all observers, who are observing a particular resource <COAP_ObservedResource> |
| // |
| // Parameters: |
| // p_obsResIdx - *in* *integer* - The index of the <COAP_ObservedResource> instance in the <COAP_ObservedResource_DB> |
| // p_msg - *inout* <EPTF_COAP_PDU> - The NOTIFICATION message that will be sent to the observers |
| // |
| // Related Types: |
| // <COAP_ObservedResource> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_ObservedResource_sendNotification(in integer p_obsResIdx, inout EPTF_COAP_PDU p_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId)); |
| |
| if (p_obsResIdx < 0 or p_obsResIdx >= sizeof(v_COAP_observedResourceDB.data)) |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, "Invalid p_obsResIdx: ",p_obsResIdx)); |
| return |
| } |
| |
| for (var integer i:=0; i<sizeof(v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices); i:=i+1) |
| { |
| var integer v_obServerIdx := v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices[i]; |
| f_EPTF_COAP_ObservationServer_sendNotification(v_obServerIdx, p_msg); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_ObservedResource_cleanUp |
| // |
| // Purpose: |
| // Cleans up the <COAP_ObservedResource> instance |
| // |
| // Parameters: |
| // p_obsResIdx - *in* *integer* - The index of the <COAP_ObservedResource> instance in the <COAP_ObservedResource_DB> |
| // |
| // Related Types: |
| // <COAP_ObservedResource> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_ObservedResource_cleanUp(in integer p_obsResIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (p_obsResIdx < 0 or p_obsResIdx >= sizeof(v_COAP_observedResourceDB.data)) { return } |
| |
| var integer vl_obsIdx; |
| for (var integer i:=0; i<sizeof(v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices); i:=i+1) |
| { |
| vl_obsIdx := v_COAP_observedResourceDB.data[p_obsResIdx].observationServersIndices[i]; |
| f_EPTF_COAP_observationDB_remove(vl_obsIdx); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_ObservationServer_sendNotification |
| // |
| // Purpose: |
| // Sends a notification for a particular observer of an observation relationship |
| // |
| // Parameters: |
| // p_obsIdx - *in* *integer* - The index of the <COAP_Observation_Server> instance in the <COAP_Observation_DB> |
| // p_msg - *inout* <EPTF_COAP_PDU> - The NOTIFICATION message that will be sent to the observer |
| // |
| // Related Types: |
| // <COAP_Observation_Server> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_ObservationServer_sendNotification(in integer p_obsIdx, inout EPTF_COAP_PDU p_msg) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId)); |
| |
| if (p_obsIdx < 0 or p_obsIdx >= sizeof(v_COAP_observationDB.data)) |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, "Invalid p_obsIdx: ",p_obsIdx)); |
| return |
| } |
| |
| // We assume: |
| // 1. That the template to be sent is already loaded into p_msg! |
| // 2. That the v_COAP_ctx is set from the f_EPTF_COAP_sendNotification! |
| if (f_EPTF_COAP_isResponse(v_COAP_msgToSend.pdu)) |
| { |
| // Setting the msg type |
| if (v_COAP_observationDB.data[p_obsIdx].confirmable) { p_msg.pdu.header.msg_type := CONFIRMABLE; } |
| else { p_msg.pdu.header.msg_type := NON_CONFIRMABLE; } |
| |
| // Setting the observe option |
| v_COAP_observationDB.data[p_obsIdx].seqNum := v_COAP_observationDB.data[p_obsIdx].seqNum + 1; |
| var integer vl_obsOptionIdx := f_EPTF_COAP_hasObserve(p_msg.pdu); |
| if (vl_obsOptionIdx < 0) { vl_obsOptionIdx := sizeof(p_msg.pdu.options); } |
| p_msg.pdu.options[vl_obsOptionIdx] := { observe := v_COAP_observationDB.data[p_obsIdx].seqNum }; |
| |
| // Set local address |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| p_msg.transportParams.localAddress := v_COAP_transportEndpoint.socket; |
| p_msg.transportParams.transport := v_COAP_transportEndpoint.proto; |
| p_msg.eIdx := v_COAP_ctx.eIdx; |
| |
| // Set remote address |
| p_msg.transportParams.remoteAddress.hostName := v_COAP_observationDB.data[p_obsIdx].remoteAddress; |
| p_msg.transportParams.remoteAddress.portNumber := v_COAP_observationDB.data[p_obsIdx].remotePort; |
| |
| // Set the protocol |
| p_msg.transportParams.transport := v_COAP_observationDB.data[p_obsIdx].protocol; |
| |
| // Set the token |
| p_msg.pdu.token := v_COAP_observationDB.data[p_obsIdx].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.obsIdx := p_obsIdx; |
| vl_tr.rrIdx := -1; |
| vl_tr.addrIdx := v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx; |
| vl_tr.state := CLOSED; |
| vl_tr.direction := OUTGOING; |
| vl_tr.retransmitTimerValue := tsp_EPTF_COAP_LGen_retransmitTimerInitialValue; |
| |
| 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); |
| |
| // Set pointer to tr |
| v_COAP_observationDB.data[p_obsIdx].trIdx := vl_trIdx; |
| |
| // trOut.send |
| f_EPTF_COAP_tr_fromRR(p_msg, vl_trIdx); |
| |
| v_COAP_stats.outgoing.noNotifications := v_COAP_stats.outgoing.noNotifications + 1; |
| } |
| else { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " the message is not a notification therefore it cannot be sent using sendNotification!")); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_ObservationServer_cancelReceivedFromEnv |
| // |
| // Purpose: |
| // When an observation is canceled this can be called function to remove the corresponding <COAP_Observation_Server> instance |
| // |
| // Parameters: |
| // p_obsIdx - *in* *integer* - The index of the <COAP_Observation_Server> instance in the <COAP_Observation_DB> |
| // |
| // Related Types: |
| // <COAP_Observation_Server> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_ObservationServer_cancelReceivedFromEnv(in integer p_obsIdx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId)); |
| |
| if (p_obsIdx < 0 or p_obsIdx >= sizeof(v_COAP_observationDB.data)) { return } |
| |
| if (v_COAP_observationDB.data[p_obsIdx].observedResourceIdx != -1) { |
| f_EPTF_COAP_ObservedResource_removeObserver(v_COAP_observationDB.data[p_obsIdx].observedResourceIdx, p_obsIdx); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_declareEvents |
| // |
| // Purpose: |
| // Declares the FSM events to the CLL framework implemented by <EPTF_COAP_LGen_CT> |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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) or |
| c_COAP_eventIdx_OBSERVE != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_OBSERVE) |
| ){ |
| f_EPTF_LGenBase_log(); |
| log("f_EPTF_COAP_declareEvents() error at requests"); mtc.stop |
| } |
| |
| for (var integer i:=6; 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) or |
| c_COAP_eventIdx_observeCanceled != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_observeCanceled) or |
| c_COAP_eventIdx_resourceNotObservedIndication != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_resourceNotObservedIndication) or |
| c_COAP_eventIdx_dtlsConnectionClosed != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_dtlsConnectionClosed) or |
| c_COAP_eventIdx_BLOCK1_init != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_BLOCK1_init) or |
| c_COAP_eventIdx_BLOCK1_block != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_BLOCK1_block) or |
| c_COAP_eventIdx_BLOCK1_last != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_BLOCK1_last) or |
| c_COAP_eventIdx_BLOCK1_atomic_succ != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_BLOCK1_atomic_succ) or |
| c_COAP_eventIdx_BLOCK1_atomic_fail != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_BLOCK1_atomic_fail) or |
| c_COAP_eventIdx_niddMessageBuffered != f_EPTF_LGenBase_declareFsmEvent(c_COAP_behaviorType, c_COAP_eventName_niddMessageBuffered) |
| ){ |
| f_EPTF_LGenBase_log(); |
| log("f_EPTF_COAP_declareEvents() error at responses"); mtc.stop |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_declareSteps |
| // |
| // Purpose: |
| // Declares the FSM steps to the CLL framework implemented by <EPTF_COAP_LGen_CT> |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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)}) or |
| c_COAP_stepIdx_sendNotification_byIntIdx != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_sendNotification_byIntIdx, refers(f_COAP_step_sendNotification_byIntIdx)}) or |
| c_COAP_stepIdx_sendNotification_byStringId != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_sendNotification_byStringId, refers(f_COAP_step_sendNotification_byStringId)}) or |
| c_COAP_stepIdx_removeResourceObservations_byIntIdx != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_removeResourceObservations_byIntIdx, refers(f_COAP_step_removeResourceObservations_byIntIdx)}) or |
| c_COAP_stepIdx_removeResourceObservations_byStringId != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_removeResourceObservations_byStringId, refers(f_COAP_step_removeResourceObservations_byStringId)}) or |
| c_COAP_stepIdx_startDTLS != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_startDTLS, refers(f_COAP_step_startDTLS)}) or |
| c_COAP_stepIdx_startDTLS_byVarIds != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_startDTLS_byVarIds, refers(f_COAP_step_startDTLS_byVarIds)}) or |
| c_COAP_stepIdx_startDTLS_byIntIdx != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_startDTLS_byIntIdx, refers(f_COAP_step_startDTLS_byIntIdx)}) or |
| c_COAP_stepIdx_confirmableNotificationForEntity != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_confirmableNotificationForEntity, refers(f_COAP_step_confirmableNotificationForEntity)}) or |
| c_COAP_stepIdx_setPreferredBlocksize != f_EPTF_LGenBase_declareStep(c_COAP_behaviorType,{c_COAP_stepName_setPreferredBlocksize, refers(f_COAP_step_setPreferredBlocksize)}) |
| ) |
| { |
| f_EPTF_LGenBase_log(); |
| log("f_EPTF_COAP_declareSteps() error"); mtc.stop |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_init |
| // |
| // Purpose: |
| // Test Step to dynamically allocate and initialize the COAP FSM context for the caller FSM. Prerequisite to call any other COAP test step. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_init> |
| // - <c_COAP_stepName_init> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Test Step to free up the COAP FSM context for the caller FSM. Frees up all allocated instances that were used by this FSM instance. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_cleanUp> |
| // - <c_COAP_stepName_cleanUp> |
| /////////////////////////////////////////////////////////// |
| 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_eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(vl_eIdx, v_COAP_bIdx, 0); |
| var integer vl_fsmIdx := pl_ptr.refContext.fCtxIdx; |
| var integer vl_fsmCtxIdx := -1; |
| |
| f_EPTF_COAP_EntityCtx_cleanUp(vl_eCtxIdx); |
| |
| if (not f_EPTF_COAP_isFsmInitialized(vl_eIdx, vl_fsmIdx, vl_fsmCtxIdx)) |
| { |
| f_EPTF_COAP_Logging_DEBUG(%definitionId&": FSM has not been initialized"); |
| return; |
| } |
| |
| 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 |
| // |
| // Purpose: |
| // Test step to set the local address in the entity context. Integer parameter required. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - *integer* - Index of the endpoint to use as local address |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_setLocalAddress> |
| // - <c_COAP_stepName_setLocalAddress> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Test step to set the remote address in the FSM context <COAP_FsmCtx>. Integer parameter required. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - *integer* - Index of the endpoint to use as remote address |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_setRemoteAddress_byIntIdx> |
| // - <c_COAP_stepName_setRemoteAddress_byIntIdx> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Test step to load a <CoAP_Template> from <tsp_EPTF_COAP_LGen_templates> into *v_COAP_msgToSend* |
| // (which can be sent using the send test step). Integer parameter required. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - *integer* - Index of the template to load into *v_COAP_msgToSend* |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_loadTemplate_byIntIdx> |
| // - <c_COAP_stepName_loadTemplate_byIntIdx> |
| // |
| // Related Steps: |
| // <f_COAP_step_send> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Test step to load a <CoAP_Template> from <tsp_EPTF_COAP_LGen_templates> into *v_COAP_msgToSend* |
| // (which can be sent using the send test step). String parameter required. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // contextArgs.charstringVal - *charstring* - ID the template to load into *v_COAP_msgToSend* |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_loadTemplate_byStringId> |
| // - <c_COAP_stepName_loadTemplate_byStringId> |
| // |
| // Related Steps: |
| // <f_COAP_step_send> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Test step to send out a COAP message from *v_COAP_msgToSend*. |
| // The message will be processed by the Applib's COAP stack |
| // The step expects the localAddress and the remoteAddress to be configured |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_send> |
| // - <c_COAP_stepName_send> |
| // |
| // Related Steps: |
| // - <f_COAP_step_loadTemplate_byIntIdx> |
| // - <f_COAP_step_loadTemplate_byStringId> |
| // |
| // Related functions: |
| // <f_EPTF_COAP_stack_fromApp> |
| /////////////////////////////////////////////////////////// |
| 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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| v_COAP_msgToSend.transportParams.localAddress := v_COAP_transportEndpoint.socket; |
| 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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].remoteAddressIdx); |
| v_COAP_msgToSend.transportParams.remoteAddress := v_COAP_transportEndpoint.socket; |
| } |
| v_COAP_msgToSend.transportParams.transport := v_COAP_transportEndpoint.proto; |
| v_COAP_msgToSend.eIdx := v_COAP_ctx.eIdx; |
| v_COAP_msgToSend.fsmIdx := v_COAP_ctx.fsmIdx; |
| |
| 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 |
| // |
| // Purpose: |
| // The test step can be called from an FSM to handle a reported COAP request. |
| // The test step will bind the current request to the caller FSM. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_handleRequest> |
| // - <c_COAP_stepName_handleRequest> |
| /////////////////////////////////////////////////////////// |
| 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); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_sendResponse |
| // |
| // Purpose: |
| // The test step expects an ongoing request bound to the FSM by <f_COAP_step_handleRequest> |
| // and a response message loaded into *v_COAP_msgToSend* by <f_COAP_step_loadTemplate_byIntIdx> |
| // The test step will take the template and process it in the applib's stack that will fill in |
| // the necessary id (e.g. mid, token) and will match the message type to the request the following way: |
| // - req.NON -> rsp.NON |
| // - req.CON && state.SERVING -> rsp.ACK |
| // - req.CON && state.SEPARATE -> rsp.CON |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_sendResponse> |
| // - <c_COAP_stepName_sendResponse> |
| // |
| // Related Steps: |
| // - <f_COAP_step_handleRequest> |
| // - <f_COAP_step_loadTemplate_byIntIdx> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_sendResponse(in EPTF_LGenBase_TestStepArgs pl_ptr) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId)); |
| |
| // 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 |
| |
| 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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| v_COAP_msgToSend.transportParams.localAddress := v_COAP_transportEndpoint.socket; |
| v_COAP_msgToSend.transportParams.transport := v_COAP_transportEndpoint.proto; |
| v_COAP_msgToSend.eIdx := v_COAP_ctx.eIdx; |
| v_COAP_msgToSend.fsmIdx := v_COAP_ctx.fsmIdx; |
| |
| 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 |
| // |
| // Purpose: |
| // The test step expects an ongoing request bound to the FSM by <f_COAP_step_handleRequest> |
| // The test step will send an accept (eg. ACK to a CON) without the body thus indicating to |
| // the client, that the request is accepted, but time is needed to produce the content. This |
| // accept will make the client cease its request retranmissions |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_sendAccept> |
| // - <c_COAP_stepName_sendAccept> |
| // |
| // Related Steps: |
| // - <f_COAP_step_handleRequest> |
| /////////////////////////////////////////////////////////// |
| 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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| v_COAP_msgToSend.transportParams.localAddress := v_COAP_transportEndpoint.socket; |
| v_COAP_msgToSend.transportParams.transport := v_COAP_transportEndpoint.proto; |
| v_COAP_msgToSend.eIdx := v_COAP_ctx.eIdx; |
| v_COAP_msgToSend.fsmIdx := v_COAP_ctx.fsmIdx; |
| |
| 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 |
| // |
| // Purpose: |
| // The test step expects that a transport endpoint is set in the entity context: <COAP_EntityCtx> as a local address |
| // The step will initiate allocating the local address using the transport layer and eventually |
| // it will report back if it was successful or it failed |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_startListening> |
| // - <c_COAP_stepName_startListening> |
| // |
| // Related Events: |
| // - <c_COAP_eventIdx_transportSucc> |
| // - <c_COAP_eventIdx_transportFail> |
| // |
| // Related Steps: |
| // - <f_COAP_step_setLocalAddress> |
| /////////////////////////////////////////////////////////// |
| 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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| |
| if (ischosen(v_COAP_transportEndpoint.proto.ip)) |
| { |
| vl_req.params.startListening.localAddress := v_COAP_transportEndpoint.socket; |
| vl_req.params.startListening.protocol := v_COAP_transportEndpoint.proto.ip; |
| |
| vf_EPTF_COAP_Transport_apiRequest.apply(vl_req); |
| } |
| else |
| { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " listening is only for IP transport!")); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_startDTLS |
| // |
| // Purpose: |
| // The test step expects that a transport endpoint is set in the entity context as a local address |
| // and a remote address is set in the FSM context. |
| // The step will use PSK for authentication in case the PSK identity and key is set in the FSM context: <COAP_FsmCtx> |
| // The step will initiate creating a DTLS connection and |
| // it will report back if it was successful or it failed |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_startDTLS> |
| // - <c_COAP_stepName_startDTLS> |
| // |
| // Related Events: |
| // - <c_COAP_eventIdx_transportSucc> |
| // - <c_COAP_eventName_transportSucc> |
| // - <c_COAP_eventIdx_transportFail> |
| // - <c_COAP_eventName_transportFail> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_startDTLS(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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| vl_req.params.startDTLS.localAddress := v_COAP_transportEndpoint.socket; |
| |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].remoteAddressIdx); |
| vl_req.params.startDTLS.remoteAddress := v_COAP_transportEndpoint.socket; |
| |
| vl_req.params.startDTLS.pskIdentity := omit; |
| vl_req.params.startDTLS.pskKey := omit; |
| |
| if (ispresent(v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].psk)) |
| { |
| vl_req.params.startDTLS.pskIdentity := v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].psk.identity; |
| vl_req.params.startDTLS.pskKey := v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].psk.key; |
| } |
| |
| vf_EPTF_COAP_Transport_apiRequest.apply(vl_req); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_startDTLS_byVarIds |
| // |
| // Purpose: |
| // The test step expects that a transport endpoint is set in the entity context as a local address |
| // and a remote address is set in the FSM context. |
| // The step will use PSK for authentication. The PSK identity and key will be taken from the steps parameters |
| // and loaded into the FSM context: <COAP_FsmCtx> |
| // The step will initiate creating a DTLS connection and |
| // it will report back if it was successful or it failed |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // contextArgs.varNames[0] - *charstring variable* - PSK identity |
| // contextArgs.varNames[1] - *charstring variable* - PSK key |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_startDTLS_byVarIds> |
| // - <c_COAP_stepName_startDTLS_byVarIds> |
| // |
| // Related Events: |
| // - <c_COAP_eventIdx_transportSucc> |
| // - <c_COAP_eventName_transportSucc> |
| // - <c_COAP_eventIdx_transportFail> |
| // - <c_COAP_eventName_transportFail> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_startDTLS_byVarIds(in EPTF_LGenBase_TestStepArgs pl_ptr) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; } |
| |
| // 1st param: psk id: charstring |
| // 2nd param: psk key: charstring |
| |
| var EPTF_IntegerList vl_varIds := {}; |
| f_EPTF_LGenBase_fsmVarIdListFromStep(pl_ptr, vl_varIds); |
| |
| 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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| vl_req.params.startDTLS.localAddress := v_COAP_transportEndpoint.socket; |
| |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].remoteAddressIdx); |
| vl_req.params.startDTLS.remoteAddress := v_COAP_transportEndpoint.socket; |
| |
| vl_req.params.startDTLS.pskIdentity := omit; |
| vl_req.params.startDTLS.pskKey := omit; |
| |
| if (sizeof(vl_varIds)==2) |
| { |
| var EPTF_Var_DirectContent vl_id, vl_key; |
| f_EPTF_Var_getContent(vl_varIds[0], vl_id); |
| f_EPTF_Var_getContent(vl_varIds[1], vl_key); |
| |
| if (not ischosen(vl_id.charstringVal)) { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " first param is not charstring variable!")); |
| return; |
| } |
| if (not ischosen(vl_key.charstringVal)) { |
| f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " second param is not charstring variable!")); |
| return; |
| } |
| |
| vl_req.params.startDTLS.pskIdentity := vl_id.charstringVal; |
| vl_req.params.startDTLS.pskKey := vl_key.charstringVal; |
| } |
| else if (ispresent(v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].psk)) |
| { |
| vl_req.params.startDTLS.pskIdentity := v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].psk.identity; |
| vl_req.params.startDTLS.pskKey := v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].psk.key; |
| } |
| |
| vf_EPTF_COAP_Transport_apiRequest.apply(vl_req); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_startDTLS_byIntIdx |
| // |
| // Purpose: |
| // The test step expects that a transport endpoint is set in the entity context as a local address |
| // and a remote address is set in the FSM context. |
| // The step will use PSK for authentication. The PSK identity and key will be taken from the step's parameters |
| // and loaded into the FSM context: <COAP_FsmCtx> |
| // The step will initiate creating a DTLS connection and |
| // it will report back if it was successful or it failed |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - *charstring variable* - integer idx of the PSK parameters in <tsp_EPTF_COAP_LGen_psks> |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_startDTLS_byIntIdx> |
| // - <c_COAP_stepName_startDTLS_byIntIdx> |
| // |
| // Related Events: |
| // - <c_COAP_eventIdx_transportSucc> |
| // - <c_COAP_eventName_transportSucc> |
| // - <c_COAP_eventIdx_transportFail> |
| // - <c_COAP_eventName_transportFail> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_startDTLS_byIntIdx(in EPTF_LGenBase_TestStepArgs pl_ptr) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; } |
| |
| // idx param: psk idx in tsp_EPTF_COAP_LGen_psks |
| |
| var integer vl_pskIdx; |
| if (f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_pskIdx)) |
| { |
| if (sizeof(tsp_EPTF_COAP_LGen_psks)>0 and vl_pskIdx < sizeof(tsp_EPTF_COAP_LGen_psks)) |
| { |
| 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_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| vl_req.params.startDTLS.localAddress := v_COAP_transportEndpoint.socket; |
| |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].remoteAddressIdx); |
| vl_req.params.startDTLS.remoteAddress := v_COAP_transportEndpoint.socket; |
| |
| v_COAP_FsmCtxDB.data[v_COAP_ctx.fsmCtxIdx].psk := tsp_EPTF_COAP_LGen_psks[vl_pskIdx]; |
| |
| vl_req.params.startDTLS.pskIdentity := tsp_EPTF_COAP_LGen_psks[vl_pskIdx].identity; |
| vl_req.params.startDTLS.pskKey := tsp_EPTF_COAP_LGen_psks[vl_pskIdx].key; |
| |
| vf_EPTF_COAP_Transport_apiRequest.apply(vl_req); |
| } |
| else {f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " element idx",vl_pskIdx ,"is invalid in tsp_EPTF_COAP_LGen_psks modulepar!")); } |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " an integer is needed as param!")); } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_setRemoteAddress_byVars |
| // |
| // Purpose: |
| // Test step to set the remote address by variable parameters in the FSM context <COAP_FsmCtx>. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // contextArgs.varNames[0] - *charstring variable* - remoteHost |
| // contextArgs.varNames[1] - *integer variable* - remotePort |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_setRemoteAddress_byVars> |
| // - <c_COAP_stepName_setRemoteAddress_byVars> |
| /////////////////////////////////////////////////////////// |
| 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; } |
| |
| // 1st param: remoteHost: charstring |
| // 2nd param: remotePort: integer |
| |
| 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; |
| } |
| |
| v_COAP_transportEndpoint := c_COAP_TransportEndpoint_empty; |
| v_COAP_transportEndpoint.socket.hostName := vl_host.charstringVal; |
| v_COAP_transportEndpoint.socket.portNumber := vl_port.intVal; |
| |
| f_EPTF_COAP_transportEndpointDB_add( |
| v_COAP_transportEndpoint, |
| 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 |
| // |
| // Purpose: |
| // The test step will turn on/off the COAP event reporting for the entity in the entity context <COAP_EntityCtx> |
| // It is recommended to turn the reporting off, when the COAP applib is used as a transport for the LWM2M applib |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - 0: false, 1: true |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_reportCoapEventForEntity> |
| // - <c_COAP_stepName_reportCoapEventForEntity> |
| /////////////////////////////////////////////////////////// |
| 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; |
| if (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_COAP_step_confirmableNotificationForEntity |
| // |
| // Purpose: |
| // The test step will turn on/off the COAP CON notifications for the entity in the entity context <COAP_EntityCtx> |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - 0: NON notifications, 1: CON notifications |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_confirmableNotificationForEntity> |
| // - <c_COAP_stepName_confirmableNotificationForEntity> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_confirmableNotificationForEntity(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; |
| if (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].confirmableNotification := true; |
| } |
| else { |
| v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].confirmableNotification := false; |
| } |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_sendNotification_byIntIdx |
| // |
| // Purpose: |
| // The test step send notifications to the observers of the observed resource pointed by the idx parameter |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - *integer* - observed resource idx in the entity context <COAP_EntityCtx> |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_sendNotification_byIntIdx> |
| // - <c_COAP_stepName_sendNotification_byIntIdx> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_sendNotification_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; } |
| |
| // 1st param: integer, the index of the resource of the given entity |
| |
| var integer vl_observedResourceIdx_Idx := -1; |
| if (f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_observedResourceIdx_Idx)) |
| { |
| var integer vl_observedResourceIdx := -1; |
| if (f_EPTF_COAP_getIntValue(v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].observedResourceIndices, vl_observedResourceIdx_Idx, vl_observedResourceIdx)) |
| { |
| f_EPTF_COAP_ObservedResource_sendNotification(vl_observedResourceIdx, v_COAP_msgToSend); |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " it was not possible to fetch the referred observedResourceIdx")); } |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " an integer is needed as param!")); } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_sendNotification_byStringId |
| // |
| // Purpose: |
| // The test step send notifications to the observers of the observed resource identified by the string uri given as parameter |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // contextArgs.charstringValue - *charstring* - observed resource uri |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_sendNotification_byStringId> |
| // - <c_COAP_stepName_sendNotification_byStringId> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_sendNotification_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; } |
| |
| // 1st param: charstring, the URI of the observed resource |
| |
| var charstring vl_observedResourceId := f_EPTF_LGenBase_charstringValOfStep(pl_ptr); |
| |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| |
| var integer vl_observedResourceIdx := f_EPTF_COAP_observedResourceDB_lookUp( |
| v_COAP_transportEndpoint.socket.hostName, |
| v_COAP_transportEndpoint.socket.portNumber, |
| vl_observedResourceId |
| ); |
| |
| if (vl_observedResourceIdx != -1) |
| { |
| f_EPTF_COAP_ObservedResource_sendNotification(vl_observedResourceIdx, v_COAP_msgToSend); |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " it was not possible to fetch the referred observedResourceIdx")); } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_sendNotification_internal |
| // |
| // Purpose: |
| // This function sends notifications to the observers of the observed resource identified by the string uri given as parameter |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // contextArgs.charstringValue - *charstring* - observed resource uri |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_sendNotification_internal(in EPTF_LGenBase_TestStepArgs pl_ptr, in charstring p_observedResourceId) |
| runs on EPTF_COAP_LGen_CT |
| { |
| f_EPTF_COAP_Logging_DEBUG(log2str(%definitionId,":",p_observedResourceId)); |
| |
| if (not f_EPTF_COAP_setStepCtx(pl_ptr, v_COAP_ctx)) { return; } |
| |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| |
| var integer vl_observedResourceIdx := f_EPTF_COAP_observedResourceDB_lookUp( |
| v_COAP_transportEndpoint.socket.hostName, |
| v_COAP_transportEndpoint.socket.portNumber, |
| p_observedResourceId |
| ); |
| |
| if (vl_observedResourceIdx != -1) |
| { |
| f_EPTF_COAP_ObservedResource_sendNotification(vl_observedResourceIdx, v_COAP_msgToSend); |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " it was not possible to fetch the referred observedResourceIdx")); } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_removeResourceObservations_byIntIdx |
| // |
| // Purpose: |
| // The test step removes the observers of the observed resource pointed by the idx parameter |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - *integer* - observed resource idx in the entity context <COAP_EntityCtx> |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_removeResourceObservations_byIntIdx> |
| // - <c_COAP_stepName_removeResourceObservations_byIntIdx> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_removeResourceObservations_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; } |
| |
| // 1st param: integer, the index of the resource of the given entity |
| |
| var integer vl_observedResourceIdx_Idx := -1; |
| if (f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_observedResourceIdx_Idx)) |
| { |
| var integer vl_observedResourceIdx := -1; |
| if (f_EPTF_COAP_getIntValue(v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].observedResourceIndices, vl_observedResourceIdx_Idx, vl_observedResourceIdx)) |
| { |
| f_EPTF_COAP_EntityCtx_removeObservedResource(v_COAP_ctx.eCtxIdx, vl_observedResourceIdx); |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " it was not possible to fetch the referred observedResourceIdx")); } |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " an integer is needed as param!")); } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_removeResourceObservations_byStringId |
| // |
| // Purpose: |
| // The test step removes the observers of the observed resource identified by the string uri given as parameter |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // contextArgs.charstringValue - *charstring* - observed resource uri |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_removeResourceObservations_byStringId> |
| // - <c_COAP_stepName_removeResourceObservations_byStringId> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_removeResourceObservations_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; } |
| |
| // 1st param: charstring, the URI of the observed resource |
| |
| var charstring vl_observedResourceId := f_EPTF_LGenBase_charstringValOfStep(pl_ptr); |
| |
| f_EPTF_COAP_transportEndpointDB_get(v_COAP_transportEndpoint, v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].localAddressIdx); |
| |
| var integer vl_observedResourceIdx := f_EPTF_COAP_observedResourceDB_lookUp( |
| v_COAP_transportEndpoint.socket.hostName, |
| v_COAP_transportEndpoint.socket.portNumber, |
| vl_observedResourceId |
| ); |
| |
| if (vl_observedResourceIdx != -1) |
| { |
| f_EPTF_COAP_EntityCtx_removeObservedResource(v_COAP_ctx.eCtxIdx, vl_observedResourceIdx); |
| } |
| else { f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " it was not possible to fetch the referred observedResourceIdx")); } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_COAP_step_setPreferredBlocksize |
| // |
| // Purpose: |
| // Test step to set the preferred blocksize (szx) in the entity context. Integer parameter required. |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // pl_ptr.refContext.fRefArgs[0] - *integer* - SZX value to be set. 0 will set to omit. |
| // |
| // Related Constants: |
| // - <c_COAP_stepIdx_setPreferredBlocksize> |
| // - <c_COAP_stepName_setPreferredBlocksize> |
| /////////////////////////////////////////////////////////// |
| function f_COAP_step_setPreferredBlocksize(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; } |
| |
| // 1st param: integer with the szx |
| var integer vl_szx := 1; |
| |
| if (f_EPTF_COAP_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_szx)) |
| { |
| if (vl_szx == 0) |
| { |
| v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].preferredBlocksize := omit; |
| } |
| else |
| { |
| v_COAP_EntityCtxDB.data[v_COAP_ctx.eCtxIdx].preferredBlocksize := vl_szx; |
| } |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_setStepCtx |
| // |
| // Purpose: |
| // This sets the instance pointers of <COAP_StepCtx> to the related instances of a simulated device (entity) |
| // calculated from the test step args <EPTF_LGenBase_TestStepArgs> |
| // |
| // Parameters: |
| // pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args |
| // p_ctx - <COAP_StepCtx> - step context with pointers to the related instances |
| // |
| // Related Types: |
| // - <COAP_EntityCtx> |
| // - <COAP_StepCtx> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // This sets the instance pointers of <COAP_StepCtx> to the related instances of a simulated device (entity) |
| // calculated from the test step args <EPTF_LGenBase_TestStepArgs> |
| // |
| // Parameters: |
| // p_eIdx - *in* *integer* - entity index |
| // p_fsmIdx - *in* *integer* - fsm instace index |
| // |
| // Returns: |
| // p_ctx - <COAP_StepCtx> - step context with pointers to the related instances |
| // |
| // Related Types: |
| // - <COAP_EntityCtx> |
| // - <COAP_StepCtx> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Checks if the <COAP_FsmCtx> instace was created for an FSM instance and returns with a pointer to it |
| // |
| // Parameters: |
| // p_eIdx - *in* *integer* - entity index |
| // p_fsmIdx - *in* *integer* - fsm instace index |
| // |
| // Returns: |
| // pl_fsmCtxIdx - *inout* *integer* - index of the <COAP_FsmCtx> instance in the <COAP_FsmCtx_DB> |
| // |
| // Related Types: |
| // <COAP_FsmCtx> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Retreives an element of an <EPTF_IntegerList> if it exists |
| // |
| // Parameters: |
| // pl_intList - *in* <EPTF_IntegerList> - list of integers |
| // pl_number - *in* *integer* - index of the integer to be retrieved |
| // |
| // Returns: |
| // pl_value - *inout* *integer* - value of the retrieved integer |
| // *boolean* - true if the element existed in the integer list |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Converts the <Code> ot a COAP PDU to an integer number |
| // |
| // Parameters: |
| // p_code - *in* <Code> - code of a COAP PDU |
| // |
| // Returns: |
| // *integer* - the returned id |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_CodeToEventIdx(in Code p_code) |
| return integer |
| { |
| return p_code.class*100+p_code.detail; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_isCoapReportEnabledForEntity |
| // |
| // Purpose: |
| // Checks if the COAP event reporting is enabled for a particular entity |
| // |
| // Parameters: |
| // pl_eIdx - *in* *integer* - the index of the entity |
| // |
| // Returns: |
| // *boolean* - *true* if COAP event reporting is enabled, *false* otherwise |
| // |
| // Related Types: |
| // <COAP_EntityCtx> |
| /////////////////////////////////////////////////////////// |
| 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_dispatchEventForObserve_ifExists |
| // |
| // Purpose: |
| // Dispatches the <c_COAP_eventIdx_OBSERVE> event to an entity/fsm if the COAP message has an OBSERVE option |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - the COAP PDU |
| // pl_eIdx - *in* *integer* - the index of the entity |
| // pl_fsmCtx - *in* *integer* - the index of FSM |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_dispatchEventForObserve_ifExists(in CoAP_ReqResp p_pdu, in integer pl_eIdx, in integer pl_fsmCtx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (not f_EPTF_COAP_isCoapReportEnabledForEntity(pl_eIdx) ) { return; } |
| |
| var integer i:= f_EPTF_COAP_hasObserve(p_pdu); |
| if (i >= 0) |
| { |
| if (p_pdu.options[i].observe == 0) { |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_OBSERVE, pl_eIdx, pl_fsmCtx, {}); |
| } |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_dispatchEventForBlock1 |
| // |
| // Purpose: |
| // Dispatches the <c_COAP_eventIdx_BLOCK1_init> event to an entity/fsm if the COAP message has an block1 option |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - the COAP PDU |
| // pl_eIdx - *in* *integer* - the index of the entity |
| // pl_fsmCtx - *in* *integer* - the index of FSM |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_dispatchEventForBlock1(in BlockOption p_block1, in integer pl_eIdx, in integer pl_fsmCtx) |
| runs on EPTF_COAP_LGen_CT |
| { |
| if (not f_EPTF_COAP_isCoapReportEnabledForEntity(pl_eIdx) ) { return; } |
| |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_BLOCK1_block, pl_eIdx, pl_fsmCtx, {}); |
| if (p_block1.num == 0) { |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_BLOCK1_init, pl_eIdx, pl_fsmCtx, {}); |
| } |
| else if (p_block1.m == false) { |
| f_EPTF_COAP_dispatchEvent(c_COAP_eventIdx_BLOCK1_last, pl_eIdx, pl_fsmCtx, {}); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_dispatchEventsForCode |
| // |
| // Purpose: |
| // Dispatches events to an entity/fsm based on the COAP PDU's code |
| // |
| // Parameters: |
| // pl_code - *in* <Code> - the COAP PDU's code |
| // pl_eIdx - *in* *integer* - the index of the entity |
| // pl_fsmCtx - *in* *integer* - the index of FSM |
| // pl_reportedArgs - *in* <EPTF_IntegerList> - additional arguments to be reported to the entity/FSM |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Wrapper for CLL's <f_EPTF_LGenBase_postEvent> to handle multi level event (generic, entity, FSM) reporting |
| // |
| // Parameters: |
| // pl_eventIdx - *in* *integer* - index of the vent to be reported |
| // pl_eIdx - *in* *integer* - the index of the entity, in case it's -1 the reported event will be *generic* level |
| // pl_fsmCtx - *in* *integer* - the index of FSM, , in case it's -1 the reported event will be *entity* level |
| // pl_reportedArgs - *in* <EPTF_IntegerList> - additional arguments to be reported to the entity/FSM |
| // |
| // Related Types: |
| // <EPTF_COAP_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Checks if the COAP PDU is empty |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU to be checked |
| // |
| // Returns: |
| // *boolean* - true in case the COAP PDU is empty |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Checks if the COAP PDU is a request |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU to be checked |
| // |
| // Returns: |
| // *boolean* - true in case the COAP PDU is a request |
| /////////////////////////////////////////////////////////// |
| 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 |
| // |
| // Purpose: |
| // Checks if the COAP PDU is a response |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU to be checked |
| // |
| // Returns: |
| // *boolean* - true in case the COAP PDU is a response |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_isResponse(in CoAP_ReqResp p_pdu) |
| return boolean |
| { |
| if (p_pdu.header.code.class > 0) { |
| return true; |
| } |
| return false; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_hasObserve |
| // |
| // Purpose: |
| // Checks if the COAP PDU has an OBSERVE option |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU to be checked |
| // |
| // Returns: |
| // *integer* - index of the observe option in case the COAP PDU has an OBSERVE option |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_hasObserve(in CoAP_ReqResp p_pdu) |
| return integer |
| { |
| for (var integer i:=0; i<sizeof(p_pdu.options); i:=i+1) { |
| if (ischosen(p_pdu.options[i].observe)) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_hasBlock1 |
| // |
| // Purpose: |
| // Checks if the COAP PDU has a BLOCK1 option |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU to be checked |
| // |
| // Returns: |
| // *integer* - index of the block1 option in case the COAP PDU has a BLOCK1 option |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_hasBlock1(in CoAP_ReqResp p_pdu) |
| return integer |
| { |
| for (var integer i:=0; i<sizeof(p_pdu.options); i:=i+1) { |
| if (ischosen(p_pdu.options[i].block1)) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_isReset |
| // |
| // Purpose: |
| // Checks if the COAP PDU is a RST |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU to be checked |
| // |
| // Returns: |
| // *boolean* - true in case the COAP PDU is a RST |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_isReset(in CoAP_ReqResp p_pdu) |
| return boolean |
| { |
| if (p_pdu.header.msg_type == RESET) { |
| return true; |
| } |
| return false; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_uriPathToString |
| // |
| // Purpose: |
| // Converts the uri path of the COAP PDU into one string using "/" as delimiter |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU |
| // |
| // Returns: |
| // *charstring* - uri path of the COAP PDU in one string using "/" as delimiter |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_uriPathToString(in CoAP_ReqResp p_pdu) |
| return charstring |
| { |
| var charstring v_ret := ""; |
| for (var integer i:=0; i<sizeof(p_pdu.options); i:=i+1) |
| { |
| if (ischosen(p_pdu.options[i].uri_path)) { |
| v_ret := v_ret & "/" & oct2char(unichar2oct(p_pdu.options[i].uri_path)); |
| } |
| } |
| return v_ret; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_fetchUriPath |
| // |
| // Purpose: |
| // Fetches the uri path of the COAP PDU |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU |
| // |
| // Returns: |
| // *charstring* - uri path of the COAP PDU in one string using "/" as delimiter |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_fetchUriPath(in CoAP_ReqResp p_pdu) |
| return UriPath_List |
| { |
| var UriPath_List v_ret := {}; |
| for (var integer i:=0; i<sizeof(p_pdu.options); i:=i+1) |
| { |
| if (ischosen(p_pdu.options[i].uri_path)) { |
| v_ret[sizeof(v_ret)] := p_pdu.options[i].uri_path; |
| } |
| } |
| return v_ret; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_fetchContentFormat |
| // |
| // Purpose: |
| // Fetches the content format of the COAP PDU |
| // |
| // Parameters: |
| // p_pdu - *in* <CoAP_ReqResp> - COAP PDU |
| // |
| // Returns: |
| // *integer* - content format of the COAP PDU |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_fetchContentFormat(in CoAP_ReqResp p_pdu) |
| return integer |
| { |
| for (var integer i:=0; i<sizeof(p_pdu.options); i:=i+1) |
| { |
| if (ischosen(p_pdu.options[i].content_format)) { |
| return p_pdu.options[i].content_format; |
| } |
| } |
| return -1; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_COAP_addOption |
| // |
| // Purpose: |
| // Adds <CoAP_Options> options to a the COAP PDU |
| // |
| // Parameters: |
| // p_pdu - *inout* <CoAP_ReqResp> - COAP PDU |
| // p_option - *in* <CoAP_Options> - COAP options to be added |
| /////////////////////////////////////////////////////////// |
| function f_EPTF_COAP_addOption(inout CoAP_ReqResp p_coap, in CoAP_Options p_option) |
| { |
| if (not ispresent(p_coap.options)) { p_coap.options := {} } |
| |
| p_coap.options[sizeof(p_coap.options)] := p_option; |
| } |
| |
| function f_EPTF_COAP_updateMessageStatistics(inout EPTF_COAP_Message_Statistics p_stats, in EPTF_COAP_PDU p_pdu) |
| { |
| // request |
| if (p_pdu.pdu.header.code.class == 0) |
| { |
| // empty |
| if (p_pdu.pdu.header.code.detail == 0) { p_stats.noEMPTY := p_stats.noEMPTY + 1; } |
| // GET |
| else if (p_pdu.pdu.header.code.detail == 1) { p_stats.noGET := p_stats.noGET + 1; } |
| // POST |
| else if (p_pdu.pdu.header.code.detail == 2) { p_stats.noPOST := p_stats.noPOST + 1; } |
| // PUT |
| else if (p_pdu.pdu.header.code.detail == 3) { p_stats.noPUT := p_stats.noPUT + 1; } |
| // DELETE |
| else if (p_pdu.pdu.header.code.detail == 4) { p_stats.noDELETE := p_stats.noDELETE + 1; } |
| } |
| // positive response |
| else if (p_pdu.pdu.header.code.class == 2) { p_stats.noPosResp := p_stats.noPosResp + 1; } |
| // negative response |
| else if (p_pdu.pdu.header.code.class >= 3) { p_stats.noNegResp := p_stats.noNegResp + 1; } |
| |
| if (p_pdu.pdu.header.msg_type == CONFIRMABLE) { p_stats.noCON := p_stats.noCON + 1; } |
| else if (p_pdu.pdu.header.msg_type == NON_CONFIRMABLE) { p_stats.noNON := p_stats.noNON + 1; } |
| else if (p_pdu.pdu.header.msg_type == ACKNOWLEDGEMENT) { p_stats.noACK := p_stats.noACK + 1; } |
| else if (p_pdu.pdu.header.msg_type == RESET) { p_stats.noRST := p_stats.noRST + 1; } |
| } |
| |
| template CoAP_ReqResp t_CoAP_EmptyAck := |
| { |
| header := |
| { |
| version := 1, |
| msg_type := ACKNOWLEDGEMENT, |
| code := EMPTY_MESSAGE, |
| message_id := 0 |
| }, |
| token := ''O, |
| options := omit, |
| payload := omit |
| } |
| } |