| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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: IOT_LGen_Functions.ttcn |
| // Description: |
| // Rev: R1B |
| // Prodnr: CNL 113 909 |
| // Updated: 2021-02-03 |
| // Contact: http://ttcn.ericsson.se |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /////////////////////////////////////////////////////////// |
| // Module: IOT_LGen_Functions |
| // |
| // Purpose: |
| // This module contains the functions of an IoT load generator component |
| // |
| // See also: |
| // <IOT_LGen_Definitions> |
| // |
| // Module depends on: |
| // - <IOT_LGen_Definitions> |
| // - <IOT_LGen_Steps> |
| // - <EPTF_MQTT_LGen_Definitions> |
| // - <EPTF_MQTT_LGen_Functions> |
| // - <EPTF_MQTT_LocalTransport_Functions> |
| // - <EPTF_COAP_LGen_Definitions> |
| // - <EPTF_COAP_LGen_Functions> |
| // - <EPTF_COAP_Transport_Definitions> |
| // - <EPTF_COAP_LocalTransport_Functions> |
| // - <EPTF_LwM2M_LGen_Definitions> |
| // - <EPTF_LwM2M_LGen_Functions> |
| // - <EPTF_LwM2M_CoapApplibTransport_Functions> |
| // - <EPTF_LwM2M_Object_Definitions> |
| // - <EPTF_LwM2M_Object_Functions> |
| // - <EPTF_HTTP_Definitions> |
| // - <EPTF_HTTP_Functions> |
| // - <EPTF_HTTP_Transport_Functions> |
| // - <EPTF_CLL_Common_Definitions> |
| // - <EPTF_CLL_Base_Functions> |
| // - <EPTF_CLL_ExecCtrl_Definitions> |
| // - <EPTF_CLL_ExecCtrlClient_Functions> |
| // - <EPTF_CLL_LGenBase_Functions> |
| // - <EPTF_CLL_LGenBase_ConfigFunctions> |
| // - <EPTF_CLL_Logging_Definitions> |
| // - <EPTF_CLL_Logging_Functions> |
| // - <InfluxDB_Definitions> |
| // - <InfluxDB_Functions> |
| /////////////////////////////////////////////////////////////// |
| module IOT_LGen_Functions |
| { |
| import from IOT_LGen_Definitions all; |
| import from IOT_LGen_Steps all; |
| |
| import from EPTF_MQTT_LGen_Definitions all; |
| import from EPTF_MQTT_LGen_Functions all; |
| import from EPTF_MQTT_LocalTransport_Functions all; |
| import from EPTF_COAP_LGen_Definitions all; |
| import from EPTF_COAP_LGen_Functions all; |
| import from EPTF_COAP_Transport_Definitions all; |
| import from EPTF_COAP_LocalTransport_Functions all; |
| import from EPTF_LwM2M_LGen_Definitions all; |
| import from EPTF_LwM2M_LGen_Functions all; |
| import from EPTF_LwM2M_CoapApplibTransport_Functions all; |
| import from EPTF_LwM2M_Object_Definitions all; |
| import from EPTF_LwM2M_Object_Functions all; |
| import from EPTF_HTTP_Definitions all; |
| import from EPTF_HTTP_Functions all; |
| import from EPTF_HTTP_Transport_Functions all; |
| |
| import from EPTF_CLL_Common_Definitions all; |
| import from EPTF_CLL_Base_Functions all; |
| import from EPTF_CLL_ExecCtrl_Definitions all; |
| import from EPTF_CLL_ExecCtrlClient_Functions all; |
| import from EPTF_CLL_LGenBase_Functions all; |
| import from EPTF_CLL_LGenBase_ConfigFunctions all; |
| import from EPTF_CLL_Logging_Definitions all; |
| import from EPTF_CLL_Logging_Functions all; |
| |
| import from InfluxDB_Definitions all; |
| //import from InfluxDB_Functions all; |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_LGen_behavior |
| // |
| // Purpose: |
| // The main service function of the <IOT_LGen_CT> component type |
| // After initialization, this is that function that is continuously running |
| // until the RIoT application exits |
| // |
| // Parameters: |
| // pl_name - *in* *charstring* - the name for the component instance |
| // |
| // Related Type: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_LGen_behavior(in charstring pl_selfName, in integer p_idx, in EPTF_ExecCtrl_CT pl_ExecCtrlRef) |
| runs on IOT_LGen_CT |
| { |
| log(%definitionId,": started..."); |
| |
| f_IOT_LGen_init(pl_selfName, p_idx, pl_ExecCtrlRef); |
| f_EPTF_ExecCtrlClient_init_CT(pl_selfName, pl_ExecCtrlRef); // Only after library init(s) |
| |
| f_EPTF_Base_wait4Shutdown(); |
| |
| f_LwM2M_DataSamples_DB_cleanUp(v_IOT_LGen_DataSamples_DB); |
| |
| f_EPTF_Base_cleanup_CT(); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_LGen_init |
| // |
| // Purpose: |
| // The main init function of the <IOT_LGen_CT> component type |
| // It initializes the integrated application libraries and defines |
| // its own <c_IOT_behaviorType> and test steps <f_IOT_LGen_declareSteps> |
| // The sample database of the smart objects are also filled in here by calling <f_IOT_LGen_initSamples> |
| // |
| // Parameters: |
| // pl_name - *in* *charstring* - the name for the component instance |
| // |
| // Related Type: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_LGen_init(in charstring pl_selfName, in integer p_idx, in EPTF_ExecCtrl_CT pl_ExecCtrlRef) |
| runs on IOT_LGen_CT |
| { |
| v_IOT_LGen_name := pl_selfName; |
| v_IOT_LGen_idx := p_idx; |
| |
| f_IOT_LGen_initLogging(pl_selfName); |
| |
| f_EPTF_LGenBase_init(pl_selfName, 0, "IoT_Entity#"); |
| |
| v_InfluxDB_ctx.localPort := tsp_InfluxDB_client_basePort + p_idx; |
| //f_InfluxDB_init(); |
| |
| f_IOT_LGen_initSamples(pl_selfName); |
| |
| ////////////////////// |
| // COAP applib init |
| |
| f_EPTF_COAP_LGen_init(pl_selfName); |
| f_EPTF_COAP_LocalTransport_init(); |
| |
| vf_EPTF_COAP_Transport_send := refers(f_IOT_COAP_LocalTransport_send); |
| vf_EPTF_COAP_Transport_receiveMessage := refers(f_IOT_COAP_LGen_receiveMessage); |
| vf_EPTF_COAP_Transport_receiveEvent := refers(f_EPTF_COAP_LGen_receiveEvent); |
| vf_EPTF_COAP_Transport_apiRequest := refers(f_EPTF_COAP_LocalTransport_transportApiRequest); |
| vf_EPTF_COAP_Transport_apiResponse := refers(f_EPTF_COAP_LGen_transportApiResponse); |
| |
| ////////////////////// |
| // LWM2M applib init |
| |
| f_EPTF_LwM2M_LGen_init(pl_selfName); |
| f_EPTF_LwM2M_CoapApplibTransport_init(pl_selfName); |
| |
| vf_COAP_msgReceived := refers(f_EPTF_LwM2M_CoapApplibTransport_messageReceived); |
| vf_COAP_eventIndication := refers(f_EPTF_LwM2M_CoapApplibTransport_eventIndication); |
| vf_EPTF_LwM2M_Transport_send := refers(f_EPTF_LwM2M_CoapApplibTransport_send); |
| vf_EPTF_LwM2M_Transport_receiveMessage := refers(f_EPTF_LwM2M_LGen_receiveMessage); |
| vf_EPTF_LwM2M_Transport_receiveEvent := refers(f_EPTF_LwM2M_LGen_receiveEvent); |
| |
| ////////////////////// |
| // HTTP applib init |
| |
| f_EPTF_HTTP_init("HTTP", 0, "Demo Entity#"); |
| |
| f_EPTF_HTTP_LocalTransport_init_CT("HTTP", |
| refers(f_EPTF_HTTP_messageReceived), |
| refers(f_EPTF_HTTP_eventReceived), |
| refers(f_EPTF_HTTP_socketErrorReceived) |
| ); |
| |
| f_EPTF_HTTP_setSendRequestFunction(refers(f_EPTF_HTTP_LocalTransport_sendMessage)); |
| f_EPTF_HTTP_setConnectionCloseFunction(refers(f_EPTF_HTTP_LocalTransport_connectionClose)); |
| f_EPTF_HTTP_setConnectionOpenFunction(refers(f_EPTF_HTTP_LocalTransport_connectionOpen)); |
| f_EPTF_HTTP_setConnectionHalfCloseFunction(refers(f_EPTF_HTTP_LocalTransport_connectionHalfClose)); |
| f_EPTF_HTTP_setClosePortOfUserFunction(refers(f_EPTF_HTTP_LocalTransport_closePortOfUser)); |
| f_EPTF_HTTP_setFreePortOfUserFunction(refers(f_EPTF_HTTP_LocalTransport_freePortOfUser)); |
| |
| ////////////////////// |
| // MQTT applib init |
| |
| f_EPTF_MQTT_LGen_init(pl_selfName); |
| f_EPTF_MQTT_LocalTransport_init(); |
| |
| vf_EPTF_MQTT_Transport_send := refers(f_EPTF_MQTT_LocalTransport_send); |
| vf_EPTF_MQTT_Transport_receiveMessage := refers(f_EPTF_MQTT_LGen_receiveMessage); |
| vf_EPTF_MQTT_Transport_receiveEvent := refers(f_EPTF_MQTT_LGen_receiveEvent); |
| vf_EPTF_MQTT_Transport_apiRequest := refers(f_EPTF_MQTT_LocalTransport_transportApiRequest); |
| vf_EPTF_MQTT_Transport_apiResponse := refers(f_EPTF_MQTT_LGen_transportApiResponse); |
| |
| ////////////////////// |
| // CLL config |
| |
| v_IOT_bIdx := f_EPTF_LGenBase_declareBehaviorType(c_IOT_behaviorType, -1, null, null, null); |
| f_EPTF_LGenBase_declareEntityType( |
| c_IOT_entityType, |
| { |
| c_COAP_behaviorType, |
| c_LwM2M_behaviorType, |
| c_EPTF_HTTP_myBName, |
| c_MQTT_behaviorType |
| } |
| ); |
| |
| // Steps |
| f_IOT_LGen_declareSteps(); |
| |
| // FSMs |
| f_EPTF_LGenBase_declareFSMTables(tsp_IOT_LGen_FSMs); |
| } |
| |
| function f_IOT_LGen_initLogging(in charstring p_selfName) |
| runs on IOT_LGen_CT |
| { |
| f_EPTF_Logging_init_CT(p_selfName); |
| v_IOT_LGen_loggingMaskId := |
| f_EPTF_Logging_registerComponentMasks( |
| "IOT_LGen_Logging", |
| {"WARNING", "DEBUG", "DEBUGV", "ERROR"}, |
| EPTF_Logging_CLL |
| ); |
| |
| if(tsp_IOT_LGen_debug){ |
| f_EPTF_Logging_enableLocalMask(v_IOT_LGen_loggingMaskId, c_IOT_LGen_Logging_DEBUG); |
| } |
| else { |
| f_EPTF_Logging_disableLocalMask(v_IOT_LGen_loggingMaskId, c_IOT_LGen_Logging_DEBUG); |
| } |
| |
| if(tsp_IOT_LGen_debugVerbose) { |
| f_EPTF_Logging_enableLocalMask(v_IOT_LGen_loggingMaskId, c_IOT_LGen_Logging_DEBUGV); |
| } |
| else { |
| f_EPTF_Logging_disableLocalMask(v_IOT_LGen_loggingMaskId, c_IOT_LGen_Logging_DEBUGV); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_LGen_Logging_VERBOSE |
| // |
| // Purpose: |
| // Logging functions for the VERBOSE log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_LGen_Logging_VERBOSE(in @lazy charstring pl_message) |
| runs on IOT_LGen_CT |
| { |
| if (c_EPTF_Common_debugSwitch) { |
| f_EPTF_Logging_debugV2(pl_message, v_IOT_LGen_loggingMaskId, {c_IOT_LGen_Logging_DEBUGV}); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_LGen_Logging_DEBUG |
| // |
| // Purpose: |
| // Logging functions for the DEBUG log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_LGen_Logging_DEBUG(in @lazy charstring pl_message) |
| runs on IOT_LGen_CT |
| { |
| if (c_EPTF_Common_debugSwitch) { |
| f_EPTF_Logging_debugV2(pl_message, v_IOT_LGen_loggingMaskId, {c_IOT_LGen_Logging_DEBUG}); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_LGen_Logging_WARNING |
| // |
| // Purpose: |
| // Logging functions for the WARNING log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_LGen_Logging_WARNING(in @lazy charstring pl_message) |
| runs on IOT_LGen_CT |
| { |
| if (c_EPTF_Common_debugSwitch) { |
| f_EPTF_Logging_debugV2(pl_message, v_IOT_LGen_loggingMaskId, {c_IOT_LGen_Logging_WARNING}); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_LGen_Logging_ERROR |
| // |
| // Purpose: |
| // Logging functions for the ERROR log level |
| // |
| // Parameters: |
| // pl_message - *in* *charstring* - string to be logged |
| // |
| // Related Types: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_LGen_Logging_ERROR(in @lazy charstring pl_message) |
| runs on IOT_LGen_CT |
| { |
| if (c_EPTF_Common_debugSwitch) { |
| f_EPTF_Logging_debugV2(pl_message, v_IOT_LGen_loggingMaskId, {c_IOT_LGen_Logging_ERROR}); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_COAP_LocalTransport_send |
| // |
| // Purpose: |
| // Wrapper of <f_IOT_COAP_LocalTransport_send>, used for |
| // catching outgoing COAP messages. |
| // |
| // Parameters: |
| // pl_msg - *in* <EPTF_COAP_PDU> - outgoing message |
| // |
| // Related Types: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_COAP_LocalTransport_send(in EPTF_COAP_PDU pl_msg) |
| runs on IOT_LGen_CT |
| { |
| f_EPTF_COAP_LocalTransport_send(pl_msg); |
| |
| /* |
| f_EPTF_COAP_PDU_to_Influx( |
| v_IOT_LGen_name & int2str(v_IOT_LGen_idx), |
| "out", |
| pl_msg, |
| v_InfluxDB_msgToSend |
| ); |
| //f_InfluxDB_send(v_InfluxDB_msgToSend); |
| */ |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_COAP_LGen_receiveMessage |
| // |
| // Purpose: |
| // Wrapper of <f_EPTF_COAP_LGen_receiveMessage>, used for |
| // catching and incoming COAP messages. |
| // |
| // Parameters: |
| // pl_message - *in* <EPTF_COAP_PDU> - incoming message |
| // |
| // Related Types: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_COAP_LGen_receiveMessage(in EPTF_COAP_PDU pl_message) |
| runs on IOT_LGen_CT |
| { |
| f_EPTF_COAP_LGen_receiveMessage(pl_message); |
| |
| /* |
| f_EPTF_COAP_PDU_to_Influx( |
| v_IOT_LGen_name & int2str(v_IOT_LGen_idx), |
| "in", |
| pl_message, |
| v_InfluxDB_msgToSend |
| ); |
| f_InfluxDB_send(v_InfluxDB_msgToSend); |
| */ |
| } |
| |
| /* |
| function f_EPTF_COAP_PDU_to_Influx( |
| in charstring p_lgenId, |
| in charstring p_direction, |
| in EPTF_COAP_PDU p_pdu, |
| inout InfluxLineProtocol p_influx) |
| { |
| var charstring vl_mtype := ""; |
| if (p_pdu.pdu.header.msg_type == CONFIRMABLE) { vl_mtype := "CON" } |
| else if (p_pdu.pdu.header.msg_type == NON_CONFIRMABLE) { vl_mtype := "NON" } |
| else if (p_pdu.pdu.header.msg_type == ACKNOWLEDGEMENT) { vl_mtype := "ACK" } |
| else if (p_pdu.pdu.header.msg_type == RESET) { vl_mtype := "RST" } |
| |
| var charstring vl_mcode := "NA"; |
| if (p_pdu.pdu.header.code.class == 0) |
| { |
| if (p_pdu.pdu.header.code.detail == 0) { vl_mcode := "EMPTY"; } |
| else if (p_pdu.pdu.header.code.detail == 1) { vl_mcode := "GET"; } |
| else if (p_pdu.pdu.header.code.detail == 2) { vl_mcode := "POST"; } |
| else if (p_pdu.pdu.header.code.detail == 3) { vl_mcode := "PUT"; } |
| else if (p_pdu.pdu.header.code.detail == 4) { vl_mcode := "DELETE"; } |
| } |
| else |
| { |
| vl_mcode := int2str(p_pdu.pdu.header.code.class*100 + p_pdu.pdu.header.code.detail); |
| } |
| |
| if (not isbound(p_pdu.fsmIdx)) { p_pdu.fsmIdx := -1 } |
| |
| p_influx := c_InfluxLineProtocol_empty; |
| |
| p_influx.measurement := "COAP_PDUs"; |
| |
| f_InfluxDB_addField(p_influx, {name := "direction", val := "\"" & p_direction & "\""}); |
| f_InfluxDB_addField(p_influx, {name := "lgen", val := "\"" & p_lgenId & "\""}); |
| f_InfluxDB_addField(p_influx, {name := "entity", val := int2str(p_pdu.eIdx)}); |
| f_InfluxDB_addField(p_influx, {name := "fsm", val := int2str(p_pdu.fsmIdx)}); |
| f_InfluxDB_addField(p_influx, {name := "ip", val := "\"" & p_pdu.transportParams.localAddress.hostName & "\""}); |
| f_InfluxDB_addField(p_influx, {name := "port", val := int2str(p_pdu.transportParams.localAddress.portNumber)}); |
| f_InfluxDB_addField(p_influx, {name := "token", val := "\"" & oct2str(p_pdu.pdu.token) & "\""}); |
| f_InfluxDB_addField(p_influx, {name := "mid", val := int2str(p_pdu.pdu.header.message_id)}); |
| f_InfluxDB_addField(p_influx, {name := "type", val := "\"" & vl_mtype & "\""}); |
| f_InfluxDB_addField(p_influx, {name := "code", val := "\"" & vl_mcode & "\""}); |
| |
| } |
| */ |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_IOT_LGen_initSamples |
| // |
| // Purpose: |
| // Initializes the *v_IOT_LGen_DataSamples_DB* database by loading |
| // a set of data samples |
| // |
| // Parameters: |
| // p_selfName - *in charstring* - load generator instance's name |
| // |
| // Related Types: |
| // <IOT_LGen_CT> |
| /////////////////////////////////////////////////////////// |
| function f_IOT_LGen_initSamples(in charstring p_selfName) |
| runs on IOT_LGen_CT |
| { |
| f_LwM2M_DataSamples_DB_init(v_IOT_LGen_DataSamples_DB, p_selfName&"_SamplesDB"); |
| |
| for (var integer i:=0; i<sizeof(tsp_IOT_LGen_dataSamples); i:=i+1) |
| { |
| f_LwM2M_DataSamples_DB_add(v_IOT_LGen_DataSamples_DB, tsp_IOT_LGen_dataSamples[i]); |
| } |
| |
| //var LwM2M_DataSamples v_longitudes := c_DataSamples_Longitude; |
| //var LwM2M_DataSamples v_latitudes := c_DataSamples_Latitude; |
| |
| //if (sizeof(v_longitudes.values) != sizeof(v_latitudes.values)) { |
| // f_IOT_LGen_Logging_ERROR("Data sample latitude longitude mismatch!"); |
| //} |
| |
| //f_LwM2M_DataSamples_DB_add(v_IOT_LGen_DataSamples_DB, v_longitudes); |
| //f_LwM2M_DataSamples_DB_add(v_IOT_LGen_DataSamples_DB, v_latitudes); |
| } |
| } |