blob: eb39d653c643bb01fcd94326d091ca1c3c5c5fec [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015-2019 Florian Froschermeier <florian.froschermeier@tum.de>,
* fortiss GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Froschermeier
* - initial integration of the OPC-UA protocol
* Stefan Profanter
* - refactoring and adaption to new concept
* Jose Cabral:
* - refactoring to cleaner architecture
*******************************************************************************/
#ifndef SRC_MODULES_OPC_UA_OPCUALOCALHANDLER_H_
#define SRC_MODULES_OPC_UA_OPCUALOCALHANDLER_H_
#include <forte_thread.h>
#include <conn.h>
#include <forte_sem.h>
#include <forte_sync.h>
#include "../../core/fortelist.h"
#include "opcua_handler_abstract.h"
#include "opcua_helper.h"
/**
* Class to handle all action that are executed on a local OPC UA server
*/
// cppcheck-suppress noConstructor
class COPC_UA_Local_Handler : public COPC_UA_HandlerAbstract, public CThread {
DECLARE_HANDLER(COPC_UA_Local_Handler)
public:
/**
* Starts OPC UA Server
*/
void enableHandler(void);
/**
* Stops the OPC UA server
*/
void disableHandler(void);
/**
* Class containing all local callback functions that are called by the OPC UA stack
*/
class CUA_LocalCallbackFunctions {
public:
/**
* Callback when a method in the OPC UA server was executed
*/
static UA_StatusCode onServerMethodCall(UA_Server *paServer, const UA_NodeId *paSessionId, void *paSessionContext, const UA_NodeId *paMethodId,
void *paMethodContext, const UA_NodeId *paObjectId, void *paObjectContext, size_t paInputSize, const UA_Variant *paInput, size_t paOutputSize,
UA_Variant *paOutput);
/**
* Callback when an external client writes to a variable on this server.
*/
static void onWrite(UA_Server *paServer, const UA_NodeId *paSessionId, void *paSessionContext, const UA_NodeId *paNodeId, void *paNodeContext,
const UA_NumericRange *paRange, const UA_DataValue *paData);
};
protected:
/**
* Perform all the needed initialization of the action
* @param paActionInfo Action to be initialized
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
virtual UA_StatusCode initializeAction(CActionInfo &paActionInfo);
/**
* Execute the action
* @param paActionInfo Action to be executed
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
virtual UA_StatusCode executeAction(CActionInfo &paActionInfo);
/**
* Uninitialize the action
* @param paActionInfo Action to be Uninitialized
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
virtual UA_StatusCode uninitializeAction(CActionInfo &paActionInfo);
private:
/**
* Overridden run() from CThread which loops the UA Server.
*/
virtual void run();
/**
* Starts the OPC UA server, if it is not already running
*/
void startServer();
/**
* Indicates that the server has started, and allow waiting threads to work on it
*/
CSemaphore mServerStarted;
/**
* Stops the OPC UA server
*/
void stopServer();
/**
* Structure to contain all needed strings to configure the server
*/
struct UA_ServerStrings {
CIEC_STRING mHostname;
CIEC_STRING mAppURI;
};
/**
* Generate the hostname and the application URI that will be used to configure the server
* @param paUAServerPort Port where the OPC UA server will listen
* @param paServerStrings Place to store the generated strings
*/
void generateServerStrings(TForteUInt16 paUAServerPort, UA_ServerStrings &paServerStrings);
/**
* Creates the configuration for the OPC UA Server.
* @param paServerStrings Strings needed to configure the server
* @param paUaServerConfig Place to store all the configurations
*/
void configureUAServer(UA_ServerStrings &paServerStrings, UA_ServerConfig &paUaServerConfig);
/**
* Handler of the OPC UA stack server
*/
UA_Server *mUaServer;
/**
* Flag indicating if the server should be running or not
*/
volatile UA_Boolean mUaServerRunningFlag;
/**
* Maximal length for the server name
*/
static const size_t scmMaxServerNameLength = 255;
/**
* Generated function that call the initialization of all nodespaces added by the user in CMake
* @param paUaServer OPC UA Server
* @return True if no error occurred, false otherwise
*/
bool initializeNodesets(UA_Server &paUaServer);
/**
* Map to know which actions are using which nodes. When an action is unitialized, this is checked
* to see if the nodeId still has some action using it. If not, then it can be safely deleted
*/
struct nodesReferencedByActions {
const UA_NodeId *mNodeId;
CSinglyLinkedList<CActionInfo*> mActionsReferencingIt;
};
/**
* For each node that is accessed by the action, an entry in this list is added
*/
CSinglyLinkedList<nodesReferencedByActions*> mNodesReferences;
/**
* Mutex to access mNodesReferences
*/
CSyncObject mNodesReferencesMutex;
/**
* For all nodes that an action is referencing, it adds the action as reference
* @param paNodes Nodes being referenced by the action
* @param paActionInfo Action referencing the nodes
*/
void referencedNodesIncrement(const CSinglyLinkedList<UA_NodeId *> &paNodes, CActionInfo &paActionInfo);
/**
* Removes the action from the references from all the nodes where it's present
* @param paActionInfo Action to be removed
*/
void referencedNodesDecrement(const CActionInfo &paActionInfo);
/**
* Looks for all nodes which an action is referencing
* @param paActionInfo Action to be look for as a reference
* @param paNodes Place to store the nodes that are referencing the action
*/
void getNodesReferencedByAction(const CActionInfo &paActionInfo, CSinglyLinkedList<const UA_NodeId *> &paNodes);
/**
* Parent class that encapsulates the information needed to create something in the OPC UA Stack
*/
class CCreateInfo {
public:
CCreateInfo() :
mRequestedNodeId(0), mParentNodeId(0), mBrowseName(UA_QualifiedName_new()), mReturnedNodeId(UA_NodeId_new()) {
}
virtual ~CCreateInfo() {
UA_NodeId_delete(mReturnedNodeId);
UA_QualifiedName_delete(mBrowseName);
}
UA_NodeId *mRequestedNodeId;
const UA_NodeId *mParentNodeId;
UA_QualifiedName *mBrowseName;
UA_NodeId *mReturnedNodeId;
private:
CCreateInfo(const CCreateInfo &other);
CCreateInfo& operator=(const CCreateInfo &other);
};
/**
* Class that encapsulates the information needed to create an object in the OPC UA Stack
*/
class CCreateObjectInfo : public CCreateInfo {
public:
CCreateObjectInfo() :
CCreateInfo(), mTypeNodeId(0) {
}
~CCreateObjectInfo() {
}
UA_NodeId *mTypeNodeId;
private:
CCreateObjectInfo(const CCreateObjectInfo &paObj);
CCreateObjectInfo& operator=(const CCreateObjectInfo &other);
};
/**
* Class that encapsulates the information needed to create a variable in the OPC UA Stack
*/
class CCreateVariableInfo : public CCreateInfo {
public:
CCreateVariableInfo() :
CCreateInfo(), mTypeConvert(0), mInitData(0), mAllowWrite(false) {
}
~CCreateVariableInfo() {
}
const UA_DataType *mTypeConvert;
const CIEC_ANY *mInitData;
bool mAllowWrite;
private:
CCreateVariableInfo(const CCreateVariableInfo &paObj);
CCreateVariableInfo& operator=(const CCreateVariableInfo &other);
};
/**
* Class that encapsulates the information needed to create a method in the OPC UA Stack
*/
class CCreateMethodInfo : public CCreateInfo {
public:
explicit CCreateMethodInfo(CLocalMethodInfo &paCallack) :
CCreateInfo(), mInputArguments(0), mOutputArguments(0), mLocalMethodInfo(paCallack), mInputSize(0), mOutputSize(0) {
}
~CCreateMethodInfo() {
UA_Array_delete(mInputArguments, mInputSize, &UA_TYPES[UA_TYPES_ARGUMENT]);
UA_Array_delete(mOutputArguments, mOutputSize, &UA_TYPES[UA_TYPES_ARGUMENT]);
}
UA_Argument *mInputArguments;
UA_Argument *mOutputArguments;
CLocalMethodInfo &mLocalMethodInfo;
size_t mInputSize;
size_t mOutputSize;
private:
CCreateMethodInfo(CCreateMethodInfo &other);
CCreateMethodInfo& operator=(const CCreateMethodInfo &other);
};
/**
* Takes care of the requested nodeId, parent nodeId and the browsename to be given to the new created object/method/variable.
* The critical part is the browsename, since it can be given with the namespace using a semicolon (e.g. /Objects/1:myPath/), so
* this function handles this case
* @param paNodeName Nodename given by the user in the parameters of the action
* @param paNodePairInfo Information containing the requested node ID
* @param paParentNodeId Information containing the parent node ID
* @param paResult Place to store the results
*/
void initializeCreateInfo(CIEC_STRING &paNodeName, CActionInfo::CNodePairInfo &paNodePairInfo, const UA_NodeId *paParentNodeId, CCreateInfo &paResult);
/**
* Context passed to a variable node in the OPC UA stack, which is returned when the variable is written from a client.
* ATTENTION: this is exactly the same class as the one used for subscription in the client (UA_SubscribeContext_Handle),
* but because of compilation errors occurred when including headers, it was copied, since no right place could be found where to
* declare/define this class. If someone can manage to use the same class both in the CUA_ClientInformation and here, it can be deleted
*/
struct UA_VariableContext_Handle {
UA_VariableContext_Handle(CActionInfo &paActionInfo, size_t paPortIndex) :
mActionInfo(paActionInfo), mPortIndex(paPortIndex) {
}
//default copy constructor should be enough
bool operator==(UA_VariableContext_Handle const &paRightObject) const {
return (&mActionInfo == &paRightObject.mActionInfo && mPortIndex == paRightObject.mPortIndex);
}
CActionInfo &mActionInfo;
size_t mPortIndex;
};
/**
* List for callback handles to be able to clean them up on destroy.
*/
CSinglyLinkedList<UA_VariableContext_Handle> mNodeCallbackHandles;
/**
* Mutex used to avoid many threads (Resources) to create the same node at the same time
*/
CSyncObject mCreateNodesMutex;
/**
* This class is used to store who is the parent of each method. This need comes from the fact when creating objects that have methods,
* the method nodeId of every instance is the same as the method nodeID of the Object type. We can then use a CREATE_METHOD action pointing to this instance of the method,
* (let's call it "reference CREATE_METHOD") but there's no way of setting a specific context (in our case, a CLocalMethodInfo) that is returned in the callback, because the
* OPC UA API ask just for nodeID of the node when setting the context (and as said before, all methods instances share the same nodeId).
* We can set the context for methods that are created directly (no "reference CREATE_METHOD"), but for keeping the context the same for all kind of methods,
* in those cases, we also store the information using this class
*/
class UA_ParentNodeHandler {
public:
UA_ParentNodeHandler(UA_NodeId &paParentNodeId, UA_NodeId *paMethodNodeId, CLocalMethodInfo &paActionInfo) :
mParentNodeId(UA_NodeId_new()), mMethodNodeId(paMethodNodeId), mActionInfo(paActionInfo) {
UA_NodeId_copy(&paParentNodeId, mParentNodeId);
}
~UA_ParentNodeHandler() {
UA_NodeId_delete(mParentNodeId);
}
UA_ParentNodeHandler(const UA_ParentNodeHandler &other) :
mParentNodeId(UA_NodeId_new()), mMethodNodeId(other.mMethodNodeId), mActionInfo(other.mActionInfo) {
UA_NodeId_copy(other.mParentNodeId, mParentNodeId);
}
UA_NodeId *mParentNodeId;
UA_NodeId *mMethodNodeId;
CLocalMethodInfo &mActionInfo;
private:
UA_ParentNodeHandler& operator=(const UA_ParentNodeHandler &other);
};
/**
* The list of parent/method information of the used methods
*/
CSinglyLinkedList<UA_ParentNodeHandler> mMethodsContexts;
/**
* Initialization of read and write of variables. It handles both existing and non-existing cases
* @param paActionInfo Action to be initialized
* @param paWrite True if the action is to write a variable, false if it's for reading
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode initializeVariable(CActionInfo &paActionInfo, bool isWrite);
/**
* When an action refers to variable that already exist in the OPC UA server, another variable shouldn't be created. If you are trying to read a variable
* that has already another FB reading from it, it will fail. If the variable was created as a write, by reading it, it will set the writing permission
* to the variable and set the action as a callback context
* @param paActionInfo Action accessing the existing variable
* @param paNodePairInfo Information about the variable being accessed
* @param paVariable Variable to check the type
* @param paIndexOfNodePair Information about on which RD the variable will be read
* @param paWrite True if the action is to write a variable, false if it's for reading
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode handleExistingVariable(CActionInfo &paActionInfo, CActionInfo::CNodePairInfo &paNodePairInfo, const CIEC_ANY &paVariable,
size_t paIndexOfNodePair, bool paWrite);
/**
* Creates the variable in the OPC UA server. If the folders in the path to the variable don't exist, it will create them with random nodeIds
* @param paActionInfo Action creating the variable
* @param paNodePairInfo Information about the variable node being created
* @param paVariable Variable to get the type from
* @param paIndexOfNodePair Information about which RD/SD should be used to read/write the variable
* @param paReferencedNodes Place to store the nodes being references by the action (the variable node and folders)
* @param paWrite True if the action is to write a variable, false if it's for reading
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode handleNonExistingVariable(CActionInfo &paActionInfo, CActionInfo::CNodePairInfo &paNodePairInfo, const CIEC_ANY &paVariable,
size_t paIndexOfNodePair, CSinglyLinkedList<UA_NodeId*> &paReferencedNodes, bool paWrite);
/**
* Creates a variable in the OPC UA server using directly the API from the passed information
* @param paCreateVariableInfo Information needed to create the variable
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode createVariableNode(CCreateVariableInfo &paCreateVariableInfo);
/**
* Update a variable node value from a IEC61499 data object.
* @param paNodeId Node Id of the node to be updated
* @param paData Source data for the new value
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode updateNodeValue(const UA_NodeId &paNodeId, const CIEC_ANY *paData);
/**
* Register the onWrite function as callback routine when a variable is written and also the context that is passed back
* @param paNodeId Node ID of the node where to register the callback function and context
* @param paActionInfo The action executing the register
* @param paPortIndex Which RD is requesting the callback
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode
registerVariableCallBack(const UA_NodeId &paNodeId, CActionInfo &paActionInfo, size_t paPortIndex);
/**
* Adds write permission to a node
* @param paNodeId Node Id of the node to add write permission
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode addWritePermission(const UA_NodeId &paNodeId);
/**
* Perform all the needed initialization of the create method action
* @param paActionInfo Action to be initialized
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode initializeCreateMethod(CActionInfo &paActionInfo);
/**
* When an action references a method that already exists in the OPC UA server, it checks that another action is no already referencing it,
* and if that's the case, it stores the information about the parent.
* @param paActionInfo The action referencing the existing method
* @param paParentNode Parent node of the method. For methods instances of an object, the node id of the methods is the same, only the parent is different
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode handleExistingMethod(CActionInfo &paActionInfo, UA_NodeId &paParentNode);
/**
* Create the arguments for a method from the information of the action and store it in the encasulation for creating a method
* @param paActionInfo Action containing information about the arguments characteristics
* @param paCreateMethodInfo Place to store the created arguments
*/
void createMethodArguments(CActionInfo &paActionInfo, CCreateMethodInfo &paCreateMethodInfo);
/**
* Creates a method node in the OPC UA server using directly the API from the passed information
* @param paMethodInfo Information needed to create the method node
* @param paNodeId Place to store the node id of the created method
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode createMethodNode(CCreateMethodInfo &paMethodInfo, UA_NodeId **paNodeId);
/**
* Perform all the needed initialization of the create object action
* @param paActionInfo Action to be initialized
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode initializeCreateObject(CActionInfo &paActionInfo);
/**
* Perform all the needed initialization of the delet object action
* @param paActionInfo Action to be initialized
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode initializeDeleteObject(CActionInfo &paActionInfo);
/**
* Execute the write action to a local variable
* @param paActionInfo Action to be executed
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode executeWrite(CActionInfo &paActionInfo);
/**
* When the FB of the local method is triggered to signalize the end of the method, this function is called
* @param paActionInfo Action to be executed
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode executeCreateMethod(CActionInfo &paActionInfo);
/**
* Creates an object in the local server
* @param paActionInfo Action to be executed
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode executeCreateObject(CActionInfo &paActionInfo);
/**
* Creates an object in the OPC UA server using directly the API from the passed information
* @param paCreateObjectInfo Information needed to create the object
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode createObjectNode(CCreateObjectInfo &paCreateObjectInfo);
/**
* Checks if the type of an object exist in the local server
* @param paNodePairInfo Information about the Node Type
* @return True if it exists, false otherwise
*/
bool isTypeOfObjectPresent(CActionInfo::CNodePairInfo &paNodePairInfo);
/**
* Deletes an object from the local server
* @param paActionInfo Action to be executed
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode executeDeleteObject(CActionInfo &paActionInfo);
/**
* Looks for a node in the local OPC UA Server. If both the browsepath and NodeId are provided, they should match to consider that the
* node exists.
* @param paNodeInfo Information about the node to look for. If no nodeId was provided and the node exist, the node Id of the existing node is stored here
* @param paFoundNodeIds Place to store the found nodes (folders included). The list is altered only the final node is present
* @param paIsPresent Place to store true if the node is present in the local server, false otherwise
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode getNode(CActionInfo::CNodePairInfo &paNodeInfo, CSinglyLinkedList<UA_NodeId*> &paFoundNodeIds, bool *paIsPresent);
/**
* Execute the TranslateBrowsePathToNodeIds service in the local OPC UA server from a string containing the path
* @param paBrowsePath Path used to execute the service. Each element of the path is checked
* @param paBrowsePaths Place to store the request to the service, created from paBrowsePath
* @param paFoldercount Place to store how many folders were found in the path
* @param paFirstNonExistingNode Place to store the first non existing node in the path
* @param paFoundNodeIds Place to store the found node IDs
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode translateBrowseNameAndStore(const char *paBrowsePath, UA_BrowsePath **paBrowsePaths, size_t *paFoldercount, size_t *paFirstNonExistingNode,
CSinglyLinkedList<UA_NodeId*> &paFoundNodeIds);
/**
* Store the existing node from a TranslateBrowsePathToNodeIds service in a list of node Ids
* @param paBrowsePathsResults Results of a TranslateBrowsePathToNodeIds service
* @param paFolderCnt Size of paBrowsePathsResults
* @param paFirstNonExistingNode Store to place the first non existing node in paBrowsePathsResults
* @param paCreatedNodeIds Place to store the existing Node IDs
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode storeAlreadyExistingNodes(UA_BrowsePathResult *paBrowsePathsResults, size_t paFolderCnt, size_t* paFirstNonExistingNode,
CSinglyLinkedList<UA_NodeId*> &paCreatedNodeIds);
/**
* Create folder objects in the OPC UA server from the string. It's assumed that the end node is not present in the path
* @param paFolders Path of folders
* @param paCreatedNodeIds Place to store the created nodeIds
* @return UA_STATUSCODE_GOOD on success, other value otherwise
*/
UA_StatusCode createFolders(const char *paFolders, CSinglyLinkedList<UA_NodeId*> &paCreatedNodeIds);
/**
* Splits a browsepath into folders and node name. The non-existing folders are created in the local server
* @param paBrowsePath Browsepath to be splitted
* @param paNodeName Place to store the nodename
* @param paRreferencedNodes List of nodes that are used by this browsename. It will include all folders, but not the end node since it was not created yet
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode splitAndCreateFolders(CIEC_STRING &paBrowsePath, CIEC_STRING &paNodeName, CSinglyLinkedList<UA_NodeId*> &paRreferencedNodes);
/**
* Split a string into folders and node name. The provided place for store of the folder and node name are only
* changed if the result value is true
* @param paOriginal String containing the path to be split
* @param paFolder Place to store the folders part of the string
* @param paNodeName Place to store the node name part of the string
* @return True if the provided string is a valid path, false otherwise
*/
bool splitFoldersFromNode(const CIEC_STRING &paOriginal, CIEC_STRING &paFolder, CIEC_STRING &paNodeName);
/**
* If paFailed is true, it deletes all NodeIds from paPresentNodes, otherwise it copies them to paReferencedNodes.
* It's used to handle the NodeIds that been previously allocated, and decide if they should be stored or deleted
* @param paPresentNodes NodeIds to be analyzed
* @param paReferencedNodes Place to store the NodeIds if paFailed is true
* @param paFailed True if the NodeIds should be deleted, false if they need to be copied into paReferencedNodes
*/
void handlePresentNodes(CSinglyLinkedList<UA_NodeId*> &paPresentNodes, CSinglyLinkedList<UA_NodeId*> &paReferencedNodes, bool paFailed);
/**
* Maximum time a local method can take to finish execution without producing an error
*/
static const size_t scmMethodCallTimeoutInNanoSeconds = 4 * 1E9; //4s
/**
* Encapsulation of the information of an external call to a local server
*/
struct CLocalMethodCall {
CLocalMethodCall(CLocalMethodInfo &paActionInfo, COPC_UA_Helper::UA_SendVariable_handle &paSendHandle) :
mActionInfo(paActionInfo), mSendHandle(paSendHandle) {
}
//default copy constructor should be enough
bool operator==(CLocalMethodCall const &rhs) const {
return this == &rhs;
}
CLocalMethodInfo &mActionInfo;
COPC_UA_Helper::UA_SendVariable_handle &mSendHandle;
};
/**
* List of external method calls currently being executed. This is to allow many external calls in parallalel.
* TODO: It seems that the OPC UA server cannot execute many calls at the same time. For each call, onServerMethodCall
* is called which waits for the method to finish before returning, meaning that always only 1 method call can be executed.
* Check if this is always true, and if yes, the following related functions and variables aren't necessary, and only one
* CLocalMethodCall is necessary
*/
CSinglyLinkedList<CLocalMethodCall> mMethodCalls;
/**
* Mutex to access mMethodCalls
*/
CSyncObject mMethodCallsMutex;
/**
* Add a method call to the list when onServerMethodCall is called
* @param paActionInfo Action adding the call
* @param paHandleRecv Information to later store the results of the method call
* @return The result added method call
*/
CLocalMethodCall& addMethodCall(CLocalMethodInfo &paActionInfo, COPC_UA_Helper::UA_SendVariable_handle &paHandleRecv);
/**
* Removes a method call from the list when the method is finished
* @param toDelete Call to remove
*/
void removeMethodCall(CLocalMethodCall &toRemove);
/**
* Look for the oldest method call of an action
* @param paActionInfo Action on which the call was triggered
* @return The method call. 0 if an external call for the action was not triggered
*/
CLocalMethodCall* getLocalMethodCall(CLocalMethodInfo &paActionInfo);
/**
* Default value for the namespace of the browsename for all created nodes
*/
static const UA_UInt16 scmDefaultBrowsenameNameSpace = 1;
/**
* English locale used as default for all nodes
*/
static const char * const mEnglishLocaleForNodes;
/**
* Default description for variable nodes
*/
static const char * const mDefaultDescriptionForVariableNodes;
#ifdef FORTE_COM_OPC_UA_MULTICAST
# ifndef UA_ENABLE_DISCOVERY_MULTICAST
# error open62541 needs to be built with UA_ENABLE_DISCOVERY_MULTICAST=ON
# else // UA_ENABLE_DISCOVERY_MULTICAST
# ifdef FORTE_COM_OPC_UA_MASTER_BRANCH
//nothing here
# else
/**
* Server configuration
*/
UA_ServerConfig *mServerConfig;
# endif
/**
* List of LDS servers where this instance is already registered.
*/
CSinglyLinkedList<UA_String*> mRegisteredWithLds;
const UA_String getDiscoveryUrl() const;
void registerWithLds(const UA_String *paDiscoveryUrl);
void removeLdsRegister(const UA_String *paDiscoveryUrl);
static void serverOnNetworkCallback(const UA_ServerOnNetwork *paServerOnNetwork, UA_Boolean paIsServerAnnounce, UA_Boolean paIsTxtReceived, void *paData);
# endif //UA_ENABLE_DISCOVERY_MULTICAST
#endif //FORTE_COM_OPC_UA_MULTICAST
};
#endif /* SRC_MODULES_OPC_UA_OPCUALOCALHANDLER_H_ */