Initial code contribution
diff --git a/EPTF_Applib_LWM2M_CNL113859.tpd b/EPTF_Applib_LWM2M_CNL113859.tpd
new file mode 100644
index 0000000..960b569
--- /dev/null
+++ b/EPTF_Applib_LWM2M_CNL113859.tpd
@@ -0,0 +1,47 @@
+<!--
+Copyright (c) 2000-2017 Ericsson Telecom AB
+
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+
+ File: EPTF_Applib_LWM2M_CNL113859.tpd
+ Description: tpd project file
+ Rev: R1A
+ Prodnr: CNL 113 859
+ Updated: 2017-09-01
+ Contact: http://ttcn.ericsson.se
+
+-->
+<TITAN_Project_File_Information version="1.0">
+<ProjectName>EPTF_Applib_LWM2M_CNL113859</ProjectName>
+<Files>
+ <FileResource projectRelativePath="EPTF_LwM2M_LGen_Definitions.ttcn" relativeURI="src/EPTF_LwM2M_LGen_Definitions.ttcn"/>
+ <FileResource projectRelativePath="EPTF_LwM2M_LGen_Functions.ttcn" relativeURI="src/EPTF_LwM2M_LGen_Functions.ttcn"/>
+ <FileResource projectRelativePath="EPTF_LwM2M_Object_Functions.ttcn" relativeURI="src/EPTF_LwM2M_Object_Functions.ttcn"/>
+ <FileResource projectRelativePath="EPTF_LwM2M_CoapApplibTransport_Definitions.ttcn" relativeURI="src/EPTF_LwM2M_CoapApplibTransport_Definitions.ttcn"/>
+ <FileResource projectRelativePath="EPTF_LwM2M_CoapApplibTransport_Functions.ttcn" relativeURI="src/EPTF_LwM2M_CoapApplibTransport_Functions.ttcn"/>
+ <FileResource projectRelativePath="EPTF_LwM2M_Object_Definitions.ttcn" relativeURI="src/EPTF_LwM2M_Object_Definitions.ttcn"/>
+ <FileResource projectRelativePath="EPTF_LwM2M_Transport_Definitions.ttcn" relativeURI="src/EPTF_LwM2M_Transport_Definitions.ttcn"/>
+ <FileResource projectRelativePath="LightweightM2M_Types.ttcn" relativeURI="src/LightweightM2M_Types.ttcn"/>
+ <FileResource projectRelativePath="LightweightM2M_CoAP_Binding.ttcn" relativeURI="src/LightweightM2M_CoAP_Binding.ttcn"/>
+ </Files>
+ <ActiveConfiguration>Default</ActiveConfiguration>
+ <Configurations>
+ <Configuration name="Default">
+ <ProjectProperties>
+ <MakefileSettings>
+ <generateInternalMakefile>true</generateInternalMakefile>
+ <GNUMake>true</GNUMake>
+ <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+ <targetExecutable>bin/EPTF_Applib_LWM2M_CNL113859</targetExecutable>
+ <buildLevel>Level 3 - Creating object files with dependency update</buildLevel>
+ </MakefileSettings>
+ <LocalBuildSettings>
+ <workingDirectory>bin</workingDirectory>
+ </LocalBuildSettings>
+ </ProjectProperties>
+ </Configuration>
+ </Configurations>
+</TITAN_Project_File_Information>
diff --git a/src/EPTF_LwM2M_CoapApplibTransport_Definitions.ttcn b/src/EPTF_LwM2M_CoapApplibTransport_Definitions.ttcn
new file mode 100644
index 0000000..36ccf68
--- /dev/null
+++ b/src/EPTF_LwM2M_CoapApplibTransport_Definitions.ttcn
@@ -0,0 +1,30 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_CoapApplibTransport_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_LwM2M_CoapApplibTransport_Definitions
+{
+ import from EPTF_LwM2M_Transport_Definitions all;
+ import from EPTF_COAP_LGen_Definitions all;
+ import from EPTF_CLL_Base_Definitions all;
+
+ modulepar boolean tsp_EPTF_LwM2M_CoapApplibTransport_debug := false;
+
+ type component EPTF_LwM2M_CoapApplibTransport_CT
+ extends EPTF_LwM2M_Transport_Provider_CT, EPTF_Base_CT, EPTF_COAP_LGen_CT
+ {
+ var boolean v_EPTF_LwM2M_CoapApplibTransport_initialized := false;
+ }
+}
diff --git a/src/EPTF_LwM2M_CoapApplibTransport_Functions.ttcn b/src/EPTF_LwM2M_CoapApplibTransport_Functions.ttcn
new file mode 100644
index 0000000..0c1d909
--- /dev/null
+++ b/src/EPTF_LwM2M_CoapApplibTransport_Functions.ttcn
@@ -0,0 +1,111 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_CoapApplibTransport_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_LwM2M_CoapApplibTransport_Functions
+{
+ import from EPTF_LwM2M_Transport_Definitions all;
+ import from EPTF_LwM2M_CoapApplibTransport_Definitions all;
+ import from LightweightM2M_CoAP_Binding all;
+ import from EPTF_COAP_Transport_Definitions all;
+ import from EPTF_COAP_LGen_Functions all;
+ import from EPTF_CLL_Base_Functions all;
+ import from EPTF_CLL_LGenBase_Definitions all;
+
+ import from LightweightM2M_CoAP_Binding all;
+
+ modulepar boolean tsp_EPTF_LwM2M_CoapApplibTransport_enabled := true;
+
+ function f_EPTF_LwM2M_CoapApplibTransport_init(in charstring pl_name)
+ runs on EPTF_LwM2M_CoapApplibTransport_CT
+ {
+ if (v_EPTF_LwM2M_CoapApplibTransport_initialized) {return;}
+
+ f_EPTF_COAP_LGen_init(pl_name);
+
+ f_EPTF_Base_registerCleanup(refers(f_EPTF_LwM2M_CoapApplibTransport_cleanup));
+
+ v_EPTF_LwM2M_CoapApplibTransport_initialized := true;
+ }
+
+ function f_EPTF_LwM2M_CoapApplibTransport_cleanup()
+ runs on EPTF_LwM2M_CoapApplibTransport_CT
+ {
+ // Reset DBs, close connections
+ v_EPTF_LwM2M_CoapApplibTransport_initialized := false;
+
+ vf_EPTF_LwM2M_Transport_receiveMessage := null;
+ }
+
+ function f_EPTF_LwM2M_CoapApplibTransport_send(in EPTF_LwM2M_PDU pl_msg)
+ runs on EPTF_LwM2M_CoapApplibTransport_CT
+ {
+ f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " ", pl_msg));
+
+ if (not tsp_EPTF_LwM2M_CoapApplibTransport_enabled) { return }
+
+ var integer vl_eIdx := pl_msg.eIdx;
+ var integer vl_fsmIdx := pl_msg.fsmIdx;
+ var integer vl_newFsmCtxIdx := -1;
+
+ if (not f_EPTF_COAP_isFsmInitialized(vl_eIdx, vl_fsmIdx, vl_newFsmCtxIdx))
+ {
+ 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;
+ }
+
+ if (tsp_EPTF_LwM2M_CoapApplibTransport_debug) { action("lwm2m sending:\n", pl_msg); }
+
+ f_enc_LWM2M_to_COAP(pl_msg.pdu, v_COAP_msgToSend.pdu);
+
+ var EPTF_LGenBase_TestStepArgs l_args := c_EPTF_LGenBase_emptyTestStepArgs;
+
+ l_args.eIdx := pl_msg.eIdx;
+ l_args.refContext.fCtxIdx := pl_msg.fsmIdx;
+
+ if (ischosen(pl_msg.pdu.Response))
+ {
+ f_COAP_step_sendResponse(l_args);
+ }
+ else
+ {
+ f_COAP_step_send(l_args);
+ }
+ }
+
+ function f_EPTF_LwM2M_CoapApplibTransport_messageReceived(in EPTF_COAP_PDU pl_message, in boolean p_duplicate)
+ runs on EPTF_LwM2M_CoapApplibTransport_CT
+ {
+ f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " ", pl_message));
+
+ if (not tsp_EPTF_LwM2M_CoapApplibTransport_enabled) { return }
+
+ if (p_duplicate) { return }
+
+ var EPTF_LwM2M_PDU v_pdu;
+
+ f_dec_COAP_to_LWM2M(v_COAP_msgToProcess.pdu, v_pdu.pdu);
+ v_pdu.eIdx := pl_message.eIdx;
+ v_pdu.fsmIdx := pl_message.fsmIdx;
+
+ if (tsp_EPTF_LwM2M_CoapApplibTransport_debug) { action("lwm2m receiving: ", v_pdu); }
+
+ if (vf_EPTF_LwM2M_Transport_receiveMessage != null)
+ {
+ vf_EPTF_LwM2M_Transport_receiveMessage.apply(v_pdu);
+ }
+ }
+}
diff --git a/src/EPTF_LwM2M_LGen_Definitions.ttcn b/src/EPTF_LwM2M_LGen_Definitions.ttcn
new file mode 100644
index 0000000..e5c4d8a
--- /dev/null
+++ b/src/EPTF_LwM2M_LGen_Definitions.ttcn
@@ -0,0 +1,226 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_LGen_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_LwM2M_LGen_Definitions
+{
+ import from EPTF_CLL_LGenBase_Definitions all;
+ import from EPTF_CLL_Logging_Definitions all;
+ import from EPTF_CLL_FBQ_Definitions all;
+ import from EPTF_LwM2M_Object_Definitions all;
+ import from EPTF_LwM2M_Transport_Definitions all;
+ import from LightweightM2M_Types all;
+
+ modulepar boolean tsp_EPTF_LwM2M_LGen_debug := false;
+ modulepar boolean tsp_EPTF_LwM2M_LGen_debugVerbose := false;
+ modulepar integer tsp_EPTF_LwM2M_LGen_maxBindableCtx := -1;
+
+ modulepar LwM2M_Template_List tsp_EPTF_LwM2M_LGen_templates := {};
+
+ const integer c_LwM2M_LGen_Logging_WARNING := 0;
+ const integer c_LwM2M_LGen_Logging_DEBUG := 1;
+ const integer c_LwM2M_LGen_Logging_DEBUGV := 2;
+ const integer c_LwM2M_LGen_Logging_ERROR := 3;
+
+ const charstring c_LwM2M_behaviorType := "LWM2M Behavior";
+
+ type record LwM2M_EntityCtx
+ {
+ integer eIdx,
+ integer currentDevice
+ }
+
+ const LwM2M_EntityCtx c_LwM2M_EntityCtx_init :=
+ {
+ eIdx := -1,
+ currentDevice := -1
+ }
+
+ type record of LwM2M_EntityCtx LwM2M_EntityCtx_List;
+
+ type record LwM2M_EntityCtx_DB
+ {
+ EPTF_FreeBusyQueue queue,
+ LwM2M_EntityCtx_List data,
+ integer hashRef
+ }
+
+ type record LwM2M_Device
+ {
+ Location registeredLocation,
+ LwM2M_ObjectDB objects,
+ LwM2M_Device_State state
+ }
+
+ type enumerated LwM2M_Device_State
+ {
+ NOT_REGISTERED,
+ REGISTERED
+ }
+
+ const LwM2M_Device c_LwM2M_Device_init :=
+ {
+ registeredLocation := {},
+ objects := c_LwM2M_ObjectDB_init,
+ state := NOT_REGISTERED
+ }
+
+ type record of LwM2M_Device LwM2M_Device_List;
+
+ type record LwM2M_Device_DB
+ {
+ EPTF_FreeBusyQueue queue,
+ LwM2M_Device_List data,
+ integer hashRef
+ }
+
+ type record LwM2M_Template
+ {
+ charstring id,
+ LWM2M_PDU msg
+ }
+
+ type record of LwM2M_Template LwM2M_Template_List;
+
+ type record LwM2M_Template_DB
+ {
+ LwM2M_Template_List data,
+ integer hashRef
+ }
+
+
+ type record LwM2M_StepCtx
+ {
+ integer eIdx,
+ integer fsmIdx,
+ integer eCtxIdx,
+ integer deviceIdx
+ }
+
+ const LwM2M_StepCtx c_LwM2M_StepCtx_empty :=
+ {
+ eIdx := -1,
+ fsmIdx := -1,
+ eCtxIdx := -1,
+ deviceIdx := -1
+ }
+
+ type component EPTF_LwM2M_LGen_CT extends EPTF_LwM2M_Transport_User_CT, EPTF_LGenBase_CT, EPTF_Logging_CT
+ {
+ var boolean v_LwM2M_initialized := false;
+
+ var integer v_LwM2M_bIdx;
+
+ var integer v_LwM2M_loggingMaskId := -1;
+
+ var LwM2M_ObjectSpecificationDB v_LwM2M_ObjectSpecificationDB;
+ var LwM2M_EntityCtx_DB v_LwM2M_EntityCtxDB;
+ var LwM2M_Device_DB v_LwM2M_DeviceDB;
+ var LwM2M_Template_DB v_LwM2M_templateDB := {};
+
+ var LwM2M_StepCtx v_LwM2M_ctx := c_LwM2M_StepCtx_empty;
+
+ var EPTF_LwM2M_PDU v_LwM2M_msgToProcess;
+ var EPTF_LwM2M_PDU v_LwM2M_msgToSend;
+ }
+
+ // FSM AppData
+
+ const integer c_LwM2M_AppData_deviceIdx := 0;
+
+ // Events
+
+ const integer c_LwM2M_eventIdx_Register := 0;
+ const charstring c_LwM2M_eventName_Register := "LWM2M req: Register";
+
+ const integer c_LwM2M_eventIdx_Update := 1;
+ const charstring c_LwM2M_eventName_Update := "LWM2M req: Update";
+
+ const integer c_LwM2M_eventIdx_Deregister := 2;
+ const charstring c_LwM2M_eventName_Deregister := "LWM2M req: Deregister";
+
+ const integer c_LwM2M_eventIdx_Read := 3;
+ const charstring c_LwM2M_eventName_Read := "LWM2M req: Read";
+
+ const integer c_LwM2M_eventIdx_Write := 4;
+ const charstring c_LwM2M_eventName_Write := "LWM2M req: Write";
+
+ const integer c_LwM2M_eventIdx_Execute := 5;
+ const charstring c_LwM2M_eventName_Execute := "LWM2M req: Execute";
+
+ const integer c_LwM2M_eventIdx_Create := 6;
+ const charstring c_LwM2M_eventName_Create := "LWM2M req: Create";
+
+ const integer c_LwM2M_eventIdx_Delete := 7;
+ const charstring c_LwM2M_eventName_Delete := "LWM2M req: Delete";
+
+ const integer c_LwM2M_eventIdx_1xx := 700;
+ const charstring c_LwM2M_eventName_1xx := "LWM2M rsp: 1xx";
+
+ const integer c_LwM2M_eventIdx_2xx := 701;
+ const charstring c_LwM2M_eventName_2xx := "LWM2M rsp: 2xx";
+
+ const integer c_LwM2M_eventIdx_3xx := 702;
+ const charstring c_LwM2M_eventName_3xx := "LWM2M rsp: 3xx";
+
+ const integer c_LwM2M_eventIdx_4xx := 703;
+ const charstring c_LwM2M_eventName_4xx := "LWM2M rsp: 4xx";
+
+ const integer c_LwM2M_eventIdx_5xx := 704;
+ const charstring c_LwM2M_eventName_5xx := "LWM2M rsp: 5xx";
+
+ const integer c_LwM2M_eventIdx_6xx := 705;
+ const charstring c_LwM2M_eventName_6xx := "LWM2M rsp: 6xx";
+
+ const integer c_LwM2M_eventIdx_3xxto6xx := 706;
+ const charstring c_LwM2M_eventName_3xxto6xx := "LWM2M rsp: 3xxto6xx";
+
+ // Steps
+
+ const integer c_LwM2M_stepIdx_loadTemplate_byIntIdx := 0;
+ const charstring c_LwM2M_stepName_loadTemplate_byIntIdx := "LWM2M Applib: loadTemplate_byIntIdx";
+
+ const integer c_LwM2M_stepIdx_send := 1;
+ const charstring c_LwM2M_stepName_send := "LWM2M Applib: send";
+
+ const integer c_LwM2M_stepIdx_createDevice := 2;
+ const charstring c_LwM2M_stepName_createDevice := "LWM2M Applib: createDevice";
+
+ const integer c_LwM2M_stepIdx_cleanupDevice := 3;
+ const charstring c_LwM2M_stepName_cleanupDevice := "LWM2M Applib: cleanupDevice";
+
+ const integer c_LwM2M_stepIdx_logDevice := 4;
+ const charstring c_LwM2M_stepName_logDevice := "LWM2M Applib: logDevice";
+
+ const integer c_LwM2M_stepIdx_createObject := 5;
+ const charstring c_LwM2M_stepName_createObject := "LWM2M Applib: createObject";
+
+ const integer c_LwM2M_stepIdx_createObjectInstance := 6;
+ const charstring c_LwM2M_stepName_createObjectInstance := "LWM2M Applib: createObjectInstance";
+
+ const integer c_LwM2M_stepIdx_handleReadRequest := 7;
+ const charstring c_LwM2M_stepName_handleReadRequest := "LWM2M Applib: handleReadRequest";
+
+ const integer c_LwM2M_stepIdx_handleWriteRequest := 8;
+ const charstring c_LwM2M_stepName_handleWriteRequest := "LWM2M Applib: handleWriteRequest";
+
+ const integer c_LwM2M_stepIdx_handleExecuteRequest := 9;
+ const charstring c_LwM2M_stepName_handleExecuteRequest := "LWM2M Applib: handleExecuteRequest";
+
+ const integer c_LwM2M_stepIdx_loadTemplate_byStringId := 10;
+ const charstring c_LwM2M_stepName_loadTemplate_byStringId := "LWM2M Applib: loadTemplate_byStringId";
+
+ const integer c_LwM2M_stepParam_createObjectInstance_DoNotAddResources := 0;
+}
diff --git a/src/EPTF_LwM2M_LGen_Functions.ttcn b/src/EPTF_LwM2M_LGen_Functions.ttcn
new file mode 100644
index 0000000..399b332
--- /dev/null
+++ b/src/EPTF_LwM2M_LGen_Functions.ttcn
@@ -0,0 +1,987 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_LGen_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+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(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)
+ );
+
+ v_LwM2M_loggingMaskId :=
+ f_EPTF_Logging_registerComponentMasks(
+ "LwM2M_Logging",
+ {"WARNING", "DEBUG", "3xx", "4xx", "5xx", "6xx", "3xxTo6xx"},
+ EPTF_Logging_CLL);
+
+ 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);
+
+ f_EPTF_Base_registerCleanup(refers(f_LwM2M_cleanUp));
+
+ v_LwM2M_initialized := true;
+ }
+
+ 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_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()
+ 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(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(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(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()
+ 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()
+ 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()
+ 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(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(in integer p_idx)
+ runs on EPTF_LwM2M_LGen_CT
+ {
+ 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(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(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()
+ 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()
+ 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(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(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(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()
+ 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(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(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(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(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(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_stack_fromEnv(v_LwM2M_msgToProcess);
+ }
+
+ 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)
+ ){
+ f_EPTF_LGenBase_log();
+ log("error"); mtc.stop
+ }
+
+ for (var integer i:=8; 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)
+ ){
+ f_EPTF_LGenBase_log();
+ log("error"); mtc.stop
+ }
+ }
+
+ 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)})
+ )
+ {
+ f_EPTF_LGenBase_log();
+ log("EPTF_LwM2M_LGen declaration error"); mtc.stop
+ }
+ }
+
+ 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(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(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);
+
+ //action(v_LwM2M_msgToSend);
+
+ f_EPTF_SchedulerComp_refreshSnapshotTime();
+ }
+
+ 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(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_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(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) { action("device: \n", v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx]); }
+ }
+ }
+
+ 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(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(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)) {
+ v_res.observe := v_LwM2M_msgToProcess.pdu.Read_.observe;
+ f_LwM2M_ObjectDB_setResource(
+ 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
+ );
+ }
+ }
+ 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 :=
+ {
+ Response := {
+ location := {},
+ code := 205,
+ contentFormat := 1543, // JSON format
+ observe := omit,
+ resources := v_resources
+ }
+ }
+ }
+ else
+ {
+ v_LwM2M_msgToSend.pdu :=
+ {
+ Response := {
+ location := {},
+ code := 404,
+ contentFormat := omit,
+ observe := omit,
+ resources := {}
+ }
+ }
+ }
+ if (ispresent(v_LwM2M_msgToProcess.pdu.Read_.observe)) {
+ v_LwM2M_msgToSend.pdu.Response.observe := v_LwM2M_msgToProcess.pdu.Read_.observe;
+ }
+
+ 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(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;
+
+ 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
+ )
+ {
+ 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)
+ {
+ // 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; }
+
+ if (vl_typeMatched)
+ {
+ 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
+ );
+ }
+ }
+ }
+
+ v_LwM2M_msgToSend.eIdx := v_LwM2M_ctx.eIdx;
+ v_LwM2M_msgToSend.fsmIdx := v_LwM2M_ctx.fsmIdx;
+ if (vl_found and vl_typeMatched)
+ {
+ v_LwM2M_msgToSend.pdu :=
+ {
+ Response := {
+ location := {},
+ code := 204,
+ contentFormat := omit, // JSON format
+ resources := {}
+ }
+ }
+ }
+ else
+ {
+ v_LwM2M_msgToSend.pdu :=
+ {
+ Response := {
+ location := {},
+ code := 404,
+ contentFormat := omit,
+ resources := {}
+ }
+ }
+ }
+ 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(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 :=
+ {
+ Response := {
+ location := {},
+ code := 204,
+ contentFormat := omit,
+ resources := {}
+ }
+ }
+ 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_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(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(in LwM2M_StepCtx p_ctx)
+ return boolean
+ {
+ return p_ctx.deviceIdx >= 0;
+ }
+
+ 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;
+ }
+ }
+ }
+ }
+
+ vf_EPTF_LwM2M_Transport_send.apply(p_pdu);
+ }
+
+ 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(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(in EPTF_LGenBase_TestStepArgs pl_ptr, LwM2M_Resource v_res)
+ runs on EPTF_LwM2M_LGen_CT
+ {
+ if (ispresent(v_res.observe)) {
+ //v_res.objId := -1; v_res.objInstId := -1; v_res.id := -1;
+
+ v_LwM2M_msgToSend.pdu :=
+ {
+ Response := {
+ location := {},
+ code := 205,
+ contentFormat := 1543, // JSON format
+ observe := v_res.observe,
+ resources := { v_res }
+ }
+ }
+ f_LwM2M_step_send(pl_ptr);
+ }
+ }
+
+ function f_EPTF_LwM2M_incObserveForResource(inout LwM2M_Resource v_res) {
+ if (ispresent(v_res.observe)) { v_res.observe.observe := v_res.observe.observe + 1 }
+ }
+
+ 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.Response)) { return p_pdu.Response.code; }
+ else {
+ return -1;
+ }
+ }
+
+ 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(
+ 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;
+ }
+
+}
diff --git a/src/EPTF_LwM2M_Object_Definitions.ttcn b/src/EPTF_LwM2M_Object_Definitions.ttcn
new file mode 100644
index 0000000..3deafa8
--- /dev/null
+++ b/src/EPTF_LwM2M_Object_Definitions.ttcn
@@ -0,0 +1,797 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_Object_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_LwM2M_Object_Definitions {
+
+ import from LightweightM2M_Types all;
+
+ type record LwM2M_ObjectDB
+ {
+ integer id,
+ LwM2M_Object_List objs,
+ LwM2M_Resource_List resources,
+ integer objHashRef,
+ integer resHashRef
+ }
+
+ const LwM2M_ObjectDB c_LwM2M_ObjectDB_init :=
+ {
+ id := -1,
+ objs := {},
+ resources := {},
+ objHashRef := -1,
+ resHashRef := -1
+ }
+
+ type record of LwM2M_Object LwM2M_Object_List;
+
+ type record LwM2M_Object
+ {
+ integer id,
+ LwM2M_ObjectInstance_List instances
+ }
+
+ const LwM2M_Object c_LwM2M_Object_init :=
+ {
+ id := -1,
+ instances := {}
+ }
+
+ type record LwM2M_ObjectInstance
+ {
+ integer id,
+ integer objId,
+ LwM2M_ResourceIdx_List resources
+ }
+
+ type record of integer LwM2M_ResourceIdx_List;
+
+ const LwM2M_ObjectInstance c_LwM2M_ObjectInstance_init :=
+ {
+ id := -1,
+ objId := -1,
+ resources := {}
+ }
+
+ type record of LwM2M_ObjectInstance LwM2M_ObjectInstance_List;
+
+ type record LwM2M_ObjectSpecificationDB
+ {
+ integer id,
+ LwM2M_ObjectSpecification_List specs,
+ integer hashRef // obj id to idx in specs
+ }
+
+ const LwM2M_ObjectSpecificationDB c_LwM2M_ObjectSpecificationDB_init :=
+ {
+ id := -1,
+ specs := {},
+ hashRef := -1
+ }
+
+ type record LwM2M_ObjectSpecification
+ {
+ charstring name,
+ integer id,
+ LwM2M_InstanceTypeEnum instancetype,
+ boolean mandatory,
+ charstring description,
+ LwM2M_ResourceSpecification_List resourcedefs
+ }
+
+ type record of LwM2M_ObjectSpecification LwM2M_ObjectSpecification_List;
+
+ type record of LwM2M_ResourceSpecification LwM2M_ResourceSpecification_List;
+
+ type record LwM2M_ResourceSpecification
+ {
+ integer id,
+ charstring name,
+ LwM2M_OperationTypeEnum operations,
+ LwM2M_InstanceTypeEnum instancetype,
+ boolean mandatory,
+ LwM2M_TypeEnum type_,
+ charstring range,
+ charstring units,
+ charstring description
+ }
+
+ type enumerated LwM2M_OperationTypeEnum
+ {
+ NONE,
+ R,
+ RW,
+ RE,
+ E,
+ RWE
+ }
+
+ type enumerated LwM2M_InstanceTypeEnum
+ {
+ SINGLE,
+ MULTIPLE
+ }
+
+ type enumerated LwM2M_TypeEnum
+ {
+ STRING,
+ FLOAT,
+ BOOLEAN,
+ INTEGER,
+ OPAQUE,
+ TIME
+ }
+
+ const integer c_LwM2M_Security_obj_id := 0;
+ const integer c_LwM2M_Server_obj_id := 1;
+ const integer c_LwM2M_Device_obj_id := 3;
+
+ const LwM2M_ObjectSpecification c_LwM2M_Security_spec :=
+ {
+ name := "LWM2M Security",
+ id := c_LwM2M_Security_obj_id,
+ instancetype := MULTIPLE,
+ mandatory := true,
+ description := "",
+ resourcedefs :=
+ {
+ {
+ id := 0,
+ name := "LWM2M Server URI",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := STRING,
+ range := "0-255 bytes",
+ units := "",
+ description := ""
+ },
+ {
+ id := 1,
+ name := "Bootstrap Server",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := BOOLEAN,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 2,
+ name := "Security Mode",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := INTEGER,
+ range := "0-3",
+ units := "",
+ description := ""
+ },
+ {
+ id := 3,
+ name := "Public Key or Identity",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := OPAQUE,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 4,
+ name := "Server Public Key or Identity",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := OPAQUE,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 5,
+ name := "Secret Key",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := OPAQUE,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 6,
+ name := "SMS Security Mode",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := INTEGER,
+ range := "0-255",
+ units := "",
+ description := ""
+ },
+ {
+ id := 7,
+ name := "SMS Binding Key Parameters",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := OPAQUE,
+ range := "6 bytes",
+ units := "",
+ description := ""
+ },
+ {
+ id := 8,
+ name := "SMS Binding Secret Keys",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := OPAQUE,
+ range := "32-48 bytes",
+ units := "",
+ description := ""
+ },
+ {
+ id := 9,
+ name := "LWM2M Server SMS Number",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 10,
+ name := "Short Server ID",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "1-65535",
+ units := "",
+ description := ""
+ },
+ {
+ id := 11,
+ name := "Client Hold Off Time",
+ operations := NONE,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := INTEGER,
+ range := "",
+ units := "s",
+ description := ""
+ }
+ }
+ }
+
+ const LwM2M_ObjectSpecification c_LwM2M_Server_spec :=
+ {
+ name := "LWM2M Server",
+ id := c_LwM2M_Server_obj_id,
+ instancetype := MULTIPLE,
+ mandatory := true,
+ description := "",
+ resourcedefs :=
+ {
+ {
+ id := 0,
+ name := "Short Server ID",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := INTEGER,
+ range := "1-65535",
+ units := "",
+ description := ""
+ },
+ {
+ id := 1,
+ name := "Lifetime",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := INTEGER,
+ range := "",
+ units := "s",
+ description := ""
+ },
+ {
+ id := 2,
+ name := "Default Minimum Period",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "",
+ units := "s",
+ description := ""
+ },
+ {
+ id := 3,
+ name := "Default Maximum Period",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "",
+ units := "s",
+ description := ""
+ },
+ {
+ id := 4,
+ name := "Disable",
+ operations := E,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 5,
+ name := "Disable Timeout",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "",
+ units := "s",
+ description := ""
+ },
+ {
+ id := 6,
+ name := "Notification Storing When Disabled or Offline",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := BOOLEAN,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 7,
+ name := "Binding",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := STRING,
+ range := "The possible values of Resource are listed in 5.2.1.1",
+ units := "",
+ description := ""
+ },
+ {
+ id := 8,
+ name := "Registration Update Trigger",
+ operations := E,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ }
+ }
+ }
+
+ const integer c_LwM2M_Device_Manufacturer := 0;
+ const integer c_LwM2M_Device_ModelNumber := 1;
+ const integer c_LwM2M_Device_SerialNumberNumber := 2;
+
+ const LwM2M_ObjectSpecification c_LwM2M_Device_spec :=
+ {
+ name := "Device",
+ id := 3,
+ instancetype := SINGLE,
+ mandatory := true,
+ description := "",
+ resourcedefs :=
+ {
+ {
+ id := 0,
+ name := "Manufacturer",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 1,
+ name := "Model Number",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 2,
+ name := "Serial Number",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 3,
+ name := "Firmware Version",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 4,
+ name := "Reboot",
+ operations := E,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 5,
+ name := "Factory Reset",
+ operations := E,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 6,
+ name := "Available Power Sources",
+ operations := R,
+ instancetype := MULTIPLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "0-7",
+ units := "",
+ description := ""
+ },
+ {
+ id := 7,
+ name := "Power Source Voltage",
+ operations := R,
+ instancetype := MULTIPLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "",
+ units := "mV",
+ description := ""
+ },
+ {
+ id := 8,
+ name := "Power Source Current",
+ operations := R,
+ instancetype := MULTIPLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "",
+ units := "mA",
+ description := ""
+ },
+ {
+ id := 9,
+ name := "Battery Level",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "0-100",
+ units := "%",
+ description := ""
+ },
+ {
+ id := 10,
+ name := "Memory Free",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := INTEGER,
+ range := "",
+ units := "KB",
+ description := ""
+ },
+ {
+ id := 11,
+ name := "Error Code",
+ operations := R,
+ instancetype := MULTIPLE,
+ mandatory := true,
+ type_ := INTEGER,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 12,
+ name := "Reset Error Code",
+ operations := E,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 13,
+ name := "Current Time",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := TIME,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 14,
+ name := "UTC Offset",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 15,
+ name := "Timezone",
+ operations := RW,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ },
+ {
+ id := 16,
+ name := "Supported Binding and Modes",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := ""
+ }
+ }
+ }
+
+ const LwM2M_ObjectSpecification c_LwM2M_Location_spec :=
+ {
+
+ name := "Location",
+ id := 6,
+ instancetype := SINGLE,
+ mandatory := false,
+ description := "",
+ resourcedefs :=
+ {
+ {
+ id := 0,
+ name := "Latitude",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := FLOAT,
+ range := "",
+ units := "Deg",
+ description := ""
+ },
+ {
+ id := 1,
+ name := "Longitude",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := FLOAT,
+ range := "",
+ units := "Deg",
+ description := ""
+ },
+ {
+ id := 2,
+ name := "Altitude",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := FLOAT,
+ range := "",
+ units := "m",
+ description := ""
+ },
+ {
+ id := 3,
+ name := "Uncertainty",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := STRING,
+ range := "",
+ units := "m",
+ description := ""
+ },
+ {
+ id := 4,
+ name := "Velocity",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := OPAQUE,
+ range := "",
+ units := "Refers to 3GPP GAD specs",
+ description := ""
+ },
+ {
+ id := 5,
+ name := "Timestamp",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := TIME,
+ range := "0-6",
+ units := "",
+ description := ""
+ }
+ }
+ }
+
+ const LwM2M_ObjectSpecification c_LwM2M_IPSO_Temperature_spec :=
+ {
+
+ name := "IPSO Temperature",
+ id := 3303,
+ instancetype := MULTIPLE,
+ mandatory := false,
+ description := "Description: This IPSO object should be used with a temperature sensor to report a temperature measurement. It also provides resources for minimum/maximum measured values and the minimum/maximum range that can be measured by the temperature sensor. An example measurement unit is degrees Celsius (ucum:Cel). ",
+ resourcedefs :=
+ {
+ {
+ id := 5601,
+ name := "Min Measured Value",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := FLOAT,
+ range := "",
+ units := "Defined by Units resource.",
+ description := "The minimum value measured by the sensor since power ON or reset"
+ },
+ {
+ id := 5602,
+ name := "Max Measured Value",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := FLOAT,
+ range := "",
+ units := "Defined by Units resource.",
+ description := "The maximum value measured by the sensor since power ON or reset"
+ },
+ {
+ id := 5603,
+ name := "Min Range Value",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := FLOAT,
+ range := "",
+ units := "Defined by Units resource.",
+ description := "The minimum value that can be measured by the sensor"
+ },
+ {
+ id := 5604,
+ name := "Max Range Value",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := FLOAT,
+ range := "",
+ units := "Defined by Units resource.",
+ description := "The maximum value that can be measured by the sensor"
+ },
+ {
+ id := 5605,
+ name := "Reset Min and Max Measured Values",
+ operations := E,
+ instancetype := SINGLE,
+ mandatory := false,
+ type_ := OPAQUE,
+ range := "",
+ units := "",
+ description := "Reset the Min and Max Measured Values to Current Value"
+ },
+ {
+ id := 5700,
+ name := "Sensor Value",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := FLOAT,
+ range := "",
+ units := "Defined by Units resource.",
+ description := "Last or Current Measured Value from the Sensor"
+ },
+ {
+ id := 5701,
+ name := "Sensor Units",
+ operations := R,
+ instancetype := SINGLE,
+ mandatory := true,
+ type_ := STRING,
+ range := "",
+ units := "",
+ description := "Measurement Units Definition e.g. Cel for Temperature in Celsius."
+ }
+ }
+ }
+
+ type record LwM2M_DataSamples
+ {
+ charstring name,
+ LwM2M_ResourceValue_List values
+ }
+
+ type record of LwM2M_DataSamples LwM2M_DataSamples_List;
+
+ const LwM2M_DataSamples c_LwM2M_DataSamples_init :=
+ {
+ name := "",
+ values := {}
+ }
+
+ type record LwM2M_DataSamples_DB
+ {
+ charstring name,
+ LwM2M_DataSamples_List data,
+ integer hashRef
+ }
+
+ const LwM2M_DataSamples_DB c_LwM2M_DataSamples_DB_init :=
+ {
+ name := "",
+ data := {},
+ hashRef := -1
+ }
+
+}
diff --git a/src/EPTF_LwM2M_Object_Functions.ttcn b/src/EPTF_LwM2M_Object_Functions.ttcn
new file mode 100644
index 0000000..d28d889
--- /dev/null
+++ b/src/EPTF_LwM2M_Object_Functions.ttcn
@@ -0,0 +1,379 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_Object_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_LwM2M_Object_Functions {
+
+ import from LightweightM2M_Types all;
+ import from EPTF_LwM2M_Object_Definitions all;
+ import from EPTF_CLL_HashMapInt2Int_Functions all;
+ import from EPTF_CLL_HashMapStr2Int_Functions all;
+
+ function f_LwM2M_ObjectSpecificationDB_init(inout LwM2M_ObjectSpecificationDB p_db, in integer p_id)
+ {
+ p_db := c_LwM2M_ObjectSpecificationDB_init;
+ p_db.id := p_id;
+ p_db.hashRef := f_EPTF_int2int_HashMap_New("EPTF_LwM2M_ObjectSpecificationDB_"&int2str(p_id)&"_Hash");
+ }
+
+ function f_LwM2M_ObjectSpecificationDB_cleanUp(inout LwM2M_ObjectSpecificationDB p_db)
+ {
+ f_EPTF_int2int_HashMap_Delete("EPTF_LwM2M_ObjectSpecificationDB_"&int2str(p_db.id)&"_Hash");
+ p_db := c_LwM2M_ObjectSpecificationDB_init;
+ }
+
+ function f_LwM2M_ObjectSpecificationDB_add(inout LwM2M_ObjectSpecificationDB p_db, LwM2M_ObjectSpecification p_spec)
+ return integer
+ {
+ var integer vl_idx := -1;
+ if (not f_EPTF_int2int_HashMap_Find(p_db.hashRef, p_spec.id, vl_idx))
+ {
+ vl_idx := sizeof(p_db.specs);
+ p_db.specs[vl_idx] := p_spec;
+ f_EPTF_int2int_HashMap_Insert(p_db.hashRef, p_spec.id, vl_idx);
+ }
+ return vl_idx;
+ }
+
+ function f_LwM2M_ObjectSpecificationDB_lookUp(in LwM2M_ObjectSpecificationDB p_db, in integer p_objId)
+ return integer
+ {
+ var integer vl_idx := -1;
+ if (f_EPTF_int2int_HashMap_Find(p_db.hashRef, p_objId, vl_idx)) {
+ return vl_idx;
+ }
+ return -1;
+ }
+
+ function f_LwM2M_ObjectSpecificationDB_fillInOmaSpecs(inout LwM2M_ObjectSpecificationDB p_db)
+ {
+ f_LwM2M_ObjectSpecificationDB_add(p_db, c_LwM2M_Security_spec);
+ f_LwM2M_ObjectSpecificationDB_add(p_db, c_LwM2M_Server_spec);
+ f_LwM2M_ObjectSpecificationDB_add(p_db, c_LwM2M_Device_spec);
+ f_LwM2M_ObjectSpecificationDB_add(p_db, c_LwM2M_Location_spec);
+ f_LwM2M_ObjectSpecificationDB_add(p_db, c_LwM2M_IPSO_Temperature_spec);
+ }
+
+ function f_LwM2M_ObjectDB_init(inout LwM2M_ObjectDB p_db, in integer p_id)
+ {
+ p_db := c_LwM2M_ObjectDB_init;
+ p_db.id := p_id;
+ p_db.objHashRef := f_EPTF_int2int_HashMap_New("EPTF_LwM2M_ObjectDB_"&int2str(p_db.id)&"_objHash");
+ p_db.resHashRef := f_EPTF_str2int_HashMap_New("EPTF_LwM2M_ObjectDB_"&int2str(p_db.id)&"_resHash");
+ }
+
+ function f_LwM2M_ObjectDB_cleanUp(inout LwM2M_ObjectDB p_db)
+ {
+ f_EPTF_int2int_HashMap_Delete("EPTF_LwM2M_ObjectDB_"&int2str(p_db.id)&"_objHash");
+ f_EPTF_str2int_HashMap_Delete("EPTF_LwM2M_ObjectDB_"&int2str(p_db.id)&"_resHash");
+ p_db := c_LwM2M_ObjectDB_init;
+ }
+
+ function f_LwM2M_ObjectDB_createObject(inout LwM2M_ObjectDB p_db, in LwM2M_ObjectSpecification p_spec)
+ return integer
+ {
+ var integer vl_idx := -1;
+ if (not f_EPTF_int2int_HashMap_Find(p_db.objHashRef, p_spec.id, vl_idx))
+ {
+ vl_idx := sizeof(p_db.objs);
+ f_EPTF_int2int_HashMap_Insert(p_db.objHashRef, p_spec.id, vl_idx);
+ p_db.objs[vl_idx] := c_LwM2M_Object_init;
+ p_db.objs[vl_idx].id := p_spec.id;
+ }
+ return vl_idx;
+ }
+
+ function f_LwM2M_ObjectDB_getObject(in LwM2M_ObjectDB p_db, in integer p_id, inout LwM2M_Object p_obj)
+ return boolean
+ {
+ var integer vl_idx := f_LwM2M_ObjectDB_getObjectIdx(p_db, p_id);
+ if (vl_idx >= 0)
+ {
+ p_obj := p_db.objs[vl_idx];
+ return true;
+ }
+ return false;
+ }
+
+ function f_LwM2M_ObjectDB_getObjectIdx(in LwM2M_ObjectDB p_db, in integer p_id)
+ return integer
+ {
+ var integer vl_idx := -1;
+ if (f_EPTF_int2int_HashMap_Find(p_db.objHashRef, p_id, vl_idx))
+ {
+ return vl_idx;
+ }
+ return -1;
+ }
+
+ function f_LwM2M_ObjectDB_createObjectInstance(inout LwM2M_ObjectDB p_db, in LwM2M_ObjectSpecificationDB p_spec_db, in integer p_id, in boolean p_createResources := true)
+ return integer
+ {
+ var integer vl_objIdx := -1
+ var integer vl_objInstIdx := -1;
+ var integer vl_objSpecIdx := -1;
+
+ vl_objIdx := f_LwM2M_ObjectDB_getObjectIdx(p_db, p_id);
+
+ if (vl_objIdx >= 0)
+ {
+ vl_objSpecIdx := f_LwM2M_ObjectSpecificationDB_lookUp(p_spec_db, p_id);
+ if (vl_objSpecIdx >= 0)
+ {
+ vl_objInstIdx := sizeof(p_db.objs[vl_objIdx].instances);
+ p_db.objs[vl_objIdx].instances[vl_objInstIdx] := c_LwM2M_ObjectInstance_init;
+ p_db.objs[vl_objIdx].instances[vl_objInstIdx].id := vl_objInstIdx;
+ p_db.objs[vl_objIdx].instances[vl_objInstIdx].objId := p_spec_db.specs[vl_objSpecIdx].id;
+
+ // Creating resources according to spec
+ if (p_createResources) {
+ for (var integer i:=0; i<sizeof(p_spec_db.specs[vl_objSpecIdx].resourcedefs); i:=i+1)
+ {
+ var LwM2M_Resource v_res := f_LwM2M_createResource(p_db.objs[vl_objIdx].instances[vl_objInstIdx], p_spec_db.specs[vl_objSpecIdx].resourcedefs[i]);
+ f_LwM2M_ObjectDB_addResource(p_db, v_res);
+ }
+ }
+ }
+ }
+ return vl_objInstIdx;
+ }
+
+ function f_LwM2M_ObjectDB_addResource(inout LwM2M_ObjectDB p_db, in LwM2M_Resource p_resource)
+ return boolean
+ {
+ var integer vl_resIdx;
+ if (not f_EPTF_str2int_HashMap_Find(p_db.resHashRef, f_LwM2M_resourceHash_forResource(p_resource), vl_resIdx))
+ {
+ var integer vl_objIdx := f_LwM2M_ObjectDB_getObjectIdx(p_db, p_resource.objId);
+ if (vl_objIdx >= 0)
+ {
+ // Adding to resource array
+ vl_resIdx := sizeof(p_db.resources);
+ p_db.resources[vl_resIdx] := p_resource;
+ // Linking it under the object instance
+ var integer vl_resIdxInObjInst := sizeof(p_db.objs[vl_objIdx].instances[p_resource.objInstId].resources);
+ p_db.objs[vl_objIdx].instances[p_resource.objInstId].resources[vl_resIdxInObjInst] := vl_resIdx;
+ // Adding it to the hash
+ f_EPTF_str2int_HashMap_Insert(p_db.resHashRef, f_LwM2M_resourceHash_forResource(p_resource), vl_resIdx);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function f_LwM2M_ObjectDB_getObjectInstance(in LwM2M_ObjectDB p_db,
+ in integer p_objId, in integer p_objInstId, inout LwM2M_ObjectInstance p_objInst)
+ return boolean
+ {
+ var integer vl_objIdx := f_LwM2M_ObjectDB_getObjectIdx(p_db, p_objId);
+ if (vl_objIdx >= 0) {
+ if (sizeof(p_db.objs[vl_objIdx].instances) > p_objInstId and p_objInstId >= 0) {
+ p_objInst := p_db.objs[vl_objIdx].instances[p_objInstId];
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function f_LwM2M_ObjectDB_getResource(in LwM2M_ObjectDB p_db,
+ in integer p_objId, in integer p_objInstId, in integer p_resourceId, inout LwM2M_Resource p_resource)
+ return boolean
+ {
+ var integer vl_resIdx;
+ if (f_EPTF_str2int_HashMap_Find(p_db.resHashRef, f_LwM2M_resourceHash_forIds(p_objId, p_objInstId, p_resourceId), vl_resIdx))
+ {
+ p_resource := p_db.resources[vl_resIdx];
+ return true;
+ }
+ return false;
+ }
+
+ function f_LwM2M_ObjectDB_setResource(inout LwM2M_ObjectDB p_db,
+ in integer p_objId, in integer p_objInstId, in integer p_resourceId, in LwM2M_Resource p_resource)
+ return boolean
+ {
+ var integer vl_resIdx;
+ if (f_EPTF_str2int_HashMap_Find(p_db.resHashRef, f_LwM2M_resourceHash_forIds(p_objId, p_objInstId, p_resourceId), vl_resIdx))
+ {
+ p_db.resources[vl_resIdx] := p_resource;
+ return true;
+ }
+ return false;
+ }
+
+ function f_LwM2M_ObjectDB_getResourceValue(in LwM2M_ObjectDB p_db,
+ in integer p_objId, in integer p_objInstId, in integer p_resourceId, inout LwM2M_ResourceValue p_value)
+ return boolean
+ {
+ var integer vl_resIdx;
+ if (f_EPTF_str2int_HashMap_Find(p_db.resHashRef, f_LwM2M_resourceHash_forIds(p_objId, p_objInstId, p_resourceId), vl_resIdx))
+ {
+ p_value := p_db.resources[vl_resIdx].val;
+ return true;
+ }
+ return false;
+ }
+
+ function f_LwM2M_ObjectDB_setResourceValue(inout LwM2M_ObjectDB p_db,
+ in integer p_objId, in integer p_objInstId, in integer p_resourceId, in LwM2M_ResourceValue p_value)
+ return boolean
+ {
+ var integer vl_resIdx;
+ if (f_EPTF_str2int_HashMap_Find(p_db.resHashRef, f_LwM2M_resourceHash_forIds(p_objId, p_objInstId, p_resourceId), vl_resIdx))
+ {
+ p_db.resources[vl_resIdx].val := p_value;
+ return true;
+ }
+ return false;
+ }
+
+ function f_LwM2M_ObjectDB_getObjectPaths(in LwM2M_ObjectDB p_db, inout ObjectPath_List p_paths)
+ {
+ if (p_db.id != -1) {
+ for (var integer i:=0; i<sizeof(p_db.objs); i:=i+1) {
+ // No instances for object
+ if (sizeof(p_db.objs[i].instances)==0) {
+ p_paths[sizeof(p_paths)] := {
+ objectId := p_db.objs[i].id,
+ objectInstanceId := omit,
+ resourceId := omit
+ }
+ }
+ // There are object instances
+ else {
+ for (var integer j:=0; j<sizeof(p_db.objs[i].instances); j:=j+1) {
+ p_paths[sizeof(p_paths)] := {
+ objectId := p_db.objs[i].id,
+ objectInstanceId := p_db.objs[i].instances[j].id,
+ resourceId := omit
+ }
+ }
+ }
+ }
+ }
+ }
+
+ function f_LwM2M_resourceHash_forResource(in LwM2M_Resource p_res)
+ return charstring
+ {
+ return int2str(p_res.objId) & "/" & int2str(p_res.objInstId) & "/" & int2str(p_res.id);
+ }
+
+ function f_LwM2M_resourceHash_forIds(in integer p_objId, in integer p_objInstId, in integer p_resId)
+ return charstring
+ {
+ return int2str(p_objId) & "/" & int2str(p_objInstId) & "/" & int2str(p_resId);
+ }
+
+ function f_LwM2M_createResource(inout LwM2M_ObjectInstance p_oi, in LwM2M_ResourceSpecification p_spec)
+ return LwM2M_Resource
+ {
+ var LwM2M_Resource v_ret := c_LwM2M_Resource_init;
+
+ v_ret.id := p_spec.id;
+
+ v_ret.objId := p_oi.objId;
+ v_ret.objInstId := p_oi.id;
+
+ if (p_spec.type_ == FLOAT) {
+ v_ret.val.floatValue := 0.0;
+ }
+ else if (p_spec.type_ == INTEGER) {
+ v_ret.val.intValue := 0;
+ }
+ else if (p_spec.type_ == STRING) {
+ v_ret.val.strValue := "";
+ }
+ else if (p_spec.type_ == OPAQUE) {
+ v_ret.val.opaqueValue := ''O;
+ }
+ else if (p_spec.type_ == BOOLEAN) {
+ v_ret.val.boolValue := false;
+ }
+
+ return v_ret;
+ }
+
+ function f_LwM2M_Resource_setNextDataSample(inout LwM2M_Resource p_res, inout LwM2M_DataSamples_DB p_db)
+ {
+ if (ispresent(p_res.dataSample)) {
+ // Init samplesPointer
+ if (p_res.dataSample.samplesPointer == -1) {
+ p_res.dataSample.samplesPointer := f_LwM2M_DataSamples_DB_lookUp(p_db, p_res.dataSample.samplesName);
+ }
+ // We found the dataSamples
+ if (p_res.dataSample.samplesPointer >=0 and p_res.dataSample.samplesPointer < sizeof(p_db.data)) {
+ // We have values
+ if (sizeof(p_db.data[p_res.dataSample.samplesPointer].values)>0) {
+ // Check value pointer boundaries
+ if (p_res.dataSample.valuePointer < 0 or
+ p_res.dataSample.valuePointer >= sizeof(p_db.data[p_res.dataSample.samplesPointer].values))
+ {
+ // Outside of boundaries, set it to zero
+ p_res.dataSample.valuePointer := 0;
+ }
+ // Set the value
+ p_res.val := p_db.data[p_res.dataSample.samplesPointer].values[p_res.dataSample.valuePointer];
+ // Step value pointer
+ p_res.dataSample.valuePointer := p_res.dataSample.valuePointer+1;
+ }
+ }
+ }
+ }
+
+ function f_LwM2M_DataSamples_DB_init(inout LwM2M_DataSamples_DB p_db, in charstring p_name)
+ {
+ p_db.name := p_name;
+ p_db.data := {};
+ p_db.hashRef := f_EPTF_str2int_HashMap_New(p_name);
+ }
+
+ function f_LwM2M_DataSamples_DB_add(inout LwM2M_DataSamples_DB p_db, in LwM2M_DataSamples p_samples)
+ return integer
+ {
+ var integer p_idx := f_LwM2M_DataSamples_DB_lookUp(p_db, p_samples.name);
+
+ if (p_idx == -1)
+ {
+ p_idx := sizeof(p_db.data);
+ f_EPTF_str2int_HashMap_Insert(p_db.hashRef, p_samples.name, p_idx);
+ p_db.data[p_idx] := p_samples;
+ }
+
+ return p_idx;
+ }
+
+ function f_LwM2M_DataSamples_DB_lookUp(inout LwM2M_DataSamples_DB p_db, in charstring p_sampleName)
+ return integer
+ {
+ var integer vl_idx := -1;
+ f_EPTF_str2int_HashMap_Find(p_db.hashRef, p_sampleName, vl_idx);
+ return vl_idx;
+ }
+
+ function f_LwM2M_DataSamples_DB_get(inout LwM2M_DataSamples_DB p_db, in integer p_idx, inout LwM2M_DataSamples p_samples)
+ {
+ if (p_idx < sizeof(p_db.data))
+ {
+ p_samples := p_db.data[p_idx];
+ }
+ }
+
+ function f_LwM2M_DataSamples_DB_cleanUp(inout LwM2M_DataSamples_DB p_db)
+ {
+ p_db.data := {};
+ f_EPTF_str2int_HashMap_Delete(p_db.name);
+ }
+}
diff --git a/src/EPTF_LwM2M_Transport_Definitions.ttcn b/src/EPTF_LwM2M_Transport_Definitions.ttcn
new file mode 100644
index 0000000..2ae5c69
--- /dev/null
+++ b/src/EPTF_LwM2M_Transport_Definitions.ttcn
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_Transport_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_LwM2M_Transport_Definitions
+{
+ import from LightweightM2M_Types all;
+
+ type function fcb_EPTF_LwM2M_Transport_receiveMessage(in EPTF_LwM2M_PDU pl_message) runs on self;
+ type function fcb_EPTF_LwM2M_Transport_sendMessage(in EPTF_LwM2M_PDU pl_msg) runs on self;
+
+ type record EPTF_LwM2M_PDU
+ {
+ LWM2M_PDU pdu,
+ integer eIdx,
+ integer fsmIdx
+ }
+
+ type component EPTF_LwM2M_Transport_Provider_CT
+ {
+ var fcb_EPTF_LwM2M_Transport_receiveMessage vf_EPTF_LwM2M_Transport_receiveMessage := null;
+ }
+
+ type component EPTF_LwM2M_Transport_User_CT
+ {
+ var fcb_EPTF_LwM2M_Transport_sendMessage vf_EPTF_LwM2M_Transport_send := null;
+ }
+}
diff --git a/src/LightweightM2M_CoAP_Binding.ttcn b/src/LightweightM2M_CoAP_Binding.ttcn
new file mode 100644
index 0000000..90b9607
--- /dev/null
+++ b/src/LightweightM2M_CoAP_Binding.ttcn
@@ -0,0 +1,344 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: LightweightM2M_CoAP_Binding.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module LightweightM2M_CoAP_Binding {
+
+ import from LightweightM2M_Types all;
+ import from CoAP_Types all;
+
+ function f_enc_LWM2M_to_COAP(in LWM2M_PDU p_lwm2m, inout CoAP_ReqResp p_coap)
+ return boolean
+ {
+ if (ischosen(p_lwm2m.Register))
+ {
+ p_coap := valueof(t_coap_base(METHOD_POST, CONFIRMABLE));
+
+ f_addOption(p_coap, { uri_path := "rd" });
+ f_addOption(p_coap, { content_format := 40 });
+ f_addOption(p_coap, { uri_query := "ep=" & p_lwm2m.Register.endpointClientName });
+
+ if (ispresent(p_lwm2m.Register.lifetime)) {
+ f_addOption(p_coap, { uri_query := "lt=" & int2str(p_lwm2m.Register.lifetime) });
+ }
+ if (ispresent(p_lwm2m.Register.version)) {
+ f_addOption(p_coap, { uri_query := "lwm2m=" & p_lwm2m.Register.version });
+ }
+ if (ispresent(p_lwm2m.Register.bindingMode)) {
+ f_addOption(p_coap, { uri_query := "b=" & f_BindingMode2str(p_lwm2m.Register.bindingMode) });
+ }
+ if (ispresent(p_lwm2m.Register.smsNumber)) {
+ f_addOption(p_coap, { uri_query := "sms=" & int2str(p_lwm2m.Register.smsNumber) });
+ }
+ if (sizeof(p_lwm2m.Register.objectsAndObjectInstances)>0) {
+ f_addOption(p_coap, { content_format := 40 });
+ p_coap.payload := char2oct(f_ObjectPathList2str(p_lwm2m.Register.objectsAndObjectInstances));
+ }
+ }
+ else if (ischosen(p_lwm2m.Update))
+ {
+ p_coap := valueof(t_coap_base(METHOD_PUT, CONFIRMABLE));
+
+ f_addLocation(p_coap, p_lwm2m.Update.location);
+
+ if (ispresent(p_lwm2m.Update.lifetime)) {
+ f_addOption(p_coap, { uri_query := "lt=" & int2str(p_lwm2m.Update.lifetime) });
+ }
+ if (ispresent(p_lwm2m.Update.bindingMode)) {
+ f_addOption(p_coap, { uri_query := "b=" & f_BindingMode2str(p_lwm2m.Update.bindingMode) });
+ }
+ if (ispresent(p_lwm2m.Update.smsNumber)) {
+ f_addOption(p_coap, { uri_query := "sms=" & int2str(p_lwm2m.Update.smsNumber) });
+ }
+ if (sizeof(p_lwm2m.Update.objectsAndObjectInstances)>0) {
+ f_addOption(p_coap, { content_format := 40 });
+ p_coap.payload := char2oct(f_ObjectPathList2str(p_lwm2m.Update.objectsAndObjectInstances));
+ }
+ }
+ else if (ischosen(p_lwm2m.Deregister))
+ {
+ p_coap := valueof(t_coap_base(METHOD_DELETE, CONFIRMABLE));
+
+ f_addLocation(p_coap, p_lwm2m.Deregister.location);
+ }
+ else if (ischosen(p_lwm2m.Response))
+ {
+ p_coap := valueof(t_coap_base(f_int2Code(p_lwm2m.Response.code), ACKNOWLEDGEMENT));
+ f_addLocation(p_coap, p_lwm2m.Response.location);
+ if (ispresent(p_lwm2m.Response.contentFormat)) {
+ f_addContentFormat(p_coap, p_lwm2m.Response.contentFormat);
+ }
+ //if (ispresent(p_lwm2m.Response.observe)) {
+ // f_addOption(p_coap, {observe := p_lwm2m.Response.observe.observe});
+ // p_coap.token := p_lwm2m.Response.observe.token;
+ //}
+ p_coap.payload := f_enc_LwM2M_Resources_to_JSON(p_lwm2m.Response.resources);
+ }
+ else
+ {
+ log(%definitionId," Unhandled message type in LWM2M_PDU");
+ return false;
+ }
+ return true;
+ }
+
+ function f_dec_COAP_to_LWM2M(in CoAP_ReqResp p_coap, inout LWM2M_PDU p_lwm2m)
+ return boolean
+ {
+ if (p_coap.header.code.class > 0)
+ {
+ p_lwm2m := c_LWM2M_Response_init;
+ p_lwm2m.Response.code := f_Code2int(p_coap.header.code);
+ if (ispresent(p_coap.options)) {
+ f_fetchLocation(p_coap.options, p_lwm2m.Response.location);
+ }
+ return true;
+ }
+ else if (p_coap.header.code == METHOD_GET)
+ {
+ p_lwm2m := c_LWM2M_Read_init;
+ var Location v_loc := {};
+ f_fetchUriPath(p_coap.options, v_loc);
+ f_LocationToObjectPath(v_loc, p_lwm2m.Read_.path);
+ f_fetchAccept(p_coap.options, p_lwm2m.Read_.accept);
+ var integer p_obs := -1;
+ /*
+ if (f_fetchObserve(p_coap.options, p_obs)) {
+ p_lwm2m.Read_.observe := {
+ observe := p_obs,
+ token := p_coap.token
+ }
+ }
+ */
+ return true;
+ }
+ else if (p_coap.header.code == METHOD_PUT)
+ {
+ p_lwm2m := c_LWM2M_Write_init;
+ var Location v_loc := {};
+ f_fetchUriPath(p_coap.options, v_loc);
+ f_LocationToObjectPath(v_loc, p_lwm2m.Write.path);
+ f_fetchContentFormat(p_coap.options, p_lwm2m.Write.contentFormat);
+ if (p_lwm2m.Write.contentFormat == 1543)
+ { // JSON
+ var LwM2M_JSON_Resources v_decoded_json;
+ v_decoded_json := f_dec_LwM2M_JSON_Resources(p_coap.payload);
+ action("Decoded json: ", v_decoded_json);
+ p_lwm2m.Write.resources := f_LwM2M_JSON_Resources_toResources(v_decoded_json);
+ p_lwm2m.Write.resources[0].objId := p_lwm2m.Write.path.objectId;
+ p_lwm2m.Write.resources[0].objInstId := p_lwm2m.Write.path.objectInstanceId;
+ p_lwm2m.Write.resources[0].id:= p_lwm2m.Write.path.resourceId;
+ }
+ return true;
+ }
+ else if (p_coap.header.code == METHOD_POST)
+ {
+ var Location v_loc := {};
+ f_fetchUriPath(p_coap.options, v_loc);
+ if (sizeof(v_loc)==3)
+ { // Execute
+ p_lwm2m := c_LWM2M_Execute_init;
+ f_LocationToObjectPath(v_loc, p_lwm2m.Execute.path);
+ }
+ else
+ { // Create
+ p_lwm2m := c_LWM2M_Create_init;
+ f_LocationToObjectPath(v_loc, p_lwm2m.Execute.path);
+ }
+ return true;
+ }
+ else if (p_coap.header.code == METHOD_DELETE)
+ {
+ p_lwm2m := c_LWM2M_Delete_init;
+ var Location v_loc := {};
+ f_fetchUriPath(p_coap.options, v_loc);
+ f_LocationToObjectPath(v_loc, p_lwm2m.Delete.path);
+ return true;
+ }
+ else
+ {
+ log(%definitionId," Unrecognized lwm2m pdu in coap ", p_coap);
+ return false;
+ }
+ return false;
+ }
+
+ function f_ObjectPath2str(ObjectPath p_op)
+ return charstring
+ {
+ var charstring v_ret := "</" & int2str(p_op.objectId);
+
+ if (ispresent(p_op.objectInstanceId)) {
+ v_ret := v_ret & "/" & int2str(p_op.objectInstanceId);
+ }
+ if (ispresent(p_op.resourceId)) {
+ v_ret := v_ret & "/" & int2str(p_op.resourceId);
+ }
+
+ return v_ret & ">";
+ }
+
+ function f_ObjectPathList2str(ObjectPath_List p_ol)
+ return charstring
+ {
+ var charstring v_ret := "";
+ for (var integer i:=0; i<sizeof(p_ol); i:=i+1)
+ {
+ v_ret := v_ret & f_ObjectPath2str(p_ol[i]);
+ if (i != sizeof(p_ol)-1) { v_ret := v_ret & "," }
+ }
+ return v_ret;
+ }
+
+ function f_LocationToObjectPath(in Location p_location, inout ObjectPath p_path)
+ {
+ if (sizeof(p_location) >= 1) { p_path.objectId := str2int(oct2char(unichar2oct(p_location[0]))); }
+ else { p_path.objectId := -1 }
+
+ if (sizeof(p_location) >= 2) { p_path.objectInstanceId := str2int(oct2char(unichar2oct(p_location[1]))); }
+ else { p_path.objectInstanceId := omit }
+
+ if (sizeof(p_location) >= 3) { p_path.resourceId := str2int(oct2char(unichar2oct(p_location[2]))); }
+ else { p_path.resourceId := omit }
+ }
+
+ function f_BindingMode2str(BindingMode p_b)
+ return charstring
+ {
+ if (p_b == U) {
+ return "U";
+ }
+ else if (p_b == UQ) {
+ return "UQ";
+ }
+ else if (p_b == S) {
+ return "S";
+ }
+ else if (p_b == SQ) {
+ return "SQ";
+ }
+ else if (p_b == US) {
+ return "US";
+ }
+ else if (p_b == UQS) {
+ return "UQS";
+ }
+ else {
+ log(%definitionId," Unrecognized binding mode: ", p_b)
+ return "";
+ }
+ return "";
+ }
+
+ function f_addLocation(inout CoAP_ReqResp p_coap, in Location p_location)
+ {
+ for (var integer i:=0; i<sizeof(p_location); i:=i+1)
+ {
+ f_addOption(p_coap, { uri_path := p_location[i] } );
+ }
+ }
+
+ function f_addContentFormat(inout CoAP_ReqResp p_coap, in integer p_cf)
+ {
+ f_addOption(p_coap, { content_format := p_cf } );
+ }
+
+ function f_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_Code2int(in Code p_code)
+ return integer
+ {
+ return p_code.class*100+p_code.detail;
+ }
+
+ function f_int2Code(in integer p_code)
+ return Code
+ {
+ var Code v_ret;
+ v_ret.class := p_code/100;
+ v_ret.detail := p_code rem 100;
+
+ return v_ret;
+ }
+
+ function f_fetchLocation(in CoAP_OptionsList p_options, inout Location p_location)
+ {
+ for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
+ if (ischosen(p_options[i].location_path)) {
+ p_location[sizeof(p_location)] := p_options[i].location_path;
+ }
+ }
+ }
+
+ function f_fetchUriPath(in CoAP_OptionsList p_options, inout Location p_location)
+ {
+ for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
+ if (ischosen(p_options[i].uri_path)) {
+ p_location[sizeof(p_location)] := p_options[i].uri_path;
+ }
+ }
+ }
+
+ function f_fetchAccept(in CoAP_OptionsList p_options, inout Integer_List p_accept)
+ {
+ for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
+ if (ischosen(p_options[i].accept)) {
+ p_accept[sizeof(p_accept)] := p_options[i].accept;
+ }
+ }
+ }
+
+ /*
+ function f_fetchObserve(in CoAP_OptionsList p_options, inout integer p_observe)
+ return boolean
+ {
+ for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
+ if (ischosen(p_options[i].observe)) {
+ p_observe := p_options[i].observe;
+ return true;
+ }
+ }
+ return false;
+ }
+ */
+
+ function f_fetchContentFormat(in CoAP_OptionsList p_options, inout integer p_cf)
+ {
+ for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
+ if (ischosen(p_options[i].content_format)) {
+ p_cf := p_options[i].content_format;
+ }
+ }
+ }
+
+ template CoAP_ReqResp t_coap_base(Code p_code, Type p_type) :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := p_type,
+ code := p_code,
+ message_id := 0
+ },
+ token := ''O,
+ options := {},
+ payload := omit
+ }
+}
diff --git a/src/LightweightM2M_Types.ttcn b/src/LightweightM2M_Types.ttcn
new file mode 100644
index 0000000..5c8d19a
--- /dev/null
+++ b/src/LightweightM2M_Types.ttcn
@@ -0,0 +1,422 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: LightweightM2M_Types.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module LightweightM2M_Types
+{
+ type universal charstring URN;
+ type record of universal charstring Location;
+ type record of integer Integer_List;
+
+ type union LWM2M_PDU
+ {
+ // -----
+ LWM2M_Register Register,
+ LWM2M_Update Update,
+ LWM2M_Deregister Deregister,
+ LWM2M_Response Response,
+ // -----
+ LWM2M_Read Read_,
+ LWM2M_Write Write,
+ LWM2M_Execute Execute,
+ // -----
+ LWM2M_Create Create,
+ LWM2M_Delete Delete
+ }
+
+ type record LWM2M_Register
+ {
+ URN endpointClientName,
+ integer lifetime optional,
+ charstring version optional,
+ BindingMode bindingMode optional,
+ integer smsNumber optional,
+ ObjectPath_List objectsAndObjectInstances
+ }
+
+ const LWM2M_PDU c_LWM2M_Register_init :=
+ {
+ Register := {
+ endpointClientName := "",
+ lifetime := omit,
+ version := omit,
+ bindingMode := omit,
+ smsNumber := omit,
+ objectsAndObjectInstances := {}
+ }
+ }
+
+ type record LWM2M_Update
+ {
+ Location location,
+ integer lifetime optional,
+ BindingMode bindingMode optional,
+ integer smsNumber optional,
+ ObjectPath_List objectsAndObjectInstances
+ }
+
+ const LWM2M_PDU c_LWM2M_Update_init :=
+ {
+ Update := {
+ location := {},
+ lifetime := omit,
+ bindingMode := omit,
+ smsNumber := omit,
+ objectsAndObjectInstances := {}
+ }
+ }
+
+ type record LWM2M_Read
+ {
+ ObjectPath path,
+ Integer_List accept,
+ LwM2M_Observe_Information observe optional
+ }
+
+ const LWM2M_PDU c_LWM2M_Read_init :=
+ {
+ Read_ := {
+ path := {-1, omit, omit},
+ accept := {},
+ observe := omit
+ }
+ }
+
+ type record LWM2M_Write
+ {
+ ObjectPath path,
+ integer contentFormat,
+ LwM2M_Resource_List resources
+ }
+
+ const LWM2M_PDU c_LWM2M_Write_init :=
+ {
+ Write := {
+ path := { -1, omit, omit},
+ contentFormat := -1,
+ resources := {}
+ }
+ }
+
+ type record LWM2M_Execute
+ {
+ ObjectPath path
+ }
+
+ const LWM2M_PDU c_LWM2M_Execute_init :=
+ {
+ Execute := {
+ path := { -1, omit, omit}
+ }
+ }
+
+ type record LWM2M_Create
+ {
+ ObjectPath path
+ }
+
+ const LWM2M_PDU c_LWM2M_Create_init :=
+ {
+ Create := {
+ path := { -1, omit, omit}
+ }
+ }
+
+ type record LWM2M_Delete
+ {
+ ObjectPath path
+ }
+
+ const LWM2M_PDU c_LWM2M_Delete_init :=
+ {
+ Delete := {
+ path := { -1, omit, omit}
+ }
+ }
+
+ type record LWM2M_Deregister
+ {
+ Location location
+ }
+
+ type record LWM2M_Response
+ {
+ Location location,
+ integer code,
+ integer contentFormat optional,
+ LwM2M_Observe_Information observe optional,
+ LwM2M_Resource_List resources
+ }
+
+ const LWM2M_PDU c_LWM2M_Response_init :=
+ {
+ Response := {
+ location := {},
+ code := 0,
+ contentFormat := omit,
+ observe := omit,
+ resources := {}
+ }
+ }
+
+ type enumerated BindingMode
+ {
+ U, UQ, S, SQ, US, UQS
+ }
+
+ type record ObjectPath
+ {
+ integer objectId,
+ integer objectInstanceId optional,
+ integer resourceId optional
+ }
+
+ type record of ObjectPath ObjectPath_List;
+
+ type record LwM2M_Resource
+ {
+ integer id,
+ integer objId,
+ integer objInstId,
+ LwM2M_Observe_Information observe optional,
+ LwM2M_DataSample_Information dataSample optional,
+ LwM2M_ResourceValue val
+ }
+
+ type record LwM2M_Observe_Information
+ {
+ integer observe,
+ octetstring token
+ }
+
+ const LwM2M_Observe_Information c_LwM2M_Observe_Information_init :=
+ {
+ observe := -1,
+ token := ''O
+ }
+
+ type record LwM2M_DataSample_Information
+ {
+ charstring samplesName,
+ integer samplesPointer,
+ integer valuePointer
+ }
+
+ const LwM2M_DataSample_Information c_LwM2M_DataSample_Information_init :=
+ {
+ samplesName := "",
+ samplesPointer := -1,
+ valuePointer := -1
+ }
+
+ const LwM2M_Resource c_LwM2M_Resource_init :=
+ {
+ id := -1,
+ objId := -1,
+ objInstId := -1,
+ observe := omit,
+ dataSample := omit,
+ val := { boolValue := false }
+ }
+
+ type union LwM2M_ResourceValue
+ {
+ integer intValue,
+ charstring strValue,
+ float floatValue,
+ octetstring opaqueValue,
+ boolean boolValue
+ }
+
+ type record of LwM2M_ResourceValue LwM2M_ResourceValue_List;
+
+ type record of LwM2M_Resource LwM2M_Resource_List;
+
+ function f_LwM2M_ObjectPath_isResource(in ObjectPath p_path)
+ return boolean
+ {
+ return ispresent(p_path.objectInstanceId) and ispresent(p_path.resourceId)
+ }
+
+ function f_LwM2M_ObjectPath_isObjectInstance(in ObjectPath p_path)
+ return boolean
+ {
+ return ispresent(p_path.objectInstanceId) and not ispresent(p_path.resourceId)
+ }
+
+ function f_LwM2M_ObjectPath_isObject(in ObjectPath p_path)
+ return boolean
+ {
+ return not ispresent(p_path.objectInstanceId) and not ispresent(p_path.resourceId)
+ }
+
+ ///////////////////////////////////////
+ // JSON representation and enc/dec
+ ///////////////////////////////////////
+ function f_enc_LwM2M_Resources_to_JSON(in LwM2M_Resource_List p_res_list) return octetstring
+ {
+ var charstring v_result :=
+ "{\"bn\":\"/\",\n"&
+ "\"e\":[\n";
+
+ for (var integer i:=0; i<sizeof(p_res_list); i:=i+1)
+ {
+ v_result := v_result & f_enc_LwM2M_Resource_to_JSON(p_res_list[i]);
+ if (i != sizeof(p_res_list)-1) { v_result := v_result & ",\n"}
+ else { v_result := v_result & "\n"}
+ }
+
+ v_result := v_result & "]}";
+
+ return char2oct(v_result);
+ }
+
+ function f_enc_LwM2M_Resource_to_JSON(in LwM2M_Resource p_res) return charstring
+ {
+ var charstring v_ret := "";
+
+ // "n":"65/3/3"
+ var charstring v_name := "";
+
+ if (p_res.objId != -1) {
+ v_name := v_name & int2str(p_res.objId)
+ }
+ if (p_res.objInstId != -1) {
+ if (lengthof(v_name) > 0) { v_name := v_name & "/" & int2str(p_res.objInstId) }
+ else { v_name := int2str(p_res.objInstId) }
+ }
+ if (p_res.id != -1) {
+ if (lengthof(v_name) > 0) { v_name := v_name & "/" & int2str(p_res.id) }
+ else { v_name := int2str(p_res.id) }
+ }
+ v_name := "\"n\":\"" & v_name & "\"";
+
+ var charstring v_value := "";
+
+ if (ischosen(p_res.val.intValue)) {
+ v_value := "\"v\":" & int2str(p_res.val.intValue);
+ }
+ else if (ischosen(p_res.val.floatValue)) {
+ v_value := "\"v\":" & float2str(p_res.val.floatValue);
+ }
+ else if (ischosen(p_res.val.strValue)) {
+ v_value := "\"sv\":" & "\"" & p_res.val.strValue & "\"";
+ }
+ else if (ischosen(p_res.val.boolValue)) {
+ v_value := "\"bv\":" & "\"" & f_bool2str(p_res.val.boolValue) & "\"";
+ }
+ else if (ischosen(p_res.val.opaqueValue)) {
+ v_value := "\"ov\":" & "\"" & oct2str(p_res.val.opaqueValue) & "\"";
+ }
+
+ v_ret := "{" & v_name & ", " & v_value & "}";
+
+ return v_ret;
+ }
+
+ function f_bool2str(in boolean p_b) return charstring { if (p_b) {return "true"} else {return "false" }}
+
+ function f_enc_LwM2M_Resources_to_JSON_old(in LwM2M_Resource_List p_res_list) return octetstring
+ {
+ var LwM2M_JSON_Resources v_json_res_list;
+ v_json_res_list.e := {};
+
+ for (var integer i:=0; i<sizeof(p_res_list); i:=i+1)
+ {
+ v_json_res_list.e[sizeof(v_json_res_list.e)] := f_LwM2M_Resource_toJSONStructure(p_res_list[i]);
+ }
+
+ return f_enc_LwM2M_JSON_Resources(v_json_res_list);
+ }
+
+ function f_LwM2M_Resource_toJSONStructure(in LwM2M_Resource p_in)
+ return LwM2M_JSON_Resource
+ {
+ var LwM2M_JSON_Resource v_out;
+
+ v_out.n := "";
+
+ if (p_in.objId != -1) {
+ v_out.n := int2str(p_in.objId)
+ }
+ if (p_in.objInstId != -1) {
+ if (lengthof(v_out.n) > 0) { v_out.n := v_out.n & "/" & int2str(p_in.objInstId) }
+ else { v_out.n := int2str(p_in.objInstId) }
+ }
+ if (p_in.id != -1) {
+ if (lengthof(v_out.n) > 0) { v_out.n := v_out.n & "/" & int2str(p_in.id) }
+ else { v_out.n := int2str(p_in.id) }
+ }
+
+ if (ischosen(p_in.val.intValue)) { v_out.v := int2float(p_in.val.intValue) }
+ else if (ischosen(p_in.val.floatValue)) { v_out.v := p_in.val.floatValue }
+ else if (ischosen(p_in.val.strValue)) { v_out.sv := p_in.val.strValue }
+ else if (ischosen(p_in.val.boolValue)) { v_out.bv := p_in.val.boolValue }
+ else if (ischosen(p_in.val.opaqueValue)) { v_out.sv := oct2str(p_in.val.opaqueValue) }
+
+ return v_out;
+ }
+
+ function f_LwM2M_JSON_Resources_toResources(in LwM2M_JSON_Resources p_json_res_list)
+ return LwM2M_Resource_List
+ {
+ var LwM2M_Resource_List v_ret := {};
+
+ for (var integer i:=0; i<sizeof(p_json_res_list.e); i:=i+1) {
+ v_ret[sizeof(v_ret)] := f_LwM2M_JSON_Resource_toResource(p_json_res_list.e[i]);
+ }
+
+ return v_ret;
+ }
+
+ function f_LwM2M_JSON_Resource_toResource(in LwM2M_JSON_Resource p_json_res)
+ return LwM2M_Resource
+ {
+ var LwM2M_Resource v_ret := c_LwM2M_Resource_init;
+
+ if (ispresent(p_json_res.bv)) { v_ret.val.boolValue := p_json_res.bv; }
+ if (ispresent(p_json_res.sv)) { v_ret.val.strValue := p_json_res.sv; }
+ if (ispresent(p_json_res.v)) { v_ret.val.floatValue := p_json_res.v; }
+
+ return v_ret;
+ }
+
+ external function f_enc_LwM2M_JSON_Resources(in LwM2M_JSON_Resources p_res) return octetstring
+ with { extension "prototype(convert) encode(JSON) printing(pretty)" }
+
+ external function f_dec_LwM2M_JSON_Resources(in octetstring p_res) return LwM2M_JSON_Resources
+ with { extension "prototype(convert) decode(JSON)" }
+
+ type record LwM2M_JSON_Resources
+ {
+ LwM2M_JSON_Resource_List e
+ }
+ with { encode "JSON" }
+
+ type record of LwM2M_JSON_Resource LwM2M_JSON_Resource_List
+ with { encode "JSON" }
+
+ type record LwM2M_JSON_Resource
+ {
+ charstring n,
+ float v optional,
+ boolean bv optional,
+ charstring sv optional
+ }
+ with {
+ encode "JSON"
+ optional "implicit omit"
+ }
+}
diff --git a/test/EPTF_LwM2M_Tests.ttcn b/test/EPTF_LwM2M_Tests.ttcn
new file mode 100644
index 0000000..a8b3c96
--- /dev/null
+++ b/test/EPTF_LwM2M_Tests.ttcn
@@ -0,0 +1,19 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 Ericsson Telecom AB
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+///////////////////////////////////////////////////////////////////////////////
+// File: EPTF_LwM2M_Tests.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: CNL 113 859
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module EPTF_LwM2M_Tests {
+
+}