| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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; |
| } |
| } |