blob: 3c925229ac2e127fd283e3c1eb27e2859add387c [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2021 Ericsson Telecom AB
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v2.0
// which accompanies this distribution, and is available at
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
///////////////////////////////////////////////////////////////////////////////
// File: EPTF_LwM2M_CoapApplibTransport_Functions.ttcn
// Description:
// Rev: R1B
// Prodnr: CNL 113 859
// Updated: 2021-02-03
// Contact: http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_LwM2M_CoapApplibTransport_Functions
//
// Purpose:
// This module contains the functions for the LWM2M transport layer that uses the COAP applib
//
// Module Parameters:
// tsp_EPTF_LwM2M_CoapApplibTransport_enabled - <tsp_EPTF_LwM2M_CoapApplibTransport_enabled> - *boolean* - Enable/disable the transport layer itself
//
// See also:
// <EPTF_LwM2M_CoapApplibTransport_Definitions>
///////////////////////////////////////////////////////////////
module EPTF_LwM2M_CoapApplibTransport_Functions
{
import from EPTF_LwM2M_Transport_Definitions all;
import from EPTF_LwM2M_CoapApplibTransport_Definitions all;
import from LightweightM2M_Types all;
import from LightweightM2M_CoAP_Binding all;
import from EPTF_COAP_Transport_Definitions all;
import from EPTF_COAP_LGen_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;
///////////////////////////////////////////////////////////
// Module parameter: tsp_EPTF_LwM2M_CoapApplibTransport_enabled
//
// Purpose:
// Enabled/disable the transport layer implementation
//
// Type:
// *boolean*
//
// Default value:
// *true*
///////////////////////////////////////////////////////////
modulepar boolean tsp_EPTF_LwM2M_CoapApplibTransport_enabled := true;
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_CoapApplibTransport_init
//
// Purpose:
// The main initialization function of the <EPTF_LwM2M_CoapApplibTransport_CT> component type
//
// Related Type:
// <EPTF_LwM2M_CoapApplibTransport_CT>
///////////////////////////////////////////////////////////
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
//
// Purpose:
// The main clean up function for the <EPTF_LwM2M_CoapApplibTransport_CT> component type
//
// Related Type:
// <EPTF_LwM2M_CoapApplibTransport_CT>
///////////////////////////////////////////////////////////
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;
vf_EPTF_LwM2M_Transport_receiveEvent := null;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_CoapApplibTransport_send
//
// Purpose:
// Function to send out a <EPTF_LwM2M_PDU> message using the local transport. It expects
// that the COAP context of the caller [entity, fsm] is initialized.
//
// Parameters:
// pl_msg - *in* <EPTF_COAP_PDU> - message to be sent
//
// Related Type:
// <EPTF_COAP_LocalTransport_CT>
///////////////////////////////////////////////////////////
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); }
if (f_enc_LWM2M_to_COAP(pl_msg.pdu, v_COAP_msgToSend.pdu))
{
v_EPTF_LwM2M_CoapApplibTransport_stats.nofSentMessages := v_EPTF_LwM2M_CoapApplibTransport_stats.nofSentMessages + 1;
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 if (ischosen(pl_msg.pdu.Notification))
{
f_COAP_step_sendNotification_internal(l_args, f_EPTF_LwM2M_CoapApplibTransport_ObjectPath_to_resourceIdString(pl_msg.pdu.Notification.path));
}
else
{
f_COAP_step_send(l_args);
}
}
else
{
f_EPTF_COAP_Logging_WARNING(%definitionId &": Could not encode LWM2M PDU to COAP!");
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_CoapApplibTransport_messageReceived
//
// Purpose:
// Handler function to be regsitered into the COAP applib used as transport layer to receive <EPTF_COAP_PDU>
// <EPTF_COAP_LGen_CT> component has a variable *vf_COAP_msgReceived* with type <fcb_EPTF_COAP_messageReceived>
// where this function can be registered in.
// It is used to receieve LwM@M messages from the underlying COAP layer.
//
// Parameters:
// pl_message - *in* <EPTF_COAP_PDU> - incoming message
// pl_duplicate - *in boolean* - false to indicate, if the incoming message is a duplicate
//
// Related Type:
// <EPTF_LwM2M_CoapApplibTransport_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_CoapApplibTransport_messageReceived(in EPTF_COAP_PDU pl_message, in boolean p_duplicate, in boolean p_autoHandled)
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 or p_autoHandled) { return }
var EPTF_LwM2M_PDU v_pdu;
if (v_COAP_msgToProcess.pdu.header.msg_type != RESET)
{
if (f_dec_COAP_to_LWM2M(v_COAP_msgToProcess.pdu, v_pdu.pdu))
{
v_pdu.eIdx := pl_message.eIdx;
v_pdu.fsmIdx := pl_message.fsmIdx;
v_EPTF_LwM2M_CoapApplibTransport_stats.nofReceivedMessages := v_EPTF_LwM2M_CoapApplibTransport_stats.nofReceivedMessages + 1;
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);
}
}
else
{
f_EPTF_COAP_Logging_WARNING(%definitionId &": Could not decode COAP to LWM2M!");
v_EPTF_LwM2M_CoapApplibTransport_stats.nofDecodingErrors := v_EPTF_LwM2M_CoapApplibTransport_stats.nofDecodingErrors + 1;
}
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_CoapApplibTransport_eventIndication
//
// Purpose:
// Handler function to be registered into the COAP applib used as transport layer to receive <EPTF_COAP_EventDescriptor>
// <EPTF_COAP_LGen_CT> component has a variable *vf_COAP_eventIndication* with type <fcb_EPTF_COAP_eventIndication>
// where this function can be registered in.
// It is used to receieve LwM@M messages from the underlying COAP layer.
//
// Parameters:
// pl_event - *in* <EPTF_COAP_EventDescriptor> - incoming COAP event
// pl_duplicate - *in boolean* - falg to indicate, if the incoming message is a duplicate
//
// Related Type:
// <EPTF_LwM2M_CoapApplibTransport_CT>
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_CoapApplibTransport_eventIndication(in EPTF_COAP_EventDescriptor pl_event)
runs on EPTF_LwM2M_CoapApplibTransport_CT
{
f_EPTF_COAP_Logging_VERBOSE(log2str(%definitionId, " ", pl_event));
if (not tsp_EPTF_LwM2M_CoapApplibTransport_enabled) { return }
if (ischosen(pl_event.resourceNotObserved))
{
var EPTF_LwM2M_Event v_event;
v_event.eIdx := pl_event.resourceNotObserved.eIdx;
f_LocationToObjectPath(pl_event.resourceNotObserved.uriPath, v_event.event.resourceNotObserved);
if (vf_EPTF_LwM2M_Transport_receiveEvent != null)
{
vf_EPTF_LwM2M_Transport_receiveEvent.apply(v_event);
}
}
else if (ischosen(pl_event.atomicBlock1Finished))
{
var EPTF_LwM2M_Event v_event :=
{
event := { atomicBlock1Finished := c_LWM2M_Event_Block1_empty },
eIdx := pl_event.atomicBlock1Finished.eIdx
};
if (pl_event.atomicBlock1Finished.method == { 0, 3 }) { v_event.event.atomicBlock1Finished.method := WRITE; }
else { v_event.event.atomicBlock1Finished.method := UNMAPPED; }
f_LocationToObjectPath(pl_event.atomicBlock1Finished.uriPath, v_event.event.atomicBlock1Finished.path);
v_event.event.atomicBlock1Finished.contentFormat := pl_event.atomicBlock1Finished.contentFormat;
if (pl_event.atomicBlock1Finished.content != ''O)
{
@try
{
f_dec_LwM2M_Resources(
v_event.event.atomicBlock1Finished.contentFormat,
pl_event.atomicBlock1Finished.content,
v_event.event.atomicBlock1Finished.resources,
pl_event.atomicBlock1Finished.uriPath
);
}
@catch(err)
{
f_EPTF_COAP_Logging_WARNING(log2str(%definitionId, " exception during decoding ", pl_event));
v_event.event.atomicBlock1Finished.resources := {};
}
}
if (vf_EPTF_LwM2M_Transport_receiveEvent != null)
{
vf_EPTF_LwM2M_Transport_receiveEvent.apply(v_event);
}
}
else
{
f_EPTF_COAP_Logging_WARNING(%definitionId &": Could not translate COAP event to LWM2M!");
return
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_LwM2M_CoapApplibTransport_ObjectPath_to_resourceIdString
//
// Purpose:
// This function translates an <ObjectPath> to its charstring representation
//
// Parameters:
// p_path - *in* <ObjectPath> - object path to be translated
//
// Returns:
// charstring - the translation, e.g. "/1/0/13"
///////////////////////////////////////////////////////////
function f_EPTF_LwM2M_CoapApplibTransport_ObjectPath_to_resourceIdString(in ObjectPath p_path)
return charstring
{
var charstring v_ret := "/" & int2str(p_path.objectId);
if (ispresent(p_path.objectInstanceId))
{
v_ret := v_ret & "/" & int2str(p_path.objectInstanceId);
if (ispresent(p_path.resourceId))
{
v_ret := v_ret & "/" & int2str(p_path.resourceId);
}
}
return v_ret;
}
}