Quellcode durchsuchen

Generate statuscode and nodeid description from schema files

Julius Pfrommer vor 6 Jahren
Ursprung
Commit
71a2d50101

+ 23 - 6
CMakeLists.txt

@@ -345,6 +345,8 @@ include_directories(${PROJECT_SOURCE_DIR}/include
 set(exported_headers ${PROJECT_BINARY_DIR}/src_generated/ua_config.h
                      ${PROJECT_SOURCE_DIR}/deps/ms_stdint.h
                      ${PROJECT_SOURCE_DIR}/include/ua_constants.h
+                     ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.h
+                     ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids.h
                      ${PROJECT_SOURCE_DIR}/include/ua_types.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated_handling.h
@@ -389,7 +391,7 @@ set(lib_sources ${PROJECT_SOURCE_DIR}/src/ua_types.c
                 ${PROJECT_SOURCE_DIR}/src/ua_types_encoding_binary.c
                 ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.c
                 ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated.c
-                ${PROJECT_BINARY_DIR}/src_generated/ua_statuscode_descriptions.c
+                ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.c
                 ${PROJECT_SOURCE_DIR}/src/ua_util.c
                 ${PROJECT_SOURCE_DIR}/src/ua_timer.c
                 ${PROJECT_SOURCE_DIR}/src/ua_connection.c
@@ -503,6 +505,7 @@ if (UA_ENABLE_FULL_NS0)
     endif()
     set(UA_FILE_DATATYPES "")
     set(UA_FILE_NODEIDS ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/NodeIds.csv)
+    set(UA_FILE_STATUSCODES ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/StatusCode.csv)
     set(UA_FILE_TYPES_BSD ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.Types.bsd)
 else()
     if(NOT UA_FILE_NS0)
@@ -510,6 +513,7 @@ else()
     endif()
     set(UA_FILE_DATATYPES "${PROJECT_SOURCE_DIR}/tools/schema/datatypes_minimal.txt")
     set(UA_FILE_NODEIDS ${PROJECT_SOURCE_DIR}/tools/schema/NodeIds.csv)
+    set(UA_FILE_STATUSCODES ${PROJECT_SOURCE_DIR}/tools/schema/StatusCode.csv)
     set(UA_FILE_TYPES_BSD ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.Types.bsd)
 endif()
 if(NOT EXISTS "${UA_FILE_NS0}")
@@ -571,15 +575,28 @@ add_custom_target(open62541-generator-transport DEPENDS
         ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated_encoding_binary.h)
 
 # statuscode explanation
-add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_statuscode_descriptions.c
+add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.h
+                          ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.c
         PRE_BUILD
         COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_statuscode_descriptions.py
-        ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.StatusCodes.csv ${PROJECT_BINARY_DIR}/src_generated/ua_statuscode_descriptions
+        ${UA_FILE_STATUSCODES} ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes
         DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/generate_statuscode_descriptions.py
-        ${CMAKE_CURRENT_SOURCE_DIR}/tools/schema/Opc.Ua.StatusCodes.csv)
-# we need a custom target to avoid that the generator is called concurrently and thus overwriting files while the other thread is compiling
+                ${UA_FILE_STATUSCODES})
+
+# nodeid explanation
+add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids.h
+        PRE_BUILD
+        COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_nodeid_descriptions.py
+        ${UA_FILE_NODEIDS}  ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids
+        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/generate_nodeid_descriptions.py
+        ${UA_FILE_NODEIDS})
+
+# we need a custom target to avoid that the generator is called concurrently and
+# thus overwriting files while the other thread is compiling
 add_custom_target(open62541-generator-statuscode DEPENDS
-        ${PROJECT_BINARY_DIR}/src_generated/ua_statuscode_descriptions.c)
+        ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids.h
+        ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.h
+        ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.c)
 
 # single-file release
 add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/open62541.h

+ 3 - 0
doc/CMakeLists.txt

@@ -19,6 +19,7 @@ endfunction()
 # Doc from headers
 generate_rst(${PROJECT_SOURCE_DIR}/include/ua_types.h ${DOC_SRC_DIR}/types.rst)
 generate_rst(${PROJECT_SOURCE_DIR}/include/ua_constants.h ${DOC_SRC_DIR}/constants.rst)
+generate_rst(${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.h ${DOC_SRC_DIR}/statuscodes.rst)
 generate_rst(${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h ${DOC_SRC_DIR}/types_generated.rst)
 generate_rst(${PROJECT_SOURCE_DIR}/include/ua_server_config.h ${DOC_SRC_DIR}/server_config.rst)
 generate_rst(${PROJECT_SOURCE_DIR}/include/ua_server.h ${DOC_SRC_DIR}/server.rst)
@@ -47,6 +48,7 @@ generate_rst(${PROJECT_SOURCE_DIR}/examples/tutorial_client_firststeps.c ${DOC_S
 add_custom_target(doc_latex ${SPHINX_EXECUTABLE}
   -b latex "${DOC_SRC_DIR}" "${DOC_LATEX_DIR}"
   DEPENDS ${DOC_SRC_DIR}/types.rst ${DOC_SRC_DIR}/constants.rst ${DOC_SRC_DIR}/types_generated.rst
+          ${DOC_SRC_DIR}/statuscodes.rst
           ${DOC_SRC_DIR}/server.rst ${DOC_SRC_DIR}/server_config.rst
           ${DOC_SRC_DIR}/client.rst ${DOC_SRC_DIR}/client_subscriptions.rst
           ${DOC_SRC_DIR}/client_highlevel.rst ${DOC_SRC_DIR}/client_config.rst
@@ -78,6 +80,7 @@ add_dependencies(doc_pdf doc_latex)
 add_custom_target(doc ${SPHINX_EXECUTABLE}
   -b html "${DOC_SRC_DIR}" "${DOC_HTML_DIR}"
   DEPENDS ${DOC_SRC_DIR}/types.rst ${DOC_SRC_DIR}/constants.rst ${DOC_SRC_DIR}/types_generated.rst
+          ${DOC_SRC_DIR}/statuscodes.rst
           ${DOC_SRC_DIR}/server.rst ${DOC_SRC_DIR}/server_config.rst
           ${DOC_SRC_DIR}/client.rst ${DOC_SRC_DIR}/client_subscriptions.rst
           ${DOC_SRC_DIR}/client_highlevel.rst ${DOC_SRC_DIR}/client_config.rst

+ 1 - 0
doc/internal.rst

@@ -3,6 +3,7 @@ Internals
 
 .. toctree::
 
+   statuscodes
    plugin_network
    plugin_access_control
    plugin_log

+ 1 - 0
include/ua_client.h

@@ -28,6 +28,7 @@ extern "C" {
 #include "ua_plugin_network.h"
 #include "ua_plugin_log.h"
 #include "ua_client_config.h"
+#include "ua_nodeids.h"
 
 /**
  * .. _client:

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 1544
include/ua_constants.h


+ 1 - 0
include/ua_server.h

@@ -20,6 +20,7 @@ extern "C" {
 #include "ua_types.h"
 #include "ua_types_generated.h"
 #include "ua_types_generated_handling.h"
+#include "ua_nodeids.h"
 
 struct UA_ServerConfig;
 typedef struct UA_ServerConfig UA_ServerConfig;

+ 1 - 0
include/ua_types.h

@@ -22,6 +22,7 @@ extern "C" {
 
 #include "ua_config.h"
 #include "ua_constants.h"
+#include "ua_statuscodes.h"
 
 #define UA_BUILTIN_TYPES_COUNT 25U
 

+ 55 - 0
tools/generate_nodeid_descriptions.py

@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this 
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from __future__ import print_function
+import sys
+import platform
+import getpass
+import time
+import argparse
+from io import open
+
+parser = argparse.ArgumentParser()
+parser.add_argument('statuscodes', help='path/to/Opc.Ua.NodeIds.csv')
+parser.add_argument('outfile', help='outfile w/o extension')
+args = parser.parse_args()
+
+rows = []
+with open(args.statuscodes, mode="rt") as f:
+    lines = f.readlines()
+    for l in lines:
+        rows.append(tuple(l.strip().split(',')))
+
+fh = open(args.outfile + ".h", "wt", encoding='utf8')
+def printh(string):
+    print(string, end=u'\n', file=fh)
+
+#########################
+# Print the header file #
+#########################
+
+printh(u'''/*---------------------------------------------------------
+ * Autogenerated -- do not modify
+ * Generated from %s with script %s
+ *-------------------------------------------------------*/
+
+#ifndef UA_NODEIDS_H_
+#define UA_NODEIDS_H_
+
+/**
+ * Namespace Zero NodeIds
+ * ----------------------
+ * Numeric identifiers of standard-defined nodes in namespace zero. The
+ * following definitions are autogenerated from the ``NodeIds.csv`` file
+ * provided with the OPC UA standard. */
+''' % (args.statuscodes, sys.argv[0]))
+
+for row in rows:
+    printh(u"#define UA_NS0ID_%s %s /* %s */" % (row[0].upper(), row[1], row[2]))
+
+printh(u'''#endif /* UA_NODEIDS_H_ */ ''')
+
+fh.close()

+ 37 - 3
tools/generate_statuscode_descriptions.py

@@ -23,10 +23,45 @@ with open(args.statuscodes, mode="rt") as f:
     for l in lines:
         rows.append(tuple(l.strip().split(',')))
 
+fh = open(args.outfile + ".h", "wt", encoding='utf8')
 fc = open(args.outfile + ".c", "wt", encoding='utf8')
+def printh(string):
+    print(string, end=u'\n', file=fh)
 def printc(string):
     print(string, end=u'\n', file=fc)
 
+#########################
+# Print the header file #
+#########################
+
+printh(u'''/*---------------------------------------------------------
+ * Autogenerated -- do not modify
+ * Generated from %s with script %s
+ *-------------------------------------------------------*/
+
+/**
+ * .. _statuscodes:
+ *
+ * StatusCodes
+ * -----------
+ * StatusCodes are extensively used in the OPC UA protocol and in the open62541
+ * API. They are represented by the :ref:`statuscode` data type. The following
+ * definitions are autogenerated from the ``Opc.Ua.StatusCodes.csv`` file provided
+ * with the OPC UA standard. */
+
+/* These StatusCodes are manually generated. */
+#define UA_STATUSCODE_GOOD 0x00
+#define UA_STATUSCODE_INFOTYPE_DATAVALUE 0x00000400
+#define UA_STATUSCODE_INFOBITS_OVERFLOW 0x00000080
+''' % (args.statuscodes, sys.argv[0]))
+
+for row in rows:
+    printh(u"#define UA_STATUSCODE_%s %s /* %s */" % (row[0].upper(), row[1], row[2]))
+
+#########################
+# Print the source file #
+#########################
+
 printc(u'''/**********************************************************
  * Autogenerated -- do not modify
  * Generated from %s with script %s
@@ -37,7 +72,6 @@ printc(u'''/**********************************************************
 count = 2 + len(rows)
 
 printc(u'''
-
 /* Definition for the deprecated StatusCode description API */
 const UA_StatusCodeDescription statusCodeExplanation_default = {0xffffffff, "", ""};
 
@@ -54,8 +88,7 @@ const char * UA_StatusCode_name(UA_StatusCode code) {
 #else
 static const size_t statusCodeDescriptionsSize = %s;
 static const UA_StatusCodeName statusCodeDescriptions[%i] = {
-    {UA_STATUSCODE_GOOD, \"Good\"},
-''' % (count, count))
+    {UA_STATUSCODE_GOOD, \"Good\"},''' % (count, count))
 
 for row in rows:
     printc(u"    {UA_STATUSCODE_%s, \"%s\"}," % (row[0].upper(), row[0]))
@@ -73,3 +106,4 @@ const char * UA_StatusCode_name(UA_StatusCode code) {
 #endif''')
 
 fc.close()
+fh.close()

+ 3 - 2
tools/nodeset_compiler/backend_open62541_nodes.py

@@ -290,13 +290,14 @@ def generateExtensionObjectSubtypeCode(node, parent, nodeset, recursionDepth=0,
     return [code, codeCleanup]
 
 
-def generateValueCodeDummy(dataTypeNode, parentNode, nodeset, bootstrapping=True):
+def generateValueCodeDummy(dataTypeNode, parentNode, nodeset):
     code = []
     valueName = generateNodeIdPrintable(parentNode) + "_variant_DataContents"
 
     typeBrowseNode = dataTypeNode.browseName.name
     if typeBrowseNode == "NumericRange":
-        # in the stack we define a separate structure for the numeric range, but the value itself is just a string
+        # in the stack we define a separate structure for the numeric range, but
+        # the value itself is just a string
         typeBrowseNode = "String"
 
     typeArr = dataTypeNode.typesArray + "[" + dataTypeNode.typesArray + "_" + typeBrowseNode.upper() + "]"

Datei-Diff unterdrückt, da er zu groß ist
+ 1126 - 1714
tools/schema/NodeIds.csv


+ 23 - 15
tools/schema/Opc.Ua.StatusCodes.csv

@@ -20,15 +20,16 @@ BadTooManyMonitoredItems,0x80DB0000,The request could not be processed because t
 BadDataTypeIdUnknown,0x80110000,The extension object cannot be (de)serialized because the data type id is not recognized.
 BadCertificateInvalid,0x80120000,The certificate provided as a parameter is not valid.
 BadSecurityChecksFailed,0x80130000,An error occurred verifying security.
-BadCertificateTimeInvalid,0x80140000,The Certificate has expired or is not yet valid.
-BadCertificateIssuerTimeInvalid,0x80150000,An Issuer Certificate has expired or is not yet valid.
-BadCertificateHostNameInvalid,0x80160000,The HostName used to connect to a Server does not match a HostName in the Certificate.
-BadCertificateUriInvalid,0x80170000,The URI specified in the ApplicationDescription does not match the URI in the Certificate.
-BadCertificateUseNotAllowed,0x80180000,The Certificate may not be used for the requested operation.
-BadCertificateIssuerUseNotAllowed,0x80190000,The Issuer Certificate may not be used for the requested operation.
-BadCertificateUntrusted,0x801A0000,The Certificate is not trusted.
-BadCertificateRevocationUnknown,0x801B0000,It was not possible to determine if the Certificate has been revoked.
-BadCertificateIssuerRevocationUnknown,0x801C0000,It was not possible to determine if the Issuer Certificate has been revoked.
+BadCertificatePolicyCheckFailed,0x81140000,The certificate does not meet the requirements of the security policy.
+BadCertificateTimeInvalid,0x80140000,The certificate has expired or is not yet valid.
+BadCertificateIssuerTimeInvalid,0x80150000,An issuer certificate has expired or is not yet valid.
+BadCertificateHostNameInvalid,0x80160000,The HostName used to connect to a server does not match a HostName in the certificate.
+BadCertificateUriInvalid,0x80170000,The URI specified in the ApplicationDescription does not match the URI in the certificate.
+BadCertificateUseNotAllowed,0x80180000,The certificate may not be used for the requested operation.
+BadCertificateIssuerUseNotAllowed,0x80190000,The issuer certificate may not be used for the requested operation.
+BadCertificateUntrusted,0x801A0000,The certificate is not trusted.
+BadCertificateRevocationUnknown,0x801B0000,It was not possible to determine if the certificate has been revoked.
+BadCertificateIssuerRevocationUnknown,0x801C0000,It was not possible to determine if the issuer certificate has been revoked.
 BadCertificateRevoked,0x801D0000,The certificate has been revoked.
 BadCertificateIssuerRevoked,0x801E0000,The issuer certificate has been revoked.
 BadCertificateChainIncomplete,0x810D0000,The certificate chain is incomplete.
@@ -46,6 +47,9 @@ BadRequestHeaderInvalid,0x802A0000,The header for the request is missing or inva
 BadTimestampsToReturnInvalid,0x802B0000,The timestamps to return parameter is invalid.
 BadRequestCancelledByClient,0x802C0000,The request was cancelled by the client.
 BadTooManyArguments,0x80E50000,Too many arguments were provided.
+BadLicenseExpired,0x810E0000,The server requires a license to operate in general or to perform a service or operation, but existing license is expired.
+BadLicenseLimitsExceeded,0x810F0000,The server has limits on number of allowed operations / objects, based on installed licenses, and these limits where exceeded.
+BadLicenseNotAvailable,0x81100000,The server does not have a license which is required to operate in general or to perform a service or operation.
 GoodSubscriptionTransferred,0x002D0000,The subscription was transferred to another session.
 GoodCompletesAsynchronously,0x002E0000,The processing will complete asynchronously.
 GoodOverload,0x002F0000,Sampling has slowed down due to resource limitations.
@@ -85,18 +89,19 @@ BadNoContinuationPoints,0x804B0000,The operation could not be processed because
 BadReferenceTypeIdInvalid,0x804C0000,The operation could not be processed because all continuation points have been allocated.
 BadBrowseDirectionInvalid,0x804D0000,The browse direction is not valid.
 BadNodeNotInView,0x804E0000,The node is not part of the view.
+BadNumericOverflow,0x81120000,The number was not accepted because of a numeric overflow.
 BadServerUriInvalid,0x804F0000,The ServerUri is not a valid URI.
 BadServerNameMissing,0x80500000,No ServerName was specified.
 BadDiscoveryUrlMissing,0x80510000,No DiscoveryUrl was specified.
 BadSempahoreFileMissing,0x80520000,The semaphore file specified by the client is not valid.
 BadRequestTypeInvalid,0x80530000,The security token request type is not valid.
-BadSecurityModeRejected,0x80540000,The security mode does not meet the requirements set by the Server.
-BadSecurityPolicyRejected,0x80550000,The security policy does not meet the requirements set by the Server.
+BadSecurityModeRejected,0x80540000,The security mode does not meet the requirements set by the server.
+BadSecurityPolicyRejected,0x80550000,The security policy does not meet the requirements set by the server.
 BadTooManySessions,0x80560000,The server has reached its maximum number of sessions.
 BadUserSignatureInvalid,0x80570000,The user token signature is missing or invalid.
 BadApplicationSignatureInvalid,0x80580000,The signature generated with the client certificate is missing or invalid.
 BadNoValidCertificates,0x80590000,The client did not provide at least one software certificate that is valid and meets the profile requirements for the server.
-BadIdentityChangeNotSupported,0x80C60000,The Server does not support changing the user identity assigned to the session.
+BadIdentityChangeNotSupported,0x80C60000,The server does not support changing the user identity assigned to the session.
 BadRequestCancelledByRequest,0x805A0000,The request was cancelled by the client with the Cancel service.
 BadParentNodeIdInvalid,0x805B0000,The parent node id does not to refer to a valid node.
 BadReferenceNotAllowed,0x805C0000,The reference could not be created because it violates constraints imposed by the data model.
@@ -131,24 +136,26 @@ BadSecurityModeInsufficient,0x80E60000,The operation is not permitted over the c
 BadHistoryOperationInvalid,0x80710000,The history details parameter is not valid.
 BadHistoryOperationUnsupported,0x80720000,The server does not support the requested operation.
 BadInvalidTimestampArgument,0x80BD0000,The defined timestamp to return was invalid.
-BadWriteNotSupported,0x80730000,The server not does support writing the combination of value, status and timestamps provided.
+BadWriteNotSupported,0x80730000,The server does not support writing the combination of value, status and timestamps provided.
 BadTypeMismatch,0x80740000,The value supplied for the attribute is not of the same type as the attribute's value.
 BadMethodInvalid,0x80750000,The method id does not refer to a method for the specified object.
 BadArgumentsMissing,0x80760000,The client did not specify all of the input arguments for the method.
+BadNotExecutable,0x81110000,The executable attribute does not allow the execution of the method.
 BadTooManySubscriptions,0x80770000,The server has reached its  maximum number of subscriptions.
 BadTooManyPublishRequests,0x80780000,The server has reached the maximum number of queued publish requests.
 BadNoSubscription,0x80790000,There is no subscription available for this session.
 BadSequenceNumberUnknown,0x807A0000,The sequence number is unknown to the server.
 BadMessageNotAvailable,0x807B0000,The requested notification message is no longer available.
-BadInsufficientClientProfile,0x807C0000,The Client of the current Session does not support one or more Profiles that are necessary for the Subscription.
+BadInsufficientClientProfile,0x807C0000,The client of the current session does not support one or more Profiles that are necessary for the subscription.
 BadStateNotActive,0x80BF0000,The sub-state machine is not currently active.
+BadAlreadyExists,0x81150000,An equivalent rule already exists.
 BadTcpServerTooBusy,0x807D0000,The server cannot process the request because it is too busy.
 BadTcpMessageTypeInvalid,0x807E0000,The type of the message specified in the header invalid.
 BadTcpSecureChannelUnknown,0x807F0000,The SecureChannelId and/or TokenId are not currently in use.
 BadTcpMessageTooLarge,0x80800000,The size of the message specified in the header is too large.
 BadTcpNotEnoughResources,0x80810000,There are not enough resources to process the request.
 BadTcpInternalError,0x80820000,An internal error occurred.
-BadTcpEndpointUrlInvalid,0x80830000,The Server does not recognize the QueryString specified.
+BadTcpEndpointUrlInvalid,0x80830000,The server does not recognize the QueryString specified.
 BadRequestInterrupted,0x80840000,The request could not be sent because of a network interruption.
 BadRequestTimeout,0x80850000,Timeout occurred while processing the request.
 BadSecureChannelClosed,0x80860000,The secure channel has been closed.
@@ -201,6 +208,7 @@ BadAggregateInvalidInputs,0x80D60000,The aggregate value could not be derived du
 BadAggregateConfigurationRejected,0x80DA0000,The aggregate configuration is not valid for specified node.
 GoodDataIgnored,0x00D90000,The request pecifies fields which are not valid for the EventType or cannot be saved by the historian.
 BadRequestNotAllowed,0x80E40000,The request was rejected by the server because it did not meet the criteria set by the server.
+BadRequestNotComplete,0x81130000,The request has not been processed by the server yet.
 GoodEdited,0x00DC0000,The value does not come from the real source and has been edited by the server.
 GoodPostActionFailed,0x00DD0000,There was an error in execution of these post-actions.
 UncertainDominantValueChanged,0x40DE0000,The related EngineeringUnit has been changed but the Variable Value is still provided based on the previous unit.