| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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_DataSourceClient_Functions |
| // |
| // Purpose: |
| // This module contains the implementation of EPTF_CLL_DataSource functions. |
| // |
| // Module depends on: |
| // <EPTF_CLL_Base_Functions> |
| // <EPTF_CLL_Variable_Functions> |
| // <EPTF_CLL_DataSource_Definitions> |
| // <EPTF_CLL_HashMapStr2Int_Functions> |
| // <EPTF_CLL_HashMap_Functions> |
| // <EPTF_CLL_Semaphore_Functions> |
| // <EPTF_CLL_Variable_Definitions> |
| // |
| // Module Parameters: |
| // tsp_debug_EPTF_DataSource_Functions - boolean - enable/disable debug logs |
| // |
| // Current Owner: |
| // Jozsef Gyurusi (ethjgi) |
| // |
| // Last Review Date: |
| // 2011-02-03 |
| // |
| // Detailed Comments: |
| // This module contains the interface functions for the EPTF_CLL_DataSource. |
| // |
| // Public functions: |
| // <f_EPTF_DataSourceClient_init_CT> |
| // <f_EPTF_DataSourceClient_connectToServer> |
| // <f_EPTF_DataSourceClient_registerData> |
| // <f_EPTF_DataSourceClient_registerDataValue> |
| // <f_EPTF_DataSourceClient_registerSetDataValue> |
| // <f_EPTF_DataSourceClient_registerCondition> |
| // <f_EPTF_DataSourceClient_sendReady> |
| // <f_EPTF_DataSourceClient_getData> |
| // <f_EPTF_DataSourceClient_getData_nonBlocking> |
| // <f_EPTF_DataSourceClient_getDataValue> |
| // <f_EPTF_DataSourceClient_getDataValue_nonBlocking> |
| // <f_EPTF_DataSourceClient_setDataValue> |
| // <f_EPTF_DataSourceClient_setDataValue_nonBlocking> |
| // <f_EPTF_DataSourceClient_checkData> |
| // <f_EPTF_DataSourceClient_enableUpdate> |
| // <f_EPTF_DataSourceClient_disableUpdate> |
| // <f_EPTF_DataSourceClient_getCondition> - to be implemented |
| // <f_EPTF_DataSourceClient_getCondition_nonBlocking> |
| // <f_EPTF_DataSourceClient_extractParams> |
| // |
| // All other functions in this module are private! |
| // |
| /////////////////////////////////////////////////////////////// |
| |
| module EPTF_CLL_DataSourceClient_Functions { |
| import from EPTF_CLL_Logging_Definitions all; |
| |
| import from EPTF_CLL_Logging_Functions all; |
| |
| import from EPTF_CLL_Common_Definitions all; |
| |
| |
| import from EPTF_CLL_Base_Functions all; |
| import from EPTF_CLL_Variable_Functions all; |
| import from EPTF_CLL_DataSource_Definitions all; |
| import from EPTF_CLL_DataSource_Functions all; |
| import from EPTF_CLL_HashMapStr2Int_Functions all; |
| import from EPTF_CLL_HashMap_Functions all; |
| import from EPTF_CLL_Semaphore_Functions all; |
| import from EPTF_CLL_Variable_Definitions all; |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_init_CT |
| // |
| // Purpose: |
| // Init function for DataSourceClient_CT |
| // |
| // Parameters: |
| // *in charstring pl_selfName* - the name of the component |
| // *in* <EPTF_DataSource_CT> *pl_sourceCompRef* - the |
| // main DataSource component (server). |
| // If it is null, no connection is made, the function |
| // <f_EPTF_DataSourceClient_connectToServer> should be called |
| // later. |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // Has to be called before any other DataSourceClient |
| // function is used |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_init_CT(in charstring pl_selfName, in EPTF_DataSource_CT pl_sourceCompRef) |
| runs on EPTF_DataSourceClient_CT { |
| if (v_EPTF_DataSourceClient_initialized) { |
| return; |
| } |
| f_EPTF_Base_init_CT(pl_selfName); |
| f_EPTF_Logging_init_CT(pl_selfName); |
| f_EPTF_Var_init_CT(pl_selfName); |
| f_EPTF_HashMap_init_CT(pl_selfName); |
| f_EPTF_Semaphore_init_CT(pl_selfName); |
| v_EPTF_DataSourceClient_connected := false; |
| f_EPTF_DataSourceClient_connectToServer(pl_sourceCompRef); |
| v_EPTF_DataSourceClient_initialized := true; |
| v_DataSourceClient_handler := activate(as_EPTF_DataSourceClient_EventHandler()); |
| f_EPTF_Base_registerCleanup(refers(f_EPTF_DataSourceClient_cleanup_CT)); |
| |
| v_fcb_EPTF_DataSourceClient_dataHandler_List := {}; |
| v_fcb_EPTF_DataSourceClient_dataValueHandler_List := {}; |
| v_fcb_EPTF_DataSourceClient_setDataValueHandler_List := {}; |
| v_EPTF_DataSourceClient_dataHandlerHash := f_EPTF_str2int_HashMap_New(c_EPTF_DataSourceClient_dataHandlerHashName); |
| |
| v_fcb_EPTF_DataSourceClient_conditionHandler_List := {}; |
| |
| v_EPTF_DataSourceClient_dataValueHash := f_EPTF_str2int_HashMap_New(c_EPTF_DataSourceClient_dataValueHashName); |
| v_EPTF_DataSourceClient_dataValue_List := {}; |
| v_EPTF_DataSourceClient_Msg_List := {}; |
| v_EPTF_DataSourceClient_GetDataHandler_DB := {}; |
| v_EPTF_DataSourceClient_GetDataValueHandler_DB := {}; |
| v_EPTF_DataSourceClient_pendingGetDataHash := f_EPTF_str2int_HashMap_New(c_EPTF_DataSourceClient_pendingGetDataHashName); |
| } |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_connectToServer |
| // |
| // Purpose: |
| // Connects to the specified DataSource component |
| // |
| // Parameters: |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef |
| // to connect to. If it is null, no connection is made. |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // If this function is called only once with non-null argument, |
| // the <f_EPTF_DataSourceClient_registerData> can be called |
| // without specifying the *pl_sourceCompRef* argument. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_connectToServer(in EPTF_DataSource_CT pl_sourceCompRef) runs on EPTF_DataSourceClient_CT { |
| if (pl_sourceCompRef!=null) { |
| connect(pl_sourceCompRef:EPTF_DataSourceIf,self:EPTF_DataSourceClientIf); |
| v_EPTF_DataSourceClient_connected := true; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_registerData |
| // |
| // Purpose: |
| // Registers a data handler into the DataSource_CT |
| // |
| // 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 <fcb_EPTF_DataSourceClient_dataHandler> pl_dataHandler* - this function is called |
| // when a data is requested for the given dataSource and ptcName |
| // The function should return the name of the EPTF Variable that contains the value |
| // of the requested data. |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef |
| // to register the data into. If not specified the data is registered to the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // Only one handler can be registered for the same pl_source and pl_ptcName, |
| // but it processes all dataElements and its parameters. |
| // The function might create the variable, or just return |
| // its name if it already existed before. |
| // The registered function can be called by calling <f_EPTF_DataSource_getData> |
| // on the component pl_sourceCompRef with the pl_source and pl_ptcName arguments registered here. |
| // Compare with <f_EPTF_DataSourceClient_registerDataValue>. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_registerData( |
| in charstring pl_source, |
| in charstring pl_ptcName := "", |
| in fcb_EPTF_DataSourceClient_dataHandler pl_dataHandler, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT { |
| if(not v_EPTF_DataSourceClient_connected) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register handler fn ",pl_dataHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " into pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource")); |
| return; |
| } |
| |
| var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| vl_handlerId := sizeof(v_fcb_EPTF_DataSourceClient_dataHandler_List); |
| v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] := pl_dataHandler; |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId); |
| } else { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register handler fn ",pl_dataHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName,": Handler already registered")); |
| return; |
| } |
| f_EPTF_DataSourceClient_registerSource(pl_source,pl_ptcName,pl_sourceCompRef); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_registerDataValue |
| // |
| // Purpose: |
| // Registers a dataValue handler into the DataSource_CT |
| // |
| // 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 <fcb_EPTF_DataSourceClient_dataValueHandler> pl_dataValueHandler* - this function is called |
| // when a data value is requested for the given dataSource and ptcName |
| // The function should return the value of the requested data. |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef |
| // to register the data into. If not specified the data is registered to the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // Only one value-handler can be registered for the same pl_source and pl_ptcName, |
| // but it processes all dataElements and its parameters. |
| // |
| // The registered function can be called by calling <f_EPTF_DataSource_getDataValue> |
| // on the component pl_sourceCompRef with the pl_source and pl_ptcName arguments registered here. |
| // |
| // Note, that if no dataValue-handler was specified, getData handlers are checked |
| // if they can return the variable name for the requested data. If they can, the value |
| // contained in the variable will be returned. |
| // If there is no such variable, the condition handlers are checked. If there is a condition, |
| // its value will be retured. |
| // This means that getDataValue can be used for dataElements with getDataHandler only or request the value |
| // of conditions. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_registerDataValue( |
| in charstring pl_source, |
| in charstring pl_ptcName := "", |
| in fcb_EPTF_DataSourceClient_dataValueHandler pl_dataValueHandler, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT { |
| if(not v_EPTF_DataSourceClient_connected) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register value-handler fn ",pl_dataValueHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " into pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource")); |
| return; |
| } |
| |
| // data value handler names will be prefixed with "DVH_", uses same hashTable |
| var charstring vl_handlerIdStr := "DVH_"&pl_source&"@"&pl_ptcName; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| vl_handlerId := sizeof(v_fcb_EPTF_DataSourceClient_dataValueHandler_List); |
| v_fcb_EPTF_DataSourceClient_dataValueHandler_List[vl_handlerId] := pl_dataValueHandler; |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId); |
| } else { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register value-handler fn ",pl_dataValueHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName,": Value-handler already registered")); |
| return; |
| } |
| f_EPTF_DataSourceClient_registerSource(pl_source,pl_ptcName,pl_sourceCompRef); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_registerSetDataValue |
| // |
| // Purpose: |
| // Registers a setDataValue handler into the DataSource_CT |
| // |
| // 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 <fcb_EPTF_DataSourceClient_setDataValueHandler> pl_setDataValueHandler* - this function is called |
| // when a set data value is requested for the given dataSource and ptcName |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef |
| // to register the data into. If not specified the data is registered to the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // Only one setDataValue handler can be registered for the same pl_source and pl_ptcName, |
| // but it processes all dataElements and its parameters. |
| // |
| // The registered function can be called by calling <f_EPTF_DataSource_setDataValue> |
| // on the component pl_sourceCompRef with the pl_source and pl_ptcName arguments registered here. |
| // |
| // Note, that if there is a getData handler but no setDataValue handler for the given data, |
| // the value of the variable returned by the getData handler will be set to the requested value. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_registerSetDataValue( |
| in charstring pl_source, |
| in charstring pl_ptcName := "", |
| in fcb_EPTF_DataSourceClient_setDataValueHandler pl_setDataValueHandler, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT { |
| if(not v_EPTF_DataSourceClient_connected) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register set-value-handler fn ",pl_setDataValueHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " into pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource")); |
| return; |
| } |
| |
| // set data value handler names will be prefixed with "SDVH_", uses same hashTable |
| var charstring vl_handlerIdStr := "SDVH_"&pl_source&"@"&pl_ptcName; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| vl_handlerId := sizeof(v_fcb_EPTF_DataSourceClient_setDataValueHandler_List); |
| v_fcb_EPTF_DataSourceClient_setDataValueHandler_List[vl_handlerId] := pl_setDataValueHandler; |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId); |
| } else { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register value-handler fn ",pl_setDataValueHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName,": Set-Value-handler already registered")); |
| return; |
| } |
| f_EPTF_DataSourceClient_registerSource(pl_source,pl_ptcName,pl_sourceCompRef); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_registerCondition |
| // |
| // Purpose: |
| // Registers a condition handler into the DataSource_CT |
| // |
| // 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 <fcb_EPTF_DataSourceClient_conditionHandler> pl_conditionHandler* - this function is called |
| // when a condition value is requested for the given dataSource, ptcName and method |
| // *in charstring pl_method* - the name of the method that corresponds to this condition handler |
| // (dataSource+ptcName should be a unigue id of the location of the condition) and |
| // (dataSource+ptcName+method should be a unigue id of the condition). Default: "" which means |
| // that log2str(pl_conditionHandler) is used for the method. |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef |
| // to register the data into. If not specified the data is registered to the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // Only one handler can be registered for the same pl_source, pl_ptcName and pl_method, |
| // but it processes all parameters. |
| // The registered function can be called by calling <f_EPTF_DataSource_getCondition> |
| // on the component pl_sourceCompRef with the pl_source,pl_ptcName and pl_method arguments registered here. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_registerCondition( |
| in charstring pl_source, |
| in charstring pl_ptcName := "", |
| in fcb_EPTF_DataSourceClient_conditionHandler pl_conditionHandler, |
| in charstring pl_method := "", |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT { |
| if(not v_EPTF_DataSourceClient_connected) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register condition handler fn ",pl_conditionHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_method: ",pl_method, " into pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource")); |
| return; |
| } |
| if (pl_method=="") { |
| pl_method := log2str(pl_conditionHandler); |
| } |
| var charstring vl_handlerIdStr := pl_source&"@"&pl_ptcName&"/"&pl_method; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| vl_handlerId := sizeof(v_fcb_EPTF_DataSourceClient_conditionHandler_List); |
| v_fcb_EPTF_DataSourceClient_conditionHandler_List[vl_handlerId] := pl_conditionHandler; |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId); |
| } else { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot register condition handler fn ",pl_conditionHandler, |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName," pl_method: ",pl_method,": Handler already registered")); |
| return; |
| } |
| f_EPTF_DataSourceClient_registerSource(pl_source,pl_ptcName,pl_sourceCompRef); |
| } |
| |
| |
| private function f_EPTF_DataSourceClient_registerSource( |
| in charstring pl_source, |
| in charstring pl_ptcName := "", |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT { |
| // send registerData if it was not already sent: |
| var charstring vl_handlerIdStr := "Registered:"&pl_source&"@"&pl_ptcName; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId); |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{registerData:={pl_source,pl_ptcName}},pl_sourceCompRef); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_sendReady |
| // |
| // Purpose: |
| // Notifies the DataSource_CT that the client is ready to receive data requests |
| // |
| // 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) |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef |
| // If not specified the data is sent to the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // Notifies the DataSource_CT that the client is ready to receive data requests. |
| // When a client becomes ready on the DataSource component, the callback functions |
| // registered by <f_EPTF_DataSource_registerReadyCallback> are called. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_sendReady( |
| in charstring pl_source, |
| in charstring pl_ptcName, |
| in EPTF_DataSource_CT pl_sourceCompRef := null) |
| runs on EPTF_DataSourceClient_CT { |
| if(not v_EPTF_DataSourceClient_connected) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot send Ready ", |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " to pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource")); |
| return; |
| } |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{clientReady:={pl_source, pl_ptcName}}, pl_sourceCompRef); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_getData |
| // |
| // Purpose: |
| // To get the value of a 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 |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef to get the value from |
| // If not specified the data is requested from the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // 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: |
| // Sends a request to the main DataSource_CT component |
| // to request the EPTF Variable name for the given dataSource. |
| // It will automatically subscribe to the source variable. |
| // The subscription is done directly to the source PTC, there is no subscription |
| // performed by the DataSource_CT |
| // |
| // In case of error, the pl_dataVarName argument may contain a charstring with an error message. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_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, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| if(not v_EPTF_DataSourceClient_connected) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot get data ", |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_element: ",pl_element," pl_params: ",pl_params, " from pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource")); |
| pl_dataVarName := ""; |
| return -99; |
| } |
| |
| f_EPTF_DataSource_sortParams(pl_params); |
| |
| pl_dataVarName := ""; |
| var integer vl_localDataVarId; |
| var EPTF_Var_CT vl_ownerCompRef; |
| var charstring vl_remoteDataVarName; |
| // check if already subscribed: |
| var charstring vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params); |
| var integer vl_dataValueId; |
| var integer vl_errorCode; |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_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_DataSourceClient_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_DataSourceClient_dataValue_List[vl_dataValueId].remoteDataVarName; |
| vl_ownerCompRef := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].ownerCompRef; |
| vl_errorCode := 0; |
| } else { |
| |
| var integer vl_transactionId := f_EPTF_Semaphore_new(); |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{getData:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| dataElement := pl_element, |
| params := pl_params |
| }}, pl_sourceCompRef); |
| |
| //wait for the result: |
| if (f_EPTF_Semaphore_waitForUnlock(vl_transactionId,tsp_EPTF_DataSourceClient_maxWaitTime)) { |
| // max wait time expired before response received: |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Communication error: No response received for getData message: ",vl_transactionId)); |
| 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_ownerCompRef := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValue.ownerCompRef; |
| vl_remoteDataVarName := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValue.dataVarName; |
| vl_errorCode := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValue.errorCode; |
| |
| //set the variable name |
| // this will always be true if errorCode == 0: |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) { |
| vl_localDataVarId := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].localDataVarId; |
| pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId); |
| |
| if(f_EPTF_Var_checkSubscriptionMode(vl_localDataVarId,pl_subscriptionMode)) { |
| return 0; |
| } |
| } |
| } |
| |
| //subscribe to the source variable: |
| // if returned error code is 0 (no error) subscibe to the provider data variable: |
| if (vl_errorCode==0) { |
| // The presence of the source variable is not checked. It was done on the main dataSource component. |
| // If error code is 0, it will be there |
| |
| f_EPTF_Var_resubscribeRemote( |
| vl_ownerCompRef, |
| vl_remoteDataVarName, |
| pl_subscriptionMode, |
| vl_localDataVarId, |
| pl_dataVarName, |
| pl_refreshRate |
| ); |
| } else { |
| f_EPTF_DataSourceClient_warning(vl_remoteDataVarName); // warning message is received in the dataVarName |
| } |
| return vl_errorCode; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_getData_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_GetDataHandler> - pl_getDataHandler - the handler function (with user arguments) to call |
| // when response is received |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef to get the value from |
| // If not specified the data is requested from the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // integer - 0 if request is OK, nonzero if request is invalid. In both cases the handler will be called. |
| // |
| // Detailed Comments: |
| // Sends a request to the main DataSource_CT component |
| // to request the EPTF Variable name for the given dataSource. |
| // The given handler function is called when the response is available. |
| // 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_DataSourceClient_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_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| |
| var integer vl_errorCode; |
| |
| if(not v_EPTF_DataSourceClient_connected) { |
| vl_errorCode := -99; |
| var charstring vl_errorMsg := log2str(%definitionId&": Cannot get data ", |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_element: ",pl_element," pl_params: ",pl_params, " from pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource"); |
| f_EPTF_DataSourceClient_warning(vl_errorMsg); |
| |
| // 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_errorMsg, // var name on the remote component. In case errorCode!=0: it contains the error message |
| pl_ownerCompRef := null, // reference to the remote component |
| pl_localDataVarId := -1, // var id on the local component (contains the current value, not subscribed to remote!) |
| pl_dataValue := {charstringVal:=vl_errorMsg}, // the value of the data |
| // user data |
| pl_userData := pl_getDataHandler.userData // user specific data given at the request |
| ); |
| } |
| return vl_errorCode; |
| } |
| |
| f_EPTF_DataSource_sortParams(pl_params); |
| |
| // check if already subscribed: |
| 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_DataSourceClient_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) { |
| |
| 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; |
| |
| 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_DataSourceClient_dataValue_List[vl_dataValueId].remoteDataVarName; |
| vl_ownerCompRef := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].ownerCompRef; |
| vl_localDataVarId := v_EPTF_DataSourceClient_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 { |
| |
| //recalculate vl_dataValueIdStr with given PTCName: |
| vl_dataValueIdStr := pl_source&"@"&pl_ptcName&"."&pl_element&":"&log2str(pl_params); |
| var integer vl_transactionId; |
| // check if there is a pending request: |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_pendingGetDataHash,vl_dataValueIdStr,vl_transactionId)) { |
| v_EPTF_DataSourceClient_GetDataHandler_DB[vl_transactionId] := v_EPTF_DataSourceClient_GetDataHandler_DB[vl_transactionId] & {pl_getDataHandler}; |
| } else { |
| vl_transactionId := f_EPTF_Semaphore_new(); |
| v_EPTF_DataSourceClient_GetDataHandler_DB[vl_transactionId] := {pl_getDataHandler}; |
| //f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_pendingGetDataHash,vl_dataValueIdStr,vl_transactionId); |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{getData:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| dataElement := pl_element, |
| params := pl_params |
| }}, pl_sourceCompRef); |
| } |
| |
| vl_errorCode := 0; |
| } |
| |
| return vl_errorCode; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_getDataValue |
| // |
| // Purpose: |
| // To get the value of a 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 |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef to get the value from |
| // If not specified the data is requested from the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // 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 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 <EPTF_Var_DirectContent> value which is set in the pl_dataValue |
| // argument. The value will be returned by this function |
| // together with the error code returned by the handler function. |
| // |
| // In case of error, the pl_dataValue argument may contain a charstring with an error message. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_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, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| |
| var integer vl_errorCode; |
| |
| if(not v_EPTF_DataSourceClient_connected) { |
| vl_errorCode := -99; |
| var charstring vl_errorMsg := log2str(%definitionId&": Cannot get data value ", |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_element: ",pl_element," pl_params: ",pl_params, " from pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource"); |
| f_EPTF_DataSourceClient_warning(vl_errorMsg); |
| pl_dataValue := {charstringVal := vl_errorMsg}; |
| return vl_errorCode; |
| } |
| |
| f_EPTF_DataSource_sortParams(pl_params); |
| |
| var integer vl_transactionId := f_EPTF_Semaphore_new(); |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{getDataValue:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| dataElement := pl_element, |
| params := pl_params, |
| filter := pl_filter |
| }}, pl_sourceCompRef); |
| |
| //wait for the result: |
| if (f_EPTF_Semaphore_waitForUnlock(vl_transactionId,tsp_EPTF_DataSourceClient_maxWaitTime)) { |
| // max wait time expired before response received: |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Communication error: No response received for getDataValue message: ",vl_transactionId)); |
| pl_dataValue := {charstringVal := log2str(%definitionId&": Communication error: No response received for getDataValue message: ",vl_transactionId)}; |
| 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_ownerCompRef := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValue.ownerCompRef; |
| pl_dataValue := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValueResponse.dataValue; |
| vl_errorCode := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValueResponse.errorCode; |
| return vl_errorCode; |
| } |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_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 |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef to get the value from |
| // If not specified the data is requested from the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // integer - 0 if request is OK, nonzero in case of invalid request |
| // |
| // 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 which is set in its pl_dataValue |
| // argument and an error code set in the pl_errorCode argument. These parameters are passed to the |
| // handler function given in pl_getDataValueHandler. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_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, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| |
| var integer vl_errorCode; |
| |
| if(not v_EPTF_DataSourceClient_connected) { |
| vl_errorCode := -99; |
| var charstring vl_errorMsg := log2str(%definitionId&": Cannot get data value ", |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_element: ",pl_element," pl_params: ",pl_params, " from pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource"); |
| f_EPTF_DataSourceClient_warning(vl_errorMsg); |
| |
| // call handler: |
| if (pl_getDataValueHandler.getDataValueHandler!=null) { |
| pl_getDataValueHandler.getDataValueHandler.apply( |
| // reponse parameters: |
| pl_errorCode := vl_errorCode, // error code in the response |
| pl_dataValue := {charstringVal:=vl_errorMsg}, // the value of the data |
| // user data |
| pl_userData := pl_getDataValueHandler.userData // user specific data given at the request |
| ); |
| } |
| return vl_errorCode; |
| } |
| |
| |
| f_EPTF_DataSource_sortParams(pl_params); |
| |
| var integer vl_transactionId := f_EPTF_Semaphore_new(); |
| v_EPTF_DataSourceClient_GetDataValueHandler_DB[vl_transactionId] := pl_getDataValueHandler; |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{getDataValue:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| dataElement := pl_element, |
| params := pl_params, |
| filter := pl_filter |
| }}, pl_sourceCompRef); |
| |
| vl_errorCode := 0; |
| return vl_errorCode; |
| } |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_setDataValue |
| // |
| // Purpose: |
| // To set the value of a given data |
| // |
| // Parameters: |
| // *inout* <EPTF_Var_DirectContent> *pl_dataValue* - this is the value of the data to be set |
| // after call, it will return the changed value that might be different after the function call |
| // *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_CT> pl_sourceCompRef* - the DataSource_CT componentRef to set the value on. |
| // If not specified the data is requested from the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // integer - 0 if OK, nonzero in case of failure to show that changing of the value was 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 a value which is set in the pl_dataValue |
| // argument and returns an error code to show if the change was successful or not. |
| // This function will return these values in its pl_dataValue argument and the return value. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_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 := {}, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| |
| var integer vl_errorCode; |
| |
| if(not v_EPTF_DataSourceClient_connected) { |
| vl_errorCode := -99; |
| var charstring vl_errorMsg := log2str(%definitionId&": Cannot set data value to ",pl_dataValue, |
| " for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_element: ",pl_element," pl_params: ",pl_params, " from pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource"); |
| f_EPTF_DataSourceClient_warning(vl_errorMsg); |
| pl_dataValue := {charstringVal := vl_errorMsg}; |
| return vl_errorCode; |
| } |
| |
| f_EPTF_DataSource_sortParams(pl_params); |
| |
| var integer vl_transactionId := f_EPTF_Semaphore_new(); |
| |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{setDataValue:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| dataElement := pl_element, |
| params := pl_params, |
| dataValue := pl_dataValue, |
| indexList := pl_indexList |
| }}, pl_sourceCompRef); |
| |
| //wait for the result: |
| if (f_EPTF_Semaphore_waitForUnlock(vl_transactionId,tsp_EPTF_DataSourceClient_maxWaitTime)) { |
| // max wait time expired before response received: |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Communication error: No response received for setDataValue message: ",vl_transactionId)); |
| pl_dataValue := {charstringVal := log2str(%definitionId&": Communication error: No response received for setDataValue message: ",vl_transactionId)}; |
| 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_ownerCompRef := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValue.ownerCompRef; |
| pl_dataValue := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValueResponse.dataValue; |
| vl_errorCode := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValueResponse.errorCode; |
| return vl_errorCode; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_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 |
| // 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 |
| // *in* <EPTF_DataSource_GetDataValueHandler> - pl_getDataValueHandler - the handler function (with user arguments) to call |
| // when response is received |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef to set the value on |
| // If not specified the data is modified on the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // integer - 0 if request is OK, nonzero in case of failure to show that the request is not valid |
| // |
| // Detailed Comments: |
| // This function will make a request for the given data source and return the value of the changed 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 which is set in the pl_dataVarName |
| // argument together with the error code. |
| // These values are passed to the handler given in the pl_getDataValueHandler parameter. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_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_getDataValueHandler := cg_EPTF_DataSource_GetDataValueHandler_null, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| |
| var integer vl_errorCode; |
| |
| if(not v_EPTF_DataSourceClient_connected) { |
| vl_errorCode := -99; |
| var charstring vl_errorMsg := log2str(%definitionId&": Cannot set data value ",pl_dataValue, |
| " for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_element: ",pl_element," pl_params: ",pl_params, " from pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource"); |
| f_EPTF_DataSourceClient_warning(vl_errorMsg); |
| |
| // call handler: |
| if (pl_getDataValueHandler.getDataValueHandler!=null) { |
| pl_getDataValueHandler.getDataValueHandler.apply( |
| // reponse parameters: |
| pl_errorCode := vl_errorCode, // error code in the response |
| pl_dataValue := {charstringVal:=vl_errorMsg}, // the value of the data |
| // user data |
| pl_userData := pl_getDataValueHandler.userData // user specific data given at the request |
| ); |
| } |
| return vl_errorCode; |
| } |
| |
| f_EPTF_DataSource_sortParams(pl_params); |
| |
| var integer vl_transactionId := f_EPTF_Semaphore_new(); |
| v_EPTF_DataSourceClient_GetDataValueHandler_DB[vl_transactionId] := pl_getDataValueHandler; |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{setDataValue:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| dataElement := pl_element, |
| params := pl_params, |
| dataValue := pl_dataValue, |
| indexList := pl_indexList |
| }}, pl_sourceCompRef); |
| |
| vl_errorCode := 0; |
| return vl_errorCode; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_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 |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef to get the value from |
| // If not specified the data is requested from the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // integer - 0 if OK, nonzero if pl_dataVarName is not valid |
| // |
| // Detailed Comments: |
| // This function is almost the same as <f_EPTF_DataSourceClient_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. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_checkData( |
| out charstring pl_dataVarName, |
| in charstring pl_source, |
| in charstring pl_ptcName := "", |
| in charstring pl_element, |
| in EPTF_DataSource_Params pl_params := {}, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| if(not v_EPTF_DataSourceClient_connected) { |
| return -99; // not connected |
| } |
| |
| f_EPTF_DataSource_sortParams(pl_params); |
| pl_dataVarName := ""; |
| // check if already subscribed: |
| 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_DataSourceClient_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_DataSourceClient_dataValue_List[vl_dataValueId].localDataVarId; |
| pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId); |
| return 0; |
| } |
| |
| pl_dataVarName := ""; |
| var integer vl_transactionId := f_EPTF_Semaphore_new(); |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{getData:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| dataElement := pl_element, |
| params := pl_params |
| }}, pl_sourceCompRef); |
| |
| //wait for the result: |
| if (f_EPTF_Semaphore_waitForUnlock(vl_transactionId,tsp_EPTF_DataSourceClient_maxWaitTime)) { |
| // max wait time expired before response received: |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Communication error: No response received for getData message: ",vl_transactionId)); |
| 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_DataSourceClient_Msg_List[vl_transactionId].dataValue.errorCode; |
| //var EPTF_DataSourceClient_CT vl_ownerCompRef := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValue.ownerCompRef; |
| var charstring vl_remoteDataVarName := v_EPTF_DataSourceClient_Msg_List[vl_transactionId].dataValue.dataVarName; |
| |
| // this will always be true if errorCode == 0: |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) { |
| var integer vl_localDataVarId := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].localDataVarId; |
| pl_dataVarName := f_EPTF_Var_getName(vl_localDataVarId); |
| } |
| |
| return vl_errorCode; |
| } |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_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 |
| // |
| // Return Value: |
| // integer - 0 if OK, nonzero if pl_localDataVarName is not valid |
| // |
| // Detailed Comments: |
| // This function can be called after a <f_EPTF_DataSourceClient_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_DataSourceClient_disableUpdate> |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_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_DataSourceClient_CT return integer { |
| var integer vl_dataValueId := f_EPTF_DataSourceClient_getDataValueId(pl_localDataVarName); |
| |
| if (vl_dataValueId==-1) { |
| return 1; //error; |
| } |
| |
| var integer vl_localDataVarId := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].localDataVarId; |
| |
| if(f_EPTF_Var_checkSubscriptionMode(vl_localDataVarId,pl_subscriptionMode)) { |
| return 0; // already subscribed |
| } |
| |
| var charstring vl_remoteDataVarName := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].remoteDataVarName; |
| var EPTF_Var_CT vl_ownerCompRef := v_EPTF_DataSourceClient_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_DataSourceClient_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_DataSourceClient_enableUpdate> |
| // to unsubscribe the local dataSource variable from the source variable. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_disableUpdate( |
| in charstring pl_localDataVarName |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| var integer vl_dataValueId := f_EPTF_DataSourceClient_getDataValueId(pl_localDataVarName); |
| |
| if (vl_dataValueId==-1) { |
| return 1; //error; |
| } |
| |
| var integer vl_localDataVarId := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].localDataVarId; |
| |
| f_EPTF_Var_unsubscribe(vl_localDataVarId); |
| return 0; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_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_DataSourceClient_checkData> |
| // or <f_EPTF_DataSourceClient_getData>. |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_DataSourceClient_getDataValueId( |
| in charstring pl_localDataVarName |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| var integer vl_dataValueId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataValueHash,pl_localDataVarName,vl_dataValueId)) { |
| vl_dataValueId := -1; |
| } |
| return vl_dataValueId; |
| } |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_getCondition_nonBlocking |
| // |
| // Purpose: |
| // To get the value of a given condition 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_method* - the type of condition |
| // *in* <EPTF_DataSource_Params> *pl_params* - additional parameters (default: {}) |
| // The parameters are sorted lexicographically according to the paramNames |
| // *in* <EPTF_DataSource_GetConditionHandler> - pl_getConditionHandler - the handler function (with user arguments) to call |
| // when response is received |
| // *in <EPTF_DataSource_CT> pl_sourceCompRef* - the DataSource_CT componentRef to get the value from |
| // If not specified the data is requested from the only one |
| // DataSource component which is connected (= for which the <f_EPTF_DataSourceClient_connectToServer> was called) |
| // |
| // Return Value: |
| // integer - 0 if OK, nonzero if dataSource is not available. In both cases the handler will be called. |
| // |
| // Detailed Comments: |
| // Sends a request to the main DataSource_CT component |
| // to request the condition value from the given dataSource. |
| // The given handler function is called when the response is available. |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_getCondition_nonBlocking( |
| in charstring pl_source, |
| in charstring pl_ptcName := "", |
| in charstring pl_method, |
| in EPTF_DataSource_Params pl_params := {}, |
| in EPTF_DataSource_GetConditionHandler pl_getConditionHandler := cg_EPTF_DataSource_GetDataHandler_null, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT return integer { |
| |
| var integer vl_errorCode; |
| |
| if(not v_EPTF_DataSourceClient_connected) { |
| vl_errorCode := -99; |
| var charstring vl_remoteDataVarName := log2str(%definitionId&": Cannot get condition ", |
| "for pl_source: ",pl_source," pl_ptcName: ",pl_ptcName, " pl_method: ",pl_method," pl_params: ",pl_params, " from pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource"); |
| f_EPTF_DataSourceClient_warning(vl_remoteDataVarName); |
| |
| // call handler: |
| if (pl_getConditionHandler.getDataHandler!=null) { |
| pl_getConditionHandler.getDataHandler.apply( |
| //request parameters: |
| pl_source := pl_source, |
| pl_ptcName := pl_ptcName, // response may fill this if it was "" |
| pl_element := pl_method, |
| 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 := null, // reference to the remote component |
| pl_localDataVarId := -1, // var id on the local component (contains the current value, not subscribed to remote!) |
| pl_dataValue := {unknownVal:={omit}}, // the value of the data |
| // user data |
| pl_userData := pl_getConditionHandler.userData // user specific data given at the request |
| ); |
| } |
| return vl_errorCode; |
| } |
| |
| var integer vl_transactionId := f_EPTF_Semaphore_new(); |
| v_EPTF_DataSourceClient_GetDataHandler_DB[vl_transactionId] := {pl_getConditionHandler}; |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{getCondition:={ |
| transactionId := vl_transactionId, |
| dataSource := pl_source, |
| ptcName := pl_ptcName, |
| method := pl_method, |
| params := pl_params |
| }}, pl_sourceCompRef); |
| |
| vl_errorCode := 0; |
| |
| return vl_errorCode; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // Private functions: |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| |
| |
| private function f_EPTF_DataSourceClient_cleanup_CT() runs on EPTF_DataSourceClient_CT { |
| if (not v_EPTF_DataSourceClient_initialized) { |
| return; |
| } |
| v_EPTF_DataSourceClient_initialized := false; |
| //disconnect(pl_sourceCompRef:EPTF_DataSourceIf,self:EPTF_DataSourceClientIf); |
| deactivate(v_DataSourceClient_handler); |
| v_DataSourceClient_handler := null; |
| if (v_EPTF_DataSourceClient_dataHandlerHash!=-1) { |
| v_EPTF_DataSourceClient_dataHandlerHash := -1; |
| f_EPTF_str2int_HashMap_Delete(c_EPTF_DataSourceClient_dataHandlerHashName); |
| } |
| if (v_EPTF_DataSourceClient_dataValueHash!=-1) { |
| v_EPTF_DataSourceClient_dataValueHash := -1; |
| f_EPTF_str2int_HashMap_Delete(c_EPTF_DataSourceClient_dataValueHashName); |
| } |
| if (v_EPTF_DataSourceClient_pendingGetDataHash!=-1) { |
| v_EPTF_DataSourceClient_pendingGetDataHash := -1; |
| f_EPTF_str2int_HashMap_Delete(c_EPTF_DataSourceClient_pendingGetDataHashName); |
| } |
| } |
| |
| private function f_EPTF_DataSourceClient_handleGetData( |
| in EPTF_DataSource_Msg_GetData pl_getData, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| // find handler: |
| var charstring vl_handlerIdStr := pl_getData.dataSource&"@"&pl_getData.ptcName; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| // send errorCode to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{dataValue:={ |
| pl_getData.transactionId, |
| pl_getData.dataSource, |
| pl_getData.ptcName, |
| pl_getData.dataElement, |
| pl_getData.params, |
| "Handler not registered", |
| {unknownVal:={omit}}, |
| 1, |
| self // it is the same as the sender of the message |
| }},pl_sourceCompRef); |
| return; |
| } |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var charstring vl_dataVarName; |
| var integer vl_errorCode := v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId].apply( |
| vl_dataVarName, |
| pl_getData.dataSource, |
| pl_getData.ptcName, |
| pl_getData.dataElement, |
| pl_getData.params |
| ); |
| |
| if (not isbound(vl_dataVarName)) { |
| vl_dataVarName := ""; |
| } |
| |
| var EPTF_Var_DirectContent vl_currentContent := {unknownVal:={omit}}; |
| if (vl_errorCode==0) { |
| var integer vl_varIdx := f_EPTF_Var_getId(vl_dataVarName); |
| if (vl_varIdx==-1) { |
| // source variable does not exist: |
| // send errorCode to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{dataValue:={ |
| pl_getData.transactionId, |
| pl_getData.dataSource, |
| pl_getData.ptcName, |
| pl_getData.dataElement, |
| pl_getData.params, |
| log2str("Source Variable ",vl_dataVarName," not found"), |
| {unknownVal:={omit}}, |
| 2, |
| self // it is the same as the sender of the message |
| }},pl_sourceCompRef); |
| return; |
| } else { |
| f_EPTF_Var_getContent(vl_varIdx,vl_currentContent); |
| } |
| } |
| // send vl_dataVarName to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{dataValue:={ |
| pl_getData.transactionId, |
| pl_getData.dataSource, |
| pl_getData.ptcName, |
| pl_getData.dataElement, |
| pl_getData.params, |
| vl_dataVarName, |
| vl_currentContent, |
| vl_errorCode, |
| self // it is the same as the sender of the message |
| }},pl_sourceCompRef); |
| } |
| |
| private function f_EPTF_DataSourceClient_getErrMsg4Get( |
| in EPTF_DataSource_Msg_GetDataValue pl_getDataValue, |
| in charstring pl_errMsg |
| ) runs on EPTF_DataSourceClient_CT |
| return charstring { |
| return |
| log2str("f_EPTF_DataSourceClient_handleGetDataValue: Invalid iterator or externalData or parameter: ", |
| "\nSource: ", pl_getDataValue.dataSource, |
| "\nPTC : ", pl_getDataValue.ptcName , |
| "\nElement Name : " , pl_getDataValue.dataElement, |
| "\nParams: " , pl_getDataValue.params)&"\nReason: "&pl_errMsg; |
| } |
| |
| private function f_EPTF_DataSourceClient_getErrMsg4Set( |
| in EPTF_DataSource_Msg_SetDataValue pl_setDataValue, |
| in charstring pl_errMsg |
| ) runs on EPTF_DataSourceClient_CT |
| return charstring { |
| return |
| log2str("f_EPTF_DataSourceClient_handleSetDataValue: Invalid iterator or externalData or parameter: ", |
| "\nSource: ", pl_setDataValue.dataSource, |
| "\nPTC : ", pl_setDataValue.ptcName , |
| "\nElement Name : " , pl_setDataValue.dataElement, |
| "\nParams: " , pl_setDataValue.params, |
| "\nValue to Set: ", pl_setDataValue.dataValue, |
| "\nIndex List: ", pl_setDataValue.indexList)&"\nReason: "&pl_errMsg; |
| } |
| |
| private function f_EPTF_DataSourceClient_handleBuiltInElements( |
| out EPTF_DataSource_Msg_DataValueResponse pl_dataValueResponse, |
| in EPTF_DataSource_Msg_GetDataValue pl_getDataValue |
| ) runs on EPTF_DataSourceClient_CT { |
| |
| var EPTF_DataSource_Msg_DataValueResponse vl_dataValueResponse := { |
| pl_getDataValue.transactionId, |
| {unknownVal:={omit}}, |
| -54321 |
| } |
| |
| var charstring vl_dataElement := pl_getDataValue.dataElement; |
| |
| select( vl_dataElement ) |
| { |
| case(c_EPTF_DataSource_dataElement_sizeOf) { |
| vl_dataValueResponse.errorCode := 0; |
| |
| var charstring vl_source; |
| var charstring vl_ptcName; |
| var charstring vl_element; |
| var EPTF_DataSource_Params vl_params; |
| |
| vl_dataValueResponse.errorCode := f_EPTF_DataSource_getRequestPartsFromParams( |
| pl_getDataValue.params, |
| vl_source, |
| vl_ptcName, |
| vl_element, |
| vl_params |
| ); |
| |
| if (vl_dataValueResponse.errorCode == 0) { |
| var EPTF_DataSource_Msg_GetDataValue vl_getDataValue := { |
| pl_getDataValue.transactionId, |
| vl_source, |
| vl_ptcName, |
| vl_element, |
| vl_params |
| } |
| var EPTF_DataSource_Msg_DataValueResponse vl_dataValueResponseForOriginalRequest; |
| f_EPTF_DataSourceClient_handleClientElements( |
| vl_dataValueResponseForOriginalRequest, |
| vl_getDataValue |
| ); |
| |
| var EPTF_Var_DirectContent vl_dataValue := vl_dataValueResponseForOriginalRequest.dataValue; |
| if (vl_dataValueResponseForOriginalRequest.errorCode == 0) { |
| var integer vl_size := f_EPTF_DataSource_getSizeOfDataValue(vl_dataValue); |
| vl_dataValueResponse.dataValue := {intVal := vl_size}; |
| } else { |
| // could not get the element |
| vl_dataValueResponse.errorCode := vl_dataValueResponseForOriginalRequest.errorCode; |
| var charstring vl_msg := "Could not determine the size of the dataelement"; |
| if (ischosen(vl_dataValue.charstringVal)) { |
| vl_msg := vl_msg & ": " & vl_dataValue.charstringVal; |
| } |
| vl_dataValueResponse.dataValue := {charstringVal := vl_msg}; |
| } |
| } else { |
| // wrong params |
| var charstring vl_msg := "Could not determine the size of the dataelement, invalid parameters: " & log2str(pl_getDataValue.params); |
| vl_dataValueResponse.dataValue := {charstringVal := vl_msg}; |
| } |
| } |
| case(c_EPTF_DataSource_dataElement_isWritable) { |
| vl_dataValueResponse.errorCode := 0; |
| |
| // TODO check if element is writable |
| vl_dataValueResponse.dataValue := {boolVal := false}; |
| |
| var charstring vl_source; |
| var charstring vl_ptcName; |
| var charstring vl_element; |
| var EPTF_DataSource_Params vl_params; |
| |
| vl_dataValueResponse.errorCode := f_EPTF_DataSource_getRequestPartsFromParams( |
| pl_getDataValue.params, |
| vl_source, |
| vl_ptcName, |
| vl_element, |
| vl_params |
| ); |
| |
| if (vl_dataValueResponse.errorCode == 0) { |
| |
| var charstring vl_handlerIdStr := vl_source&"@"&vl_ptcName; |
| var charstring vl_dataValueHandlerIdStr := "DVH_"&vl_handlerIdStr; |
| var integer vl_handlerId; |
| |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash, vl_dataValueHandlerIdStr, vl_handlerId)) { |
| vl_dataValueResponse.errorCode := v_fcb_EPTF_DataSourceClient_dataValueHandler_List[vl_handlerId].apply( |
| vl_dataValueResponse.dataValue, |
| vl_source, |
| pl_getDataValue.ptcName, |
| c_EPTF_DataSource_dataElement_isWritable, //pl_getDataValue.dataElement |
| pl_getDataValue.params |
| ); |
| } |
| // try to find getData handler: |
| if (vl_dataValueResponse.errorCode != 0 and f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var charstring vl_dataVarName; |
| vl_dataValueResponse.errorCode := v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId].apply( |
| vl_dataVarName, |
| vl_source, |
| vl_ptcName, |
| vl_element, |
| vl_params |
| ); |
| |
| if (not isbound(vl_dataVarName)) { |
| vl_dataVarName := ""; |
| } |
| if (vl_dataValueResponse.errorCode==0) { |
| // read value from the variable: |
| var integer vl_varIdx := f_EPTF_Var_getId(vl_dataVarName); |
| if (vl_varIdx==-1) { |
| // source variable does not exist: |
| // set error message and error code: |
| vl_dataValueResponse.dataValue := {charstringVal := log2str("Source Variable ",vl_dataVarName," not found")}; |
| vl_dataValueResponse.errorCode := 2; // error code |
| } else { |
| // get current value from the variable: |
| vl_dataValueResponse.dataValue := {boolVal := f_EPTF_Var_getSubsCanAdjust(vl_varIdx)}; |
| } |
| } else { |
| // append current error messages together: |
| if (not isbound(vl_dataVarName)) { |
| vl_dataVarName := ""; |
| } |
| if (isbound(vl_dataValueResponse.dataValue) and ischosen(vl_dataValueResponse.dataValue.charstringVal)) { |
| if (vl_dataVarName=="") { |
| vl_dataVarName := vl_dataValueResponse.dataValue.charstringVal; |
| } else { |
| vl_dataVarName := vl_dataValueResponse.dataValue.charstringVal&" or "&vl_dataVarName; |
| } |
| } else if (vl_dataVarName == "") { |
| vl_dataVarName := "Unknown error"; |
| } |
| vl_dataValueResponse.dataValue := {charstringVal := vl_dataVarName}; |
| } |
| } |
| } else { |
| // wrong params |
| var charstring vl_msg := "Could not determine whether the dataelement is writable, invalid parameters: " & log2str(pl_getDataValue.params); |
| vl_dataValueResponse.dataValue := {charstringVal := vl_msg}; |
| } |
| } |
| case else { |
| // TODO error handling? |
| vl_dataValueResponse.dataValue := {charstringVal := "Unknown error"}; |
| vl_dataValueResponse.errorCode := -10; |
| } |
| } |
| |
| pl_dataValueResponse := vl_dataValueResponse; |
| } |
| |
| private function f_EPTF_DataSourceClient_handleClientElements( |
| out EPTF_DataSource_Msg_DataValueResponse pl_dataValueResponse, |
| in EPTF_DataSource_Msg_GetDataValue pl_getDataValue |
| ) runs on EPTF_DataSourceClient_CT { |
| var EPTF_DataSource_Msg_DataValueResponse vl_dataValueResponse := { |
| pl_getDataValue.transactionId, |
| {unknownVal:={omit}}, |
| -54321 |
| } |
| |
| // find handler: |
| var charstring vl_handlerIdStr := pl_getDataValue.dataSource&"@"&pl_getDataValue.ptcName; |
| var charstring vl_valueHandlerIdStr := "DVH_"&vl_handlerIdStr; |
| var integer vl_handlerId := -1; |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_valueHandlerIdStr,vl_handlerId)) { |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataValueHandler_List[vl_handlerId] |
| vl_dataValueResponse.errorCode := v_fcb_EPTF_DataSourceClient_dataValueHandler_List[vl_handlerId].apply( |
| vl_dataValueResponse.dataValue, |
| pl_getDataValue.dataSource, |
| pl_getDataValue.ptcName, |
| pl_getDataValue.dataElement, |
| pl_getDataValue.params |
| ); |
| } |
| |
| if (vl_dataValueResponse.errorCode != 0) { |
| // try to find condition handler: |
| vl_handlerIdStr := pl_getDataValue.dataSource&"@"&pl_getDataValue.ptcName&"/"&pl_getDataValue.dataElement; |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var boolean vl_conditionValue; |
| vl_dataValueResponse.errorCode := v_fcb_EPTF_DataSourceClient_conditionHandler_List[vl_handlerId].apply( |
| vl_conditionValue, |
| pl_getDataValue.dataSource, |
| pl_getDataValue.ptcName, |
| pl_getDataValue.dataElement, |
| pl_getDataValue.params |
| ); |
| |
| if (not isbound(vl_conditionValue)) { |
| vl_conditionValue := false; |
| } |
| if (vl_dataValueResponse.errorCode==0) { |
| vl_dataValueResponse.dataValue := {boolVal := vl_conditionValue}; |
| } else { |
| var charstring vl_errorMsg := log2str("Invalid parameters for condition: ", pl_getDataValue.dataElement); |
| // append error messages together: |
| if (isbound(vl_dataValueResponse.dataValue) and ischosen(vl_dataValueResponse.dataValue.charstringVal)) { |
| vl_errorMsg := vl_dataValueResponse.dataValue.charstringVal&" or "&vl_errorMsg; |
| } |
| vl_dataValueResponse.dataValue := {charstringVal := vl_errorMsg}; |
| } |
| } |
| } |
| |
| if (vl_dataValueResponse.errorCode != 0) { |
| // try to find getData handler: |
| vl_handlerIdStr := pl_getDataValue.dataSource&"@"&pl_getDataValue.ptcName; |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var charstring vl_dataVarName; |
| vl_dataValueResponse.errorCode := v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId].apply( |
| vl_dataVarName, |
| pl_getDataValue.dataSource, |
| pl_getDataValue.ptcName, |
| pl_getDataValue.dataElement, |
| pl_getDataValue.params |
| ); |
| |
| if (not isbound(vl_dataVarName)) { |
| vl_dataVarName := ""; |
| } |
| if (vl_dataValueResponse.errorCode==0) { |
| // read value from the variable: |
| var integer vl_varIdx := f_EPTF_Var_getId(vl_dataVarName); |
| if (vl_varIdx==-1) { |
| // source variable does not exist: |
| // set error message and error code: |
| vl_dataValueResponse.dataValue := {charstringVal := log2str("Source Variable ",vl_dataVarName," not found")}; |
| vl_dataValueResponse.errorCode := 2; // error code |
| } else { |
| // get current value from the variable: |
| f_EPTF_Var_getContent(vl_varIdx,vl_dataValueResponse.dataValue); |
| } |
| } else { |
| // append current error messages together: |
| if (not isbound(vl_dataVarName)) { |
| vl_dataVarName := ""; |
| } |
| if (isbound(vl_dataValueResponse.dataValue) and ischosen(vl_dataValueResponse.dataValue.charstringVal)) { |
| if (vl_dataVarName=="") { |
| vl_dataVarName := vl_dataValueResponse.dataValue.charstringVal; |
| } else { |
| vl_dataVarName := vl_dataValueResponse.dataValue.charstringVal&" or "&vl_dataVarName; |
| } |
| } else if (vl_dataVarName == "") { |
| vl_dataVarName := "Unknown error"; |
| } |
| vl_dataValueResponse.dataValue := {charstringVal := vl_dataVarName}; |
| } |
| } |
| } |
| |
| // if error code is the default (= getData, value handler and condition handler was not found): |
| if (vl_dataValueResponse.errorCode == -54321) { |
| // set errorCode to the DataSource_CT: |
| vl_dataValueResponse.dataValue := {charstringVal := "Handler not registered"}; |
| vl_dataValueResponse.errorCode := 1; // error code |
| } |
| |
| if (vl_dataValueResponse.errorCode!=0) { |
| if(not isbound(vl_dataValueResponse.dataValue)) { |
| vl_dataValueResponse.dataValue := {charstringVal:=f_EPTF_DataSourceClient_getErrMsg4Get(pl_getDataValue, "Unknown error")}; |
| } else { |
| if (ischosen(vl_dataValueResponse.dataValue.charstringVal)){ |
| vl_dataValueResponse.dataValue := {charstringVal:=f_EPTF_DataSourceClient_getErrMsg4Get(pl_getDataValue, vl_dataValueResponse.dataValue.charstringVal)}; |
| } else { |
| vl_dataValueResponse.dataValue := {charstringVal:=f_EPTF_DataSourceClient_getErrMsg4Get(pl_getDataValue, log2str(vl_dataValueResponse.dataValue))}; |
| } |
| } |
| } |
| |
| pl_dataValueResponse := vl_dataValueResponse; |
| } |
| |
| private function f_EPTF_DataSourceClient_handleGetDataValue( |
| in EPTF_DataSource_Msg_GetDataValue pl_getDataValue, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| |
| var EPTF_DataSource_Msg_DataValueResponse vl_dataValueResponse; |
| if (pl_getDataValue.dataSource == "DataSource") { |
| f_EPTF_DataSourceClient_handleBuiltInElements( |
| vl_dataValueResponse, |
| pl_getDataValue |
| ) |
| } else { |
| f_EPTF_DataSourceClient_handleClientElements( |
| vl_dataValueResponse, |
| pl_getDataValue |
| ) |
| } |
| |
| if (ispresent(pl_getDataValue.filter) and ispresent(pl_getDataValue.filter.rangeFilter)) { |
| f_EPTF_DataSourceClient_applyRangeFilter(vl_dataValueResponse, pl_getDataValue.filter.rangeFilter); |
| } |
| |
| // send response to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{dataValueResponse:=vl_dataValueResponse},pl_sourceCompRef); |
| } |
| |
| private function f_EPTF_DataSourceClient_applyRangeFilter( |
| inout EPTF_DataSource_Msg_DataValueResponse pl_dataValueResponse, |
| in EPTF_DataSource_RangeFilter pl_rangeFilter |
| ) { |
| |
| if (ischosen(pl_dataValueResponse.dataValue.integerlistVal)) { |
| var EPTF_IntegerList vl_list := pl_dataValueResponse.dataValue.integerlistVal; |
| // find the first index |
| var integer vl_from; |
| if (ispresent(pl_rangeFilter.offset)) { |
| vl_from := pl_rangeFilter.offset; |
| if (vl_from < 0) { |
| vl_from := 0; |
| } else if (vl_from >= sizeof(vl_list)) { |
| pl_dataValueResponse.dataValue.integerlistVal := {}; |
| return; |
| } |
| } else { |
| vl_from := 0; |
| } |
| // find the number of elements |
| var integer vl_count; |
| if (ispresent(pl_rangeFilter.count) and pl_rangeFilter.count >= 0 and vl_from + pl_rangeFilter.count < sizeof(vl_list)) { |
| vl_count := pl_rangeFilter.count; |
| } else { |
| vl_count := sizeof(vl_list) - vl_from; |
| } |
| |
| pl_dataValueResponse.dataValue.integerlistVal := substr(vl_list, vl_from, vl_count); |
| |
| } else if (ischosen(pl_dataValueResponse.dataValue.charstringlistVal)) { |
| var EPTF_CharstringList vl_list := pl_dataValueResponse.dataValue.charstringlistVal; |
| // find the first index |
| var integer vl_from; |
| if (ispresent(pl_rangeFilter.offset)) { |
| vl_from := pl_rangeFilter.offset; |
| if (vl_from < 0) { |
| vl_from := 0; |
| } else if (vl_from >= sizeof(vl_list)) { |
| pl_dataValueResponse.dataValue.charstringlistVal := {}; |
| return; |
| } |
| } else { |
| vl_from := 0; |
| } |
| // find the number of elements |
| var integer vl_count; |
| if (ispresent(pl_rangeFilter.count) and pl_rangeFilter.count >= 0 and vl_from + pl_rangeFilter.count < sizeof(vl_list)) { |
| vl_count := pl_rangeFilter.count; |
| } else { |
| vl_count := sizeof(vl_list) - vl_from; |
| } |
| |
| pl_dataValueResponse.dataValue.charstringlistVal := substr(vl_list, vl_from, vl_count); |
| |
| } else if (ischosen(pl_dataValueResponse.dataValue.floatlistVal)) { |
| var EPTF_FloatList vl_list := pl_dataValueResponse.dataValue.floatlistVal; |
| // find the first index |
| var integer vl_from; |
| if (ispresent(pl_rangeFilter.offset)) { |
| vl_from := pl_rangeFilter.offset; |
| if (vl_from < 0) { |
| vl_from := 0; |
| } else if (vl_from >= sizeof(vl_list)) { |
| pl_dataValueResponse.dataValue.floatlistVal := {}; |
| return; |
| } |
| } else { |
| vl_from := 0; |
| } |
| // find the number of elements |
| var integer vl_count; |
| if (ispresent(pl_rangeFilter.count) and pl_rangeFilter.count >= 0 and vl_from + pl_rangeFilter.count < sizeof(vl_list)) { |
| vl_count := pl_rangeFilter.count; |
| } else { |
| vl_count := sizeof(vl_list) - vl_from; |
| } |
| |
| pl_dataValueResponse.dataValue.floatlistVal := substr(vl_list, vl_from, vl_count); |
| |
| } else { |
| // we do not filter single elements |
| } |
| |
| } |
| |
| private function f_EPTF_DataSourceClient_handleSetDataValue( |
| in EPTF_DataSource_Msg_SetDataValue pl_setDataValue, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| var EPTF_DataSource_Msg_DataValueResponse vl_dataValueResponse := { |
| pl_setDataValue.transactionId, |
| pl_setDataValue.dataValue, |
| -54321 |
| } |
| // find handler: |
| var charstring vl_handlerIdStr := pl_setDataValue.dataSource&"@"&pl_setDataValue.ptcName; |
| var charstring vl_valueHandlerIdStr := "SDVH_"&vl_handlerIdStr; |
| var integer vl_handlerId := -1; |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_valueHandlerIdStr,vl_handlerId)) { |
| // calling handler: v_fcb_EPTF_DataSourceClient_setDataValueHandler_List[vl_handlerId] |
| vl_dataValueResponse.errorCode := v_fcb_EPTF_DataSourceClient_setDataValueHandler_List[vl_handlerId].apply( |
| vl_dataValueResponse.dataValue, |
| pl_setDataValue.dataSource, |
| pl_setDataValue.ptcName, |
| pl_setDataValue.dataElement, |
| pl_setDataValue.params, |
| pl_setDataValue.indexList |
| ); |
| } |
| |
| if (vl_dataValueResponse.errorCode < 0) { |
| // try to find getData handler: |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var charstring vl_dataVarName; |
| vl_dataValueResponse.errorCode := v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId].apply( |
| vl_dataVarName, |
| pl_setDataValue.dataSource, |
| pl_setDataValue.ptcName, |
| pl_setDataValue.dataElement, |
| pl_setDataValue.params |
| ); |
| if (not isbound(vl_dataVarName)) { |
| vl_dataVarName := ""; |
| } |
| if (vl_dataValueResponse.errorCode==0) { |
| // set value to the variable: |
| var integer vl_varIdx := f_EPTF_Var_getId(vl_dataVarName); |
| if (vl_varIdx==-1) { |
| // source variable does not exist: |
| // set error message and error code: |
| vl_dataValueResponse.dataValue := {charstringVal := log2str("Source Variable ",vl_dataVarName," not found")}; |
| vl_dataValueResponse.errorCode := 2; // error code |
| } else { |
| // set current value to variable: |
| vl_dataValueResponse.dataValue := pl_setDataValue.dataValue; // restore original value |
| |
| var EPTF_Var_DirectContent vl_valueToSet := vl_dataValueResponse.dataValue; //value to set variable (if the var is list different value is set and send) |
| if (pl_setDataValue.indexList != {}) { |
| |
| //get current content |
| var EPTF_Var_DirectContent vl_listContent; |
| f_EPTF_Var_getContent(vl_varIdx, vl_listContent); |
| |
| //update list by new values in elements listed in indexList |
| vl_dataValueResponse.errorCode := f_EPTF_DataSourceClient_setListValue ( |
| pl_indexList := pl_setDataValue.indexList, |
| pl_newValue := pl_setDataValue.dataValue, |
| pl_listContent := vl_listContent |
| ); |
| |
| if (vl_dataValueResponse.errorCode != 0) { |
| vl_dataValueResponse.dataValue := {charstringVal := log2str("Error in using indexList: ", pl_setDataValue.indexList, ". New value to be set ", pl_setDataValue.dataValue, |
| " is inconsistent with the indexList or the current value of the data")}; |
| } else { |
| vl_valueToSet := vl_listContent; |
| } |
| } |
| if (vl_dataValueResponse.errorCode == 0) { |
| if(false == f_EPTF_Var_adjustContent_Blocking(vl_varIdx, vl_valueToSet)) { |
| // source variable is read-only |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot set data ",pl_setDataValue, |
| ": Source Variable ",vl_dataVarName," is read-only or value is not allowed")); |
| // set error message and error code: |
| vl_dataValueResponse.dataValue := {charstringVal := log2str("Source Variable ",vl_dataVarName," is read-only or value is not allowed")}; |
| vl_dataValueResponse.errorCode := 3; // error code |
| } |
| } |
| } |
| } else { |
| if (vl_dataVarName=="") { |
| vl_dataVarName := "Unknown error"; |
| } |
| vl_dataValueResponse.dataValue := {charstringVal := vl_dataVarName}; |
| } |
| } else { |
| // if error code is the default (= getData and value handler was not found): |
| if (vl_dataValueResponse.errorCode == -54321) { |
| // set errorCode to the DataSource_CT: |
| vl_dataValueResponse.dataValue := {charstringVal := "Handler not registered"}; |
| vl_dataValueResponse.errorCode := 1; // error code |
| } |
| } |
| } |
| |
| if (vl_dataValueResponse.errorCode!=0) { |
| if(not isbound(vl_dataValueResponse.dataValue)) { |
| vl_dataValueResponse.dataValue := {charstringVal:=f_EPTF_DataSourceClient_getErrMsg4Set(pl_setDataValue, "Unknown error")}; |
| } else { |
| if (ischosen(vl_dataValueResponse.dataValue.charstringVal)){ |
| vl_dataValueResponse.dataValue := {charstringVal:=f_EPTF_DataSourceClient_getErrMsg4Set(pl_setDataValue, vl_dataValueResponse.dataValue.charstringVal)}; |
| } else { |
| vl_dataValueResponse.dataValue := {charstringVal:=f_EPTF_DataSourceClient_getErrMsg4Set(pl_setDataValue, log2str(vl_dataValueResponse.dataValue))}; |
| } |
| } |
| } |
| |
| // send response to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{dataValueResponse:=vl_dataValueResponse},pl_sourceCompRef); |
| } |
| |
| private function f_EPTF_DataSourceClient_setListValue ( |
| in EPTF_IntegerList pl_indexList, |
| in EPTF_Var_DirectContent pl_newValue, |
| inout EPTF_Var_DirectContent pl_listContent |
| ) runs on EPTF_DataSourceClient_CT |
| return integer { |
| |
| //check if indexes are not negative |
| for (var integer vl_i := 0; vl_i < sizeof(pl_indexList); vl_i := vl_i + 1) { |
| if (pl_indexList[vl_i] < 0) { |
| return 10; |
| } |
| } |
| |
| //handle integerList |
| if (ischosen(pl_listContent.integerlistVal) and ischosen(pl_newValue.integerlistVal)) { |
| if (sizeof(pl_indexList) != sizeof(pl_newValue.integerlistVal)) { |
| return 11; |
| } |
| for (var integer vl_i := 0; vl_i < sizeof(pl_indexList); vl_i := vl_i + 1) { |
| var integer vl_index := pl_indexList[vl_i]; |
| if (sizeof(pl_listContent.integerlistVal) <= vl_index) { |
| return 12; |
| } |
| pl_listContent.integerlistVal[vl_index] := pl_newValue.integerlistVal[vl_i]; |
| } |
| return 0; |
| } |
| //handle charstringList |
| if (ischosen(pl_listContent.charstringlistVal) and ischosen(pl_newValue.charstringlistVal)) { |
| if (sizeof(pl_indexList) != sizeof(pl_newValue.charstringlistVal)) { |
| return 11; |
| } |
| for (var integer vl_i := 0; vl_i < sizeof(pl_indexList); vl_i := vl_i + 1) { |
| var integer vl_index := pl_indexList[vl_i]; |
| if (sizeof(pl_listContent.charstringlistVal) <= vl_index) { |
| return 12; |
| } |
| pl_listContent.charstringlistVal[vl_index] := pl_newValue.charstringlistVal[vl_i]; |
| } |
| return 0; |
| } |
| //handle floatList |
| if (ischosen(pl_listContent.floatlistVal) and ischosen(pl_newValue.floatlistVal)) { |
| if (sizeof(pl_indexList) != sizeof(pl_newValue.floatlistVal)) { |
| return 11; |
| } |
| for (var integer vl_i := 0; vl_i < sizeof(pl_indexList); vl_i := vl_i + 1) { |
| var integer vl_index := pl_indexList[vl_i]; |
| if (sizeof(pl_listContent.floatlistVal) <= vl_index) { |
| return 12; |
| } |
| pl_listContent.floatlistVal[vl_index] := pl_newValue.floatlistVal[vl_i]; |
| } |
| return 0; |
| } |
| |
| return 13; |
| } |
| |
| |
| private function f_EPTF_DataSourceClient_handleGetList( |
| in EPTF_DataSource_Msg_List pl_getList, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| |
| var EPTF_DataSource_Msg_List vl_valueList := {}; |
| |
| for(var integer i:=0; i<sizeof(pl_getList); i:=i+1) { |
| if (ischosen(pl_getList[i].getData)) { |
| // find handler: |
| var charstring vl_handlerIdStr := pl_getList[i].getData.dataSource&"@"&pl_getList[i].getData.ptcName; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot handle data ",pl_getList[i].getData, |
| ": Handler not registered")); |
| // send errorCode to the DataSource_CT: |
| vl_valueList[i].dataValue := { |
| pl_getList[i].getData.transactionId, |
| pl_getList[i].getData.dataSource, |
| pl_getList[i].getData.ptcName, |
| pl_getList[i].getData.dataElement, |
| pl_getList[i].getData.params, |
| "Handler not registered", |
| {unknownVal:={omit}}, |
| 1, |
| self // it is the same as the sender of the message |
| } |
| continue; |
| } |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var charstring vl_dataVarName; |
| var integer vl_errorCode := v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId].apply( |
| vl_dataVarName, |
| pl_getList[i].getData.dataSource, |
| pl_getList[i].getData.ptcName, |
| pl_getList[i].getData.dataElement, |
| pl_getList[i].getData.params |
| ); |
| |
| if (not isbound(vl_dataVarName)) { |
| vl_dataVarName := ""; |
| } |
| |
| var EPTF_Var_DirectContent vl_currentContent := {unknownVal:={omit}}; |
| if (vl_errorCode==0) { |
| var integer vl_varIdx := f_EPTF_Var_getId(vl_dataVarName); |
| if (vl_varIdx==-1) { |
| // source variable does not exist: |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot handle data ",pl_getList[i].getData, |
| ": Source Variable ",vl_dataVarName," not found")); |
| // send errorCode to the DataSource_CT: |
| vl_valueList[i].dataValue := { |
| pl_getList[i].getData.transactionId, |
| pl_getList[i].getData.dataSource, |
| pl_getList[i].getData.ptcName, |
| pl_getList[i].getData.dataElement, |
| pl_getList[i].getData.params, |
| log2str("Source Variable ",vl_dataVarName," not found"), |
| {unknownVal:={omit}}, |
| 2, |
| self // it is the same as the sender of the message |
| } |
| continue; |
| } else { |
| f_EPTF_Var_getContent(vl_varIdx,vl_currentContent); |
| } |
| } |
| // send vl_dataVarName to the DataSource_CT: |
| vl_valueList[i].dataValue := { |
| pl_getList[i].getData.transactionId, |
| pl_getList[i].getData.dataSource, |
| pl_getList[i].getData.ptcName, |
| pl_getList[i].getData.dataElement, |
| pl_getList[i].getData.params, |
| vl_dataVarName, |
| vl_currentContent, |
| vl_errorCode, |
| self // it is the same as the sender of the message |
| } |
| } else if (ischosen(pl_getList[i].getCondition)) { |
| // find handler: |
| var charstring vl_handlerIdStr := pl_getList[i].getCondition.dataSource&"@"&pl_getList[i].getCondition.ptcName&"/"&pl_getList[i].getCondition.method; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot handle condition ",pl_getList[i].getCondition, |
| ": Handler not registered")); |
| // send error code to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{conditionValue:={ |
| pl_getList[i].getCondition.transactionId, |
| pl_getList[i].getCondition.dataSource, |
| pl_getList[i].getCondition.ptcName, |
| pl_getList[i].getCondition.method, |
| pl_getList[i].getCondition.params, |
| false, |
| 1 |
| }},pl_sourceCompRef); |
| return; |
| } |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var boolean vl_conditionValue; |
| var integer vl_errorCode := v_fcb_EPTF_DataSourceClient_conditionHandler_List[vl_handlerId].apply( |
| vl_conditionValue, |
| pl_getList[i].getCondition.dataSource, |
| pl_getList[i].getCondition.ptcName, |
| pl_getList[i].getCondition.method, |
| pl_getList[i].getCondition.params |
| ); |
| |
| if (not isbound(vl_conditionValue)) { |
| vl_conditionValue := false; |
| } |
| |
| // send vl_dataVarName to the DataSource_CT: |
| vl_valueList[i].conditionValue := { |
| pl_getList[i].getCondition.transactionId, |
| pl_getList[i].getCondition.dataSource, |
| pl_getList[i].getCondition.ptcName, |
| pl_getList[i].getCondition.method, |
| pl_getList[i].getCondition.params, |
| vl_conditionValue, |
| vl_errorCode |
| } |
| } |
| } |
| // send valueList to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{valueList:=vl_valueList},pl_sourceCompRef); |
| } |
| |
| private function f_EPTF_DataSourceClient_handleGetCondition( |
| in EPTF_DataSource_Msg_GetCondition pl_getCondition, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| // find handler: |
| var charstring vl_handlerIdStr := pl_getCondition.dataSource&"@"&pl_getCondition.ptcName&"/"&pl_getCondition.method; |
| var integer vl_handlerId := -1; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataHandlerHash,vl_handlerIdStr,vl_handlerId)) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot handle condition ",pl_getCondition, |
| ": Handler not registered")); |
| // send error code to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{conditionValue:={ |
| pl_getCondition.transactionId, |
| pl_getCondition.dataSource, |
| pl_getCondition.ptcName, |
| pl_getCondition.method, |
| pl_getCondition.params, |
| false, |
| 1 |
| }},pl_sourceCompRef); |
| return; |
| } |
| // calling handler: v_fcb_EPTF_DataSourceClient_dataHandler_List[vl_handlerId] |
| var boolean vl_conditionValue; |
| var integer vl_errorCode := v_fcb_EPTF_DataSourceClient_conditionHandler_List[vl_handlerId].apply( |
| vl_conditionValue, |
| pl_getCondition.dataSource, |
| pl_getCondition.ptcName, |
| pl_getCondition.method, |
| pl_getCondition.params |
| ); |
| |
| if (not isbound(vl_conditionValue)) { |
| vl_conditionValue := false; |
| } |
| |
| // send vl_conditionValue to the DataSource_CT: |
| f_EPTF_DataSourceClient_sendMsg(EPTF_DataSource_Msg:{conditionValue:={ |
| pl_getCondition.transactionId, |
| pl_getCondition.dataSource, |
| pl_getCondition.ptcName, |
| pl_getCondition.method, |
| pl_getCondition.params, |
| vl_conditionValue, |
| vl_errorCode |
| }},pl_sourceCompRef); |
| } |
| |
| private function f_EPTF_DataSourceClient_handleDataValue( |
| in EPTF_DataSource_Msg_DataValue pl_dataValue, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| var integer vl_localDataVarId := -1; |
| v_EPTF_DataSourceClient_Msg_List[pl_dataValue.transactionId] := {dataValue := pl_dataValue}; |
| // if returned error code is non-0, update the error message: |
| if (pl_dataValue.errorCode!=0) { |
| if (not ischosen(pl_dataValue.dataValue.charstringVal)) { |
| if (ispresent(pl_dataValue.dataVarName) and pl_dataValue.dataVarName != "") { |
| pl_dataValue.dataValue := {charstringVal := pl_dataValue.dataVarName}; // error message was not present => set it to the string value of provided value |
| } else { |
| pl_dataValue.dataValue := {charstringVal := "Error info: "&ttcn2string(pl_dataValue.dataValue)}; // error message was not present => set it to the string value of provided value |
| //append general text: |
| pl_dataValue.dataValue.charstringVal := log2str(%definitionId&": Invalid iterator or externalData or parameter: ", |
| "\nSource: ",pl_dataValue.dataSource, |
| "\nPTC : ",pl_dataValue.ptcName , |
| "\nElement Name : " ,pl_dataValue.dataElement, |
| "\nParams: " , pl_dataValue.params)& |
| "\nReason: "&pl_dataValue.dataValue.charstringVal; |
| } |
| } |
| f_EPTF_DataSourceClient_warning(pl_dataValue.dataValue.charstringVal&"\nError code: "&int2str(pl_dataValue.errorCode)); |
| } |
| // store the returned varname in a hashmap: |
| var charstring vl_dataValueIdStr := pl_dataValue.dataSource&"@"&pl_dataValue.ptcName& |
| "."&pl_dataValue.dataElement&":"&log2str(pl_dataValue.params); |
| if(pl_dataValue.errorCode==0 and ispresent(pl_dataValue.dataVarName)) { |
| var charstring vl_dataValueIdStr_noPTCName := pl_dataValue.dataSource&"@."&pl_dataValue.dataElement&":"&log2str(pl_dataValue.params); |
| |
| var integer vl_dataValueId; |
| if (not f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataValueHash,vl_dataValueIdStr,vl_dataValueId)) { |
| |
| var charstring vl_remoteDataVarName := pl_dataValue.dataVarName; |
| var charstring vl_localVarName := "EPTF_DataSourceClient_"&vl_remoteDataVarName&"."&vl_dataValueIdStr; |
| //create local variable with the value in the message: |
| vl_localDataVarId := f_EPTF_Var_newVar(vl_localVarName,pl_dataValue.dataValue); |
| |
| vl_dataValueId := sizeof(v_EPTF_DataSourceClient_dataValue_List); |
| // store new datasource data: |
| v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId] := { |
| pl_dataValue.dataVarName, |
| pl_dataValue.ownerCompRef, |
| vl_localDataVarId |
| }; |
| // to be able to search by vl_dataValueIdStr: |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataValueHash,vl_dataValueIdStr,vl_dataValueId); |
| // to be able to search by vl_localVarName: |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataValueHash,vl_localVarName,vl_dataValueId); |
| // to be able to search by vl_dataValueIdStr_noPTCName: |
| f_EPTF_str2int_HashMap_Insert(v_EPTF_DataSourceClient_dataValueHash,vl_dataValueIdStr_noPTCName,vl_dataValueId); |
| } else { |
| vl_localDataVarId := v_EPTF_DataSourceClient_dataValue_List[vl_dataValueId].localDataVarId; |
| |
| // Update hashMap entry for NoPTCName: |
| // Only insert with noPTCName if it was not already added. |
| // Otherwise insert invalid data to sign that the PTC name should be specified |
| var integer vl_noPTCCheck := -1; |
| if (f_EPTF_str2int_HashMap_Find(v_EPTF_DataSourceClient_dataValueHash,vl_dataValueIdStr_noPTCName,vl_noPTCCheck)) { |
| // if valid entry found: |
| if (vl_noPTCCheck!=-1) { |
| //if it differs from the one with PTC name, then replace it with an invalid item (==more than one PTCName has the same source) |
| if (vl_noPTCCheck!=vl_dataValueId) { |
| f_EPTF_str2int_HashMap_Update(v_EPTF_DataSourceClient_dataValueHash,vl_dataValueIdStr_noPTCName,-1); |
| } |
| } |
| }// else: not possible: entry with PTC name is always there |
| } |
| } |
| |
| // call handler if it was given: |
| if (isbound(v_EPTF_DataSourceClient_GetDataHandler_DB[pl_dataValue.transactionId]) |
| and (0<sizeof(v_EPTF_DataSourceClient_GetDataHandler_DB[pl_dataValue.transactionId]))) { |
| |
| for(var integer i:=0; i<sizeof(v_EPTF_DataSourceClient_GetDataHandler_DB[pl_dataValue.transactionId]); i:=i+1) { |
| if (v_EPTF_DataSourceClient_GetDataHandler_DB[pl_dataValue.transactionId][i].getDataHandler != null) { |
| if (not ispresent(pl_dataValue.dataVarName)) { |
| pl_dataValue.dataVarName := ""; |
| } |
| v_EPTF_DataSourceClient_GetDataHandler_DB[pl_dataValue.transactionId][i].getDataHandler.apply( |
| //request parameters: |
| pl_source := pl_dataValue.dataSource, |
| pl_ptcName := pl_dataValue.ptcName, // response may fill this if it was "" |
| pl_element := pl_dataValue.dataElement, |
| pl_params := pl_dataValue.params, |
| // reponse parameters: |
| pl_errorCode := pl_dataValue.errorCode, // error code in the response |
| pl_remoteDataVarName := pl_dataValue.dataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message |
| pl_ownerCompRef := pl_dataValue.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 := pl_dataValue.dataValue, // the value of the data |
| // user data |
| pl_userData := v_EPTF_DataSourceClient_GetDataHandler_DB[pl_dataValue.transactionId][i].userData // user specific data given at the request |
| ); |
| } |
| } |
| v_EPTF_DataSourceClient_GetDataHandler_DB[pl_dataValue.transactionId] := {}; |
| //FIXME: this should be enabled for getData_nonBlocking: |
| //f_EPTF_str2int_HashMap_Erase(v_EPTF_DataSourceClient_pendingGetDataHash,vl_dataValueIdStr); |
| f_EPTF_Semaphore_delete(pl_dataValue.transactionId); |
| } else { |
| if (f_EPTF_Semaphore_isLocked(pl_dataValue.transactionId)) { |
| f_EPTF_Semaphore_unlock(pl_dataValue.transactionId); |
| } |
| } |
| } |
| |
| private function f_EPTF_DataSourceClient_handleDataValueResponse( |
| in EPTF_DataSource_Msg_DataValueResponse pl_dataValueResponse, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| var integer vl_localDataVarId := -1; |
| v_EPTF_DataSourceClient_Msg_List[pl_dataValueResponse.transactionId] := {dataValueResponse := pl_dataValueResponse}; |
| |
| // if returned error code is non-0, update the error message: |
| if (pl_dataValueResponse.errorCode!=0) { |
| if (not ischosen(pl_dataValueResponse.dataValue.charstringVal)) { |
| pl_dataValueResponse.dataValue := {charstringVal := "Error info: "&ttcn2string(pl_dataValueResponse.dataValue)}; // error message was not present => set it to the string value of provided value |
| } |
| f_EPTF_DataSourceClient_warning(pl_dataValueResponse.dataValue.charstringVal&"\nError code: "&int2str(pl_dataValueResponse.errorCode)); |
| } |
| // call handler if it was given: |
| if (isbound(v_EPTF_DataSourceClient_GetDataValueHandler_DB[pl_dataValueResponse.transactionId])) { |
| |
| if (v_EPTF_DataSourceClient_GetDataValueHandler_DB[pl_dataValueResponse.transactionId].getDataValueHandler != null) { |
| v_EPTF_DataSourceClient_GetDataValueHandler_DB[pl_dataValueResponse.transactionId].getDataValueHandler.apply( |
| // reponse parameters: |
| pl_errorCode := pl_dataValueResponse.errorCode, // error code in the response |
| pl_dataValue := pl_dataValueResponse.dataValue, // the value of the data |
| // user data |
| pl_userData := v_EPTF_DataSourceClient_GetDataValueHandler_DB[pl_dataValueResponse.transactionId].userData // user specific data given at the request |
| ); |
| } |
| |
| v_EPTF_DataSourceClient_GetDataValueHandler_DB[pl_dataValueResponse.transactionId] := {}; |
| |
| f_EPTF_Semaphore_delete(pl_dataValueResponse.transactionId); |
| } else { |
| if (f_EPTF_Semaphore_isLocked(pl_dataValueResponse.transactionId)) { |
| f_EPTF_Semaphore_unlock(pl_dataValueResponse.transactionId); |
| } |
| } |
| } |
| |
| private function f_EPTF_DataSourceClient_handleConditionValue( |
| in EPTF_DataSource_Msg_ConditionValue pl_conditionValue, |
| in EPTF_DataSource_CT pl_sourceCompRef |
| ) runs on EPTF_DataSourceClient_CT { |
| var integer vl_localDataVarId := -1; |
| v_EPTF_DataSourceClient_Msg_List[pl_conditionValue.transactionId] := {conditionValue := pl_conditionValue}; |
| |
| //no dataVarName in EPTF_DataSource_Msg_ConditionValue -> warning is not logged |
| // if (pl_conditionValue.errorCode==0) { |
| // //nothing to do |
| // } else { |
| // f_EPTF_DataSourceClient_warning(pl_conditionValue.dataVarName); // warning message is received in the dataVarName |
| // } |
| |
| // call handler if it was given: |
| if (isbound(v_EPTF_DataSourceClient_GetDataHandler_DB[pl_conditionValue.transactionId]) |
| and (0<sizeof(v_EPTF_DataSourceClient_GetDataHandler_DB[pl_conditionValue.transactionId]))) { |
| |
| for(var integer i:=0; i<sizeof(v_EPTF_DataSourceClient_GetDataHandler_DB[pl_conditionValue.transactionId]); i:=i+1) { |
| if(v_EPTF_DataSourceClient_GetDataHandler_DB[pl_conditionValue.transactionId][i].getDataHandler != null) { |
| v_EPTF_DataSourceClient_GetDataHandler_DB[pl_conditionValue.transactionId][i].getDataHandler.apply( |
| //request parameters: |
| pl_source := pl_conditionValue.dataSource, |
| pl_ptcName := pl_conditionValue.ptcName, // response may fill this if it was "" |
| pl_element := pl_conditionValue.method, |
| pl_params := pl_conditionValue.params, |
| // reponse parameters: |
| pl_errorCode := pl_conditionValue.errorCode, // error code in the response |
| pl_remoteDataVarName := "",//pl_conditionValue.dataVarName, // var name on the remote component. In case errorCode!=0: it contains the error message |
| pl_ownerCompRef := null,//pl_conditionValue.ownerCompRef, // reference to the remote component |
| pl_localDataVarId := -1, // var id on the local component (contains the current value, not subscribed to remote!) |
| pl_dataValue := {boolVal := pl_conditionValue.conditionValue}, // the value of the data |
| // user data |
| pl_userData := v_EPTF_DataSourceClient_GetDataHandler_DB[pl_conditionValue.transactionId][i].userData // user specific data given at the request |
| ); |
| } |
| } |
| v_EPTF_DataSourceClient_GetDataHandler_DB[pl_conditionValue.transactionId] := {}; |
| f_EPTF_Semaphore_delete(pl_conditionValue.transactionId); |
| } else { |
| f_EPTF_Semaphore_unlock(pl_conditionValue.transactionId); |
| } |
| } |
| |
| private function f_EPTF_DataSourceClient_sendMsg( |
| in EPTF_DataSource_Msg pl_msg, |
| in EPTF_DataSource_CT pl_sourceCompRef := null |
| ) runs on EPTF_DataSourceClient_CT { |
| if(not v_EPTF_DataSourceClient_connected) { |
| f_EPTF_DataSourceClient_warning(log2str(%definitionId&": Cannot send message ", |
| "for pl_msg: ",pl_msg," to "," pl_sourceCompRef: ",pl_sourceCompRef,": Not connected to DataSource")); |
| return; |
| } |
| if (pl_sourceCompRef==null) { |
| EPTF_DataSourceClientIf.send(pl_msg); |
| } else { |
| EPTF_DataSourceClientIf.send(pl_msg) to pl_sourceCompRef; |
| } |
| } |
| |
| private altstep as_EPTF_DataSourceClient_EventHandler() runs on EPTF_DataSourceClient_CT { |
| var EPTF_DataSource_CT vl_sourceCompRef; |
| var EPTF_DataSource_Msg vl_msg; |
| [] EPTF_DataSourceClientIf.receive(EPTF_DataSource_Msg:?) -> value vl_msg sender vl_sourceCompRef { |
| if (ischosen(vl_msg.getData)) { |
| f_EPTF_DataSourceClient_handleGetData(vl_msg.getData,vl_sourceCompRef); |
| } else if (ischosen(vl_msg.getDataValue)) { |
| f_EPTF_DataSourceClient_handleGetDataValue(vl_msg.getDataValue,vl_sourceCompRef); |
| } else if (ischosen(vl_msg.setDataValue)) { |
| f_EPTF_DataSourceClient_handleSetDataValue(vl_msg.setDataValue,vl_sourceCompRef); |
| } else if (ischosen(vl_msg.getList)) { |
| f_EPTF_DataSourceClient_handleGetList(vl_msg.getList,vl_sourceCompRef); |
| } else if (ischosen(vl_msg.getCondition)) { |
| f_EPTF_DataSourceClient_handleGetCondition(vl_msg.getCondition,vl_sourceCompRef); |
| } else if (ischosen(vl_msg.dataValue)) { |
| f_EPTF_DataSourceClient_handleDataValue(vl_msg.dataValue,vl_sourceCompRef); |
| } else if (ischosen(vl_msg.dataValueResponse)) { |
| f_EPTF_DataSourceClient_handleDataValueResponse(vl_msg.dataValueResponse,vl_sourceCompRef); |
| } else if (ischosen(vl_msg.conditionValue)) { |
| f_EPTF_DataSourceClient_handleConditionValue(vl_msg.conditionValue,vl_sourceCompRef); |
| } |
| repeat; |
| } |
| } |
| |
| private function f_EPTF_DataSourceClient_error(in charstring pl_msg) |
| runs on EPTF_Logging_CT{ |
| f_EPTF_Logging_error(true, pl_msg); |
| } |
| |
| private function f_EPTF_DataSourceClient_warning(in charstring pl_msg) |
| runs on EPTF_Logging_CT{ |
| f_EPTF_Logging_warning(true, pl_msg); |
| } |
| |
| // private function f_EPTF_DataSourceClient_debug(in charstring pl_msg) |
| // runs on EPTF_Logging_CT{ |
| // f_EPTF_Logging_debug(true,"Debug: "&pl_msg); |
| // } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_DataSourceClient_extractParams |
| // |
| // Purpose: |
| // Extracts the needed parameters from the params. |
| // It returns "" for values of params that are not found. |
| // |
| // Parameters: |
| // *in* <EPTF_DataSource_Params> *pl_params* - the actual parameters |
| // *in* <EPTF_CharstringList> *pl_needed* - the parameters needed |
| // *in* <EPTF_CharstringList> *pl_result* - the value of the needed parameters |
| // |
| // Return Value: |
| // integer - 0 if OK, nonzero in case of failure to show that |
| // unexpected parameter was specified |
| // |
| // Detailed Comments: |
| // Can be called in the dataElement handler or DScheckParams function |
| // Similar function without return value: <f_EPTF_DataSource_extractParams> |
| // This function also prints out a warning message when an |
| // unexpected parameter is specified |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_DataSourceClient_extractParams( |
| in charstring pl_element, |
| in EPTF_DataSource_Params pl_params, |
| in EPTF_CharstringList pl_needed, |
| out EPTF_CharstringList pl_result) |
| runs on EPTF_Logging_CT |
| return integer{ |
| pl_result := {}; |
| for(var integer j := 0; j < sizeof(pl_needed); j := j + 1){ |
| pl_result[j] := ""; |
| } |
| for(var integer i := 0; i < sizeof(pl_params); i:= i + 1){ |
| var boolean vl_found := false; |
| for(var integer j := 0; j < sizeof(pl_needed); j := j + 1){ |
| if(pl_params[i].paramName == pl_needed[j]){ |
| pl_result[j] := pl_params[i].paramValue; |
| vl_found := true; |
| break; |
| } |
| } |
| if(not vl_found){ |
| f_EPTF_DataSourceClient_warning("Invalid parameter: "&pl_params[i].paramName&" for element "&pl_element&". Acceptable parameters: "&log2str(pl_needed)); |
| return -1; |
| } |
| } |
| return 0 |
| } |
| |
| |
| } // module EPTF_CLL_DataSource_ClientFunctions |