| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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) { |
| |