Bläddra i källkod

finish bootstrap

Julius Pfrommer 8 år sedan
förälder
incheckning
9d592f05a8

+ 2 - 0
include/ua_client.h

@@ -172,6 +172,7 @@ UA_Client_Service_write(UA_Client *client, const UA_WriteRequest request) {
 /**
  * Method Service Set
  * ^^^^^^^^^^^^^^^^^^ */
+#ifdef UA_ENABLE_METHODCALLS
 static UA_INLINE UA_CallResponse
 UA_Client_Service_call(UA_Client *client, const UA_CallRequest request) {
     UA_CallResponse response;
@@ -179,6 +180,7 @@ UA_Client_Service_call(UA_Client *client, const UA_CallRequest request) {
                         &response, &UA_TYPES[UA_TYPES_CALLRESPONSE]);
     return response;
 }
+#endif
 
 /**
  * NodeManagement Service Set

+ 4 - 0
src/client/ua_client_highlevel.c

@@ -211,6 +211,8 @@ __UA_Client_addNode(UA_Client *client, const UA_NodeClass nodeClass, const UA_No
 /* Call */
 /********/
 
+#ifdef UA_ENABLE_METHODCALLS
+
 UA_StatusCode
 UA_Client_call(UA_Client *client, const UA_NodeId objectId, const UA_NodeId methodId, size_t inputSize,
                const UA_Variant *input, size_t *outputSize, UA_Variant **output) {
@@ -247,6 +249,8 @@ UA_Client_call(UA_Client *client, const UA_NodeId objectId, const UA_NodeId meth
     return retval;
 }
 
+#endif
+
 /********************/
 /* Write Attributes */
 /********************/

+ 140 - 126
src/server/ua_server.c

@@ -342,10 +342,12 @@ static void copyNames(UA_Node *node, char *name) {
 }
 
 static void
-addDataTypeNode(UA_Server *server, char* name, UA_UInt32 datatypeid, UA_UInt32 parent) {
+addDataTypeNode(UA_Server *server, char* name, UA_UInt32 datatypeid,
+                UA_Boolean isAbstract, UA_UInt32 parent) {
     UA_DataTypeNode *datatype = UA_NodeStore_newDataTypeNode();
     copyNames((UA_Node*)datatype, name);
     datatype->nodeId.identifier.numeric = datatypeid;
+    datatype->isAbstract = isAbstract;
     addNodeInternal(server, (UA_Node*)datatype,
                     UA_NODEID_NUMERIC(0, parent), nodeIdHasSubType);
 }
@@ -478,12 +480,11 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
 
     server->startTime = UA_DateTime_now();
 
-    /**************/
-    /* References */
-    /**************/
-
 #ifndef UA_ENABLE_GENERATE_NAMESPACE0
-    /* Bootstrap reference hierarchy by manually inserting "references" and "hassubtype" */
+
+    /*********************************/
+    /* Bootstrap reference hierarchy */
+    /*********************************/
 
     UA_ReferenceTypeNode *references = UA_NodeStore_newReferenceTypeNode();
     copyNames((UA_Node*)references, "References");
@@ -491,10 +492,6 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
     references->isAbstract = true;
     references->symmetric = true;
     references->inverseName = UA_LOCALIZEDTEXT_ALLOC("en_US", "References");
-    /* The reference to root is later inserted */
-    UA_RCU_LOCK();
-    UA_NodeStore_insert(server->nodestore, (UA_Node*)references);
-    UA_RCU_UNLOCK();
 
     UA_ReferenceTypeNode *hassubtype = UA_NodeStore_newReferenceTypeNode();
     copyNames((UA_Node*)hassubtype, "HasSubtype");
@@ -502,12 +499,12 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
     hassubtype->nodeId.identifier.numeric = UA_NS0ID_HASSUBTYPE;
     hassubtype->isAbstract = false;
     hassubtype->symmetric = false;
-    /* The reference to root is later inserted */
+
     UA_RCU_LOCK();
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)references);
     UA_NodeStore_insert(server->nodestore, (UA_Node*)hassubtype);
     UA_RCU_UNLOCK();
 
-    /* Continue adding reference types with normal "addnode" */
     UA_ReferenceTypeNode *hierarchicalreferences = UA_NodeStore_newReferenceTypeNode();
     copyNames((UA_Node*)hierarchicalreferences, "HierarchicalReferences");
     hierarchicalreferences->nodeId.identifier.numeric = UA_NS0ID_HIERARCHICALREFERENCES;
@@ -592,13 +589,13 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
 
     UA_ReferenceTypeNode *aggregates = UA_NodeStore_newReferenceTypeNode();
     copyNames((UA_Node*)aggregates, "Aggregates");
-    // Todo: Is there an inverse name?
+    aggregates->inverseName = UA_LOCALIZEDTEXT_ALLOC("en_US", "AggregatedBy");
     aggregates->nodeId.identifier.numeric = UA_NS0ID_AGGREGATES;
     aggregates->isAbstract = false;
     aggregates->symmetric  = false;
     addNodeInternal(server, (UA_Node*)aggregates, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCHILD), nodeIdHasSubType);
 
-    // complete bootstrap of hassubtype
+    /* complete bootstrap of hassubtype */
     addReferenceInternal(server, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCHILD), nodeIdHasSubType,
                          UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE), true);
 
@@ -683,29 +680,127 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
     hashistoricalconfiguration->symmetric  = false;
     addNodeInternal(server, (UA_Node*)hashistoricalconfiguration, UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES), nodeIdHasSubType);
 
-    /********************/
-    /* Object Hierarchy */
-    /********************/
+    /**************/
+    /* Data Types */
+    /**************/
 
-    /* Bootstrap object hierarchy by manually inserting "root" and "baseobjecttype" */
-    UA_ObjectNode *root = UA_NodeStore_newObjectNode();
-    copyNames((UA_Node*)root, "Root");
-    root->nodeId.identifier.numeric = UA_NS0ID_ROOTFOLDER;
+    UA_DataTypeNode *basedatatype = UA_NodeStore_newDataTypeNode();
+    copyNames((UA_Node*)basedatatype, "BaseDataType");
+    basedatatype->nodeId.identifier.numeric = UA_NS0ID_BASEDATATYPE;
+    basedatatype->isAbstract = true;
+    UA_RCU_LOCK();
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)basedatatype);
+    UA_RCU_UNLOCK();
+
+    addDataTypeNode(server, "Boolean", UA_NS0ID_BOOLEAN, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "Number", UA_NS0ID_NUMBER, true, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "Float", UA_NS0ID_FLOAT, false, UA_NS0ID_NUMBER);
+    addDataTypeNode(server, "Double", UA_NS0ID_DOUBLE, false, UA_NS0ID_NUMBER);
+    addDataTypeNode(server, "Integer", UA_NS0ID_INTEGER, true, UA_NS0ID_NUMBER);
+       addDataTypeNode(server, "SByte", UA_NS0ID_SBYTE, false, UA_NS0ID_INTEGER);
+       addDataTypeNode(server, "Int16", UA_NS0ID_INT16, false, UA_NS0ID_INTEGER);
+       addDataTypeNode(server, "Int32", UA_NS0ID_INT32, false, UA_NS0ID_INTEGER);
+       addDataTypeNode(server, "Int64", UA_NS0ID_INT64, false, UA_NS0ID_INTEGER);
+       addDataTypeNode(server, "UInteger", UA_NS0ID_UINTEGER, true, UA_NS0ID_INTEGER);
+          addDataTypeNode(server, "Byte", UA_NS0ID_BYTE, false, UA_NS0ID_UINTEGER);
+          addDataTypeNode(server, "UInt16", UA_NS0ID_UINT16, false, UA_NS0ID_UINTEGER);
+          addDataTypeNode(server, "UInt32", UA_NS0ID_UINT32, false, UA_NS0ID_UINTEGER);
+          addDataTypeNode(server, "UInt64", UA_NS0ID_UINT64, false, UA_NS0ID_UINTEGER);
+    addDataTypeNode(server, "String", UA_NS0ID_STRING, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "DateTime", UA_NS0ID_DATETIME, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "Guid", UA_NS0ID_GUID, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "ByteString", UA_NS0ID_BYTESTRING, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "XmlElement", UA_NS0ID_XMLELEMENT, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "NodeId", UA_NS0ID_NODEID, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "ExpandedNodeId", UA_NS0ID_EXPANDEDNODEID, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "StatusCode", UA_NS0ID_STATUSCODE, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "QualifiedName", UA_NS0ID_QUALIFIEDNAME, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "LocalizedText", UA_NS0ID_LOCALIZEDTEXT, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "Structure", UA_NS0ID_STRUCTURE, true, UA_NS0ID_BASEDATATYPE);
+       addDataTypeNode(server, "ServerStatusDataType", UA_NS0ID_SERVERSTATUSDATATYPE, false, UA_NS0ID_STRUCTURE);
+       addDataTypeNode(server, "BuildInfo", UA_NS0ID_BUILDINFO, false, UA_NS0ID_STRUCTURE);
+    addDataTypeNode(server, "DataValue", UA_NS0ID_DATAVALUE, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "DiagnosticInfo", UA_NS0ID_DIAGNOSTICINFO, false, UA_NS0ID_BASEDATATYPE);
+    addDataTypeNode(server, "Enumeration", UA_NS0ID_ENUMERATION, true, UA_NS0ID_BASEDATATYPE);
+       addDataTypeNode(server, "ServerState", UA_NS0ID_SERVERSTATE, false, UA_NS0ID_ENUMERATION);
+
+    /*****************/
+    /* VariableTypes */
+    /*****************/
+
+    UA_VariableTypeNode *basevartype =
+        createVariableTypeNode(server, "BaseVariableType", UA_NS0ID_BASEVARIABLETYPE, true);
+    basevartype->valueRank = -2;
+    basevartype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
+    UA_RCU_LOCK();
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)basevartype);
+    UA_RCU_UNLOCK();
+
+    UA_VariableTypeNode *basedatavartype =
+        createVariableTypeNode(server, "BaseDataVariableType", UA_NS0ID_BASEDATAVARIABLETYPE, false);
+    basedatavartype->valueRank = -2;
+    basedatavartype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
+    addNodeInternalWithType(server, (UA_Node*)basedatavartype,
+                            UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE),
+                            nodeIdHasSubType, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE));
+
+    UA_VariableTypeNode *propertytype =
+        createVariableTypeNode(server, "PropertyType", UA_NS0ID_PROPERTYTYPE, false);
+    propertytype->valueRank = -2;
+    propertytype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
+    addNodeInternalWithType(server, (UA_Node*)propertytype,
+                            UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE),
+                            nodeIdHasSubType, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE));
+
+    UA_VariableTypeNode *buildinfotype =
+        createVariableTypeNode(server, "BuildInfoType", UA_NS0ID_BUILDINFOTYPE, false);
+    buildinfotype->valueRank = -1;
+    buildinfotype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BUILDINFO);
+    addNodeInternalWithType(server, (UA_Node*)buildinfotype,
+                            UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
+                            nodeIdHasSubType, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE));
+
+    UA_VariableTypeNode *serverstatustype =
+        createVariableTypeNode(server, "ServerStatusType", UA_NS0ID_SERVERSTATUSTYPE, false);
+    serverstatustype->valueRank = -1;
+    serverstatustype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERSTATUSDATATYPE);
+    addNodeInternalWithType(server, (UA_Node*)serverstatustype,
+                            UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
+                            nodeIdHasSubType, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE));
+
+    /**********************/
+    /* Basic Object Types */
+    /**********************/
 
     UA_ObjectTypeNode *baseobjtype = UA_NodeStore_newObjectTypeNode();
     copyNames((UA_Node*)baseobjtype, "BaseObjectType");
     baseobjtype->nodeId.identifier.numeric = UA_NS0ID_BASEOBJECTTYPE;
-
     UA_RCU_LOCK();
-    UA_NodeStore_insert(server->nodestore, (UA_Node*)root);
     UA_NodeStore_insert(server->nodestore, (UA_Node*)baseobjtype);
     UA_RCU_UNLOCK();
 
+    addObjectTypeNode(server, "FolderType", UA_NS0ID_FOLDERTYPE,
+                      UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
+    addObjectTypeNode(server, "ServerType", UA_NS0ID_SERVERTYPE,
+                      UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
+    addObjectTypeNode(server, "ServerDiagnosticsType", UA_NS0ID_SERVERDIAGNOSTICSTYPE,
+                      UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
+    addObjectTypeNode(server, "ServerCapatilitiesType", UA_NS0ID_SERVERCAPABILITIESTYPE,
+                      UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
+
+    /******************/
+    /* Root and below */
+    /******************/
+
+    UA_ObjectNode *root = UA_NodeStore_newObjectNode();
+    copyNames((UA_Node*)root, "Root");
+    root->nodeId.identifier.numeric = UA_NS0ID_ROOTFOLDER;
+    UA_RCU_LOCK();
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)root);
+    UA_RCU_UNLOCK();
     addReferenceInternal(server, UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER), nodeIdHasTypeDefinition,
                          UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), true);
 
-    addObjectTypeNode(server, "FolderType", UA_NS0ID_FOLDERTYPE, UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
-
     UA_ObjectNode *objects = UA_NodeStore_newObjectNode();
     copyNames((UA_Node*)objects, "Objects");
     objects->nodeId.identifier.numeric = UA_NS0ID_OBJECTSFOLDER;
@@ -718,130 +813,51 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
     addNodeInternalWithType(server, (UA_Node*)types, UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER),
                             nodeIdOrganizes, nodeIdFolderType);
 
-    UA_ObjectNode *views = UA_NodeStore_newObjectNode();
-    copyNames((UA_Node*)views, "Views");
-    views->nodeId.identifier.numeric = UA_NS0ID_VIEWSFOLDER;
-    addNodeInternalWithType(server, (UA_Node*)views, UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER),
-                            nodeIdOrganizes, nodeIdFolderType);
-
     UA_ObjectNode *referencetypes = UA_NodeStore_newObjectNode();
     copyNames((UA_Node*)referencetypes, "ReferenceTypes");
     referencetypes->nodeId.identifier.numeric = UA_NS0ID_REFERENCETYPESFOLDER;
     addNodeInternalWithType(server, (UA_Node*)referencetypes, UA_NODEID_NUMERIC(0, UA_NS0ID_TYPESFOLDER),
                             nodeIdOrganizes, nodeIdFolderType);
-
     addReferenceInternal(server, UA_NODEID_NUMERIC(0, UA_NS0ID_REFERENCETYPESFOLDER), nodeIdOrganizes,
                          UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_REFERENCES), true);
 
-    /**********************/
-    /* Basic Object Types */
-    /**********************/
-
-    UA_ObjectNode *objecttypes = UA_NodeStore_newObjectNode();
-    copyNames((UA_Node*)objecttypes, "ObjectTypes");
-    objecttypes->nodeId.identifier.numeric = UA_NS0ID_OBJECTTYPESFOLDER;
-    addNodeInternalWithType(server, (UA_Node*)objecttypes, UA_NODEID_NUMERIC(0, UA_NS0ID_TYPESFOLDER),
-                            nodeIdOrganizes, nodeIdFolderType);
-    /* Link in the bootstrapped baseobjecttype */
-    addReferenceInternal(server, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTTYPESFOLDER), nodeIdOrganizes,
-                         UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE), true);
-
-    addObjectTypeNode(server, "ServerType", UA_NS0ID_SERVERTYPE, UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
-    addObjectTypeNode(server, "ServerDiagnosticsType", UA_NS0ID_SERVERDIAGNOSTICSTYPE,
-                      UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
-    addObjectTypeNode(server, "ServerCapatilitiesType", UA_NS0ID_SERVERCAPABILITIESTYPE,
-                      UA_NS0ID_BASEOBJECTTYPE, UA_NS0ID_HASSUBTYPE);
-    addObjectTypeNode(server, "ServerStatusType", UA_NS0ID_SERVERSTATUSTYPE, UA_NS0ID_BASEOBJECTTYPE,
-                      UA_NS0ID_HASSUBTYPE);
-    addObjectTypeNode(server, "BuildInfoType", UA_NS0ID_BUILDINFOTYPE, UA_NS0ID_BASEOBJECTTYPE,
-                      UA_NS0ID_HASSUBTYPE);
-
-    /**************/
-    /* Data Types */
-    /**************/
-
     UA_ObjectNode *datatypes = UA_NodeStore_newObjectNode();
     copyNames((UA_Node*)datatypes, "DataTypes");
     datatypes->nodeId.identifier.numeric = UA_NS0ID_DATATYPESFOLDER;
     addNodeInternalWithType(server, (UA_Node*)datatypes, UA_NODEID_NUMERIC(0, UA_NS0ID_TYPESFOLDER),
                             nodeIdOrganizes, nodeIdFolderType);
-
-    addDataTypeNode(server, "BaseDataType", UA_NS0ID_BASEDATATYPE, UA_NS0ID_DATATYPESFOLDER);
-    addDataTypeNode(server, "Boolean", UA_NS0ID_BOOLEAN, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "Number", UA_NS0ID_NUMBER, UA_NS0ID_BASEDATATYPE);
-        addDataTypeNode(server, "Float", UA_NS0ID_FLOAT, UA_NS0ID_NUMBER);
-        addDataTypeNode(server, "Double", UA_NS0ID_DOUBLE, UA_NS0ID_NUMBER);
-        addDataTypeNode(server, "Integer", UA_NS0ID_INTEGER, UA_NS0ID_NUMBER);
-            addDataTypeNode(server, "SByte", UA_NS0ID_SBYTE, UA_NS0ID_INTEGER);
-            addDataTypeNode(server, "Int16", UA_NS0ID_INT16, UA_NS0ID_INTEGER);
-            addDataTypeNode(server, "Int32", UA_NS0ID_INT32, UA_NS0ID_INTEGER);
-            addDataTypeNode(server, "Int64", UA_NS0ID_INT64, UA_NS0ID_INTEGER);
-            addDataTypeNode(server, "UInteger", UA_NS0ID_UINTEGER, UA_NS0ID_INTEGER);
-                addDataTypeNode(server, "Byte", UA_NS0ID_BYTE, UA_NS0ID_UINTEGER);
-                addDataTypeNode(server, "UInt16", UA_NS0ID_UINT16, UA_NS0ID_UINTEGER);
-                addDataTypeNode(server, "UInt32", UA_NS0ID_UINT32, UA_NS0ID_UINTEGER);
-                addDataTypeNode(server, "UInt64", UA_NS0ID_UINT64, UA_NS0ID_UINTEGER);
-    addDataTypeNode(server, "String", UA_NS0ID_STRING, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "DateTime", UA_NS0ID_DATETIME, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "Guid", UA_NS0ID_GUID, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "ByteString", UA_NS0ID_BYTESTRING, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "XmlElement", UA_NS0ID_XMLELEMENT, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "NodeId", UA_NS0ID_NODEID, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "ExpandedNodeId", UA_NS0ID_EXPANDEDNODEID, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "StatusCode", UA_NS0ID_STATUSCODE, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "QualifiedName", UA_NS0ID_QUALIFIEDNAME, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "LocalizedText", UA_NS0ID_LOCALIZEDTEXT, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "Structure", UA_NS0ID_STRUCTURE, UA_NS0ID_BASEDATATYPE);
-        addDataTypeNode(server, "ServerStatusDataType", UA_NS0ID_SERVERSTATUSDATATYPE, UA_NS0ID_STRUCTURE);
-        addDataTypeNode(server, "BuildInfo", UA_NS0ID_BUILDINFO, UA_NS0ID_STRUCTURE);
-    addDataTypeNode(server, "DataValue", UA_NS0ID_DATAVALUE, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "DiagnosticInfo", UA_NS0ID_DIAGNOSTICINFO, UA_NS0ID_BASEDATATYPE);
-    addDataTypeNode(server, "Enumeration", UA_NS0ID_ENUMERATION, UA_NS0ID_BASEDATATYPE);
-        addDataTypeNode(server, "ServerState", UA_NS0ID_SERVERSTATE, UA_NS0ID_ENUMERATION);
+    addReferenceInternal(server, UA_NODEID_NUMERIC(0, UA_NS0ID_DATATYPESFOLDER), nodeIdOrganizes,
+                         UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE), true);
 
     UA_ObjectNode *variabletypes = UA_NodeStore_newObjectNode();
     copyNames((UA_Node*)variabletypes, "VariableTypes");
     variabletypes->nodeId.identifier.numeric = UA_NS0ID_VARIABLETYPESFOLDER;
     addNodeInternalWithType(server, (UA_Node*)variabletypes, UA_NODEID_NUMERIC(0, UA_NS0ID_TYPESFOLDER),
                             nodeIdOrganizes, nodeIdFolderType);
+    addReferenceInternal(server, UA_NODEID_NUMERIC(0, UA_NS0ID_VARIABLETYPESFOLDER), nodeIdOrganizes,
+                         UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE), true);
 
-    UA_VariableTypeNode *basevartype =
-        createVariableTypeNode(server, "BaseVariableType", UA_NS0ID_BASEVARIABLETYPE, true);
-    basevartype->valueRank = -2;
-    basevartype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
-    server->bootstrapInformationModel = true;
-    addNodeInternal(server, (UA_Node*)basevartype,
-                    UA_NODEID_NUMERIC(0, UA_NS0ID_VARIABLETYPESFOLDER), nodeIdOrganizes);
-    server->bootstrapInformationModel = false;
-
-    UA_VariableTypeNode *basedatavartype =
-        createVariableTypeNode(server, "BaseDataVariableType", UA_NS0ID_BASEDATAVARIABLETYPE, false);
-    basedatavartype->valueRank = -2;
-    basedatavartype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
-    addNodeInternalWithType(server, (UA_Node*)basedatavartype,
-                            UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE),
-                            nodeIdHasSubType, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE));
-
-    UA_VariableTypeNode *propertytype =
-        createVariableTypeNode(server, "PropertyType", UA_NS0ID_PROPERTYTYPE, false);
-    propertytype->valueRank = -2;
-    propertytype->dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
-    addNodeInternalWithType(server, (UA_Node*)propertytype,
-                            UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE),
-                            nodeIdHasSubType, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE));
-
-    /***************/
-    /* Event Types */
-    /***************/
+    UA_ObjectNode *objecttypes = UA_NodeStore_newObjectNode();
+    copyNames((UA_Node*)objecttypes, "ObjectTypes");
+    objecttypes->nodeId.identifier.numeric = UA_NS0ID_OBJECTTYPESFOLDER;
+    addNodeInternalWithType(server, (UA_Node*)objecttypes, UA_NODEID_NUMERIC(0, UA_NS0ID_TYPESFOLDER),
+                            nodeIdOrganizes, nodeIdFolderType);
+    addReferenceInternal(server, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTTYPESFOLDER), nodeIdOrganizes,
+                         UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE), true);
 
     UA_ObjectNode *eventtypes = UA_NodeStore_newObjectNode();
     copyNames((UA_Node*)eventtypes, "EventTypes");
     eventtypes->nodeId.identifier.numeric = UA_NS0ID_EVENTTYPESFOLDER;
     addNodeInternalWithType(server, (UA_Node*)eventtypes, UA_NODEID_NUMERIC(0, UA_NS0ID_TYPESFOLDER),
                             nodeIdOrganizes, nodeIdFolderType);
-#endif
 
-#ifdef UA_ENABLE_GENERATE_NAMESPACE0
+    UA_ObjectNode *views = UA_NodeStore_newObjectNode();
+    copyNames((UA_Node*)views, "Views");
+    views->nodeId.identifier.numeric = UA_NS0ID_VIEWSFOLDER;
+    addNodeInternalWithType(server, (UA_Node*)views, UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER),
+                            nodeIdOrganizes, nodeIdFolderType);
+
+#else
     /* load the generated namespace externally */
     ua_namespaceinit_generated(server);
 #endif
@@ -1020,7 +1036,7 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
     serverstatus->value.dataSource = (UA_DataSource) {.handle = server, .read = readStatus,
                                                       .write = NULL};
     addNodeInternalWithType(server, (UA_Node*)serverstatus, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER),
-                            nodeIdHasComponent, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERSTATUSTYPE));
+                            nodeIdHasComponent, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE));
 
     UA_VariableNode *starttime = UA_NodeStore_newVariableNode();
     copyNames((UA_Node*)starttime, "StartTime");
@@ -1225,9 +1241,7 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
         UA_QUALIFIEDNAME(0, "GetMonitoredItems"), addmethodattributes,
         GetMonitoredItems, /* callback of the method node */
         NULL, /* handle passed with the callback */
-        1, &inputArguments,
-        2, outputArguments,
-        NULL);
+        1, &inputArguments, 2, outputArguments, NULL);
 #endif
 
     return server;

+ 7 - 6
src/server/ua_server_binary.c

@@ -346,16 +346,15 @@ processOPN(UA_Connection *connection, UA_Server *server,
     if(connection->channel && channelId != connection->channel->securityToken.channelId)
         retval |= UA_STATUSCODE_BADREQUESTTYPEINVALID;
 
+    /* Decode the request */
     UA_AsymmetricAlgorithmSecurityHeader asymHeader;
-    retval |= UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, offset, &asymHeader);
-
     UA_SequenceHeader seqHeader;
-    retval |= UA_SequenceHeader_decodeBinary(msg, offset, &seqHeader);
-
     UA_NodeId requestType;
-    retval |= UA_NodeId_decodeBinary(msg, offset, &requestType);
-
     UA_OpenSecureChannelRequest r;
+
+    retval |= UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, offset, &asymHeader);
+    retval |= UA_SequenceHeader_decodeBinary(msg, offset, &seqHeader);
+    retval |= UA_NodeId_decodeBinary(msg, offset, &requestType);
     retval |= UA_OpenSecureChannelRequest_decodeBinary(msg, offset, &r);
 
     /* Could not decode or wrong service type */
@@ -592,9 +591,11 @@ processRequest(UA_SecureChannel *channel, UA_Server *server,
         UA_LOG_INFO_CHANNEL(server->config.logger, channel, "Could not send the message over "
                              "the SecureChannel with error code 0x%08x", retval);
 
+#ifdef UA_ENABLE_SUBSCRIPTIONS
     /* See if we need to return publish requests without a subscription */
     if(session && requestType == &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST])
         UA_Session_answerPublishRequestsWithoutSubscription(session);
+#endif
 
     /* Clean up */
     UA_deleteMembers(request, requestType);

+ 0 - 3
src/server/ua_server_internal.h

@@ -76,9 +76,6 @@ struct UA_Server {
     /* Config is the last element so that MSVC allows the usernamePasswordLogins
        field with zero-sized array */
     UA_ServerConfig config;
-
-    /* Disable some consistency checks when adding nodes */
-    UA_Boolean bootstrapInformationModel;
 };
 
 typedef UA_StatusCode (*UA_EditNodeCallback)(UA_Server*, UA_Session*, UA_Node*, const void*);

+ 11 - 12
src/server/ua_services_attribute.c

@@ -92,12 +92,11 @@ static const UA_String binEncoding = {sizeof("DefaultBinary")-1, (UA_Byte*)"Defa
 /* clang complains about unused variables */
 /* static const UA_String xmlEncoding = {sizeof("DefaultXml")-1, (UA_Byte*)"DefaultXml"}; */
 
-#define CHECK_NODECLASS(CLASS) do {                             \
+#define CHECK_NODECLASS(CLASS)                                  \
         if(!(node->nodeClass & (CLASS))) {                      \
             retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;       \
             break;                                              \
-        }                                                       \
-    }while(false)
+        }
 
 /* Reads a single attribute from a node in the nodestore */
 void Service_Read_single(UA_Server *server, UA_Session *session,
@@ -777,19 +776,19 @@ writeIsAbstractAttribute(UA_Node *node, UA_Boolean value) {
     return UA_STATUSCODE_GOOD;
 }
 
-#define CHECK_DATATYPE(EXP_DT) do {                                     \
-        if(!wvalue->value.hasValue ||                                   \
-           &UA_TYPES[UA_TYPES_##EXP_DT] != wvalue->value.value.type ||  \
-           !UA_Variant_isScalar(&wvalue->value.value)) {                \
-            retval = UA_STATUSCODE_BADTYPEMISMATCH;                     \
-            break;                                                      \
-        } }while(false)
+#define CHECK_DATATYPE(EXP_DT)                                          \
+    if(!wvalue->value.hasValue ||                                       \
+       &UA_TYPES[UA_TYPES_##EXP_DT] != wvalue->value.value.type ||      \
+       !UA_Variant_isScalar(&wvalue->value.value)) {                    \
+        retval = UA_STATUSCODE_BADTYPEMISMATCH;                         \
+        break;                                                          \
+    }
 
-#define CHECK_NODECLASS_WRITE(CLASS) do {                               \
+#define CHECK_NODECLASS_WRITE(CLASS)                                    \
     if((node->nodeClass & (CLASS)) == 0) {                              \
         retval = UA_STATUSCODE_BADNODECLASSINVALID;                     \
         break;                                                          \
-    } }while(false)
+    }
 
 /* this function implements the main part of the write service */
 static UA_StatusCode

+ 21 - 22
src/server/ua_services_nodemanagement.c

@@ -31,13 +31,11 @@ Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
     }
 
     /* See if the parent exists */
-    if(!server->bootstrapInformationModel) {
-        const UA_Node *parent = UA_NodeStore_get(server->nodestore, parentNodeId);
-        if(!parent) {
-            UA_LOG_DEBUG_SESSION(server->config.logger, session, "AddNodes: Parent node not found");
-            UA_NodeStore_deleteNode(node);
-            return UA_STATUSCODE_BADPARENTNODEIDINVALID;
-        }
+    const UA_Node *parent = UA_NodeStore_get(server->nodestore, parentNodeId);
+    if(!parent) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session, "AddNodes: Parent node not found");
+        UA_NodeStore_deleteNode(node);
+        return UA_STATUSCODE_BADPARENTNODEIDINVALID;
     }
 
     /* Check the referencetype to the parent */
@@ -379,7 +377,7 @@ instantiateVariableNode(UA_Server *server, UA_Session *session,
                                         &basevartype, &hassubtype, 1, &found);
     if(!found || retval != UA_STATUSCODE_GOOD) {
         UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "AddNodes: The object if not derived from BaseObjectType");
+                             "AddNodes: The variable is not derived from BaseVariableType");
         return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
     }
 
@@ -771,22 +769,21 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
     node->methodHandle = handle;
 
     /* Add the node */
-    UA_AddNodesResult result;
-    UA_AddNodesResult_init(&result);
+    UA_NodeId newMethodId;
+    UA_NodeId_init(&newMethodId);
     UA_RCU_LOCK();
     UA_StatusCode retval = Service_AddNodes_existing(server, &adminSession, (UA_Node*)node, &parentNodeId,
-                                                     &referenceTypeId, &UA_NODEID_NULL, NULL, outNewNodeId);
+                                                     &referenceTypeId, &UA_NODEID_NULL, NULL, &newMethodId);
     UA_RCU_UNLOCK();
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
 
-    UA_NodeId *parent = &result.addedNodeId;
     const UA_NodeId hasproperty = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY);
     const UA_NodeId propertytype = UA_NODEID_NUMERIC(0, UA_NS0ID_PROPERTYTYPE);
 
     if(inputArgumentsSize > 0) {
         UA_VariableNode *inputArgumentsVariableNode = UA_NodeStore_newVariableNode();
-        inputArgumentsVariableNode->nodeId.namespaceIndex = result.addedNodeId.namespaceIndex;
+        inputArgumentsVariableNode->nodeId.namespaceIndex = newMethodId.namespaceIndex;
         inputArgumentsVariableNode->browseName = UA_QUALIFIEDNAME_ALLOC(0, "InputArguments");
         inputArgumentsVariableNode->displayName = UA_LOCALIZEDTEXT_ALLOC("en_US", "InputArguments");
         inputArgumentsVariableNode->description = UA_LOCALIZEDTEXT_ALLOC("en_US", "InputArguments");
@@ -794,9 +791,8 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
         //TODO: 0.3 work item: the addMethodNode API does not have the possibility to set nodeIDs
         //actually we need to change the signature to pass UA_NS0ID_SERVER_GETMONITOREDITEMS_INPUTARGUMENTS
         //and UA_NS0ID_SERVER_GETMONITOREDITEMS_OUTPUTARGUMENTS into the function :/
-        if(result.addedNodeId.namespaceIndex == 0 &&
-           result.addedNodeId.identifierType == UA_NODEIDTYPE_NUMERIC &&
-           result.addedNodeId.identifier.numeric == UA_NS0ID_SERVER_GETMONITOREDITEMS) {
+        if(newMethodId.namespaceIndex == 0 && newMethodId.identifierType == UA_NODEIDTYPE_NUMERIC &&
+           newMethodId.identifier.numeric == UA_NS0ID_SERVER_GETMONITOREDITEMS) {
             inputArgumentsVariableNode->nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_GETMONITOREDITEMS_INPUTARGUMENTS);
         }
         UA_Variant_setArrayCopy(&inputArgumentsVariableNode->value.data.value.value, inputArguments,
@@ -805,22 +801,21 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
         UA_RCU_LOCK();
         // todo: check if adding succeeded
         Service_AddNodes_existing(server, &adminSession, (UA_Node*)inputArgumentsVariableNode,
-                                  parent, &hasproperty, &propertytype, NULL, NULL);
+                                  &newMethodId, &hasproperty, &propertytype, NULL, NULL);
         UA_RCU_UNLOCK();
     }
 
     if(outputArgumentsSize > 0) {
         /* create OutputArguments */
         UA_VariableNode *outputArgumentsVariableNode  = UA_NodeStore_newVariableNode();
-        outputArgumentsVariableNode->nodeId.namespaceIndex = result.addedNodeId.namespaceIndex;
+        outputArgumentsVariableNode->nodeId.namespaceIndex = newMethodId.namespaceIndex;
         outputArgumentsVariableNode->browseName  = UA_QUALIFIEDNAME_ALLOC(0, "OutputArguments");
         outputArgumentsVariableNode->displayName = UA_LOCALIZEDTEXT_ALLOC("en_US", "OutputArguments");
         outputArgumentsVariableNode->description = UA_LOCALIZEDTEXT_ALLOC("en_US", "OutputArguments");
         outputArgumentsVariableNode->valueRank = 1;
         //FIXME: comment in line 882
-        if(result.addedNodeId.namespaceIndex == 0 &&
-           result.addedNodeId.identifierType == UA_NODEIDTYPE_NUMERIC &&
-           result.addedNodeId.identifier.numeric == UA_NS0ID_SERVER_GETMONITOREDITEMS) {
+        if(newMethodId.namespaceIndex == 0 && newMethodId.identifierType == UA_NODEIDTYPE_NUMERIC &&
+           newMethodId.identifier.numeric == UA_NS0ID_SERVER_GETMONITOREDITEMS) {
             outputArgumentsVariableNode->nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_GETMONITOREDITEMS_OUTPUTARGUMENTS);
         }
         UA_Variant_setArrayCopy(&outputArgumentsVariableNode->value.data.value.value, outputArguments,
@@ -829,10 +824,14 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
         UA_RCU_LOCK();
         // todo: check if adding succeeded
         Service_AddNodes_existing(server, &adminSession, (UA_Node*)outputArgumentsVariableNode,
-                                  parent, &hasproperty, &propertytype, NULL, NULL);
+                                  &newMethodId, &hasproperty, &propertytype, NULL, NULL);
         UA_RCU_UNLOCK();
     }
 
+    if(outNewNodeId)
+        *outNewNodeId = newMethodId;
+    else
+        UA_NodeId_deleteMembers(&newMethodId);
     return retval;
 }
 

+ 2 - 0
src/ua_session.h

@@ -19,11 +19,13 @@ struct ContinuationPointEntry {
 struct UA_Subscription;
 typedef struct UA_Subscription UA_Subscription;
 
+#ifdef UA_ENABLE_SUBSCRIPTIONS
 typedef struct UA_PublishResponseEntry {
     SIMPLEQ_ENTRY(UA_PublishResponseEntry) listEntry;
     UA_UInt32 requestId;
     UA_PublishResponse response;
 } UA_PublishResponseEntry;
+#endif
 
 struct UA_Session {
     UA_ApplicationDescription clientDescription;