| /******************************************************************************* |
| * 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_ */ |