Просмотр исходного кода

Serverside node iterator in place.

ichrispa лет назад: 9
Родитель
Сommit
8d09a9383e
3 измененных файлов с 72 добавлено и 2 удалено
  1. 17 1
      examples/server.c
  2. 39 1
      include/ua_server.h
  3. 16 0
      src/server/ua_server_addressspace.c

+ 17 - 1
examples/server.c

@@ -190,6 +190,17 @@ static UA_ByteString loadCertificate(void) {
     return certificate;
 }
 
+UA_StatusCode nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId);
+UA_StatusCode nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId) {  
+  printf("References ns=%d;i=%d using i=%d ", childId.namespaceIndex, childId.identifier.numeric, referenceTypeId.identifier.numeric);
+  if (isInverse != UA_TRUE) {
+    printf(" (inverse)");
+  }
+  printf("\n");
+  
+  return UA_STATUSCODE_GOOD;
+}
+
 int main(int argc, char** argv) {
 	signal(SIGINT, stopHandler); /* catches ctrl-c */
 #ifdef UA_MULTITHREADING
@@ -332,7 +343,12 @@ int main(int argc, char** argv) {
                            UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
                            &getMonitoredItems, 1, &inputArguments, 1, &outputArguments, &methodId);
 #endif
-	//start server
+   
+   // Example for iterating over all nodes referenced by "Objects":
+   printf("Nodes connected to 'Objects':\n=============================\n");
+   UA_Server_forEachChildNodeCall(server, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), nodeIter);
+   
+   //start server
 	UA_StatusCode retval = UA_Server_run(server, 1, &running); //blocks until running=false
 
 	//ctrl-c received -> clean up

+ 39 - 1
include/ua_server.h

@@ -164,7 +164,31 @@ UA_Server_AddMonodirectionalReference(UA_Server *server, UA_NodeId sourceNodeId,
 #ifdef ENABLE_METHODCALLS
 typedef UA_StatusCode (*UA_MethodCallback)(const UA_NodeId objectId, const UA_Variant *input,
                                            UA_Variant *output);
-    
+/** Creates a serverside method including input- and output variable descriptions
+ * 
+ * @param server The server object.
+ * 
+ * @param browseName BrowseName to be used for the new method.
+ * 
+ * @param nodeId Requested NodeId for the new method. If a numeric ID with i=0 is used, the server will assign a random unused id.
+ * 
+ * @param parentNodeId Parent node containing this method. Note that an ObjectNode needs to reference the method with hasProperty in order for the method to be callable.
+ * 
+ * @param referenceTypeId Reference type ID to be used by the parent to reference the new method.
+ * 
+ * @param method Userspace Method/Function of type UA_MethodCallback to be called when a client invokes the method using the Call Service Set.
+ * 
+ * @param inputArgumentsSize Number of input arguments expected to be passed by a calling client.
+ * 
+ * @param inputArguments Description of input arguments expected to be passed by a calling client.
+ * 
+ * @param outputArgumentsSize Description of output arguments expected to be passed by a calling client.
+ * 
+ * @param outputArguments Description of output arguments expected to be passed by a calling client.
+ * 
+ * @param createdNodeId Actual nodeId of the new method node if UA_StatusCode indicates success. Can be used to determine the random unique ID assigned by the server if i=0 was passed as a nodeId.
+ * 
+ */
 UA_StatusCode UA_EXPORT
 UA_Server_addMethodNode(UA_Server *server, const UA_QualifiedName browseName, UA_NodeId nodeId,
                         const UA_ExpandedNodeId parentNodeId, const UA_NodeId referenceTypeId,
@@ -174,6 +198,20 @@ UA_Server_addMethodNode(UA_Server *server, const UA_QualifiedName browseName, UA
                         UA_NodeId *createdNodeId);
 #endif
 
+typedef UA_StatusCode (*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId);
+
+/** Iterate over all nodes referenced by parentNodeId by calling the callback function for each child node
+ * 
+ * @param server The server object.
+ *
+ * @param parentNodeId The NodeId of the parent whose references are to be iterated over
+ *
+ * @param callback The function of type UA_NodeIteratorCallback to be called for each referenced child
+ *
+ * @return Upon success, UA_STATUSCODE_GOOD is returned. An error code otherwise.
+ */
+UA_StatusCode UA_EXPORT UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId, UA_NodeIteratorCallback callback);
+
 /** Jobs describe work that is executed once or repeatedly. */
 typedef struct {
     enum {

+ 16 - 0
src/server/ua_server_addressspace.c

@@ -61,6 +61,22 @@ UA_SERVER_DELETENODEALIAS(Variable)
 UA_SERVER_DELETENODEALIAS(Method)
 #endif
 
+UA_StatusCode 
+UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId, UA_NodeIteratorCallback callback) {
+  UA_StatusCode retval = UA_STATUSCODE_GOOD;
+  const UA_Node *parent = UA_NodeStore_get(server->nodestore, &parentNodeId);
+  if (!parent)
+    return UA_STATUSCODE_BADNODEIDINVALID;
+  
+  for(int i=0; i<parent->referencesSize; i++) {
+    UA_ReferenceNode *ref = &parent->references[i];
+    retval |= callback(ref->targetId.nodeId, ref->isInverse, ref->referenceTypeId);
+  }
+  
+  UA_NodeStore_release(parent);
+  return retval;
+}
+
 UA_StatusCode
 UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, const UA_QualifiedName browseName, 
                           UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,