blob: 40436a54cdcff51356ef60cf02baae64bef3b308 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_CLL_DataSource_Functions
//
// Purpose:
// This module contains the implementation of EPTF_CLL_DataSource functions.
//
// Module depends on:
// <EPTF_CLL_Base_Functions>
// <EPTF_CLL_Common_Functions>
// <EPTF_CLL_Common_Definitions>
// <EPTF_CLL_Variable_Functions>
// <EPTF_CLL_Variable_Definitions>
// <EPTF_CLL_DataSource_Definitions>
// <EPTF_CLL_Semaphore_Functions>
// <EPTF_CLL_HashMapStr2Int_Functions>
// <EPTF_CLL_HashMap_Functions>
//
// Module Parameters:
// tsp_EPTF_DataSource_maxWaitTime - float - max wait time for response (dafault:10.0)
//
// Current Owner:
// Jozsef Gyurusi (ethjgi)
//
// Last Review Date:
// 2011-02-03
//
// Detailed Comments:
// This module contains the interface functions for the EPTF_CLL_DataSource.
// The DataSource feature makes it possible to access application data
// remotely using "feature name", "ptc name" as the dataSource ID and
// "data element" and "parameters" to get the data for a given data type.
// The data value is a variable name that contains the value of the data.
// The variable is created locally in the background with the given refresh rate.
// An example:
// ExecCtrl registers itself as a dataSource with "ExecCtrl" as the feature name
// and "MyExecCtrl" as ptc name. Its handler function can provide data for example
// for the Scenarios in a given entity group. This means that the <f_EPTF_DataSource_getData>
// function will return a variable name that contains this list of scenarios. The dataElement
// parameter in this case is "ScenariosOfEGrp" and the parameter can be "EG1" to get the scenario list
// for this entity group. The handler function registered in ExecCtrl has to be able to
// process the "ScenariosOfEGrp" dataelement with the "EG1" as parameter.
//
// Public functions:
// <f_EPTF_DataSource_init_CT>
// <f_EPTF_DataSource_getData>
// <f_EPTF_DataSource_getDataValue>
// <f_EPTF_DataSource_getDataValue_nonblocking>
// <f_EPTF_DataSource_setDataValue>
// <f_EPTF_DataSource_setDataValue_nonblocking>
// <f_EPTF_DataSource_getData_nonBlocking>
// <f_EPTF_DataSource_checkData>
// <f_EPTF_DataSource_checkData_nonblocking>
// <f_EPTF_DataSource_checkDataValue_nonblocking>
// <f_EPTF_DataSource_enableUpdate>
// <f_EPTF_DataSource_disableUpdate>
// <f_EPTF_DataSource_getRequestPartsFromParams>
// <f_EPTF_DataSource_getSizeOfDataValue>
// <f_EPTF_DataSource_getHelpTEXT>
// <f_EPTF_DataSource_getHelpJSON>
// <f_EPTF_DataSource_getHelpApidoc>
// <f_EPTF_DataSource_handleHelp>
// <f_EPTF_DataSource_getCondition>
// <f_EPTF_DataSource_getCondition_nonBlocking>
// <f_EPTF_DataSource_registerReadyCallback>
// <f_EPTF_DataSource_getParams>
// <f_EPTF_DataSource_extractParams>
// <f_EPTF_DataSource_replaceParams>
//
// DataSource with CLI:
// <f_EPTF_DataSource_CLI_init_CT>
//
// All other functions in this module are private!
//
///////////////////////////////////////////////////////////////
module EPTF_CLL_DataSource_Functions {
import from EPTF_CLL_Base_Functions all;
//import from EPTF_CLL_Common_Functions all;
import from EPTF_CLL_Common_Definitions all;
import from EPTF_CLL_Variable_Functions all;
import from EPTF_CLL_Variable_Definitions all;
import from EPTF_CLL_DataSource_Definitions all;
import from EPTF_CLL_Semaphore_Functions all;
import from EPTF_CLL_HashMapStr2Int_Functions all;
import from EPTF_CLL_Logging_Functions all;
import from EPTF_CLL_HashMap_Functions all;
import from EPTF_CLL_Logging_Definitions all;
import from EPTF_CLL_CLI_Definitions all;
import from EPTF_CLL_CLI_Functions all;
import from ttcn_ericsson_se_protocolModules_xtdp_xtdl all;
friend module EPTF_CLL_DataSourceClient_Functions;
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_init_CT
//
// Purpose:
// Init function for DataSource_CT
//
// Parameters:
// *in charstring pl_selfName* - the name of the component
//
// Return Value:
// -
//
// Detailed Comments:
// Has to be called before any other DataSource
// function is used
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_init_CT(in charstring pl_selfName) runs on EPTF_DataSource_CT {
if (v_EPTF_DataSource_initialized) {
return;
}
f_EPTF_Base_init_CT(pl_selfName);
f_EPTF_Var_init_CT(pl_selfName);
f_EPTF_Semaphore_init_CT(pl_selfName);
f_EPTF_HashMap_init_CT(pl_selfName);
v_DataSource_handler := activate(as_EPTF_DataSource_EventHandler());
v_EPTF_DataSource_initialized := true;
f_EPTF_Base_registerCleanup(refers(f_EPTF_DataSource_cleanup_CT));
v_EPTF_DataSource_DataHandler_List := {};
v_EPTF_DataSource_DataHandlerHash := f_EPTF_str2int_HashMap_New(c_EPTF_DataSource_dataHandlerHashName);
v_EPTF_DataSource_DataHandlerHash_NoPTCName := f_EPTF_str2int_HashMap_New(c_EPTF_DataSource_dataHandlerHashName_NoPTCName);
v_EPTF_DataSource_dataValue_List := {};
v_EPTF_DataSource_dataValueHash := f_EPTF_str2int_HashMap_New(c_EPTF_DataSource_dataValueHashName);
v_EPTF_DataSource_pendingGetDataHash := f_EPTF_str2int_HashMap_New(c_EPTF_DataSource_pendingGetDataHashName);
// create the iterator variable for c_EPTF_DataSource_dataElement_Sources, initial value: my source name (I am also a dataSource):
var integer vl_varIdx;
f_EPTF_Var_newCharstringlist(c_EPTF_DataSource_externalDataVar_prefix&"."&c_EPTF_DataSource_dataElement_Sources, {c_EPTF_DataSource_sourceId}, vl_varIdx);
// create the PTCs variable for DataSource itself:
var charstring pl_dataVarName := c_EPTF_DataSource_externalDataVar_prefix&"."&c_EPTF_DataSource_dataElement_PTCs&"."&c_EPTF_DataSource_sourceId;
f_EPTF_Var_newCharstringlist(pl_dataVarName, {f_EPTF_Base_selfName()}, vl_varIdx);
v_EPTF_DataSource_Msg_List := {};
v_EPTF_DataSource_GetDataHandler_DB := {};
v_EPTF_DataSource_GetDataValueHandler_DB := {};
v_EPTF_DataSource_Msg_GetData_Buffer := {};
v_EPTF_DataSource_Msg_GetData_BufferStartIdx := 0;
v_EPTF_DataSource_nofPendingGetData := 0;
v_EPTF_DataSource_getDataMsgClusters := {};
v_EPTF_DataSource_getDataMsgClusters_BufferEmpty := true;
}
///////////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_compare
//
// Purpose:
// Compares two EPTF_DataSource_Param arguments by their paramName.
//
// Parameters:
// *in* <EPTF_DataSource_Param> *pl_par1* - the first parameter to compare
// *in* <EPTF_DataSource_Param> *pl_par2* - the second parameter to compare
//
// Return Value:
// integer - The function returns an integer greater than, equal to, or
// less than 0, if the string pointed to by pl_par1.paramName is greater
// than, equal to, or less than the string pointed to by pl_par2.paramName
// respectively.
//
// Errors:
// -
//
// Detailed Comments:
// Works similar to strcmp. For more details see its man page (man strcmp).
//
///////////////////////////////////////////////////////////////////////////////
private external function f_EPTF_DataSource_compare(in EPTF_DataSource_Param pl_par1, in EPTF_DataSource_Param pl_par2) return integer;
///////////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_bubblesort
//
// Purpose:
// Sorts the argument in increasing order using the bubble-sort algorithm.
//
// Parameters:
// *inout* <EPTF_DataSource_Params> *pl_list* - the list of parameters to sort,
// When the function returns it will be sorted by a bubble-sort algorithm.
//
// Return Value:
// -
//
// Errors:
// -
//
// Detailed Comments:
// The parameters are sorted by thier paramNames lexically.
//
///////////////////////////////////////////////////////////////////////////////
private function f_EPTF_DataSource_bubblesort(inout EPTF_DataSource_Params pl_list) {
var integer n := sizeof(pl_list);
var integer k;
var integer bound := n-1;
var EPTF_DataSource_Param t;
var integer last_swap;
while (bound!=0) {
last_swap := 0;
for ( k:=0; k<bound; k:=k+1 ) {
t := pl_list[k]; // t is a maximum of A[0]..A[k]
if ( f_EPTF_DataSource_compare(t,pl_list[k+1])>0 ) {
pl_list[k] := pl_list[k+1]; pl_list[k+1] := t; //swap
last_swap := k; // mark the last swap position
}//if
}//for
bound:=last_swap; // elements after bound already sorted
}//while
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_sortParams
//
// Purpose:
// Orders the given parameters lexicographically with respect to the paramNames;
//
// Parameters:
// *inout* <EPTF_DataSource_Params> *pl_params* - contains the parameters to sort.
// When the function returns it will be sorted
//
// Return Value:
// -
//
// Detailed Comments:
// -
///////////////////////////////////////////////////////////
friend function f_EPTF_DataSource_sortParams(inout EPTF_DataSource_Params pl_params) {
f_EPTF_DataSource_bubblesort(pl_params);
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getData
//
// Purpose:
// To get the name of the variable that contains the value of the given data
//
// Parameters:
// *out charstring pl_dataVarName* - this is the name of the variable
// that stores the values of the data on the local component
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
// *in* <EPTF_Var_SubscriptionMode> - pl_subscriptionMode - subscription mode: sampled or timeLine: buffered; realtime: non-buffered
// Default: tsp_EPTF_DataSource_subscriptionMode
// *in integer* - pl_refreshRate - the refresh rate for the subscription.
// default: tsp_EPTF_DataSource_refreshRate
//
// Return Value:
// integer - 0 if OK, nonzero in case of failure to show that the pl_dataVarName is not valid
//
// Detailed Comments:
// This function will make a request for the given data source and return the name of the
// variable that contains the value of the data.
//
// How it works:
// The request is forwarded to the appropriate DataSourceClient which registered
// the source and ptc name. On the client the handler function registered by
// <f_EPTF_DataSourceClient_registerData> for the given pl_source and pl_ptcName is called.
// The pl_params are passed to it as additional arguments.
// The handler function returns a charstring which is set in the pl_dataVarName
// argument. The error code returned by the handler function is returned by this function.
// A local variable is created which is subscribed to the variable returned by the handler.
// The name of the local variable is returned by this function in the pl_dataVarName argument.
// In case of non-zero return value the pl_dataVarName parameter may contain an error message.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getData(
out charstring pl_dataVarName,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_Var_SubscriptionMode pl_subscriptionMode := tsp_EPTF_DataSource_subscriptionMode,
in integer pl_refreshRate := tsp_EPTF_DataSource_refreshRate
) runs on EPTF_DataSource_CT return integer {
f_EPTF_DataSource_sortParams(pl_params);
if (pl_source==c_EPTF_DataSource_sourceId) {
var integer vl_errorCode := f_EPTF_DataSource_handleBuiltInDataElements(
pl_dataVarName,
pl_source,
pl_ptcName,
pl_element,
pl_params
); // internal elements handled successfully, or an error occured
if (vl_errorCode!=0) {
//append general text:
pl_dataVarName := log2str(%definitionId&": Invalid iterator or externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&"\n:"&pl_dataVarName;
f_EPTF_DataSource_warning(pl_dataVarName);
}
return vl_errorCode;
}
pl_dataVarName := "";
var integer vl_localDataVarId;
var EPTF_Var_CT vl_ownerCompRef;
var charstring vl_remoteDataVarName; // for nonzero error code it contains the error message
//find if pl_dataVarName already exists
var charstring vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params);
var integer vl_dataValueId;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) {
if (vl_dataValueId==-1) {
// PTC name is not given, but should be specified
pl_dataVarName := "";
return 1;
}
vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId);
// check if var exists: it is needed because checkData does not create it, but stores it in the hashMap
// if var is not subscribed, subscribe is needed => no error if variable is not found
if(f_EPTF_Var_checkSubscriptionMode(vl_localDataVarId,pl_subscriptionMode)) {
return 0;
}
vl_remoteDataVarName := v_EPTF_DataSource_dataValue_List[vl_dataValueId].remoteDataVarName;
vl_ownerCompRef := v_EPTF_DataSource_dataValue_List[vl_dataValueId].ownerCompRef;
} else {
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered"));
return 3;
} else {
if (vl_counter>1) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified"));
return 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered"));
return 4;
}
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered"));
return 1;
}
}
}
// here if pl_dataVarName != "" : only subscribe required
// if pl_dataVarName == "" : have to send message to client, because no local data was found
var integer vl_errorCode := 0;
if (pl_dataVarName=="") {
// dataVarName was not found in hashMaps, have to send request to client:
var integer vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getData:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
// wait for response
if (f_EPTF_Semaphore_waitForUnlock(vl_getDataId,tsp_EPTF_DataSource_maxWaitTime)) {
// max wait time expired before response received:
f_EPTF_DataSource_warning(log2str(%definitionId&": Communication error: No response received for getData message: ",vl_getDataId));
pl_dataVarName := "";
return -1;
}
// copy the values from the message database because it might be possible that they will be overwritten because
// the semaphore is released and there is a blocking statement before they are used:
vl_errorCode := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.errorCode;
//var EPTF_DataSourceClient_CT vl_ownerCompRef := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.ownerCompRef; // value in message is not used
vl_remoteDataVarName := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.dataVarName;
// this will always be true if errorCode == 0:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) {
vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId);
}
}
// if returned error code is 0 (no error) subscibe to the provider data variable:
if (vl_errorCode==0) {
// here the local variable exists: was created when getData response was received
f_EPTF_Var_resubscribeRemote(
vl_ownerCompRef,
vl_remoteDataVarName,
pl_subscriptionMode,
vl_localDataVarId,
pl_dataVarName,
pl_refreshRate
);
} else {
pl_dataVarName := vl_remoteDataVarName; // pass on the error message
//append general text:
pl_dataVarName := log2str(%definitionId&": Invalid iterator or externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&"\n:"&pl_dataVarName;
f_EPTF_DataSource_warning(pl_dataVarName);
pl_dataVarName := "";
}
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getDataValue
//
// Purpose:
// To get the value of the given data
//
// Parameters:
// *out* <EPTF_Var_DirectContent> *pl_dataValue* - this is the value of the data requested
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
//
// Return Value:
// integer - 0 if OK, nonzero in case of failure to show that the pl_dataValue is not valid
//
// Detailed Comments:
// This function will make a request for the given data source and return the value of the data.
//
// How it works:
// The request is forwarded to the appropriate DataSourceClient which registered
// the source and ptc name. On the client the handler function registered by
// <f_EPTF_DataSourceClient_registerDataValue> for the given pl_source and pl_ptcName is called.
// The pl_params are passed to it as additional arguments.
// The handler function returns a value together with the error code.
// These values are returned by this function in the pl_dataValue parameter and its return value.
//
// In case of nonzero return value pl_dataValue may contain an error message.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getDataValue(
out EPTF_Var_DirectContent pl_dataValue,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_Filter pl_filter := c_EPTF_DataSource_Filter_empty
) runs on EPTF_DataSource_CT return integer {
if (pl_source==c_EPTF_DataSource_sourceId) {
var integer vl_errorCode := f_EPTF_DataSource_handleBuiltInDataValues(
pl_dataValue,
pl_source,
pl_ptcName,
pl_element,
pl_params,
pl_filter
); // internal elements handled successfully, or an error occured
if (vl_errorCode!=0) {
if (not ischosen(pl_dataValue.charstringVal)) {
pl_dataValue := {charstringVal := "Error info: "&ttcn2string(pl_dataValue)}; // error message was not present => set it to the string value of provided value
}
//append general text:
pl_dataValue.charstringVal := log2str(%definitionId&": Invalid iterator or externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&
"\nReason: "&pl_dataValue.charstringVal;
f_EPTF_DataSource_warning(pl_dataValue.charstringVal&"\nError code: "&int2str(vl_errorCode));
}
return vl_errorCode;
}
var EPTF_Var_CT vl_ownerCompRef;
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
return 3;
} else {
if (vl_counter>1) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
return 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered")
return 4;
}
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
return 1;
}
}
// Now have to send message to client to get the value
var integer vl_errorCode := 0;
// have to send request to client:
var integer vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getDataValue:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params,
pl_filter
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
// wait for response
if (f_EPTF_Semaphore_waitForUnlock(vl_getDataId,tsp_EPTF_DataSource_maxWaitTime)) {
// max wait time expired before response received:
f_EPTF_DataSource_warning(log2str(%definitionId&": Communication error: No response received for getData message: ",vl_getDataId));
pl_dataValue.charstringVal := log2str(%definitionId&": Communication error: No response received for getData message: ",vl_getDataId);
return -1;
}
// copy the values from the message database because it might be possible that they will be overwritten because
// the semaphore is released and there is a blocking statement before they are used:
vl_errorCode := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValueResponse.errorCode;
pl_dataValue := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValueResponse.dataValue;
//var EPTF_DataSourceClient_CT vl_ownerCompRef := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.ownerCompRef; // value in message is not used
// if returned error code is non-0, update the error message:
if (vl_errorCode!=0) {
if (not ischosen(pl_dataValue.charstringVal)) {
pl_dataValue := {charstringVal := "Error info: "&ttcn2string(pl_dataValue)}; // error message was not present => set it to the string value of provided value
//append general text:
pl_dataValue.charstringVal := log2str(%definitionId&": Invalid iterator or externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&
"\nReason: "&pl_dataValue.charstringVal;
}
f_EPTF_DataSource_warning(pl_dataValue.charstringVal&"\nError code: "&int2str(vl_errorCode));
}
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getDataValue_nonblocking
//
// Purpose:
// To get the value of a given data in non-blocking way.
// The specified handler is called when the response arrives.
//
// Parameters:
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
// *in* <EPTF_DataSource_GetDataValueHandler> *pl_getDataValueHandler* - the handler function (with user arguments) to call
// when response is received
//
// Return Value:
// integer - 0 if OK, nonzero in case of the request is not valid
//
// Detailed Comments:
// This function will make a request for the given data source and return the value of the data.
//
// How it works:
// The request is forwarded to the appropriate DataSourceClient which registered
// the source and ptc name. On the client the handler function registered by
// <f_EPTF_DataSourceClient_registerDataValue> for the given pl_source and pl_ptcName is called.
// The pl_params are passed to it as additional arguments.
// The handler function returns a value together with the error code.
// These values are passed to the given handler in pl_getDataValueHandler.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getDataValue_nonblocking(
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_Filter pl_filter := c_EPTF_DataSource_Filter_empty,
in EPTF_DataSource_GetDataValueHandler pl_getDataValueHandler := cg_EPTF_DataSource_GetDataValueHandler_null
) runs on EPTF_DataSource_CT return integer {
var EPTF_Var_DirectContent vl_dataValue;
var integer vl_errorCode := 0;
if (pl_source==c_EPTF_DataSource_sourceId) {
vl_errorCode := f_EPTF_DataSource_handleBuiltInDataValues_nonblocking(
pl_source,
pl_ptcName,
pl_element,
pl_params,
pl_filter,
pl_getDataValueHandler
); // internal elements handled successfully, or an error occured
return vl_errorCode;
}
var EPTF_Var_CT vl_ownerCompRef := null;
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
vl_errorCode := 3;
} else {
if (vl_counter>1) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
vl_errorCode := 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered")
vl_errorCode := 4;
} else {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
vl_errorCode := 1;
}
}
}
if (vl_errorCode!=0) {
// call handler:
if (pl_getDataValueHandler.getDataValueHandler!=null) {
pl_getDataValueHandler.getDataValueHandler.apply(
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_dataValue := vl_dataValue, // the value of the data. In case errorCode!=0: it contains the error message as charstringVal
// user data
pl_userData := pl_getDataValueHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
} else {
// Now have to send message to client to get the value
var integer vl_getDataId := f_EPTF_Semaphore_new();
v_EPTF_DataSource_GetDataValueHandler_DB[vl_getDataId] := pl_getDataValueHandler;
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getDataValue:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params,
pl_filter
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
}
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_setDataValue
//
// Purpose:
// To set the value of a given data
//
// Parameters:
// *inout* <EPTF_Var_DirectContent> *pl_dataValue* - this is the value of the data requested
// after call, it will return the changed value that might be different
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
// *in* <EPTF_CharstringList> *pl_indexList* - in case of list-type values the elements of this parameter
// are the indexes in the list-type data for which the values should be set
// For elementary type values this argument is not used
//
// Return Value:
// integer - 0 if OK, nonzero in case of setting the value is unsuccessful
//
// Detailed Comments:
// This function will make a request for the given data source and return the new value of the data.
//
// How it works:
// The request is forwarded to the appropriate DataSourceClient which registered
// the source and ptc name. On the client the handler function registered by
// <f_EPTF_DataSourceClient_registerSetDataValue> for the given pl_source and pl_ptcName is called.
// The pl_params are passed to it as additional arguments.
// The handler function returns the new value together with the error code.
// The new value is then returned in pl_dataValue, and the error code in the return value of this function.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_setDataValue(
inout EPTF_Var_DirectContent pl_dataValue,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_IntegerList pl_indexList := {}
) runs on EPTF_DataSource_CT return integer {
if (pl_source==c_EPTF_DataSource_sourceId) {
return f_EPTF_DataSource_handleBuiltInSetDataValue(
pl_dataValue,
pl_source,
pl_ptcName,
pl_element,
pl_params
); // internal elements handled successfully, or an error occured
}
var EPTF_Var_CT vl_ownerCompRef;
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
return 3;
} else {
if (vl_counter>1) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
return 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered");
return 4;
}
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered"));
pl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
return 1;
}
}
// Now have to send message to client to set the value
var integer vl_errorCode := 0;
// have to send request to client:
var integer vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{setDataValue:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params,
pl_dataValue,
pl_indexList
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
// wait for response
if (f_EPTF_Semaphore_waitForUnlock(vl_getDataId,tsp_EPTF_DataSource_maxWaitTime)) {
// max wait time expired before response received:
f_EPTF_DataSource_warning(log2str(%definitionId&": Communication error: No response received for getData message: ",vl_getDataId));
return -1;
}
// copy the values from the message database because it might be possible that they will be overwritten because
// the semaphore is released and there is a blocking statement before they are used:
vl_errorCode := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValueResponse.errorCode;
pl_dataValue := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValueResponse.dataValue;
//var EPTF_DataSourceClient_CT vl_ownerCompRef := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.ownerCompRef; // value in message is not used
// if returned error code is non-0, update the error message:
if (vl_errorCode!=0) {
if (not ischosen(pl_dataValue.charstringVal)) {
pl_dataValue := {charstringVal := "Error info: "&ttcn2string(pl_dataValue)}; // error message was not present => set it to the string value of provided value
}
//append general text:
pl_dataValue.charstringVal := log2str(%definitionId&": Read-only data or invalid iterator, externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&
"\nReason: "&pl_dataValue.charstringVal;
f_EPTF_DataSource_warning(pl_dataValue.charstringVal&"\nError code: "&int2str(vl_errorCode));
}
return vl_errorCode;
}
//FIXME: schedule handler call if data is already available
// (=return statements)
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_setDataValue_nonblocking
//
// Purpose:
// To set the value of a given data in non-blocking way.
// The specified handler is called when the response arrives.
//
// Parameters:
// *in* <EPTF_Var_DirectContent> *pl_dataValue* - this is the value of the data requested
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
// *in* <EPTF_CharstringList> *pl_indexList* - in case of list-type values the elements of this parameter
// are the indexes in the list-type data for which the values should be set
// For elementary type values this argument is not used
// *in* <EPTF_DataSource_GetDataValueHandler> - pl_setDataValueHandler - the handler function (with user arguments) to call
// when response is received
//
// Return Value:
// integer - 0 if OK, nonzero in case of the request is not valid
//
// Detailed Comments:
// This function will make a request for the given data source and call the specified handler with the new value of the data.
//
// How it works:
// The request is forwarded to the appropriate DataSourceClient which registered
// the source and ptc name. On the client the handler function registered by
// <f_EPTF_DataSourceClient_registerSetDataValue> for the given pl_source and pl_ptcName is called.
// The pl_params are passed to it as additional arguments.
// The handler function returns the new value together with the error code returned by the handler function.
// Then the specified handler pl_setDataValueHandler is called with these values.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_setDataValue_nonblocking(
in EPTF_Var_DirectContent pl_dataValue,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_IntegerList pl_indexList := {},
in EPTF_DataSource_GetDataValueHandler pl_setDataValueHandler := cg_EPTF_DataSource_GetDataValueHandler_null
) runs on EPTF_DataSource_CT return integer {
var EPTF_Var_DirectContent vl_dataValue := pl_dataValue;
var integer vl_errorCode;
if (pl_source==c_EPTF_DataSource_sourceId) {
// f_EPTF_DataSource_handleBuiltInSetDataValue is nonblocking
vl_errorCode := f_EPTF_DataSource_handleBuiltInSetDataValue(
vl_dataValue,
pl_source,
pl_ptcName,
pl_element,
pl_params
); // internal elements handled successfully, or an error occured
// call handler:
if (pl_setDataValueHandler.getDataValueHandler!=null) {
pl_setDataValueHandler.getDataValueHandler.apply(
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_setDataValueHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
vl_errorCode := 0;
var EPTF_Var_CT vl_ownerCompRef := null;
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
vl_errorCode := 3;
} else {
if (vl_counter>1) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
vl_errorCode := 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered");
vl_errorCode := 4;
}
f_EPTF_DataSource_warning(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered"));
vl_dataValue.charstringVal := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
vl_errorCode := 1;
}
if (vl_errorCode!=0) {
// call handler:
if (pl_setDataValueHandler.getDataValueHandler!=null) {
pl_setDataValueHandler.getDataValueHandler.apply(
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_setDataValueHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
}
// have to send request to client to set the value
var integer vl_getDataId := f_EPTF_Semaphore_new();
v_EPTF_DataSource_GetDataValueHandler_DB[vl_getDataId] := pl_setDataValueHandler;
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{setDataValue:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params,
vl_dataValue,
pl_indexList
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getData_nonBlocking
//
// Purpose:
// To get the name of the variable that contains the value of a given data in non-blocking way.
// The specified handler is called when the response arrives.
//
// Parameters:
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
// *in* <EPTF_DataSource_GetDataHandler> - pl_getDataHandler - the handler function (with user arguments) to call
// when response is received
// // *in* <EPTF_Var_SubscriptionMode> - pl_subscriptionMode - subscription mode: sampled or timeLine: buffered; realtime: non-buffered
// // Default: tsp_EPTF_DataSource_subscriptionMode
// // *in integer* - pl_refreshRate - the refresh rate for the subscription.
// // default: tsp_EPTF_DataSource_refreshRate
//
// Return Value:
// integer - 0 if OK, nonzero if dataSource request is not valid. In both cases the handler will be called.
//
// Detailed Comments:
// Sends a request to the main DataSourceClient_CT component
// to request the EPTF Variable name for the given dataSource.
// On the component that registered the source and ptc name
// the handler function registered by <f_EPTF_DataSourceClient_registerData>
// for the given pl_source and pl_ptcName is called.
// The pl_params are passed to it as additional arguments.
//
// When the response arrives from the client, the
// given pl_getDataHandler handler function is called with all information received.
// A local variable is created which stores the current value of the dataSource,
// but this variable is not subscribed to the data owner.
//
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getData_nonBlocking(
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_GetDataHandler pl_getDataHandler := cg_EPTF_DataSource_GetDataHandler_null
// in EPTF_Var_SubscriptionMode pl_subscriptionMode := tsp_EPTF_DataSource_subscriptionMode,
// in integer pl_refreshRate := tsp_EPTF_DataSource_refreshRate
) runs on EPTF_DataSource_CT return integer {
var charstring pl_dataVarName;
f_EPTF_DataSource_sortParams(pl_params);
if (pl_source==c_EPTF_DataSource_sourceId) {
var integer vl_errorCode := f_EPTF_DataSource_handleBuiltInDataElements(
pl_dataVarName,
pl_source,
pl_ptcName,
pl_element,
pl_params
); // internal elements handled successfully, or an error occured
// call handler:
if (pl_getDataHandler.getDataHandler!=null) {
var integer vl_localDataVarId := f_EPTF_Var_getId(pl_dataVarName);
var EPTF_Var_DirectContent vl_dataValue := {unknownVal:={omit}};
if(vl_localDataVarId!=-1) {
f_EPTF_Var_getContent(vl_localDataVarId,vl_dataValue);
}
pl_getDataHandler.getDataHandler.apply(
//request parameters:
pl_source := pl_source,
pl_ptcName := f_EPTF_Base_selfName(), // response may fill this if it was ""
pl_element := pl_element,
pl_params := pl_params,
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_remoteDataVarName := pl_dataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message
pl_ownerCompRef := self, // reference to the remote component
pl_localDataVarId := vl_localDataVarId, // var id on the local component (contains the current value, not subscribed to remote!)
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_getDataHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
pl_dataVarName := "";
var integer vl_errorCode;
var EPTF_Var_CT vl_ownerCompRef;
var charstring vl_remoteDataVarName; // for nonzero error code it contains the error message
var integer vl_localDataVarId;
var EPTF_Var_DirectContent vl_dataValue;
//find if pl_dataVarName already exists
var charstring vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params);
var integer vl_dataValueId;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) {
if (vl_dataValueId==-1) {
// PTC name is not given, but should be specified
vl_errorCode := 1;
vl_remoteDataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": PTC name is not given, but should be specified since more than one PTC exist with the same source.");
vl_ownerCompRef := null;
vl_localDataVarId := -1;
vl_dataValue := {unknownVal:={omit}};
} else {
// pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId);
vl_errorCode := 0;
vl_remoteDataVarName := v_EPTF_DataSource_dataValue_List[vl_dataValueId].remoteDataVarName;
vl_ownerCompRef := v_EPTF_DataSource_dataValue_List[vl_dataValueId].ownerCompRef;
vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
vl_dataValue := {unknownVal:={omit}};
if(vl_localDataVarId!=-1) {
f_EPTF_Var_getContent(vl_localDataVarId,vl_dataValue);
}
}
// call handler:
if (pl_getDataHandler.getDataHandler!=null) {
pl_getDataHandler.getDataHandler.apply(
//request parameters:
pl_source := pl_source,
pl_ptcName := pl_ptcName, // response may fill this if it was ""
pl_element := pl_element,
pl_params := pl_params,
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_remoteDataVarName := vl_remoteDataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message
pl_ownerCompRef := vl_ownerCompRef, // reference to the remote component
pl_localDataVarId := vl_localDataVarId, // var id on the local component (contains the current value, not subscribed to remote!)
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_getDataHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
} else {
vl_errorCode := 0;
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
pl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
f_EPTF_DataSource_warning(pl_dataVarName);
vl_errorCode := 3;
} else {
if (vl_counter>1) {
pl_dataVarName := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
f_EPTF_DataSource_warning(pl_dataVarName);
vl_errorCode := 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
pl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered");
f_EPTF_DataSource_warning(pl_dataVarName);
vl_errorCode := 4;
} else {
pl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
f_EPTF_DataSource_warning(pl_dataVarName);
vl_errorCode := 1;
}
}
}
if (vl_errorCode!=0) {
// call handler:
if (pl_getDataHandler.getDataHandler!=null) {
vl_remoteDataVarName := pl_dataVarName;
vl_ownerCompRef := null;
vl_localDataVarId := -1;
vl_dataValue := {unknownVal:={omit}};
pl_getDataHandler.getDataHandler.apply(
//request parameters:
pl_source := pl_source,
pl_ptcName := pl_ptcName, // response may fill this if it was ""
pl_element := pl_element,
pl_params := pl_params,
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_remoteDataVarName := vl_remoteDataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message
pl_ownerCompRef := vl_ownerCompRef, // reference to the remote component
pl_localDataVarId := vl_localDataVarId, // var id on the local component (contains the current value, not subscribed to remote!)
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_getDataHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
}
// here if pl_dataVarName != "" : only subscribe required
// if pl_dataVarName == "" : have to send message to client, because no local data was found
vl_errorCode := 0;
if (pl_dataVarName=="") {
// dataVarName was not found in hashMaps, have to send request to client:
//recalculate vl_dataValueIdStr with given PTCName:
vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params);
var integer vl_getDataId;
// check if there is a pending request:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_pendingGetDataHash,vl_dataValueIdStr,vl_getDataId)) {
v_EPTF_DataSource_GetDataHandler_DB[vl_getDataId] := v_EPTF_DataSource_GetDataHandler_DB[vl_getDataId] & {pl_getDataHandler};
} else {
//FIXME: use FBQ instead of semaphore:
vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSource_pendingGetDataHash,vl_dataValueIdStr,vl_getDataId);
v_EPTF_DataSource_GetDataHandler_DB[vl_getDataId] := {pl_getDataHandler};
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getData:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
}
}
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_checkData
//
// Purpose:
// To check if the value of a given data exists. Returns the variable name
// of the dataSource.
//
// Parameters:
// *out charstring pl_dataVarName* - this is the name of the variable
// that stores the values of the data on the local component
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
//
// Return Value:
// integer - 0 if OK, nonzero if pl_dataVarName is not valid
//
// Detailed Comments:
// This function is almost the same as <f_EPTF_DataSource_getData>, but
// does not subscribe to the provider variable and does not check the subscription.
// It only checks if the source variable is there on the source component.
// The returned variable might not exist even if the error code is zero.
// For non-zero error code, pl_dataVarName contains the error message
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_checkData(
out charstring pl_dataVarName,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {}
) runs on EPTF_DataSource_CT return integer {
f_EPTF_DataSource_sortParams(pl_params);
if (pl_source==c_EPTF_DataSource_sourceId) {
return f_EPTF_DataSource_handleBuiltInDataElements(
pl_dataVarName,
pl_source,
pl_ptcName,
pl_element,
pl_params
); // internal elements handled successfully, or an error occured
}
pl_dataVarName := "";
var EPTF_Var_CT vl_ownerCompRef;
//find if pl_dataVarName already exists
var charstring vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params);
var integer vl_dataValueId;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) {
if (vl_dataValueId==-1) {
// PTC name is not given, but should be specified
pl_dataVarName := "";
return 1;
}
var integer vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId);
return 0;
} else {
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
pl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
f_EPTF_DataSource_debug(pl_dataVarName);
return 3;
} else {
if (vl_counter>1) {
pl_dataVarName := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
f_EPTF_DataSource_debug(pl_dataVarName);
return 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
pl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered");
f_EPTF_DataSource_debug(pl_dataVarName);
return 4;
}
pl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
f_EPTF_DataSource_debug(pl_dataVarName);
return 1;
}
}
}
var integer vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getData:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
// wait for response
if (f_EPTF_Semaphore_waitForUnlock(vl_getDataId,tsp_EPTF_DataSource_maxWaitTime)) {
// max wait time expired before response received:
f_EPTF_DataSource_debug(log2str(%definitionId&": Communication error: No response received for getData message: ",vl_getDataId));
pl_dataVarName := "";
return -1;
}
// copy the values from the message database because it might be possible that they will be overwritten because
// the semaphore is released and there is a blocking statement before they are used:
var integer vl_errorCode := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.errorCode;
//var EPTF_DataSourceClient_CT vl_ownerCompRef := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.ownerCompRef; // value in message is not used
var charstring vl_remoteDataVarName := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.dataVarName;
// this will always be true if errorCode == 0:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) {
var integer vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId);
}
// // remove the stored data from the dataBase:
// // by removing the returned varname from a hashmap, and clearing the stored variable name:
// if(vl_errorCode==0) {
// vl_dataValueIdStr2 := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.dataSource&"@"&v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.ptcName&
// "."&v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.dataElement&":"&log2str(v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.params);
//
// if(f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr2,vl_dataValueId)) {
// f_EPTF_str2int_HashMap_Erase(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr2);
// v_EPTF_DataSource_dataValue_List[vl_dataValueId] := {""};
// }
// }
//
// if returned error code is 0 (no error) check if the data variable is present on the provider:
if (vl_errorCode==0) {
// var charstring vl_localVarName := "EPTF_DataSource_"&vl_remoteDataVarName&"."&vl_dataValueIdStr;
// var integer vl_localVarIdx;
// if (not f_EPTF_Var_isPresentRemote(
// v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef,
// vl_remoteDataVarName
// )) {
// pl_dataVarName := log2str(%definitionId&": Cannot find the data variable of the dataSource: "&
// "The variable does not exist for dataSource ",pl_source, " ptcName ",pl_ptcName, " element ", pl_element, " params ", pl_params);
// f_EPTF_DataSource_debug(pl_dataVarName);
// return 5;
// }
// pl_dataVarName := vl_localVarName;
} else {
pl_dataVarName := vl_remoteDataVarName; // pass on the error message
//append general text:
pl_dataVarName := log2str(%definitionId&": Invalid iterator or externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&"\n:"&pl_dataVarName;
f_EPTF_DataSource_debug(pl_dataVarName);
}
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_checkData_nonblocking
//
// Purpose:
// To check if the value of a given data exists in non-blocking way.
// The specified handler is called when the response arrives.
//
// Parameters:
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
// *in* <EPTF_DataSource_GetDataHandler> - pl_checkDataHandler - the handler function (with user arguments) to call
// when response is received
//
// Return Value:
// integer - 0 if OK, nonzero if pl_dataVarName is not valid or data does not exist
//
// Detailed Comments:
// This function is almost the same as <f_EPTF_DataSource_checkData>, but
// does not subscribe to the provider variable and does not check the subscription.
// It only checks if the source variable is there on the source component.
// The variable with the name passed to the handler might not exist locally even if the error code is zero.
// For non-zero error code, pl_dataVarName of the handler contains the error message.
// The specified handler pl_checkDataHandler is called with the response data
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_checkData_nonblocking(
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_GetDataHandler pl_checkDataHandler := cg_EPTF_DataSource_GetDataHandler_null
) runs on EPTF_DataSource_CT return integer {
var charstring vl_dataVarName;
var integer vl_errorCode;
f_EPTF_DataSource_sortParams(pl_params);
if (pl_source==c_EPTF_DataSource_sourceId) {
// f_EPTF_DataSource_handleBuiltInDataElements is a nonblocking currently
vl_errorCode := f_EPTF_DataSource_handleBuiltInDataElements(
vl_dataVarName,
pl_source,
pl_ptcName,
pl_element,
pl_params
); // internal elements handled successfully, or an error occured
// call handler:
if (pl_checkDataHandler.getDataHandler!=null) {
var integer vl_localDataVarId := f_EPTF_Var_getId(vl_dataVarName);
var EPTF_Var_DirectContent vl_dataValue := {unknownVal:={omit}};
if(vl_localDataVarId!=-1) {
f_EPTF_Var_getContent(vl_localDataVarId,vl_dataValue);
}
pl_checkDataHandler.getDataHandler.apply(
//request parameters:
pl_source := pl_source,
pl_ptcName := f_EPTF_Base_selfName(), // response may fill this if it was ""
pl_element := pl_element,
pl_params := pl_params,
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_remoteDataVarName := vl_dataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message
pl_ownerCompRef := self, // reference to the remote component
pl_localDataVarId := vl_localDataVarId, // var id on the local component (contains the current value, not subscribed to remote!)
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_checkDataHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
vl_dataVarName := "";
var EPTF_Var_CT vl_ownerCompRef;
var charstring vl_remoteDataVarName; // for nonzero error code it contains the error message
var integer vl_localDataVarId;
var EPTF_Var_DirectContent vl_dataValue;
//find if vl_dataVarName already exists
var charstring vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params);
var integer vl_dataValueId;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) {
if (vl_dataValueId==-1) {
// PTC name is not given, but should be specified
vl_ownerCompRef := null;
vl_remoteDataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": PTC name is not given, but should be specified since more than one PTC exist with the same source.");
vl_errorCode := 1;
} else {
// pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId);
vl_errorCode := 0;
vl_remoteDataVarName := v_EPTF_DataSource_dataValue_List[vl_dataValueId].remoteDataVarName;
vl_ownerCompRef := v_EPTF_DataSource_dataValue_List[vl_dataValueId].ownerCompRef;
vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
vl_dataValue := {unknownVal:={omit}};
if(vl_localDataVarId!=-1) {
f_EPTF_Var_getContent(vl_localDataVarId,vl_dataValue);
}
}
// call handler:
if (pl_checkDataHandler.getDataHandler!=null) {
pl_checkDataHandler.getDataHandler.apply(
//request parameters:
pl_source := pl_source,
pl_ptcName := pl_ptcName, // response may fill this if it was ""
pl_element := pl_element,
pl_params := pl_params,
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_remoteDataVarName := vl_remoteDataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message
pl_ownerCompRef := vl_ownerCompRef, // reference to the remote component
pl_localDataVarId := vl_localDataVarId, // var id on the local component (contains the current value, not subscribed to remote!)
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_checkDataHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
} else {
vl_errorCode := 0;
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
vl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 3;
} else {
if (vl_counter>1) {
vl_dataVarName := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
vl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 4;
}
vl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 1;
}
}
if (vl_errorCode!=0) {
// call handler:
if (pl_checkDataHandler.getDataHandler!=null) {
vl_remoteDataVarName := vl_dataVarName;
vl_ownerCompRef := null;
vl_localDataVarId := -1;
vl_dataValue := {unknownVal:={omit}};
pl_checkDataHandler.getDataHandler.apply(
//request parameters:
pl_source := pl_source,
pl_ptcName := pl_ptcName, // response may fill this if it was ""
pl_element := pl_element,
pl_params := pl_params,
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_remoteDataVarName := vl_remoteDataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message
pl_ownerCompRef := vl_ownerCompRef, // reference to the remote component
pl_localDataVarId := vl_localDataVarId, // var id on the local component (contains the current value, not subscribed to remote!)
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_checkDataHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
}
var integer vl_getDataId;
// dataVarName was not found in hashMaps, have to send request to client:
//recalculate vl_dataValueIdStr with given PTCName:
vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params);
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_pendingGetDataHash,vl_dataValueIdStr,vl_getDataId)) {
v_EPTF_DataSource_GetDataHandler_DB[vl_getDataId] := v_EPTF_DataSource_GetDataHandler_DB[vl_getDataId] & {pl_checkDataHandler};
} else {
//FIXME: use FBQ instead of semaphore:
vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSource_pendingGetDataHash,vl_dataValueIdStr,vl_getDataId);
v_EPTF_DataSource_GetDataHandler_DB[vl_getDataId] := {pl_checkDataHandler};
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getData:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
}
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_checkDataValue_nonblocking
//
// Purpose:
// To check if the value of a given data exists in non-blocking way.
// The specified handler is called when the response arrives.
//
// Parameters:
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in charstring pl_ptcName* - the name of the PTC
// (dataSource+ptcName should be a unigue id of the data). Default: "" (i.e. PTC name is ignored)
// *in charstring pl_element* - the type of data
// *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {})
// The parameters are sorted lexicographically according to the paramNames
// *in* <EPTF_DataSource_GetDataValueHandler> - pl_checkDataValueHandler - the handler function (with user arguments) to call
// when response is received
//
// Return Value:
// integer - 0 if OK, nonzero if the request is not valid
//
// Detailed Comments:
// This function is almost the same as <f_EPTF_DataSource_checkData_nonblocking>, but
// getDataValue is used instead of getData when checking the data value.
// It only checks if the source variable is there on the source component.
// The variable with the name passed to the handler might not exist locally even if the error code is zero.
// For non-zero error code, pl_dataVarName of the handler contains the error message.
//
// The function <f_EPTF_DataSource_getDataValue_nonblocking> makes this function depricated.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_checkDataValue_nonblocking(
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_GetDataValueHandler pl_checkDataValueHandler := cg_EPTF_DataSource_GetDataValueHandler_null
) runs on EPTF_DataSource_CT return integer {
var charstring vl_dataVarName;
var integer vl_errorCode;
f_EPTF_DataSource_sortParams(pl_params);
if (pl_source==c_EPTF_DataSource_sourceId) {
// f_EPTF_DataSource_handleBuiltInDataElements is a nonblocking currently
// FIXME: use f_EPTF_DataSource_handleBuiltInDataValues_nonblocking here?
vl_errorCode := f_EPTF_DataSource_handleBuiltInDataElements(
vl_dataVarName,
pl_source,
pl_ptcName,
pl_element,
pl_params
); // internal elements handled successfully, or an error occured
// call handler:
if (pl_checkDataValueHandler.getDataValueHandler!=null) {
var integer vl_localDataVarId := f_EPTF_Var_getId(vl_dataVarName);
var EPTF_Var_DirectContent vl_dataValue := {unknownVal:={omit}};
if(vl_localDataVarId!=-1) {
f_EPTF_Var_getContent(vl_localDataVarId,vl_dataValue);
}
pl_checkDataValueHandler.getDataValueHandler.apply(
pl_errorCode := vl_errorCode, // error code in the response
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_checkDataValueHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
vl_dataVarName := "";
var EPTF_Var_CT vl_ownerCompRef;
var charstring vl_remoteDataVarName; // for nonzero error code it contains the error message
var integer vl_localDataVarId;
var EPTF_Var_DirectContent vl_dataValue;
//find if vl_dataVarName already exists
var charstring vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params);
var integer vl_dataValueId;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) {
if (vl_dataValueId==-1) {
// PTC name is not given, but should be specified
vl_ownerCompRef := null;
vl_remoteDataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": PTC name is not given, but should be specified since more than one PTC exist with the same source.");
vl_errorCode := 1;
} else {
// pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId);
vl_errorCode := 0;
vl_remoteDataVarName := v_EPTF_DataSource_dataValue_List[vl_dataValueId].remoteDataVarName;
vl_ownerCompRef := v_EPTF_DataSource_dataValue_List[vl_dataValueId].ownerCompRef;
vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
vl_dataValue := {unknownVal:={omit}};
if(vl_localDataVarId!=-1) {
f_EPTF_Var_getContent(vl_localDataVarId,vl_dataValue);
}
}
// call handler:
if (pl_checkDataValueHandler.getDataValueHandler!=null) {
pl_checkDataValueHandler.getDataValueHandler.apply(
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_checkDataValueHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
} else {
vl_errorCode := 0;
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// set ownerCompRef (ptcName is not "" here):
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
} else {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
vl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 3;
} else {
if (vl_counter>1) {
vl_dataVarName := log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
// set ptcName:
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
vl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
vl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 4;
}
vl_dataVarName := log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered");
f_EPTF_DataSource_debug(vl_dataVarName);
vl_errorCode := 1;
}
}
if (vl_errorCode!=0) {
// call handler:
if (pl_checkDataValueHandler.getDataValueHandler!=null) {
vl_remoteDataVarName := vl_dataVarName;
vl_ownerCompRef := null;
vl_localDataVarId := -1;
vl_dataValue := {unknownVal:={omit}};
pl_checkDataValueHandler.getDataValueHandler.apply(
// reponse parameters:
pl_errorCode := vl_errorCode, // error code in the response
pl_dataValue := vl_dataValue, // the value of the data
// user data
pl_userData := pl_checkDataValueHandler.userData // user specific data given at the request
);
}
return vl_errorCode;
}
}
var integer vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getDataValue:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params,
omit
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(vl_ownerCompRef)));
v_EPTF_DataSource_GetDataValueHandler_DB[vl_getDataId] := pl_checkDataValueHandler;
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_enableUpdate
//
// Purpose:
// Enables updating of the data source variable, i.e.
// it subscribes the local variable to the source
//
// Parameters:
// *in charstring pl_localDataVarName* - this is the name of the local variable
// that stores the values of the data on the local component
// *in* <EPTF_Var_SubscriptionMode> - pl_subscriptionMode - subscription mode: sampled or timeLine: buffered; realtime: non-buffered
// Default: tsp_EPTF_DataSource_subscriptionMode
// *in integer* - pl_refreshRate - the refresh rate for the subscription.
// default: tsp_EPTF_DataSource_refreshRate
//
// Return Value:
// integer - 0 if OK, nonzero if pl_localDataVarName is not valid
//
// Detailed Comments:
// This function can be called after a <f_EPTF_DataSource_getData_nonBlocking>
// to subscribe the local datasource variable to the source variable, since that function does not do it.
// To cancel the update call <f_EPTF_DataSource_disableUpdate>
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_enableUpdate(
in charstring pl_localDataVarName,
in EPTF_Var_SubscriptionMode pl_subscriptionMode := tsp_EPTF_DataSource_subscriptionMode,
in integer pl_refreshRate := tsp_EPTF_DataSource_refreshRate
) runs on EPTF_DataSource_CT return integer {
var integer vl_dataValueId := f_EPTF_DataSource_getDataValueId(pl_localDataVarName);
if (vl_dataValueId==-1) {
return 1; //error;
}
var integer vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
if(f_EPTF_Var_checkSubscriptionMode(vl_localDataVarId,pl_subscriptionMode)) {
return 0; // already subscribed
}
var charstring vl_remoteDataVarName := v_EPTF_DataSource_dataValue_List[vl_dataValueId].remoteDataVarName;
var EPTF_Var_CT vl_ownerCompRef := v_EPTF_DataSource_dataValue_List[vl_dataValueId].ownerCompRef;
f_EPTF_Var_resubscribeRemote(
vl_ownerCompRef,
vl_remoteDataVarName,
pl_subscriptionMode,
vl_localDataVarId,
pl_localDataVarName,
pl_refreshRate
);
return 0;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_disableUpdate
//
// Purpose:
// Disabled updating of the data source variable, i.e.
// it unsubscribes the local variable from the source
//
// Parameters:
// *in charstring pl_localDataVarName* - this is the name of the local variable
// that stores the values of the data on the local component
//
// Return Value:
// integer - 0 if OK, nonzero if pl_localDataVarName is not valid
//
// Detailed Comments:
// This function can be called after a <f_EPTF_DataSource_enableUpdate>
// to unsubscribe the local dataSource variable from the source variable.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_disableUpdate(
in charstring pl_localDataVarName
) runs on EPTF_DataSource_CT return integer {
var integer vl_dataValueId := f_EPTF_DataSource_getDataValueId(pl_localDataVarName);
if (vl_dataValueId==-1) {
return 1; //error;
}
var integer vl_localDataVarId := v_EPTF_DataSource_dataValue_List[vl_dataValueId].localDataVarId;
f_EPTF_Var_unsubscribe(vl_localDataVarId);
return 0;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getDataValueId
//
// Purpose:
// Returns the ID of the data value
//
// Parameters:
// *in charstring pl_localDataVarName* - this is the name of the local variable
// that stores the values of the data on the local component
//
// Return Value:
// integer - the ID of the data value if OK, -1 if pl_dataVarName is not valid
//
// Detailed Comments:
// This function returns a unique ID for a datasource
// based on the local variable name that stores its value.
// To get the local variable name for a datasource use <f_EPTF_DataSource_checkData>
// or <f_EPTF_DataSource_getData>.
///////////////////////////////////////////////////////////
private function f_EPTF_DataSource_getDataValueId(
in charstring pl_localDataVarName
) runs on EPTF_DataSource_CT return integer {
var integer vl_dataValueId := -1;
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_dataValueHash,pl_localDataVarName,vl_dataValueId)) {
vl_dataValueId := -1;
}
return vl_dataValueId;
}
private function f_EPTF_DataSource_getHandlerId(
in charstring pl_source,
in charstring pl_ptcName := ""
) runs on EPTF_DataSource_CT return integer {
// find handler compref:
var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName;
var integer vl_handlerId := -1;
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash,vl_handlerIdStr,vl_handlerId)) {
// try to find without PTC name if pl_ptcName=="":
var integer vl_counter;
if (pl_ptcName=="") {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_debug(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, ": Source is not registered"));
return -3;
} else {
if (vl_counter>1) {
f_EPTF_DataSource_debug(log2str(%definitionId&": Cannot get data for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": More than one source component exists with this dataSource, PTC name should be specified"));
return -2;
} else {
// this is always successful:
if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,pl_source,vl_handlerId)) {/*remove warning*/};
}
}
} else {
if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSource_DataHandlerHash_NoPTCName,"Counter."&pl_source,vl_counter)) {
f_EPTF_DataSource_debug(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName, ": Source is not registered"));
return -4;
}
f_EPTF_DataSource_debug(log2str(%definitionId&": Cannot get source component for dataSource ",pl_source, " and ptcName ",pl_ptcName,
": Source with the given PTC name is not registered"));
return -1;
}
}
return vl_handlerId;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getRequestPartsFromParams
//
// Purpose:
// To extract parts of a request when they are in the params of another request like sizeOf
//
// Parameters:
// *in EPTF_DataSource_Params pl_outerParams* - the params of the original request
// *out charstring pl_source* - the source of the request described in the params
// *out charstring pl_ptcName* - the ptc name
// *out charstring pl_element* - the element
// *out charstring pl_params* - the params
//
// Return Value:
// integer - the error code
//
// Detailed Comments:
// This function obtains the request contained in the parameters of another request.
// The parameters should contain the source, element and optionally the ptc name.
// If they are missing, an empty string will be returned.
// Additionally ParamName and ParamValue pairs should come one after the other
// to describe the parameters of the request.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getRequestPartsFromParams(
in EPTF_DataSource_Params pl_outerParams,
out charstring pl_source,
out charstring pl_ptcName,
out charstring pl_element,
out EPTF_DataSource_Params pl_params
) return integer {
var integer vl_errorCode := 0;
var EPTF_CharstringList vl_result;
f_EPTF_DataSource_extractParams(pl_outerParams,
{c_EPTF_DataSource_paramNameSource,
c_EPTF_DataSource_paramNamePTCName,
c_EPTF_DataSource_paramNameElement},
vl_result);
pl_source := vl_result[0];
pl_ptcName := vl_result[1];
pl_element := vl_result[2];
pl_params := {};
// extract the params:
for(var integer i:=0; i<sizeof(pl_outerParams); i:=i+1) {
if (pl_outerParams[i].paramName == c_EPTF_DataSource_paramNameParamName) {
pl_params[sizeof(pl_params)] := {paramName := pl_outerParams[i].paramValue, paramValue := ""};
i:=i+1; // jump to the next item which should be paramValue:
if (pl_outerParams[i].paramName == c_EPTF_DataSource_paramNameParamValue) {
pl_params[sizeof(pl_params)-1].paramValue := pl_outerParams[i].paramValue
} else {
// f_EPTF_DataSource_warning(%definitionId& ": "&c_EPTF_DataSource_paramNameParamValue&" is not specified for "&
// c_EPTF_DataSource_paramNameParamName&": "&pl_params[i-1].paramValue&" in the condition "&c_EPTF_DataSource_condition_dataElementPresent);
// f_EPTF_DataSource_warning(%definitionId&": Invalid condition or parameter: "&
// "\nSource: "&pl_source&
// "\nPTC : "&pl_ptcName &
// "\nMethod : " &pl_method&
// "\nParams: " & log2str(pl_params));
vl_errorCode := 1; // invalid parameters
}
}
}
return vl_errorCode;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getSizeOfDataValue
//
// Purpose:
// To get the size of an iterator.
//
// Parameters:
// *in EPTF_Var_DirectContent pl_dataValue* - the dataValue
//
// Return Value:
// integer - the size of the dataValue
//
// Detailed Comments:
// When the dataValue is a list (integer, charstring or float),
// its size will be returned.
// For single elements, 1 is returned.
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getSizeOfDataValue(in EPTF_Var_DirectContent pl_dataValue) return integer {
var integer vl_size;
if (ischosen(pl_dataValue.charstringlistVal)) {
vl_size := sizeof(pl_dataValue.charstringlistVal);
} else if (ischosen(pl_dataValue.integerlistVal)) {
vl_size := sizeof(pl_dataValue.integerlistVal);
} else if (ischosen(pl_dataValue.floatlistVal)) {
vl_size := sizeof(pl_dataValue.floatlistVal);
} else {
vl_size := 1;
}
return vl_size;
}
private function f_EPTF_DataSource_getOwnerCompRef(
in charstring pl_source,
inout charstring pl_ptcName,
out EPTF_Var_CT pl_ownerCompRef
) runs on EPTF_DataSource_CT return integer {
var integer vl_handlerId := f_EPTF_DataSource_getHandlerId(pl_source, pl_ptcName);
if (vl_handlerId >= 0) {
pl_ptcName := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ptcName;
pl_ownerCompRef := v_EPTF_DataSource_DataHandler_List[vl_handlerId].ownerCompRef;
return 0;
} else {
return vl_handlerId;
}
}
private function f_EPTF_DataSource_getHelpForAllElements(
in charstring pl_source := "",
in charstring pl_element := "",
out EPTF_DataSource_Help pl_helpForAllElements
) runs on EPTF_DataSource_CT {
var EPTF_CharstringList vl_sources := {};
if (pl_source!="") {
vl_sources := {pl_source}
} else {
var charstring vl_sourcesVarName := c_EPTF_DataSource_externalDataVar_prefix&"."&c_EPTF_DataSource_dataElement_Sources;
var integer vl_sourceVarIdx := f_EPTF_Var_getId(vl_sourcesVarName);
if (vl_sourceVarIdx!=-1) {
vl_sources := f_EPTF_Var_getCharstringlistValue(vl_sourceVarIdx);
}
}
pl_helpForAllElements := {{}}
for(var integer i:=0; i<sizeof(vl_sources); i:=i+1) {
var charstring vl_source := vl_sources[i];
// find the first PTCName for the given source
var charstring vl_ptcName := "";
var charstring vl_PTCsVarName := c_EPTF_DataSource_externalDataVar_prefix&"."&c_EPTF_DataSource_dataElement_PTCs&"."&vl_source;
var integer vl_PTCSVarIdx := f_EPTF_Var_getId(vl_PTCsVarName);
if (vl_PTCSVarIdx!=-1) {
var EPTF_CharstringList vl_ptcs := f_EPTF_Var_getCharstringlistValue(vl_PTCSVarIdx);
if (sizeof(vl_ptcs)>0) {
vl_ptcName := vl_ptcs[0];
var EPTF_Var_DirectContent vl_dataValue;
var integer vl_errorCode;
if (vl_source==c_EPTF_DataSource_sourceId) {
var octetstring vl_encodedValue;
vl_errorCode := f_EPTF_DataSource_encHelpJSON({vl_source,c_EPTF_DataSource_help},vl_encodedValue);
vl_dataValue := {octetstringVal := vl_encodedValue}
} else {
vl_errorCode := f_EPTF_DataSource_getDataValue(
pl_dataValue := vl_dataValue,
pl_source := vl_source,
pl_ptcName := vl_ptcName,
pl_element := c_EPTF_DataSource_dataElement_Help,
pl_params := {
{c_EPTF_DataSource_paramNameHelpFormat,c_EPTF_DataSource_helpFormatJSON}
}
);
}
if (vl_errorCode != 0) {
// put help entry for erroneous dataelement
var charstring vl_errorMsg := "";
if (isbound(vl_dataValue)) {
if (ischosen(vl_dataValue.charstringVal)) {
vl_errorMsg := vl_dataValue.charstringVal;
} else if (ischosen(vl_dataValue.octetstringVal)){
vl_errorMsg := oct2char(vl_dataValue.octetstringVal);
}
}
var EPTF_DataSource_Help_DataElementChildren vl_errorInHelp := {{
dataElement := {
name := "CorruptHelpInfo",
valueType := charstringType,
typeDescriptor := omit,
description := "Help information is corrupt for source \""&vl_source&"\". "&vl_errorMsg
}
}}
var octetstring vl_encodedValue;
vl_errorCode := f_EPTF_DataSource_encHelpJSON({vl_source,vl_errorInHelp},vl_encodedValue);
vl_dataValue := {octetstringVal := vl_encodedValue}
}
if (vl_errorCode == 0) {
if (ischosen(vl_dataValue.octetstringVal)) {
var EPTF_DataSource_Help_DataElements vl_help := f_EPTF_DataSource_decHelpJSON(vl_dataValue.octetstringVal);
var EPTF_DataSource_Help_DataElementChildren vl_helpFiltered := vl_help.dataElements;
// filter out the element given:
if (pl_element!="") {
vl_helpFiltered := f_EPTF_DataSource_filterHelpForElement(pl_element,vl_help.dataElements);
}
if (vl_helpFiltered!={}) {
pl_helpForAllElements.sources := pl_helpForAllElements.sources&{{vl_source,vl_helpFiltered}};
}
}
}
}
}
}
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getHelpJSON
//
// Purpose:
// To get help in JSON format for a given source and element
//
// Parameters:
// *in* *charstring* *pl_source* - the source name to get help for.
// If not specified, help for all sources will be returned
// *in* *charstring* *pl_element* - the element name to get help for.
// If not specified, help for all elements will be returned
//
// Return Value:
// octetstring - the help in JSON format
//
// Detailed Comments:
// In no source and element is given, it returns the help
// for all sources and all elements
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getHelpJSON(
in charstring pl_source := "",
in charstring pl_element := ""
) runs on EPTF_DataSource_CT return octetstring {
var octetstring vl_helpJson := ''O;
var EPTF_DataSource_Help vl_helpForAllElements;
f_EPTF_DataSource_getHelpForAllElements(
pl_source := pl_source,
pl_element := pl_element,
pl_helpForAllElements := vl_helpForAllElements
);
vl_helpJson := f_EPTF_DataSource_encAllHelpJSON(vl_helpForAllElements);
return vl_helpJson;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getHelpTEXT
//
// Purpose:
// To get human readable help text for a given source and element
//
// Parameters:
// *in* *charstring* *pl_source* - the source name to get help for.
// If not specified, help for all sources will be returned
// *in* *charstring* *pl_element* - the element name to get help for.
// If not specified, help for all elements will be returned
//
// Return Value:
// charstring - help in readable text format
//
// Detailed Comments:
// In no source and element is given, it returns the help
// for all sources and all elements
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getHelpTEXT(
in charstring pl_source := "",
in charstring pl_element := ""
) runs on EPTF_DataSource_CT return charstring {
var charstring vl_helpText := "";
var EPTF_DataSource_Help vl_helpForAllElements;
f_EPTF_DataSource_getHelpForAllElements(
pl_source := pl_source,
pl_element := pl_element,
pl_helpForAllElements := vl_helpForAllElements
);
vl_helpText := f_EPTF_DataSource_encAllHelpTEXT(vl_helpForAllElements);
return vl_helpText;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_getHelpApidoc
//
// Purpose:
// To get human readable help text for a given source and element
//
// Parameters:
// *in* *charstring* *pl_source* - the source name to get help for.
// If not specified, help for all sources will be returned
// *in* *charstring* *pl_element* - the element name to get help for.
// If not specified, help for all elements will be returned
//
// Return Value:
// charstring - help in readable text format
//
// Detailed Comments:
// In no source and element is given, it returns the help
// for all sources and all elements
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_getHelpApidoc(
in charstring pl_source := "",
in charstring pl_element := ""
) runs on EPTF_DataSource_CT return charstring {
var charstring vl_helpApiDoc := "";
var EPTF_DataSource_Help vl_helpForAllElements;
f_EPTF_DataSource_getHelpForAllElements(
pl_source := pl_source,
pl_element := pl_element,
pl_helpForAllElements := vl_helpForAllElements
);
vl_helpApiDoc := f_EPTF_DataSource_encAllHelpApidoc(vl_helpForAllElements);
return "///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_CLL_DataSource_Apidoc
//
// Purpose:
// This module contains the description of all CLL data elements.
//
// Current Owner:
// EKISTAM
//
// Last Review Date:
// 2015-xx-xx
//
// Detailed Comments:
// This file contains the description of all CLL data elements
///////////////////////////////////////////////////////////////
// This is a generated file, do not edit!
" & vl_helpApiDoc;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_encAllHelpJSON
//
// Purpose:
// To encode the help info to JSON format
//
// Parameters:
// *in* <EPTF_DataSource_Help> *pl_help* - the help info about the data elements of different sources
//
// Return Value:
// octetstring - the help in JSON format
//
// Detailed Comments:
// Converts the help information into JSON format.
// This can be used by GUI.
///////////////////////////////////////////////////////////
private external function f_EPTF_DataSource_encAllHelpJSON(in EPTF_DataSource_Help pl_help) return octetstring
with { extension "prototype(convert) encode(JSON) errorbehavior(ALL:WARNING)"};
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_encAllHelpTEXT
//
// Purpose:
// To encode the help info to TEXT format
//
// Parameters:
// *in* <EPTF_DataSource_Help> *pl_help* - the help info about the data elements of different sources
//
// Return Value:
// octetstring - the help in JSON format
//
// Detailed Comments:
// Converts the help information into JSON format.
// This can be used by GUI.
///////////////////////////////////////////////////////////
private function f_EPTF_DataSource_encAllHelpTEXT(in EPTF_DataSource_Help pl_help) return charstring {
var charstring vl_helpText := "";
for(var integer i:=0; i<sizeof(pl_help.sources); i:=i+1) {
vl_helpText := vl_helpText&f_EPTF_DataSource_encHelpTEXT(pl_help.sources[i]);
}
return vl_helpText;
}
private function f_EPTF_DataSource_encAllHelpApidoc(in EPTF_DataSource_Help pl_help) return charstring {
var charstring vl_helpApiDoc := "";
for(var integer vl_i:=0; vl_i<sizeof(pl_help.sources); vl_i:=vl_i+1) {
vl_helpApiDoc := vl_helpApiDoc&f_EPTF_DataSource_encHelpApidoc(pl_help.sources[vl_i]);
}
return vl_helpApiDoc;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_encHelpJSON_DTE
//
// Purpose:
// To encode the help info to JSON format, throws DTE on error
//
// Parameters:
// *in* <EPTF_DataSource_Help_DataElements> *pl_dataElementsHelp* - the dataElements help
//
// Return Value:
// octetstring - the help in JSON format
//
// Detailed Comments:
// Converts the dataElements help information into JSON format.
// This can be used by GUI.
///////////////////////////////////////////////////////////
private external function f_EPTF_DataSource_encHelpJSON_DTE(in EPTF_DataSource_Help_DataElements pl_dataElementsHelp) return octetstring
with { extension "prototype(convert) encode(JSON) errorbehavior(ALL:ERROR)"};
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_encHelpJSON
//
// Purpose:
// To encode the help info to JSON format
//
// Parameters:
// *in* <EPTF_DataSource_Help_DataElements> *pl_dataElementsHelp* - the dataElements help
// *out* *octetstring* *pl_encodedValue* - the encoded value
//
// Return Value:
// integer - the error code: 0 if successful, non-zero otherwise
//
// Detailed Comments:
// Converts the dataElements help information into JSON format.
// This can be used by GUI.
///////////////////////////////////////////////////////////
private function f_EPTF_DataSource_encHelpJSON(in EPTF_DataSource_Help_DataElements pl_dataElementsHelp, out octetstring pl_encodedValue) return integer {
@try {
pl_encodedValue := f_EPTF_DataSource_encHelpJSON_DTE(pl_dataElementsHelp);
} @catch(dte_msg) {
pl_encodedValue := char2oct(%definitionId&": "&log2str(dte_msg));
return 1; // encoding error
}
return 0; //OK
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_decHelpJSON
//
// Purpose:
// To decode the help info from JSON format
//
// Parameters:
// *in* *octetstring* *pl_encodedDataElementsHelp* - the dataElements help in octetstring as JSON format
//
// Return Value:
// EPTF_DataSource_Help_DataElements - the help in TTCN format
//
// Detailed Comments:
// Converts the dataElements help information from JSON format.
///////////////////////////////////////////////////////////
private external function f_EPTF_DataSource_decHelpJSON(in octetstring pl_encodedDataElementsHelp) return EPTF_DataSource_Help_DataElements
with { extension "prototype(convert) decode(JSON) errorbehavior(ALL:WARNING)"};
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_encHelpTEXT
//
// Purpose:
// To encode the help info to human readable help text
//
// Parameters:
// *in* <EPTF_DataSource_Help_DataElements> pl_dataElementsHelp - the dataElements help
//
// Return Value:
// charstring - help in readable text format
//
// Detailed Comments:
// Converts the dataElements help information into human readable format.
///////////////////////////////////////////////////////////
private function f_EPTF_DataSource_encHelpTEXT(in EPTF_DataSource_Help_DataElements pl_dataElementsHelp) return charstring {
return "\nSource: \""&pl_dataElementsHelp.source&"\"\n"&f_EPTF_DataSource_getHelpTEXTForDataElements(pl_dataElementsHelp.source, pl_dataElementsHelp.dataElements, " ")&"\n";
}
private function f_EPTF_DataSource_getHelpTEXTForDataElements(
in charstring pl_source,
in EPTF_DataSource_Help_DataElementChildren pl_dataElements,
in charstring pl_identationlevel
) return charstring {
var charstring vl_helpText := "";
for(var integer i:=0; i<sizeof(pl_dataElements); i:=i+1) {
vl_helpText := vl_helpText
&"\n"&pl_identationlevel& "DataElement: \""& pl_dataElements[i].dataElement.name&"\""
&"\n"&pl_identationlevel& " ValueType : "& ttcn2string(valueof(EPTF_DataSource_ValueType:pl_dataElements[i].dataElement.valueType));
if (isbound(pl_dataElements[i].dataElement.typeDescriptor) and ispresent(pl_dataElements[i].dataElement.typeDescriptor)) {
var charstring vl_typeDescription := "\""&pl_dataElements[i].dataElement.typeDescriptor.typeName&"\" item";
if (isbound(pl_dataElements[i].dataElement.typeDescriptor.isListOf) and isbound(pl_dataElements[i].dataElement.typeDescriptor.isListOf)
and true == pl_dataElements[i].dataElement.typeDescriptor.isListOf) {
vl_typeDescription := "List of "&vl_typeDescription&"s";
}
vl_helpText := vl_helpText
&"\n"&pl_identationlevel& " TypeDescr: "& vl_typeDescription;
}
vl_helpText := vl_helpText
&"\n"&pl_identationlevel& " Description: "& pl_dataElements[i].dataElement.description
&"\n"&pl_identationlevel& " CLI Example: "& f_EPTF_DataSource_getHelpExampleCLICommand(pl_source, pl_dataElements[i].dataElement)
&"\n"&pl_identationlevel& ""
&"\n"&pl_identationlevel& " Parameters: ";
var charstring vl_parameters := "";
if (isbound(pl_dataElements[i].dataElement.parameters) and ispresent(pl_dataElements[i].dataElement.parameters)) {
for (var integer p:=0; p<sizeof(pl_dataElements[i].dataElement.parameters); p:=p+1) {
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& " Parameter name: \""& pl_dataElements[i].dataElement.parameters[p].name&"\"";
if (ischosen(pl_dataElements[i].dataElement.parameters[p].typeDescriptor.valueType)) {
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& " TypeDescr: "& ttcn2string(valueof(EPTF_DataSource_ValueType:pl_dataElements[i].dataElement.parameters[p].typeDescriptor.valueType));
} else {
//reference
var charstring vl_reference := "\""&pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.typeName&"\" item";
if (isbound(pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.isIndexInListOf)
and ispresent(pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.isIndexInListOf)
and true == pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.isIndexInListOf) {
vl_reference := "Index in the list of "&vl_reference&"s";
}
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& " TypeDescr: "& vl_reference;
}
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& " Description : "& pl_dataElements[i].dataElement.parameters[p].description
&"\n"&pl_identationlevel& " Example Value : \""& pl_dataElements[i].dataElement.parameters[p].exampleValue&"\"";
}
}
if (vl_parameters=="") {
vl_parameters := "None."
}
vl_helpText := vl_helpText
&vl_parameters;
if (isbound(pl_dataElements[i].children) and ispresent(pl_dataElements[i].children)) {
var charstring vl_childInfo := f_EPTF_DataSource_getHelpTEXTForDataElements(pl_source,pl_dataElements[i].children,pl_identationlevel & " ");
if (vl_childInfo != "") {
vl_helpText := vl_helpText &"\n\n"&pl_identationlevel&" Children: "&vl_childInfo;
}
}
vl_helpText := vl_helpText&"\n";
}
return vl_helpText;
}
private function f_EPTF_DataSource_encHelpApidoc(in EPTF_DataSource_Help_DataElements pl_dataElementsHelp) return charstring {
return "\n// Group: \""&pl_dataElementsHelp.source&"\"\n//\ngroup "&pl_dataElementsHelp.source&" {\n"&f_EPTF_DataSource_getHelpApidocForDataElements(pl_dataElementsHelp.source, pl_dataElementsHelp.dataElements, " ")&"} // ~group \n";
}
private function f_EPTF_DataSource_getHelpApidocForDataElements(
in charstring pl_source,
in EPTF_DataSource_Help_DataElementChildren pl_dataElements,
in charstring pl_identationlevel
) return charstring {
var charstring vl_helpApiDoc := "";
for(var integer i:=0; i<sizeof(pl_dataElements); i:=i+1) {
vl_helpApiDoc := vl_helpApiDoc
&"\n"&pl_identationlevel& "// Function: \""& pl_dataElements[i].dataElement.name&"\""
&"\n"&pl_identationlevel& "//"
&"\n"&pl_identationlevel& "// *Description*: "& pl_dataElements[i].dataElement.description
&"\n"&pl_identationlevel& "//"
&"\n"&pl_identationlevel& "// *ValueType*: "& ttcn2string(valueof(EPTF_DataSource_ValueType:pl_dataElements[i].dataElement.valueType));
if (isbound(pl_dataElements[i].dataElement.typeDescriptor) and ispresent(pl_dataElements[i].dataElement.typeDescriptor)) {
var charstring vl_typeDescription := "\""&pl_dataElements[i].dataElement.typeDescriptor.typeName&"\" item";
if (isbound(pl_dataElements[i].dataElement.typeDescriptor.isListOf) and isbound(pl_dataElements[i].dataElement.typeDescriptor.isListOf)
and true == pl_dataElements[i].dataElement.typeDescriptor.isListOf) {
vl_typeDescription := "List of "&vl_typeDescription&"s";
}
vl_helpApiDoc := vl_helpApiDoc
&"\n"&pl_identationlevel& "//"
&"\n"&pl_identationlevel& "// *TypeDescriptor*: "& vl_typeDescription;
}
vl_helpApiDoc := vl_helpApiDoc
&"\n"&pl_identationlevel& "//"
&"\n"&pl_identationlevel& "// *CLI Example*: "& f_EPTF_DataSource_getHelpExampleCLICommand(pl_source, pl_dataElements[i].dataElement)
&"\n"&pl_identationlevel& "//"
&"\n"&pl_identationlevel& "// *Parameters*: ";
var charstring vl_parameters := "";
if (isbound(pl_dataElements[i].dataElement.parameters) and ispresent(pl_dataElements[i].dataElement.parameters)) {
for (var integer p:=0; p<sizeof(pl_dataElements[i].dataElement.parameters); p:=p+1) {
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& "// - *\""& pl_dataElements[i].dataElement.parameters[p].name&"\"*";
if (ischosen(pl_dataElements[i].dataElement.parameters[p].typeDescriptor.valueType)) {
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& "// - TypeDescriptor - "& ttcn2string(valueof(EPTF_DataSource_ValueType:pl_dataElements[i].dataElement.parameters[p].typeDescriptor.valueType));
} else {
//reference
var charstring vl_reference := "\""&pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.typeName&"\" item";
if (isbound(pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.isIndexInListOf)
and ispresent(pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.isIndexInListOf)
and true == pl_dataElements[i].dataElement.parameters[p].typeDescriptor.reference.isIndexInListOf) {
vl_reference := "Index in the list of "&vl_reference&"s";
}
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& "// - TypeDescriptor - "& vl_reference;
}
vl_parameters := vl_parameters
&"\n"&pl_identationlevel& "// - Description - "& pl_dataElements[i].dataElement.parameters[p].description
&"\n"&pl_identationlevel& "// - Example Value - \""& pl_dataElements[i].dataElement.parameters[p].exampleValue&"\""
&"\n"&pl_identationlevel& "//";
}
}
if (vl_parameters=="") {
vl_parameters := "None."
}
vl_helpApiDoc := vl_helpApiDoc
&vl_parameters;
if (isbound(pl_dataElements[i].children) and ispresent(pl_dataElements[i].children)) {
var charstring vl_childInfo := f_EPTF_DataSource_getHelpApidocForDataElements(pl_source,pl_dataElements[i].children,pl_identationlevel & " ");
if (vl_childInfo != "") {
vl_helpApiDoc := vl_helpApiDoc &"\n"&pl_identationlevel&"// \n"&vl_childInfo;//Children:
}
}
vl_helpApiDoc := vl_helpApiDoc&"\n";
}
return vl_helpApiDoc;
}
private function f_EPTF_DataSource_getHelpExampleCLICommand(
in charstring pl_source,
in EPTF_DataSource_Help_DataElement pl_dataElementHelp
) return charstring {
var charstring vl_exampleCLICommand := "ds get <datadescription xmlns='http://ttcn.ericsson.se/protocolModules/xtdp/xtdl' element='"
&pl_dataElementHelp.name&"' source='"&pl_source&"'> <params> ";
if (isbound(pl_dataElementHelp.parameters) and ispresent(pl_dataElementHelp.parameters)) {
for(var integer i:=0; i<sizeof(pl_dataElementHelp.parameters); i:=i+1) {
vl_exampleCLICommand := vl_exampleCLICommand
&" <dataparam name='"&pl_dataElementHelp.parameters[i].name
&"' value='"&pl_dataElementHelp.parameters[i].exampleValue&"'/>";
}
}
vl_exampleCLICommand := vl_exampleCLICommand & " </params> </datadescription>";
return vl_exampleCLICommand;
}
// returns those elements that correspond to the specified one:
private function f_EPTF_DataSource_filterHelpForElement(
in charstring pl_element,
in EPTF_DataSource_Help_DataElementChildren pl_helpList
) return EPTF_DataSource_Help_DataElementChildren {
var EPTF_DataSource_Help_DataElementChildren vl_result := {};
var integer j :=0;
for(var integer i:=0; i<sizeof(pl_helpList); i:=i+1) {
if (pl_helpList[i].dataElement.name == pl_element or pl_element=="") {
vl_result[j].dataElement := pl_helpList[i].dataElement;
j:=j+1;
}
if ((not isbound(pl_helpList[i].children)) or (not ispresent(pl_helpList[i].children))) {
pl_helpList[i].children := {};
}
vl_result := vl_result & f_EPTF_DataSource_filterHelpForElement(pl_element,pl_helpList[i].children);
}
return vl_result;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_handleHelp
//
// Purpose:
// This function can be used in the dataHander to return the help info
// for a datasource. The DataElement is <c_EPTF_DataSource_dataElement_Help>
//
// Parameters:
// *out* <EPTF_Var_DirectContent> *pl_dataValue* - this is the value of the data
// that stores the values of the data on the local component
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in* <EPTF_DataSource_Params> *pl_params* - the parameters of the datasource
// *in* <EPTF_DataSource_Help_DataElementChildren> pl_dataElementHelp - the dataElement's help information
//
// Return Value:
// integer - error code, 0 if OK, nonzero in case of error.
// When error code is not zero pl_dataValue will contain an error message.
//
// Detailed Comments:
// Converts the dataElements help information into the given format.
//
///////////////////////////////////////////////////////////
public function f_EPTF_DataSource_handleHelp(
out EPTF_Var_DirectContent pl_dataValue,
in charstring pl_source,
in EPTF_DataSource_Params pl_params,
in EPTF_DataSource_Help_DataElementChildren pl_dataElementHelp
) //runs on EPTF_DataSource_CT //EPTF_DataSourceClient_CT ??
return integer {
var EPTF_CharstringList pl_result := {}
f_EPTF_DataSource_extractParams(pl_params,
{c_EPTF_DataSource_paramNameHelpFormat},
pl_result
);
var charstring vl_format;
if (sizeof(pl_result)==0) {
vl_format := c_EPTF_DataSource_helpFormatJSON; // default format is JSON
} else {
if(sizeof(pl_result)==1 and (pl_result[0]==c_EPTF_DataSource_helpFormatJSON or pl_result[0]==c_EPTF_DataSource_helpFormatTEXT)) {
vl_format := pl_result[0];
} else {
// invalid help format
pl_dataValue := { charstringVal := log2str(%definitionId&": Invalid help format: ",c_EPTF_DataSource_dataElement_Help,
": Should be one of: ", EPTF_CharstringList:{c_EPTF_DataSource_helpFormatJSON, c_EPTF_DataSource_helpFormatTEXT}) };
return -33; // invalid help format
}
}
if (vl_format==c_EPTF_DataSource_helpFormatJSON) {
var octetstring vl_encodedValue;
if(0!=f_EPTF_DataSource_encHelpJSON({pl_source,pl_dataElementHelp},vl_encodedValue)) {
pl_dataValue := { charstringVal := log2str("Error: Cannot get help for source ",pl_source," params ",log2str(pl_params)," dataElementHelp ",pl_dataElementHelp,": ")&oct2char(vl_encodedValue) };
return -44;
}
pl_dataValue := { octetstringVal := vl_encodedValue };
} else if (vl_format==c_EPTF_DataSource_helpFormatTEXT){
pl_dataValue := { charstringVal := f_EPTF_DataSource_encHelpTEXT({pl_source,pl_dataElementHelp}) };
} else {
// cannot happen: exited earlier with error code -33
}
return 0;
}
///////////////////////////////////////////////////////////
// Function: f_EPTF_DataSource_Help_handler
//
// Purpose:
// This function can be used in the dataHander to return the help info
// for a datasource. The DataElement is <c_EPTF_DataSource_dataElement_Help>
//
// Parameters:
// *out* <EPTF_Var_DirectContent> *pl_dataValue* - this is the value of the data
// *in charstring pl_source* - the name of the dataSource 'feature'
// *in* <EPTF_DataSource_Params> *pl_params* - the parameters of the datasource
//
// Return Value:
// integer - error code, 0 if OK, nonzero in case of error.
// When error code is not zero pl_dataValue will contain an error message.
//
// Detailed Comments:
// Converts the dataElements help information into the given format.
//
///////////////////////////////////////////////////////////
private function f_EPTF_DataSource_Help_handler(
out EPTF_Var_DirectContent pl_dataValue,
in charstring pl_source,
in EPTF_DataSource_Params pl_params
) runs on EPTF_DataSource_CT //EPTF_DataSourceClient_CT ??
return integer {
var EPTF_CharstringList pl_result := {}
f_EPTF_DataSource_extractParams(pl_params,
{c_EPTF_DataSource_paramNameHelpFormat},
pl_result
);
var charstring vl_format;
if (sizeof(pl_result)==0 or sizeof(pl_result)==1 and pl_result[0]=="") {
vl_format := c_EPTF_DataSource_helpFormatJSON; // default format is JSON
} else if(sizeof(pl_result)==1 and (pl_result[0]==c_EPTF_DataSource_helpFormatJSON or pl_result[0]==c_EPTF_DataSource_helpFormatTEXT)) {
vl_format := pl_result[0];
} else {
// invalid help format
pl_dataValue := { charstringVal := log2str(%definitionId&": Invalid help format: ",pl_result[0],
": Should be one of: ", EPTF_CharstringList:{c_EPTF_DataSource_helpFormatJSON, c_EPTF_DataSource_helpFormatTEXT}) };
return -33; // invalid help format
}
// source
f_EPTF_DataSource_extractParams(pl_params,
{c_EPTF_DataSource_paramNameSource},
pl_result
);
var charstring vl_source;
if (sizeof(pl_result)==0) {
vl_source := ""; // default source is 'all'
} else if(sizeof(pl_result)==1) {
vl_source := pl_result[0];
}
// element
f_EPTF_DataSource_extractParams(pl_params,
{c_EPTF_DataSource_paramNameElement},
pl_result
);
var charstring vl_element;
if (sizeof(pl_result)==0) {
vl_element := ""; // default element is 'all'
} else if(sizeof(pl_result)==1) {
vl_element := pl_result[0];
}
if (vl_format==c_EPTF_DataSource_helpFormatJSON) {
pl_dataValue := { octetstringVal := f_EPTF_DataSource_getHelpJSON(vl_source,vl_element) };
} else if (vl_format==c_EPTF_DataSource_helpFormatTEXT){
pl_dataValue := { charstringVal := f_EPTF_DataSource_getHelpTEXT(vl_source,vl_element) };
} else {
// cannot happen: exited earlier with error code -33
}
return 0;
}
private function f_EPTF_DataSource_handleBuiltInDataElements(
out charstring pl_dataVarName,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {}
) runs on EPTF_DataSource_CT return integer {
if (pl_source!=c_EPTF_DataSource_sourceId) {
pl_dataVarName := "It should be called with pl_source="&c_EPTF_DataSource_sourceId;
return -20; // not DataSource element
}
pl_dataVarName := ""; // set it to invalid
var EPTF_CharstringList pl_result := {}
select( pl_element )
{
// data element: c_EPTF_DataSource_dataElement_PTCs
case(c_EPTF_DataSource_dataElement_PTCs) {
if (0 == f_EPTF_DataSource_getParams(pl_params,
{c_EPTF_DataSource_paramNameSource},
pl_result,
refers(f_EPTF_DataSource_DScheckParams))) {
var charstring vl_source := pl_result[0];
pl_dataVarName := c_EPTF_DataSource_externalDataVar_prefix&"."&c_EPTF_DataSource_dataElement_PTCs&"."&vl_source;
// automatically create var if does not exist:
var integer vl_varIdx := f_EPTF_Var_getId(pl_dataVarName);
if(vl_varIdx == -1) {
f_EPTF_Var_newCharstringlist(pl_dataVarName, {}, vl_varIdx);
}
} else {
// this is just to write previous warning messages as well
if (sizeof(pl_params)!=1) {
pl_dataVarName := log2str(%definitionId&": Invalid number of parameters for dataSource ",pl_source, " and element ",pl_element,
": Only one parameter has to be specified");
//return 1; // invalid number of params
} else if(pl_params[0].paramName != c_EPTF_DataSource_paramNameSource) {
pl_dataVarName := log2str(%definitionId&": Invalid name of parameter for dataSource ",pl_source, " and element ",pl_element,
": The name of parameter should be ",c_EPTF_DataSource_paramNameSource);
//return 2; // invalid name of params
}
}
}
case(c_EPTF_DataSource_dataElement_Sources) {
if (0 == f_EPTF_DataSource_getParams(pl_params,
{},
pl_result,
refers(f_EPTF_DataSource_DScheckParams))) {
pl_dataVarName := c_EPTF_DataSource_externalDataVar_prefix&"."&c_EPTF_DataSource_dataElement_Sources;
var integer vl_varIdx := f_EPTF_Var_getId(pl_dataVarName);
// automatically create var if does not exist:
if(vl_varIdx == -1) {
// cannot be reached, var is created in init function
f_EPTF_Var_newCharstringlist(pl_dataVarName, {c_EPTF_DataSource_sourceId}, vl_varIdx);
}
} else {
// this is just to write previous warning messages as well
if (sizeof(pl_params)!=0) {
pl_dataVarName := log2str(%definitionId&": Invalid number of parameters for dataSource ",pl_source, " and element ",pl_element,
": No parameter has to be specified");
//return 1; // invalid number of params
}
}
}
case else
{
// invalid element
pl_dataVarName := log2str(%definitionId&": Invalid dataElement for dataSource ",pl_source, ": ",pl_element,
": Should be one of: ", EPTF_CharstringList:{c_EPTF_DataSource_dataElement_Help, c_EPTF_DataSource_dataElement_PTCs, c_EPTF_DataSource_dataElement_Sources});
return -22; // invalid element
}
}
var integer vl_dataElementVarIdx := f_EPTF_Var_getId(pl_dataVarName);
if(vl_dataElementVarIdx == -1){
pl_dataVarName := log2str(%definitionId&": Invalid iterator or externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&"\n:"&pl_dataVarName;
return -1;
}
return 0;
}
private function f_EPTF_DataSource_getResponseForGetDataValueMsg(
out EPTF_Var_DirectContent pl_dataValue,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_Filter pl_filter := c_EPTF_DataSource_Filter_empty,
in EPTF_Var_CT pl_ownerCompRef
) runs on EPTF_DataSource_CT return integer {
var integer vl_errorCode := 0;
// have to send request to client:
var integer vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getDataValue:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params,
pl_filter
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(pl_ownerCompRef)));
// wait for response
if (f_EPTF_Semaphore_waitForUnlock(vl_getDataId,tsp_EPTF_DataSource_maxWaitTime)) {
// max wait time expired before response received:
f_EPTF_DataSource_warning(log2str(%definitionId&": Communication error: No response received for getData message: ",vl_getDataId));
pl_dataValue.charstringVal := log2str(%definitionId&": Communication error: No response received for getData message: ",vl_getDataId);
return -1;
}
// copy the values from the message database because it might be possible that they will be overwritten because
// the semaphore is released and there is a blocking statement before they are used:
vl_errorCode := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValueResponse.errorCode;
pl_dataValue := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValueResponse.dataValue;
//var EPTF_DataSourceClient_CT vl_ownerCompRef := v_EPTF_DataSource_Msg_List[vl_getDataId].dataValue.ownerCompRef; // value in message is not used
// if returned error code is non-0, update the error message:
if (vl_errorCode!=0) {
if (not ischosen(pl_dataValue.charstringVal)) {
pl_dataValue := {charstringVal := "Error info: "&ttcn2string(pl_dataValue)}; // error message was not present => set it to the string value of provided value
//append general text:
pl_dataValue.charstringVal := log2str(%definitionId&": Invalid iterator or externalData or parameter: ",
"\nSource: ",pl_source,
"\nPTC : ",pl_ptcName ,
"\nElement Name : " ,pl_element,
"\nParams: " , pl_params)&
"\nReason: "&pl_dataValue.charstringVal;
}
f_EPTF_DataSource_warning(pl_dataValue.charstringVal&"\nError code: "&int2str(vl_errorCode));
}
return vl_errorCode;
}
private function f_EPTF_DataSource_getResponseForGetDataValueMsg_nonblocking(
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_Filter pl_filter := c_EPTF_DataSource_Filter_empty,
in EPTF_Var_CT pl_ownerCompRef,
in EPTF_DataSource_GetDataValueHandler pl_getDataValueHandler
) runs on EPTF_DataSource_CT {
var integer vl_getDataId := f_EPTF_Semaphore_new();
f_EPTF_DataSource_sendMsg(EPTF_DataSource_Msg:{getDataValue:={
vl_getDataId,
pl_source,
pl_ptcName,
pl_element,
pl_params,
pl_filter
}},f_EPTF_DataSourceClient_downcast(f_EPTF_Base_upcast(pl_ownerCompRef)));
v_EPTF_DataSource_GetDataValueHandler_DB[vl_getDataId] := pl_getDataValueHandler;
}
private function f_EPTF_DataSource_handleBuiltInDataValues(
out EPTF_Var_DirectContent pl_dataValue,
in charstring pl_source,
in charstring pl_ptcName := "",
in charstring pl_element,
in EPTF_DataSource_Params pl_params := {},
in EPTF_DataSource_Filter pl_filter := c_EPTF_DataSource_Filter_empty
) runs on EPTF_DataSource_CT return integer {
if (pl_source!=c_EPTF_DataSource_sourceId) {
return -20; // not DataSource element
}
var integer vl_errorCode := -1;
pl_dataValue := {unknownVal := {omit}}; // set it to invalid
select( pl_element )
{
case(c_EPTF_DataSource_dataElement_Help) {
vl_errorCode := f_EPTF_DataSource_Help_handler(pl_dataValue,pl_source,pl_params);
}
case(c_EPTF_DataSource_dataElement_sizeOf) {
var EPTF_CharstringList vl_result;
f_EPTF_DataSource_extractParams(pl_params,
{c_EPTF_DataSource_paramNameSource,
c_EPTF_DataSource_paramNamePTCName},
vl_result);
var charstring vl_source := vl_result[0];
var charstring vl_ptcName := vl_result[1];
if (vl_source == c_EPTF_DataSource_sourceId) {
var charstring vl_element;
var EPTF_DataSource_Params vl_params;
vl_errorCode := f_EPTF_DataSource_getRequestPartsFromParams(pl_params, vl_source, vl_ptcName, vl_element, vl_params);
if (vl_errorCode == 0) {