Julius Pfrommer пре 8 година
родитељ
комит
a437267d13

+ 0 - 1
CMakeLists.txt

@@ -80,7 +80,6 @@ option(UA_BUILD_EXAMPLES_NODESET_COMPILER "Generate an OPC UA information model
 
 # Advanced Build Targets
 option(UA_BUILD_SELFSIGNED_CERTIFICATE "Generate self-signed certificate" OFF)
-mark_as_advanced(UA_BUILD_SELFSIGNED_CERTIFICATE)
 
 # Building shared libs (dll, so). This option is written into ua_config.h.
 set(UA_DYNAMIC_LINKING OFF)

+ 1 - 1
doc/in_a_nutshell.rst

@@ -13,7 +13,7 @@ methods on the server.
 
 For completeness, the following tables contain all services defined in the standard. Do not bother
 with their details yet. We will introduce the different services later in the text. In open62541,
-each service is implemented in a single function. See the \ref services section for details.
+each service is implemented in a single function. See the :ref:`services` section for details.
 
 **Establishing communication**
 

+ 7 - 5
src/server/ua_services_call.c

@@ -87,12 +87,14 @@ satisfySignature(UA_Server *server, const UA_Variant *var, const UA_Argument *ar
         break;
     }
 
-    /* do the array dimensions match? */
-    if(arg->arrayDimensionsSize != varDimsSize)
-        return UA_STATUSCODE_BADINVALIDARGUMENT;
-    for(size_t i = 0; i < varDimsSize; i++) {
-        if((UA_Int32)arg->arrayDimensions[i] != varDims[i])
+    /* Do the variants dimensions match? Check only if defined in the argument. */
+    if(arg->arrayDimensionsSize > 0) {
+        if(arg->arrayDimensionsSize != varDimsSize)
             return UA_STATUSCODE_BADINVALIDARGUMENT;
+        for(size_t i = 0; i < varDimsSize; i++) {
+            if((UA_Int32)arg->arrayDimensions[i] != varDims[i])
+                return UA_STATUSCODE_BADINVALIDARGUMENT;
+        }
     }
     return UA_STATUSCODE_GOOD;
 }

+ 2 - 2
src/ua_connection.c

@@ -43,10 +43,10 @@ UA_Connection_completeMessages(UA_Connection *connection, UA_ByteString * UA_RES
             retval = UA_STATUSCODE_BADOUTOFMEMORY;
             goto cleanup;
         }
-        memcpy(&data[connection->incompleteMessage.length], message->data, length);
+        memcpy(&data[connection->incompleteMessage.length], message->data, message->length);
         connection->releaseRecvBuffer(connection, message);
         message->data = data;
-        message->length += length;
+        message->length = length;
         *realloced = true;
         connection->incompleteMessage = UA_BYTESTRING_NULL;
     }

+ 4 - 2
tools/pyUANamespace/generate_open62541CCode.py

@@ -44,7 +44,7 @@ parser.add_argument('-i','--ignore',
                     action='append',
                     dest="ignoreFiles",
                     default=[],
-                    help='Loads a list of NodeIDs stored in ignoreFile (one NodeID per line). The compiler will assume that these Nodes have been creathed externally and not generate any code for them. They will however be linked to from other nodes.')
+                    help='Loads a list of NodeIDs stored in ignoreFile (one NodeID per line). The compiler will assume that these nodes have been created externally and not generate any code for them. They will however be linked to from other nodes.')
 parser.add_argument('-b','--blacklist',
                     metavar="<blacklistFile>",
                     type=argparse.FileType('r'),
@@ -149,7 +149,7 @@ ns.allocateVariables()
 
 # Users may have manually defined some nodes in their code already (such as serverStatus).
 # To prevent those nodes from being reprinted, we will simply mark them as already
-# converted to C-Code. That way, they will still be reffered to by other nodes, but
+# converted to C-Code. That way, they will still be referred to by other nodes, but
 # they will not be created themselves.
 ignoreNodes = []
 for ignore in args.ignoreFiles:
@@ -174,3 +174,5 @@ for line in generatedCode[1]:
 
 outfilec.close()
 outfileh.close()
+
+logger.info("Namespace generation code successfully printed")

+ 9 - 1
tools/pyUANamespace/open62541_MacroHelper.py

@@ -210,7 +210,7 @@ class open62541_MacroHelper():
 
     code.append("UA_NodeId nodeId = " + str(self.getCreateNodeIDMacro(node)) + ";")
     if nodetype in ["Object", "Variable"]:
-      code.append("UA_NodeId typeDefinition = UA_NODEID_NULL;") # todo instantiation of object and variable types
+      code.append("UA_NodeId typeDefinition = UA_NODEID_NULL;") #due to the current API we cannot set types here since the API will generate nodes with random IDs
     code.append("UA_NodeId parentNodeId = " + str(self.getCreateNodeIDMacro(parentNode)) + ";")
     code.append("UA_NodeId parentReferenceNodeId = " + str(self.getCreateNodeIDMacro(parentReference.referenceType())) + ";")
     extrNs = node.browseName().split(":")
@@ -229,6 +229,14 @@ class open62541_MacroHelper():
       code.append("       , attr, NULL, NULL);")
     else:
       code.append("       , attr, (UA_MethodCallback) NULL, NULL, " + str(len(inArgVal)) + ", inputArguments,  " + str(len(outArgVal)) + ", outputArguments, NULL);")
+      
+    #Adding a Node with typeDefinition = UA_NODEID_NULL will create a HasTypeDefinition reference to BaseDataType - remove it since 
+    #a real Reference will be add in a later step (a single HasTypeDefinition reference is assumed here)
+    #The current API does not let us specify IDs of Object's subelements.
+    if nodetype is "Object":
+      code.append("UA_Server_deleteReference(server, nodeId, UA_NODEID_NUMERIC(0, 40), true, UA_EXPANDEDNODEID_NUMERIC(0, 58), true); //remove HasTypeDefinition refs generated by addObjectNode");
+    if nodetype is "Variable":
+      code.append("UA_Server_deleteReference(server, nodeId, UA_NODEID_NUMERIC(0, 40), true, UA_EXPANDEDNODEID_NUMERIC(0, 62), true); //remove HasTypeDefinition refs generated by addVariableNode");
     return code
 
   def getCreateNodeBootstrap(self, node):

+ 5 - 4
tools/pyUANamespace/ua_builtin_types.py

@@ -397,11 +397,12 @@ class opcua_value_t():
           code.append("UA_" + self.value[0].stringRepresentation + " *" + valueName + " = " + self.value[0].printOpen62541CCode_SubType() + ";")
           code.append("UA_Variant_setScalar( &attr.value, " + valueName + ", &UA_TYPES[UA_TYPES_" + self.value[0].stringRepresentation.upper() + "]);")
           #FIXME: There is no membership definition for extensionObjects generated in this function.
-          code.append("UA_" + self.value[0].stringRepresentation + "_deleteMembers(" + valueName + ");")
+          #code.append("UA_" + self.value[0].stringRepresentation + "_deleteMembers(" + valueName + ");")
         else:
-          code.append("UA_" + self.value[0].stringRepresentation + " " + valueName + " = " + self.value[0].printOpen62541CCode_SubType() + ";")
-          code.append("UA_Variant_setScalar( &attr.value, &" + valueName + ", &UA_TYPES[UA_TYPES_" + self.value[0].stringRepresentation.upper() + "]);")
-          code.append("UA_" + self.value[0].stringRepresentation + "_deleteMembers(&" + valueName + ");")
+          code.append("UA_" + self.value[0].stringRepresentation + " *" + valueName + " =  UA_" + self.value[0].stringRepresentation + "_new();")
+          code.append("*" + valueName + " = " + self.value[0].printOpen62541CCode_SubType() + ";")
+          code.append("UA_Variant_setScalar( &attr.value, " + valueName + ", &UA_TYPES[UA_TYPES_" + self.value[0].stringRepresentation.upper() + "]);")
+          #code.append("UA_" + self.value[0].stringRepresentation + "_deleteMembers(" + valueName + ");")
     return code
 
 

+ 2 - 2
tools/pyUANamespace/ua_namespace.py

@@ -320,7 +320,7 @@ class opcua_namespace():
         No return value
 
         References that have registered themselves with linkLater() to have
-        their symbolic NodeId targets ("ns=2; i=32") substited for an actual
+        their symbolic NodeId targets ("ns=2;i=32") substituted for an actual
         node will be iterated by this function. For each reference encountered
         in the list of unlinked/open references, the target string will be
         evaluated and searched for in the node list of this namespace. If found,
@@ -680,7 +680,7 @@ class opcua_namespace():
 
       # Now for the actual references...
       for r in n.getReferences():
-        # Only print valid refernces in namespace 0 (users will not want their refs bootstrapped)
+        # Only print valid references in namespace 0 (users will not want their refs bootstrapped)
         if not r.referenceType() in refsUsed and r.referenceType() != None and r.referenceType().id().ns == 0:
           refsUsed.append(r.referenceType())
     logger.debug(str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped.")

+ 1 - 1
tools/pyUANamespace/ua_node_types.py

@@ -681,7 +681,7 @@ class opcua_node_t:
       # Parent to child reference is added by the server, do not reprint that reference
       if parentRef in unPrintedReferences:
         unPrintedReferences.remove(parentRef)
-      # the UA_Server_addNode function will use addReference which creates a biderectional reference; remove any inverse
+      # the UA_Server_addNode function will use addReference which creates a bidirectional reference; remove any inverse
       # references to our parent to avoid duplicate refs
       for ref in self.getReferences():
         if ref.target() == parentNode and ref.referenceType() == parentRef.referenceType() and ref.isForward() == False: