blob: f5fcf71e59f6a0fdf5c4da4f72775d01d1f87e40 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2019 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_LwM2M_LGen_Functions.ttcn
// Description:
// Rev: R1A
// Prodnr: CNL 113 859
// Updated: 2019-08-27
// Contact: http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_LwM2M_LGen_Functions
//
// Purpose:
// This module contains the functions of the LWM2M load generator component
//
// See also:
// <EPTF_LwM2M_LGen_Definitions>
///////////////////////////////////////////////////////////////
module EPTF_LwM2M_LGen_Functions
{
import from EPTF_LwM2M_LGen_Definitions all;
import from EPTF_LwM2M_Object_Definitions all;
import from EPTF_LwM2M_Object_Functions all;
import from EPTF_LwM2M_Transport_Definitions all;
import from LightweightM2M_Types all;
import from EPTF_CLL_Base_Functions all;
import from EPTF_CLL_Common_Definitions 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_HashMapOct2Int_Functions all;
import from EPTF_CLL_RBTScheduler_Functions all;
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_LGen_init
//
// Purpose:
// The main initialization function for the <EPTF_LwM2M_LGen_CT> component type
//
// Parameters:
// pl_name - *in* *charstring* - the name for the component instance
//
// Related Type:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_LGen_init(in charstring pl_name)
runs on EPTF_LwM2M_LGen_CT
{
if (v_LwM2M_initialized){return;}
f_EPTF_LGenBase_init(pl_name, 0, pl_name);
f_EPTF_Logging_init_CT(pl_name);
f_EPTF_str2int_HashMap_Init();
f_EPTF_oct2int_HashMap_Init();
v_LwM2M_bIdx := f_EPTF_LGenBase_declareBehaviorType(
c_LwM2M_behaviorType,
tsp_EPTF_LwM2M_LGen_maxBindableCtx,
refers(f_LwM2M_eCtxReset),
refers(f_LwM2M_eCtxBind),
refers(f_LwM2M_eCtxUnbind)
);
f_EPTF_LwM2M_LGen_initLogging();
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId,": my behavior idx is ", v_LwM2M_bIdx));
f_LwM2M_ObjectSpecificationDB_init(v_LwM2M_ObjectSpecificationDB, 0);
f_EPTF_LwM2M_EntityCtxDB_init();
f_EPTF_LwM2M_DeviceDB_init();
f_EPTF_LwM2M_TemplateDB_init();
f_EPTF_LwM2M_declareSteps();
f_EPTF_LwM2M_declareEvents();
f_LwM2M_ObjectSpecificationDB_fillInOmaSpecs(v_LwM2M_ObjectSpecificationDB);
for (var integer i:=0; i<sizeof(tsp_EPTF_LwM2M_LGen_objectSpecifications); i:=i+1)
{
f_LwM2M_ObjectSpecificationDB_add(v_LwM2M_ObjectSpecificationDB, tsp_EPTF_LwM2M_LGen_objectSpecifications[i]);
}
f_EPTF_Base_registerCleanup(refers(f_LwM2M_cleanUp));
v_LwM2M_initialized := true;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_LGen_initLogging
//
// Purpose:
// Initializing CLL's logging feature on the <EPTF_LwM2M_LGen_CT> component type
//
// Related Type:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_LGen_initLogging()
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_Logging_init_CT("LwM2M_LGen");
v_LwM2M_loggingMaskId :=
f_EPTF_Logging_registerComponentMasks(
"LwM2M_LGen_Logging",
{"WARNING", "DEBUG", "DEBUGV", "ERROR"},
EPTF_Logging_CLL
);
if(tsp_EPTF_LwM2M_LGen_log_error){
f_EPTF_Logging_enableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_ERROR);
}
else {
f_EPTF_Logging_disableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_ERROR);
}
if(tsp_EPTF_LwM2M_LGen_log_warning){
f_EPTF_Logging_enableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_WARNING);
}
else {
f_EPTF_Logging_disableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_WARNING);
}
if(tsp_EPTF_LwM2M_LGen_debug){
f_EPTF_Logging_enableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_DEBUG);
}
else {
f_EPTF_Logging_disableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_DEBUG);
}
if(tsp_EPTF_LwM2M_LGen_debugVerbose) {
f_EPTF_Logging_enableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_DEBUGV);
}
else {
f_EPTF_Logging_disableLocalMask(v_LwM2M_loggingMaskId, c_LwM2M_LGen_Logging_DEBUGV);
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_cleanUp
//
// Purpose:
// The main clean up function for the <EPTF_LwM2M_LGen_CT> component type
//
// Related Type:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_LwM2M_cleanUp()
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_EntityCtxDB_cleanUp();
f_EPTF_LwM2M_DeviceDB_cleanUp();
f_LwM2M_ObjectSpecificationDB_cleanUp(v_LwM2M_ObjectSpecificationDB);
f_EPTF_LwM2M_TemplateDB_cleanUp();
v_LwM2M_initialized := false;
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_eCtxBind
//
// Purpose:
// This function is called by the CLL for each entity instance created on a particular instace of <EPTF_LwM2M_LGen_CT>
// The function will allocate and initialize an instance of <LwM2M_EntityCtx> in *v_LwM2M_EntityCtxDB* <LwM2M_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 <LwM2M_EntityCtx_DB> instance in the *v_LwM2M_EntityCtxDB*
//
// Related Type:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_LwM2M_eCtxBind(in integer pl_eIdx)
runs on EPTF_LwM2M_LGen_CT
return EPTF_IntegerList
{
var integer vl_eCtxIdx := f_EPTF_FBQ_getOrCreateFreeSlot(v_LwM2M_EntityCtxDB.queue);
f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_LwM2M_EntityCtxDB.queue);
v_LwM2M_EntityCtxDB.data[vl_eCtxIdx] := c_LwM2M_EntityCtx_init;
v_LwM2M_EntityCtxDB.data[vl_eCtxIdx].eIdx := pl_eIdx;
return {vl_eCtxIdx};
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_eCtxUnbind
//
// Purpose:
// The reverse operation of <f_LwM2M_eCtxBind>. Cleans up resources reserved during <f_LwM2M_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_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_LwM2M_eCtxUnbind(in integer pl_eIdx)
runs on EPTF_LwM2M_LGen_CT
{
if (not v_LwM2M_initialized) {return;}
var integer vl_eCtxIdx:= f_EPTF_LGenBase_getBehaviorCtxItem(pl_eIdx, v_LwM2M_bIdx, 0);
f_EPTF_FBQ_moveFromBusyToFreeTail(vl_eCtxIdx, v_LwM2M_EntityCtxDB.queue);
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_eCtxReset
//
// Purpose:
// The resources reserved during <f_LwM2M_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_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_LwM2M_eCtxReset(in integer pl_eIdx)
runs on EPTF_LwM2M_LGen_CT
{
var integer vl_eCtxIdx:= f_EPTF_LGenBase_getBehaviorCtxItem(pl_eIdx, v_LwM2M_bIdx, 0);
v_LwM2M_EntityCtxDB.data[vl_eCtxIdx] := c_LwM2M_EntityCtx_init;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_EntityCtxDB_init
//
// Purpose:
// Initializes the *v_LwM2M_EntityCtxDB* <LwM2M_EntityCtx_DB> database
//
// Related Type:
// <LwM2M_EntityCtx_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_EntityCtxDB_init()
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_FBQ_initFreeBusyQueue(v_LwM2M_EntityCtxDB.queue);
v_LwM2M_EntityCtxDB.data := {};
v_LwM2M_EntityCtxDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_LwM2M_EnityCtxDB_Hash");
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_EntityCtxDB_cleanUp
//
// Purpose:
// Cleans up the reserved resources of the *v_LwM2M_EntityCtxDB* <LwM2M_EntityCtx_DB> database
//
// Related Type:
// <LwM2M_EntityCtx_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_EntityCtxDB_cleanUp()
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_FBQ_initFreeBusyQueue(v_LwM2M_EntityCtxDB.queue);
v_LwM2M_EntityCtxDB.data :={}
f_EPTF_str2int_HashMap_Delete("EPTF_LwM2M_EnityCtxDB_Hash");
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_DeviceDB_init
//
// Purpose:
// Initializes the *v_LwM2M_DeviceDB* <LwM2M_Device_DB> database
//
// Related Type:
// <LwM2M_Device_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_DeviceDB_init()
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_FBQ_initFreeBusyQueue(v_LwM2M_DeviceDB.queue);
v_LwM2M_DeviceDB.data := {};
v_LwM2M_DeviceDB.hashRef := f_EPTF_oct2int_HashMap_New("EPTF_LwM2M_DeviceDB_Hash");
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_DeviceDB_add
//
// Purpose:
// Adds a new element to the *v_LwM2M_DeviceDB* <LwM2M_Device_DB> database
//
// Parameters:
// p_device - *in* <LwM2M_Device> - the element to be added
//
// Returns:
// p_idx - *out* *integer* - the index of the added element in the database
//
// Related Type:
// <LwM2M_Device_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_DeviceDB_add(in LwM2M_Device p_device)
runs on EPTF_LwM2M_LGen_CT
return integer
{
var integer v_idx := f_EPTF_FBQ_getOrCreateFreeSlot(v_LwM2M_DeviceDB.queue);
f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_LwM2M_DeviceDB.queue);
f_EPTF_LwM2M_Logging_DEBUG(log2str(": "," adding device ", v_idx, " ", p_device));
if (sizeof(p_device.registeredLocation) > 0) {
f_EPTF_LwM2M_DeviceDB_setLocationKey(p_device.registeredLocation, v_idx);
}
v_LwM2M_DeviceDB.data[v_idx] := p_device;
return v_idx;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_DeviceDB_remove
//
// Purpose:
// Removes an element from the *v_LwM2M_DeviceDB* <LwM2M_Device_DB> database and frees up its reserved resources
//
// Parameters:
// p_idx - *in* *integer* - the index of the element to be removed
//
// Related Type:
// <LwM2M_Device_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_DeviceDB_remove(in integer p_idx)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str("removing device with idx: ",p_idx," device: ", v_LwM2M_DeviceDB.data[p_idx]));
v_LwM2M_DeviceDB.data[p_idx] := c_LwM2M_Device_init;
f_EPTF_FBQ_moveFromBusyToFreeTail(p_idx, v_LwM2M_DeviceDB.queue);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_DeviceDB_setLocationKey
//
// Purpose:
// Sets the hashmap key for lookups used by the *v_LwM2M_DeviceDB* <LwM2M_Device_DB> database
//
// Parameters:
// p_location - *in* <Location> - the location (of a <LwM2M_Device>)
// p_idx - *in* *integer* - the index of the <LwM2M_Device> in the *v_LwM2M_DeviceDB* database
//
// Related Type:
// <LwM2M_Device_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_DeviceDB_setLocationKey(in Location p_location, in integer p_idx)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_oct2int_HashMap_Insert(v_LwM2M_DeviceDB.hashRef, f_EPTF_LwM2M_DeviceDB_locationHash(p_location), p_idx);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_DeviceDB_locationHash
//
// Purpose:
// Hash function for lookups used by the *v_LwM2M_DeviceDB* <LwM2M_Device_DB> database
//
// Parameters:
// p_location - *in* <Location> - the location (of a <LwM2M_Device>)
//
// Returns:
// *charstring* - string hash unique for the <Location> parameter
//
// Related Type:
// <LwM2M_Device_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_DeviceDB_locationHash(in Location p_location)
return octetstring
{
var octetstring v_loc := ''O;
for (var integer i:=0; i<sizeof(p_location); i:=i+1) {
v_loc := v_loc & unichar2oct(p_location[i]);
}
return v_loc;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_DeviceDB_cleanUp
//
// Purpose:
// Cleans up the reserved resources of the *v_LwM2M_DeviceDB* <LwM2M_Device_DB> database
//
// Related Type:
// <LwM2M_Device_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_DeviceDB_cleanUp()
runs on EPTF_LwM2M_LGen_CT
{
// for each device: clean up object db if initialized
for (var integer i:=0; i < f_EPTF_FBQ_getLengthOfQueue(v_LwM2M_DeviceDB.queue); i:=i+1) {
if(f_EPTF_FBQ_itemIsBusy(i, v_LwM2M_DeviceDB.queue)) {
if (v_LwM2M_DeviceDB.data[i].objects.id >= 0) {
f_LwM2M_ObjectDB_cleanUp(v_LwM2M_DeviceDB.data[i].objects);
}
}
}
f_EPTF_FBQ_initFreeBusyQueue(v_LwM2M_DeviceDB.queue);
v_LwM2M_DeviceDB.data :={}
f_EPTF_oct2int_HashMap_Delete("EPTF_LwM2M_DeviceDB_Hash");
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_TemplateDB_init
//
// Purpose:
// Initializes the *v_LwM2M_templateDB* <LwM2M_Template_DB> database by adding the templates given in <tsp_EPTF_LwM2M_LGen_templates>
//
// Related Type:
// <LwM2M_Template_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_TemplateDB_init()
runs on EPTF_LwM2M_LGen_CT
{
v_LwM2M_templateDB.data := {};
v_LwM2M_templateDB.hashRef := f_EPTF_str2int_HashMap_New("EPTF_LwM2M_templateDB_Hash");
for (var integer i:=0; i<sizeof(tsp_EPTF_LwM2M_LGen_templates); i:=i+1) {
f_EPTF_LwM2M_TemplateDB_add(tsp_EPTF_LwM2M_LGen_templates[i]);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_TemplateDB_add
//
// Purpose:
// Adds a new element to the *v_LwM2M_templateDB* <LwM2M_Template_DB> database
//
// Parameters:
// p_template - *in* <LwM2M_Template> - the element to be added
//
// Returns:
// *integer* - the index of the added element in the database
//
// Related Type:
// <LwM2M_Template_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_TemplateDB_add(in LwM2M_Template p_template)
runs on EPTF_LwM2M_LGen_CT
return integer
{
if (f_EPTF_LwM2M_TemplateDB_lookUp(p_template.id)!=-1)
{
f_EPTF_LwM2M_Logging_WARNING(log2str(%definitionId, " template is already added with id: ", p_template.id));
return -1;
}
var integer v_idx := sizeof(v_LwM2M_templateDB.data);
v_LwM2M_templateDB.data[v_idx] := p_template;
f_EPTF_str2int_HashMap_Insert(v_LwM2M_templateDB.hashRef, p_template.id, v_idx);
f_EPTF_LwM2M_Logging_VERBOSE(log2str(%definitionId, " template was added with id: ", p_template.id, " at idx: ",v_idx));
return v_idx;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_TemplateDB_lookUp
//
// Purpose:
// Gets the index of an <LwM2M_Template> element in *v_LwM2M_templateDB* <LwM2M_Template_DB> database
//
// Parameters:
// p_id - *in* *charstring* - the id of the <LwM2M_Template>
//
// Returns:
// *integer* - the index of the added element in the database, or -1 if not found
//
// Related Type:
// <LwM2M_Template_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_TemplateDB_lookUp(in charstring p_id)
runs on EPTF_LwM2M_LGen_CT
return integer
{
var integer vl_idx := -1;
if (not f_EPTF_str2int_HashMap_Find(v_LwM2M_templateDB.hashRef, p_id, vl_idx))
{
vl_idx := -1;
}
return vl_idx;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_TemplateDB_get
//
// Purpose:
// Retrieves an element from the *v_LwM2M_templateDB* <LwM2M_Template_DB> database
//
// Parameters:
// p_idx - *in* *integer* - the index of the element to be retrieved
//
// Returns:
// p_or - *inout* <LWM2M_PDU> - the retrieved element
//
// Related Type:
// <LwM2M_Template_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_TemplateDB_get(in integer p_idx, inout LWM2M_PDU p_pdu)
runs on EPTF_LwM2M_LGen_CT
{
if (p_idx < sizeof(v_LwM2M_templateDB.data) and p_idx >= 0)
{
f_EPTF_LwM2M_Logging_VERBOSE(log2str(%definitionId, " template is fetched with idx: ", p_idx));
p_pdu := v_LwM2M_templateDB.data[p_idx].msg;
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_TemplateDB_cleanUp
//
// Purpose:
// Cleans up the reserved resources of the *v_LwM2M_templateDB* <LwM2M_Template_DB> database
//
// Related Type:
// <LwM2M_Template_DB>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_TemplateDB_cleanUp()
runs on EPTF_LwM2M_LGen_CT
{
v_LwM2M_templateDB.data := {};
f_EPTF_str2int_HashMap_Delete("EPTF_LwM2M_templateDB_Hash");
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_Logging_VERBOSE
//
// Purpose:
// Logging functions for the VERBOSE log level
//
// Parameters:
// pl_message - *in* *charstring* - string to be logged
//
// Related Types:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_Logging_VERBOSE(in @lazy charstring pl_message)
runs on EPTF_LwM2M_LGen_CT
{
if (c_EPTF_Common_debugSwitch) {
f_EPTF_Logging_debugV2(pl_message, v_LwM2M_loggingMaskId, {c_LwM2M_LGen_Logging_DEBUGV});
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_Logging_DEBUG
//
// Purpose:
// Logging functions for the DEBUG log level
//
// Parameters:
// pl_message - *in* *charstring* - string to be logged
//
// Related Types:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_Logging_DEBUG(in @lazy charstring pl_message)
runs on EPTF_LwM2M_LGen_CT
{
if (c_EPTF_Common_debugSwitch) {
f_EPTF_Logging_debugV2(pl_message, v_LwM2M_loggingMaskId, {c_LwM2M_LGen_Logging_DEBUG});
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_Logging_WARNING
//
// Purpose:
// Logging functions for the WARNING log level
//
// Parameters:
// pl_message - *in* *charstring* - string to be logged
//
// Related Types:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_Logging_WARNING(in @lazy charstring pl_message)
runs on EPTF_LwM2M_LGen_CT
{
if (c_EPTF_Common_debugSwitch) {
f_EPTF_Logging_debugV2(pl_message, v_LwM2M_loggingMaskId, {c_LwM2M_LGen_Logging_WARNING});
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_Logging_ERROR
//
// Purpose:
// Logging functions for the ERROR log level
//
// Parameters:
// pl_message - *in* *charstring* - string to be logged
//
// Related Types:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_Logging_ERROR(in @lazy charstring pl_message)
runs on EPTF_LwM2M_LGen_CT
{
if (c_EPTF_Common_debugSwitch) {
f_EPTF_Logging_debugV2(pl_message, v_LwM2M_loggingMaskId, {c_LwM2M_LGen_Logging_ERROR});
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_LGen_receiveMessage
//
// Purpose:
// The transport layer implementation <EPTF_LwM2M_Transport_Provider_CT> can report received <EPTF_LwM2M_PDU> message
// to the load generator layer <EPTF_LwM2M_Transport_User_CT> extended by <EPTF_LwM2M_LGen_CT> using this function.
//
// Parameters:
// pl_message - *in* <EPTF_LwM2M_PDU> - received message
//
// Related Types:
// - <EPTF_LwM2M_LGen_CT>
// - <fcb_EPTF_LwM2M_Transport_receiveMessage>
// - <EPTF_LwM2M_Transport_Provider_CT>
// - <EPTF_LwM2M_Transport_User_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_LGen_receiveMessage(in EPTF_LwM2M_PDU pl_message)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_VERBOSE(log2str(%definitionId, " ", pl_message));
v_LwM2M_msgToProcess := pl_message;
f_EPTF_LwM2M_updateMessageStatistics(v_LwM2M_stats.incoming, v_LwM2M_msgToProcess);
f_EPTF_LwM2M_stack_fromEnv(v_LwM2M_msgToProcess);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_LGen_receiveEvent
//
// Purpose:
// The transport layer implementation <EPTF_LwM2M_Transport_Provider_CT> can report received <EPTF_LwM2M_Event> events
// to the load generator layer <EPTF_LwM2M_Transport_User_CT> extended by <EPTF_LwM2M_LGen_CT> using this function.
//
// Parameters:
// pl_event - *in* <EPTF_LwM2M_Event> - received event
//
// Related Types:
// - <EPTF_LwM2M_LGen_CT>
// - <fcb_EPTF_LwM2M_Transport_receiveEvent>
// - <EPTF_LwM2M_Transport_Provider_CT>
// - <EPTF_LwM2M_Transport_User_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_LGen_receiveEvent(in EPTF_LwM2M_Event pl_event)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_VERBOSE(log2str(%definitionId, " ", pl_event));
v_LwM2M_eventToProcess := pl_event;
f_EPTF_LwM2M_setCtx(v_LwM2M_eventToProcess.eIdx, -1, v_LwM2M_ctx);
if (ischosen(v_LwM2M_eventToProcess.event.resourceNotObserved))
{
if (f_LwM2M_ObjectPath_isResource(v_LwM2M_eventToProcess.event.resourceNotObserved))
{
f_LwM2M_ObjectDB_setResourceObserved(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_eventToProcess.event.resourceNotObserved.objectId,
v_LwM2M_eventToProcess.event.resourceNotObserved.objectInstanceId,
v_LwM2M_eventToProcess.event.resourceNotObserved.resourceId,
false
);
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_resourceNotObservedIndication, v_LwM2M_eventToProcess.eIdx, -1, {});
}
}
else if (ischosen(v_LwM2M_eventToProcess.event.atomicBlock1Finished))
{
if (
f_LwM2M_ObjectPath_isResource(v_LwM2M_eventToProcess.event.atomicBlock1Finished.path) and
sizeof(v_LwM2M_eventToProcess.event.atomicBlock1Finished.resources) == 1 and
v_LwM2M_eventToProcess.event.atomicBlock1Finished.method == WRITE
)
{
// refresh the smart object value
var LwM2M_Resource v_res;
var boolean vl_found := false, vl_typeMatched := false;
f_EPTF_LwM2M_setCtx(v_LwM2M_eventToProcess.eIdx, -1, v_LwM2M_ctx);
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " Looking up resource"));
vl_found := f_LwM2M_ObjectDB_getResource(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Write.path.objectId,
v_LwM2M_msgToProcess.pdu.Write.path.objectInstanceId,
v_LwM2M_msgToProcess.pdu.Write.path.resourceId,
v_res
);
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " resource found: ", v_res));
if (vl_found)
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " resource found: true"));
// Value type matching
if (ischosen(v_res.val.boolValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.boolValue))
{ v_res.val := v_LwM2M_msgToProcess.pdu.Write.resources[0].val; vl_typeMatched := true; }
else if (ischosen(v_res.val.strValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.strValue))
{ v_res.val := v_LwM2M_msgToProcess.pdu.Write.resources[0].val; vl_typeMatched := true; }
else if (ischosen(v_res.val.floatValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.floatValue))
{ v_res.val := v_LwM2M_msgToProcess.pdu.Write.resources[0].val; vl_typeMatched := true; }
else if (ischosen(v_res.val.intValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.floatValue))
{ v_res.val.intValue := float2int(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.floatValue); vl_typeMatched := true; }
else if (ischosen(v_res.val.opaqueValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.opaqueValue))
{ v_res.val.opaqueValue := v_LwM2M_msgToProcess.pdu.Write.resources[0].val.opaqueValue; vl_typeMatched := true; }
if (vl_typeMatched)
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " type match: true"));
f_LwM2M_ObjectDB_setResourceValue(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Write.path.objectId,
v_LwM2M_msgToProcess.pdu.Write.path.objectInstanceId,
v_LwM2M_msgToProcess.pdu.Write.path.resourceId,
v_res.val
);
}
}
}
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_atomicBlock1Finished, v_LwM2M_eventToProcess.eIdx, -1, {});
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_LGen_isBootstrap
//
// Purpose:
// Sets p_isBootstrap true if the device is in bootstrapping state.
//
// Parameters:
// pl_eIdx - *in* integer - device index
// p_isBootstrap - *inout* boolean - is the device bootsrapping
//
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_LGen_isBootstrap(in integer pl_eIdx, inout boolean p_isBootstrap)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_VERBOSE(log2str(%definitionId, " ", pl_eIdx));
f_EPTF_LwM2M_setCtx(pl_eIdx, -1, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx > 0)
{
if (v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].state == BOOTSTRAPPING)
{
p_isBootstrap := true;
return;
}
}
p_isBootstrap := false;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_declareEvents
//
// Purpose:
// Declares the FSM events to the CLL framework implemented by <EPTF_LwM2M_LGen_CT>
//
// Related Types:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_declareEvents()
runs on EPTF_LwM2M_LGen_CT
{
var integer vl_dummy;
if (
c_LwM2M_eventIdx_Register != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Register) or
c_LwM2M_eventIdx_Update != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Update) or
c_LwM2M_eventIdx_Deregister != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Deregister) or
c_LwM2M_eventIdx_Read != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Read) or
c_LwM2M_eventIdx_Write != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Write) or
c_LwM2M_eventIdx_Execute != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Execute) or
c_LwM2M_eventIdx_Create != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Create) or
c_LwM2M_eventIdx_Delete != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Delete) or
c_LwM2M_eventIdx_Observe != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_Observe) or
c_LwM2M_eventIdx_WriteFWUri != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_WriteFWUri) or
c_LwM2M_eventIdx_WriteFWPackage != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_WriteFWPackage) or
c_LwM2M_eventIdx_ExecuteFWUpdate != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_ExecuteFWUpdate) or
c_LwM2M_eventIdx_BS_Delete != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_BS_Delete) or
c_LwM2M_eventIdx_BS_Finish != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_BS_Finish) or
c_LwM2M_eventIdx_BS_Discover != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_BS_Discover)
){
f_EPTF_LGenBase_log();
log("error"); mtc.stop;
}
for (var integer i:=15; i<700; i:=i+1)
{
vl_dummy := f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, "LWM2M rsp: "&int2str(i));
}
if (
c_LwM2M_eventIdx_1xx != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_1xx) or
c_LwM2M_eventIdx_2xx != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_2xx) or
c_LwM2M_eventIdx_3xx != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_3xx) or
c_LwM2M_eventIdx_4xx != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_4xx) or
c_LwM2M_eventIdx_5xx != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_5xx) or
c_LwM2M_eventIdx_6xx != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_6xx) or
c_LwM2M_eventIdx_3xxto6xx != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_3xxto6xx) or
c_LwM2M_eventIdx_resourceNotObservedIndication != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_resourceNotObservedIndication) or
c_LwM2M_eventIdx_atomicBlock1Finished != f_EPTF_LGenBase_declareFsmEvent(c_LwM2M_behaviorType, c_LwM2M_eventName_atomicBlock1Finished)
){
f_EPTF_LGenBase_log();
log("error"); mtc.stop
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_declareSteps
//
// Purpose:
// Declares the FSM steps to the CLL framework implemented by <EPTF_LwM2M_LGen_CT>
//
// Related Types:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_declareSteps()
runs on EPTF_LwM2M_LGen_CT
{
if (
c_LwM2M_stepIdx_loadTemplate_byIntIdx != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_loadTemplate_byIntIdx, refers(f_LwM2M_step_loadTemplate_byIntIdx)}) or
c_LwM2M_stepIdx_send != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_send, refers(f_LwM2M_step_send)}) or
c_LwM2M_stepIdx_createDevice != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_createDevice, refers(f_LwM2M_step_createDevice)}) or
c_LwM2M_stepIdx_cleanupDevice != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_cleanupDevice, refers(f_LwM2M_step_cleanupDevice)}) or
c_LwM2M_stepIdx_logDevice != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_logDevice, refers(f_LwM2M_step_logDevice)}) or
c_LwM2M_stepIdx_createObject != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_createObject, refers(f_LwM2M_step_createObject)}) or
c_LwM2M_stepIdx_createObjectInstance != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_createObjectInstance, refers(f_LwM2M_step_createObjectInstance)}) or
c_LwM2M_stepIdx_handleReadRequest != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_handleReadRequest, refers(f_LwM2M_step_handleReadRequest)}) or
c_LwM2M_stepIdx_handleWriteRequest != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_handleWriteRequest, refers(f_LwM2M_step_handleWriteRequest)}) or
c_LwM2M_stepIdx_handleExecuteRequest != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_handleExecuteRequest, refers(f_LwM2M_step_handleExecuteRequest)}) or
c_LwM2M_stepIdx_loadTemplate_byStringId != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_loadTemplate_byStringId, refers(f_LwM2M_step_loadTemplate_byStringId)}) or
c_LwM2M_stepIdx_sendNotificationForObservedResources != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_sendNotificationForObservedResources, refers(f_LwM2M_step_sendNotificationForObservedResources)}) or
c_LwM2M_stepIdx_setFirmwareUpdateState != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_setFirmwareUpdateState, refers(f_LwM2M_step_setFirmwareUpdateState)}) or
c_LwM2M_stepIdx_setFirmwareUpdateResult != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_setFirmwareUpdateResult, refers(f_LwM2M_step_setFirmwareUpdateResult)}) or
c_LwM2M_stepIdx_setBootstrapState != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_setBootstrapState, refers(f_LwM2M_step_setBootstrapState)}) or
c_LwM2M_stepIdx_setNotRegisteredState != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_setNotRegisteredState, refers(f_LwM2M_step_setNotRegisteredState)}) or
c_LwM2M_stepIdx_setBlock1Handling_stateless != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_setBlock1Handling_stateless, refers(f_LwM2M_step_setBlock1Handling_stateless)}) or
c_LwM2M_stepIdx_setBlock1Handling_atomic != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_setBlock1Handling_atomic, refers(f_LwM2M_step_setBlock1Handling_atomic)})
//c_LwM2M_stepIdx_writeOrCreateObject_BS != f_EPTF_LGenBase_declareStep(c_LwM2M_behaviorType,{c_LwM2M_stepName_writeOrCreateObject_BS, refers(f_LwM2M_step_writeOrCreateObject_BS)})
){
f_EPTF_LGenBase_log();
log("EPTF_LwM2M_LGen declaration error"); mtc.stop
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_loadTemplate_byIntIdx
//
// Purpose:
// Test step to load a <LwM2M_Template> from <tsp_EPTF_LwM2M_LGen_templates> into *v_LwM2M_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_LwM2M_msgToSend*
//
// Related Constants:
// - <c_LwM2M_stepIdx_loadTemplate_byIntIdx>
// - <c_LwM2M_stepName_loadTemplate_byIntIdx>
//
// Related Steps:
// <f_LwM2M_step_send>
///////////////////////////////////////////////////////////
function f_LwM2M_step_loadTemplate_byIntIdx(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
var integer vl_templateIdx := -1;
f_EPTF_LwM2M_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_templateIdx);
f_EPTF_LwM2M_TemplateDB_get(vl_templateIdx, v_LwM2M_msgToSend.pdu);
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_loadTemplate_byStringId
//
// Purpose:
// Test step to load a <LwM2M_Template> from <tsp_EPTF_LwM2M_LGen_templates> into *v_LwM2M_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_LwM2M_msgToSend*
//
// Related Constants:
// - <c_LwM2M_stepIdx_loadTemplate_byStringId>
// - <c_LwM2M_stepName_loadTemplate_byStringId>
//
// Related Steps:
// <f_LwM2M_step_send>
///////////////////////////////////////////////////////////
function f_LwM2M_step_loadTemplate_byStringId(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
var charstring vl_templateId := f_EPTF_LGenBase_charstringValOfStep(pl_ptr);
var integer vl_templateIdx := f_EPTF_LwM2M_TemplateDB_lookUp(vl_templateId);
if (vl_templateIdx >= 0)
{
f_EPTF_LwM2M_TemplateDB_get(vl_templateIdx, v_LwM2M_msgToSend.pdu);
}
else
{
f_EPTF_LwM2M_Logging_WARNING(log2str(%definitionId," Couldn't find template with id: ", vl_templateId));
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_send
//
// Purpose:
// Test step to send out a LWM2M message from *v_LwM2M_msgToSend*.
// The message will be processed by the Applib's LWM2M stack
// The step expects that a device was created for the entity
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_send>
// - <c_LwM2M_stepName_send>
//
// Related Steps:
// - <f_LwM2M_step_loadTemplate_byIntIdx>
// - <f_LwM2M_step_loadTemplate_byStringId>
//
// Related functions:
// <f_EPTF_LwM2M_stack_fromApp>
///////////////////////////////////////////////////////////
function f_LwM2M_step_send(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
v_LwM2M_msgToSend.eIdx := v_LwM2M_ctx.eIdx;
v_LwM2M_msgToSend.fsmIdx := v_LwM2M_ctx.fsmIdx;
f_EPTF_LwM2M_stack_fromApp(v_LwM2M_msgToSend, v_LwM2M_ctx);
f_EPTF_SchedulerComp_refreshSnapshotTime();
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_createDevice
//
// Purpose:
// Test Step to dynamically allocate and initialize a simulated <LwM2M_Device> and associate it to the
// caller entity's <LwM2M_EntityCtx>. Prerequisite to call any other LWM2M test step.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_createDevice>
// - <c_LwM2M_stepName_createDevice>
//
// Related Functions:
// - <f_LwM2M_step_cleanupDevice>
//
// Related Types:
// - <LwM2M_Device>
///////////////////////////////////////////////////////////
function f_LwM2M_step_createDevice(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
var LwM2M_Device vl_device := c_LwM2M_Device_init;
var integer vl_idx := f_EPTF_LwM2M_DeviceDB_add(vl_device);
f_LwM2M_ObjectDB_init(v_LwM2M_DeviceDB.data[vl_idx].objects, vl_idx);
v_LwM2M_EntityCtxDB.data[v_LwM2M_ctx.eCtxIdx].currentDevice := vl_idx;
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_cleanupDevice
//
// Purpose:
// Test Step to free up the <LwM2M_EntityCtx> for the caller entity. Frees up all allocated instances that were used by this FSM instance.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Functions:
// - <f_LwM2M_step_createDevice>
//
// Related Constants:
// - <c_LwM2M_stepIdx_cleanupDevice>
// - <c_LwM2M_stepName_cleanupDevice>
///////////////////////////////////////////////////////////
function f_LwM2M_step_cleanupDevice(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
f_EPTF_LwM2M_Logging_DEBUG(log2str("cleaning up objectDB id: ", v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.id));
f_LwM2M_ObjectDB_cleanUp(v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects);
f_EPTF_LwM2M_DeviceDB_remove(v_LwM2M_ctx.deviceIdx);
v_LwM2M_EntityCtxDB.data[v_LwM2M_ctx.eCtxIdx].currentDevice := -1;
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_logDevice
//
// Purpose:
// Test Step to log the contents of the <LwM2M_Device> associated to the
// caller entity's <LwM2M_EntityCtx>
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_logDevice>
// - <c_LwM2M_stepName_logDevice>
///////////////////////////////////////////////////////////
function f_LwM2M_step_logDevice(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
if (tsp_EPTF_LwM2M_LGen_debug) { log("device: \n", v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx]); }
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_setBootstrapState
//
// Purpose:
// Test Step to set the state of the device to BOOTSTRAPPING. Consequently,
// the bootstrap related LWM2M decoder functions will be used.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_setBootstrapState>
// - <c_LwM2M_stepName_setBootstrapState>
///////////////////////////////////////////////////////////
function f_LwM2M_step_setBootstrapState(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].state := BOOTSTRAPPING;
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_setBlock1Handling_stateless
//
// Purpose:
// Test Step to set the block1 handling strategy of the device to stateless
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_setBlock1Handling_stateless>
// - <c_LwM2M_stepName_setBlock1Handling_stateless>
///////////////////////////////////////////////////////////
function f_LwM2M_step_setBlock1Handling_stateless(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].block1Handling := STATELESS;
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_setBlock1Handling_atomic
//
// Purpose:
// Test Step to set the block1 handling strategy of the device to atomic
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_setBlock1Handling_atomic>
// - <c_LwM2M_stepName_setBlock1Handling_atomic>
///////////////////////////////////////////////////////////
function f_LwM2M_step_setBlock1Handling_atomic(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].block1Handling := ATOMIC;
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_setNotRegisteredState
//
// Purpose:
// Test Step to set the state of the device to BOOTSTRAPPING. Consequently,
// the bootstrap related LWM2M decoder functions will be used.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_setNotRegisteredState>
// - <c_LwM2M_stepName_setNotRegisteredState>
///////////////////////////////////////////////////////////
function f_LwM2M_step_setNotRegisteredState(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].state := NOT_REGISTERED;
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_writeOrCreateObject_BS
//
// Purpose:
// Test Step to handling the bootstrap write messge.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_writeOrCreateObject_BS>
// - <c_LwM2M_stepName_writeOrCreateObject_BS>
///////////////////////////////////////////////////////////
function f_LwM2M_step_writeOrCreateObject_BS(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
//f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_startHttpGetFirmware, v_LwM2M_msgToProcess.eIdx, v_LwM2M_msgToProcess.fsmIdx, {})
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_createObject
//
// Purpose:
// Test Step to create an <LwM2M_Object> instance on the caller entity's associated <LwM2M_Device>
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_createObject>
// - <c_LwM2M_stepName_createObject>
///////////////////////////////////////////////////////////
function f_LwM2M_step_createObject(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
var integer vl_objectId := -1;
if (f_EPTF_LwM2M_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_objectId) and v_LwM2M_ctx.deviceIdx >= 0)
{
var integer vl_specIdx := f_LwM2M_ObjectSpecificationDB_lookUp(v_LwM2M_ObjectSpecificationDB, vl_objectId);
if (vl_specIdx >= 0)
{
var integer v_ret := f_LwM2M_ObjectDB_createObject(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_ObjectSpecificationDB.specs[vl_specIdx]
);
if (v_ret < 0) { f_EPTF_LwM2M_Logging_VERBOSE(log2str("couldn't create object for id: ", vl_objectId)); }
}
else { f_EPTF_LwM2M_Logging_VERBOSE(log2str("specification is not for for id ", vl_objectId)); }
}
else { f_EPTF_LwM2M_Logging_VERBOSE(log2str("parameter is not set for test step")); }
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_createObjectInstance
//
// Purpose:
// Test Step to create an <LwM2M_ObjectInstance> instance on the caller entity's associated <LwM2M_Device>
// the instance will also created the <LwM2M_Resource> instances according to the object instance's <LwM2M_ObjectSpecification>
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_createObjectInstance>
// - <c_LwM2M_stepName_createObjectInstance>
///////////////////////////////////////////////////////////
function f_LwM2M_step_createObjectInstance(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
var integer vl_objectId := -1;
if (f_EPTF_LwM2M_getIntValue(pl_ptr.refContext.fRefArgs, 0, vl_objectId) and v_LwM2M_ctx.deviceIdx >= 0)
{
var boolean vl_addResources := true;
var integer vl_secondParam := -1;
if (f_EPTF_LwM2M_getIntValue(pl_ptr.refContext.fRefArgs, 1, vl_secondParam) and v_LwM2M_ctx.deviceIdx >= 0) {
vl_addResources := vl_secondParam != c_LwM2M_stepParam_createObjectInstance_DoNotAddResources;
}
var integer v_ret := f_LwM2M_ObjectDB_createObjectInstance(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_ObjectSpecificationDB,
vl_objectId,
vl_addResources
);
if (v_ret < 0) { f_EPTF_LwM2M_Logging_VERBOSE(log2str("couldn't create object instance for id: ", vl_objectId)); }
}
else { f_EPTF_LwM2M_Logging_VERBOSE(log2str("parameter is not set for test step")); }
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_handleReadRequest
//
// Purpose:
// The test step can be called from an FSM to handle a reported LWM2M READ request.
// The test step will bind the current request to the caller FSM, look up the <LwM2M_Resource>
// addressed in the request and create a response with <Code> 205 and content according to the
// resource value.
// In case the READ request also includes observation, the <LwM2M_Resource> will be marked as observed
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_handleReadRequest>
// - <c_LwM2M_stepName_handleReadRequest>
///////////////////////////////////////////////////////////
function f_LwM2M_step_handleReadRequest(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (ischosen(v_LwM2M_msgToProcess.pdu.Read_) and v_LwM2M_ctx.deviceIdx >= 0)
{
var LwM2M_Resource_List v_resources := {};
var boolean vl_found := false;
// Resource
if (f_LwM2M_ObjectPath_isResource(v_LwM2M_msgToProcess.pdu.Read_.path))
{
var LwM2M_Resource v_res;
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " Looking up resource"));
vl_found := f_LwM2M_ObjectDB_getResource(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
v_LwM2M_msgToProcess.pdu.Read_.path.objectInstanceId,
v_LwM2M_msgToProcess.pdu.Read_.path.resourceId,
v_res
);
if (vl_found)
{
if (ispresent(v_LwM2M_msgToProcess.pdu.Read_.observe))
{
f_LwM2M_ObjectDB_setResourceObserved(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
v_LwM2M_msgToProcess.pdu.Read_.path.objectInstanceId,
v_LwM2M_msgToProcess.pdu.Read_.path.resourceId,
true
);
}
v_resources[sizeof(v_resources)] := v_res;
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " resource found: ", v_resources));
}
}
// Object instance
else if (f_LwM2M_ObjectPath_isObjectInstance(v_LwM2M_msgToProcess.pdu.Read_.path))
{
var LwM2M_ObjectInstance v_objInst;
vl_found := f_LwM2M_ObjectDB_getObjectInstance(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
v_LwM2M_msgToProcess.pdu.Read_.path.objectInstanceId,
v_objInst
);
for (var integer i:=0; i<sizeof(v_objInst.resources); i:=i+1) {
v_resources[sizeof(v_resources)] := v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[v_objInst.resources[i]];
}
}
// Object
else if (f_LwM2M_ObjectPath_isObject(v_LwM2M_msgToProcess.pdu.Read_.path))
{
var LwM2M_ObjectInstance v_objInst;
vl_found := f_LwM2M_ObjectDB_getObjectInstance(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
0, // TODO: only for 0 object instance
v_objInst
);
for (var integer i:=0; i<sizeof(v_objInst.resources); i:=i+1) {
v_resources[sizeof(v_resources)] := v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[v_objInst.resources[i]];
}
}
v_LwM2M_msgToSend.eIdx := v_LwM2M_ctx.eIdx;
v_LwM2M_msgToSend.fsmIdx := v_LwM2M_ctx.fsmIdx;
if (vl_found)
{
//v_res.objId := -1; v_res.objInstId := -1; v_res.id := -1;
v_LwM2M_msgToSend.pdu := c_LWM2M_Response_init;
v_LwM2M_msgToSend.pdu.Response.code := 205;
v_LwM2M_msgToSend.pdu.Response.contentFormat := 1543;
v_LwM2M_msgToSend.pdu.Response.resources := v_resources;
}
else
{
v_LwM2M_msgToSend.pdu := c_LWM2M_Response_init;
v_LwM2M_msgToSend.pdu.Response.code := 404;
v_LwM2M_msgToSend.pdu.Response.contentFormat := omit;
v_LwM2M_msgToSend.pdu.Response.resources := {};
}
f_EPTF_LwM2M_updateMessageStatistics(v_LwM2M_stats.outgoing, v_LwM2M_msgToSend);
vf_EPTF_LwM2M_Transport_send.apply(v_LwM2M_msgToSend);
}
else { f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " not read pdu, or no device available, returning")); }
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_handleWriteRequest
//
// Purpose:
// The test step can be called from an FSM to handle a reported LWM2M WRITE request.
// The test step will bind the current request to the caller FSM, look up the <LwM2M_Resource>
// addressed in the request and load the updated value from the request. Finally, it will
// create a response with <Code> 204 in case the resource was found (404 otherwise).
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_handleWriteRequest>
// - <c_LwM2M_stepName_handleWriteRequest>
///////////////////////////////////////////////////////////
function f_LwM2M_step_handleWriteRequest(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
var boolean vl_found := false;
var boolean vl_typeMatched := false;
var boolean vl_block1 := ispresent(v_LwM2M_msgToProcess.pdu.Write.block1);
if (ischosen(v_LwM2M_msgToProcess.pdu.Write) and v_LwM2M_ctx.deviceIdx >= 0)
{
var LwM2M_Resource v_res;
if (f_LwM2M_ObjectPath_isResource(v_LwM2M_msgToProcess.pdu.Write.path) and
(sizeof(v_LwM2M_msgToProcess.pdu.Write.resources) == 1 or vl_block1)
)
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " Looking up resource"));
vl_found := f_LwM2M_ObjectDB_getResource(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Write.path.objectId,
v_LwM2M_msgToProcess.pdu.Write.path.objectInstanceId,
v_LwM2M_msgToProcess.pdu.Write.path.resourceId,
v_res
);
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " resource found: ", v_res));
if (vl_found)
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " resource found: true"));
if (not vl_block1)
{
// Value type matching
if (ischosen(v_res.val.boolValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.boolValue))
{ v_res.val := v_LwM2M_msgToProcess.pdu.Write.resources[0].val; vl_typeMatched := true; }
else if (ischosen(v_res.val.strValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.strValue))
{ v_res.val := v_LwM2M_msgToProcess.pdu.Write.resources[0].val; vl_typeMatched := true; }
else if (ischosen(v_res.val.floatValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.floatValue))
{ v_res.val := v_LwM2M_msgToProcess.pdu.Write.resources[0].val; vl_typeMatched := true; }
else if (ischosen(v_res.val.intValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.floatValue))
{ v_res.val.intValue := float2int(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.floatValue); vl_typeMatched := true; }
else if (ischosen(v_res.val.opaqueValue) and ispresent(v_LwM2M_msgToProcess.pdu.Write.resources[0].val.opaqueValue))
{ v_res.val.opaqueValue := v_LwM2M_msgToProcess.pdu.Write.resources[0].val.opaqueValue; vl_typeMatched := true; }
if (vl_typeMatched)
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " type match: true"));
f_LwM2M_ObjectDB_setResourceValue(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Write.path.objectId,
v_LwM2M_msgToProcess.pdu.Write.path.objectInstanceId,
v_LwM2M_msgToProcess.pdu.Write.path.resourceId,
v_res.val
);
}
}
else // if block1 Write
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " block1 arrived"));
if (v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].block1Handling == STATELESS)
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " statless block1 handling: to be done"));
}
else // atomic block1 handling
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " atomic block1 handling: will wait for final block"));
}
}
}
}
v_LwM2M_msgToSend.eIdx := v_LwM2M_ctx.eIdx;
v_LwM2M_msgToSend.fsmIdx := v_LwM2M_ctx.fsmIdx;
if (vl_found and (vl_typeMatched or vl_block1))
{
v_LwM2M_msgToSend.pdu := c_LWM2M_Response_init;
v_LwM2M_msgToSend.pdu.Response.code := 204;
if (ispresent(v_LwM2M_msgToProcess.pdu.Write.block1) and v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].block1Handling == ATOMIC)
{
v_LwM2M_msgToSend.pdu.Response.code := 231;
}
if (v_LwM2M_msgToProcess.pdu.Write.path.objectId == 5)
{
if (v_LwM2M_msgToProcess.pdu.Write.path.resourceId == 0) { f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_WriteFWPackage, v_LwM2M_msgToProcess.eIdx, -1, {}); }
if (v_LwM2M_msgToProcess.pdu.Write.path.resourceId == 1) { f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_WriteFWUri, v_LwM2M_msgToProcess.eIdx, -1, { }); }
}
}
else
{
v_LwM2M_msgToSend.pdu := c_LWM2M_Response_init;
v_LwM2M_msgToSend.pdu.Response.code := 404;
}
f_EPTF_LwM2M_updateMessageStatistics(v_LwM2M_stats.outgoing, v_LwM2M_msgToSend);
vf_EPTF_LwM2M_Transport_send.apply(v_LwM2M_msgToSend);
}
else { f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " not write pdu, or no device available, returning")); }
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_handleExecuteRequest
//
// Purpose:
// The test step can be called from an FSM to handle a reported LWM2M EXECUTE request.
// The test step will bind the current request to the caller FSM, look up the <LwM2M_Resource>
// addressed in the request and create a response with <Code> 204 in case the resource
// was found (404 otherwise).
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_handleExecuteRequest>
// - <c_LwM2M_stepName_handleExecuteRequest>
///////////////////////////////////////////////////////////
function f_LwM2M_step_handleExecuteRequest(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (ischosen(v_LwM2M_msgToProcess.pdu.Execute) and v_LwM2M_ctx.deviceIdx >= 0)
{
var LwM2M_Resource v_res;
var boolean vl_found := false;
if (f_LwM2M_ObjectPath_isResource(v_LwM2M_msgToProcess.pdu.Execute.path))
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " Looking up resource"));
vl_found := f_LwM2M_ObjectDB_getResource(
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
v_LwM2M_msgToProcess.pdu.Execute.path.objectId,
v_LwM2M_msgToProcess.pdu.Execute.path.objectInstanceId,
v_LwM2M_msgToProcess.pdu.Execute.path.resourceId,
v_res
);
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " resource found: ", v_res));
action("executed: ", v_res);
v_LwM2M_msgToSend.eIdx := v_LwM2M_ctx.eIdx;
v_LwM2M_msgToSend.fsmIdx := v_LwM2M_ctx.fsmIdx;
v_LwM2M_msgToSend.pdu := c_LWM2M_Response_init;
v_LwM2M_msgToSend.pdu.Response.code := 204;
if (v_LwM2M_msgToProcess.pdu.Execute.path.objectId == 5 and v_LwM2M_msgToProcess.pdu.Execute.path.resourceId == 2)
{
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_ExecuteFWUpdate, v_LwM2M_msgToProcess.eIdx, v_LwM2M_msgToProcess.fsmIdx, {});
}
f_EPTF_LwM2M_updateMessageStatistics(v_LwM2M_stats.outgoing, v_LwM2M_msgToSend);
vf_EPTF_LwM2M_Transport_send.apply(v_LwM2M_msgToSend);
}
else { f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " Only resource can be executed, ignoring request")); }
}
else { f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " not execute pdu, or no device available, returning")); }
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_sendNotificationForObservedResources
//
// Purpose:
// The test step will iterate through the observed resources of the caller entity's <LwM2M_Device>
// and creates and sends a NOTIFICATION for each.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_sendNotificationForObservedResources>
// - <c_LwM2M_stepName_sendNotificationForObservedResources>
///////////////////////////////////////////////////////////
function f_LwM2M_step_sendNotificationForObservedResources(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
// Should be made faster by keeping track of the observed resources in a separate list
for (var integer i:=0; i<sizeof(v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources); i:=i+1)
{
if (v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[i].observed)
{
f_EPTF_LwM2M_sendNotificationForResource(
pl_ptr,
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[i]
);
}
}
}
else { f_EPTF_LwM2M_Logging_VERBOSE(log2str("device is not initialized")); }
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_setFirmwareUpdateState
//
// Purpose:
// The test step will set the firmware update state resource value.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_setFirmwareUpdateState>
// - <c_LwM2M_stepName_setFirmwareUpdateState>
///////////////////////////////////////////////////////////
function f_LwM2M_step_setFirmwareUpdateState(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
var integer v_state := -1;
if (f_EPTF_LwM2M_getIntValue(pl_ptr.refContext.fRefArgs, 0, v_state) and v_LwM2M_ctx.deviceIdx >= 0){
var LwM2M_ResourceValue vl_state;
vl_state.intValue := v_state;
f_LwM2M_ObjectDB_setResourceValue(v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects, 5, 0, 3, vl_state);
}
}
///////////////////////////////////////////////////////////
// Function: f_LwM2M_step_setFirmwareUpdateResult
//
// Purpose:
// The test step will set the firmware update result resource value.
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
//
// Related Constants:
// - <c_LwM2M_stepIdx_setFirmwareUpdateResult>
// - <c_LwM2M_stepName_setFirmwareUpdateReslut>
///////////////////////////////////////////////////////////
function f_LwM2M_step_setFirmwareUpdateResult(in EPTF_LGenBase_TestStepArgs pl_ptr)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
var integer v_res := -1;
if (f_EPTF_LwM2M_getIntValue(pl_ptr.refContext.fRefArgs, 0, v_res) and v_LwM2M_ctx.deviceIdx >= 0){
var LwM2M_ResourceValue vl_res;
vl_res.intValue := v_res;
f_LwM2M_ObjectDB_setResourceValue(v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects, 5, 0, 5, vl_res);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_setStepCtx
//
// Purpose:
// This sets the instance pointers of <LwM2M_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 - <LwM2M_StepCtx> - step context with pointers to the related instances
//
// Related Types:
// - <LwM2M_EntityCtx>
// - <LwM2M_StepCtx>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_setStepCtx(in EPTF_LGenBase_TestStepArgs pl_ptr, inout LwM2M_StepCtx p_ctx)
runs on EPTF_LwM2M_LGen_CT
{
p_ctx.eIdx := pl_ptr.eIdx;
p_ctx.fsmIdx := pl_ptr.refContext.fCtxIdx;
p_ctx.eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(pl_ptr.eIdx, v_LwM2M_bIdx, 0);
p_ctx.deviceIdx := v_LwM2M_EntityCtxDB.data[v_LwM2M_ctx.eCtxIdx].currentDevice;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_setCtx
//
// Purpose:
// This sets the instance pointers of <LwM2M_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:
// *inout* p_ctx - <LwM2M_StepCtx> - step context with pointers to the related instances
//
// Related Types:
// - <LwM2M_EntityCtx>
// - <LwM2M_StepCtx>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_setCtx(in integer p_eIdx, in integer p_fsmIdx, inout LwM2M_StepCtx p_ctx)
runs on EPTF_LwM2M_LGen_CT
{
p_ctx.eIdx := p_eIdx;
p_ctx.fsmIdx := p_fsmIdx;
p_ctx.eCtxIdx := f_EPTF_LGenBase_getBehaviorCtxItem(p_eIdx, v_LwM2M_bIdx, 0);
p_ctx.deviceIdx := v_LwM2M_EntityCtxDB.data[v_LwM2M_ctx.eCtxIdx].currentDevice;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_hasDevice
//
// Purpose:
// Checks if the <LwM2M_EntityCtx> instance of the actual entity has an associated device or not
//
// Parameters:
// p_ctx - *in* <LwM2M_StepCtx> - pointer related to the actual entity
//
// Returns:
// *boolean* - TRUE if the <LwM2M_EntityCtx> has an associated device, FALSE otherwise
//
// Related Types:
// <LwM2M_EntityCtx>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_hasDevice(in LwM2M_StepCtx p_ctx)
return boolean
{
return p_ctx.deviceIdx >= 0;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_stack_fromApp
//
// Purpose:
// This is the main entry point for the LwM2M stack realization of the <EPTF_LwM2M_LGen_CT>
// component that handles messages received from the application layer (e.g. FSMs)
//
// Parameters:
// p_msg - *inout* <EPTF_LwM2M_PDU> - message that enters into the stack (will be modified by the stack)
// p_ctx - *in* <LwM2M_StepCtx> - pointers for the instances related to a particular simulated entity
//
// Related Types:
// <EPTF_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_stack_fromApp(inout EPTF_LwM2M_PDU p_pdu, in LwM2M_StepCtx p_ctx)
runs on EPTF_LwM2M_LGen_CT
{
if (p_ctx.deviceIdx >= 0)
{
// State: NOT_REGISTERED
if (v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].state == NOT_REGISTERED)
{
// Register available objects
if (ischosen(p_pdu.pdu.Register) and
v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].objects.id != -1) {
f_LwM2M_ObjectDB_getObjectPaths(v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].objects, p_pdu.pdu.Register.objectsAndObjectInstances);
}
}
// State: REGISTERED
else if (v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].state == REGISTERED)
{
// Include registered location in the outgoing message
if (sizeof(v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].registeredLocation) > 0) {
if (ischosen(p_pdu.pdu.Update)) {
p_pdu.pdu.Update.location := v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].registeredLocation;
}
else if (ischosen(p_pdu.pdu.Deregister)) {
p_pdu.pdu.Deregister.location := v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].registeredLocation;
v_LwM2M_DeviceDB.data[p_ctx.deviceIdx].state := NOT_REGISTERED;
}
}
}
}
f_EPTF_LwM2M_updateMessageStatistics(v_LwM2M_stats.outgoing, p_pdu);
vf_EPTF_LwM2M_Transport_send.apply(p_pdu);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_stack_fromEnv
//
// Purpose:
// This is the main entry point for the LwM2M stack realization of the <EPTF_LwM2M_LGen_CT>
// component that handles messages received from the environment layer (e.g. transport layer)
//
// Parameters:
// p_msg - *inout* <EPTF_LwM2M_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_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_stack_fromEnv(in EPTF_LwM2M_PDU p_pdu)
runs on EPTF_LwM2M_LGen_CT
{
f_EPTF_LwM2M_setCtx(p_pdu.eIdx, p_pdu.fsmIdx, v_LwM2M_ctx);
if (v_LwM2M_ctx.deviceIdx >= 0)
{
// State: NOT_REGISTERED
if (v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].state == NOT_REGISTERED)
{
// Save registered location
if (ischosen(p_pdu.pdu.Response) and p_pdu.pdu.Response.code == 201) {
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].registeredLocation := p_pdu.pdu.Response.location;
v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].state := REGISTERED;
}
}
}
f_EPTF_LwM2M_dispatchEventsForPDU(p_pdu.pdu, p_pdu.eIdx, p_pdu.fsmIdx, {});
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_dispatchEventsForPDU
//
// Purpose:
// Dispatches events to an entity/fsm based on the LWM2M PDU givenas a parameter
//
// Parameters:
// pl_pdu - *in* <LWM2M_PDU> - the LWM2M PDU
// 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_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_dispatchEventsForPDU(in LWM2M_PDU pl_pdu, in integer pl_eIdx, in integer pl_fsmCtx, in EPTF_IntegerList pl_reportedArgs)
runs on EPTF_LwM2M_LGen_CT
{
var integer vl_eventIdx := f_EPTF_LwM2M_PduToEventIdx(pl_pdu);
if (vl_eventIdx == -1) {
f_EPTF_LwM2M_Logging_ERROR(log2str(%definitionId," Couldn't find eventIdx for PDU: ", pl_pdu));
return;
}
f_EPTF_LwM2M_dispatchEvent(vl_eventIdx, pl_eIdx, pl_fsmCtx, {});
if (100 <= vl_eventIdx and vl_eventIdx <= 199)
{
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_1xx, pl_eIdx, pl_fsmCtx, {});
}
else if (200 <= vl_eventIdx and vl_eventIdx <= 299)
{
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_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_LwM2M_dispatchEvent(c_LwM2M_eventIdx_3xx, pl_eIdx, pl_fsmCtx, {});
}
else if (400 <= vl_eventIdx and vl_eventIdx <= 499)
{
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_4xx, pl_eIdx, pl_fsmCtx, {});
}
else if (500 <= vl_eventIdx and vl_eventIdx <= 599)
{
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_4xx, pl_eIdx, pl_fsmCtx, {});
}
f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_3xxto6xx, pl_eIdx, pl_fsmCtx, {});
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_sendNotificationForResource
//
// Purpose:
// The function sends a LwM2M NOTIFICATION for a resource owned by the entity addressed by the *pl_ptr* parameter
//
// Parameters:
// pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - test step args
// v_res - *in* <LwM2M_Resource> - resource for notification
//
// Related Types:
// - <LwM2M_Device>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_sendNotificationForResource(in EPTF_LGenBase_TestStepArgs pl_ptr, in LwM2M_Resource v_res)
runs on EPTF_LwM2M_LGen_CT
{
if (v_res.observed)
{
//v_res.objId := -1; v_res.objInstId := -1; v_res.id := -1;
v_LwM2M_msgToSend.pdu := c_LWM2M_Notification_init;
v_LwM2M_msgToSend.pdu.Notification.path := { v_res.objId, v_res.objInstId, v_res.id };
v_LwM2M_msgToSend.pdu.Notification.code := 205;
v_LwM2M_msgToSend.pdu.Notification.contentFormat := 1543; // JSON format
v_LwM2M_msgToSend.pdu.Notification.resources := { v_res }
f_LwM2M_step_send(pl_ptr);
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_PduToEventIdx
//
// Purpose:
// Maps a <LWM2M_PDU> to an event id (integer number) that represents the PDU's type
//
// Parameters:
// p_code - *in* <LWM2M_PDU> - the LwM2M PDU
//
// Returns:
// *integer* - the returned id
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_PduToEventIdx(in LWM2M_PDU p_pdu)
return integer
{
if (ischosen(p_pdu.Register)) { return c_LwM2M_eventIdx_Register; }
else if (ischosen(p_pdu.Update)) { return c_LwM2M_eventIdx_Update; }
else if (ischosen(p_pdu.Deregister)) { return c_LwM2M_eventIdx_Deregister; }
else if (ischosen(p_pdu.Read_)) { return c_LwM2M_eventIdx_Read; }
else if (ischosen(p_pdu.Write)) { return c_LwM2M_eventIdx_Write; }
else if (ischosen(p_pdu.Execute)) { return c_LwM2M_eventIdx_Execute; }
else if (ischosen(p_pdu.Create)) { return c_LwM2M_eventIdx_Create; }
else if (ischosen(p_pdu.Delete)) { return c_LwM2M_eventIdx_Delete; }
else if (ischosen(p_pdu.BS_Delete)) { return c_LwM2M_eventIdx_BS_Delete; }
else if (ischosen(p_pdu.BS_Request_Finish)) { return c_LwM2M_eventIdx_BS_Finish; }
else if (ischosen(p_pdu.Response)) { return p_pdu.Response.code; }
else {
return -1;
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_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_LwM2M_LGen_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_dispatchEvent(in integer pl_eventIdx, in integer pl_eIdx, in integer pl_fsmCtx, in EPTF_IntegerList pl_reportedArgs)
runs on EPTF_LwM2M_LGen_CT
{
if (pl_eIdx < 0)
{
f_EPTF_LGenBase_postEvent(
{
{
v_LwM2M_bIdx,
pl_eventIdx,
omit,
omit
},
pl_reportedArgs
});
}
else
{
if (pl_fsmCtx < 0)
{
f_EPTF_LGenBase_postEvent(
{
{
v_LwM2M_bIdx,
pl_eventIdx,
{
pl_eIdx,
omit
}, omit
},
pl_reportedArgs
});
}
else
{
f_EPTF_LGenBase_postEvent(
{
{
v_LwM2M_bIdx,
pl_eventIdx,
{
pl_eIdx,
pl_fsmCtx
}, omit
},
pl_reportedArgs
});
}
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_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_LwM2M_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_LwM2M_updateMessageStatistics(inout EPTF_LwM2M_Message_Statistics p_stats, in EPTF_LwM2M_PDU p_pdu)
{
if (ischosen(p_pdu.pdu.Register)) { p_stats.noRegister := p_stats.noRegister + 1 }
else if (ischosen(p_pdu.pdu.Update)) { p_stats.noUpdate := p_stats.noUpdate + 1 }
else if (ischosen(p_pdu.pdu.Deregister)) { p_stats.noDeregister := p_stats.noDeregister + 1 }
else if (ischosen(p_pdu.pdu.Response))
{
if (p_pdu.pdu.Response.code < 300) { p_stats.noPosResp := p_stats.noPosResp + 1 }
else { p_stats.noNegResp := p_stats.noNegResp + 1 }
}
else if (ischosen(p_pdu.pdu.Notification)) { p_stats.noNotification := p_stats.noNotification + 1 }
else if (ischosen(p_pdu.pdu.Read_)) { p_stats.noRead := p_stats.noRead + 1 }
else if (ischosen(p_pdu.pdu.Write)) { p_stats.noWrite := p_stats.noWrite + 1 }
else if (ischosen(p_pdu.pdu.Execute)) { p_stats.noExecute := p_stats.noExecute + 1 }
else if (ischosen(p_pdu.pdu.Create)) { p_stats.noCreate := p_stats.noCreate + 1 }
else if (ischosen(p_pdu.pdu.Delete)) { p_stats.noDelete := p_stats.noDelete + 1 }
}
}