Ver código fonte

Merge pull request #1373 from heno-hms/topic-OperationLimits

Added support for OperationLimits
Stefan Profanter 7 anos atrás
pai
commit
1b975925a1

+ 13 - 0
include/ua_server_config.h

@@ -75,6 +75,19 @@ struct UA_ServerConfig {
     UA_UInt16 maxSessions;
     UA_Double maxSessionTimeout; /* in ms */
 
+    /* Operation limits */
+    UA_UInt32 maxNodesPerRead;
+    UA_UInt32 maxNodesPerWrite;
+    UA_UInt32 maxNodesPerMethodCall;
+    UA_UInt32 maxNodesPerBrowse;
+    UA_UInt32 maxNodesPerRegisterNodes;
+    UA_UInt32 maxNodesPerTranslateBrowsePathsToNodeIds;
+    UA_UInt32 maxNodesPerNodeManagement;
+    UA_UInt32 maxMonitoredItemsPerCall;
+
+    /* Limits for Requests */
+    UA_UInt32 maxReferencesPerNode;
+
     /* Limits for Subscriptions */
     UA_DurationRange publishingIntervalLimits;
     UA_UInt32Range lifeTimeCountLimits;

+ 32 - 0
src/server/ua_server_ns0.c

@@ -688,6 +688,38 @@ UA_Server_initNS0(UA_Server *server) {
     retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANCYSUPPORT,
                                &redundancySupport, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]);
 
+    /* ServerCapabilities - OperationLimits - MaxNodesPerRead */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD,
+                               &server->config.maxNodesPerRead, &UA_TYPES[UA_TYPES_UINT32]);
+
+    /* ServerCapabilities - OperationLimits - maxNodesPerWrite */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERWRITE,
+                               &server->config.maxNodesPerWrite, &UA_TYPES[UA_TYPES_UINT32]);
+
+    /* ServerCapabilities - OperationLimits - MaxNodesPerMethodCall */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERMETHODCALL,
+                               &server->config.maxNodesPerMethodCall, &UA_TYPES[UA_TYPES_UINT32]);
+
+    /* ServerCapabilities - OperationLimits - MaxNodesPerBrowse */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERBROWSE,
+                               &server->config.maxNodesPerBrowse, &UA_TYPES[UA_TYPES_UINT32]);
+
+    /* ServerCapabilities - OperationLimits - MaxNodesPerRegisterNodes */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREGISTERNODES,
+                               &server->config.maxNodesPerRegisterNodes, &UA_TYPES[UA_TYPES_UINT32]);
+
+    /* ServerCapabilities - OperationLimits - MaxNodesPerTranslateBrowsePathsToNodeIds */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS,
+                               &server->config.maxNodesPerTranslateBrowsePathsToNodeIds, &UA_TYPES[UA_TYPES_UINT32]);
+
+    /* ServerCapabilities - OperationLimits - MaxNodesPerNodeManagement */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT,
+                               &server->config.maxNodesPerNodeManagement, &UA_TYPES[UA_TYPES_UINT32]);
+
+    /* ServerCapabilities - OperationLimits - MaxMonitoredItemsPerCall */
+    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL,
+                               &server->config.maxMonitoredItemsPerCall, &UA_TYPES[UA_TYPES_UINT32]);
+
 #if defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS)
     retVal |= UA_Server_setMethodNode_callback(server,
                         UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_GETMONITOREDITEMS), readMonitoredItems);

+ 12 - 0
src/server/ua_services_attribute.c

@@ -359,6 +359,12 @@ void Service_Read(UA_Server *server, UA_Session *session,
         return;
     }
 
+    if(server->config.maxNodesPerRead != 0 &&
+       request->nodesToReadSize > server->config.maxNodesPerRead) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
                   (UA_ServiceOperation)Operation_Read,
@@ -1190,6 +1196,12 @@ Service_Write(UA_Server *server, UA_Session *session,
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing WriteRequest");
 
+    if(server->config.maxNodesPerWrite != 0 &&
+       request->nodesToWriteSize > server->config.maxNodesPerWrite) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
                   (UA_ServiceOperation)Operation_Write,

+ 6 - 0
src/server/ua_services_call.c

@@ -233,6 +233,12 @@ void Service_Call(UA_Server *server, UA_Session *session,
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing CallRequest");
 
+    if(server->config.maxNodesPerMethodCall != 0 &&
+       request->methodsToCallSize > server->config.maxNodesPerMethodCall) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
                   (UA_ServiceOperation)Operation_CallMethod,

+ 28 - 0
src/server/ua_services_nodemanagement.c

@@ -967,6 +967,13 @@ Service_AddNodes(UA_Server *server, UA_Session *session,
                       UA_AddNodesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing AddNodesRequest");
+
+    if(server->config.maxNodesPerNodeManagement != 0 &&
+       request->nodesToAddSize > server->config.maxNodesPerNodeManagement) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
                   (UA_ServiceOperation)Service_AddNode,
@@ -1186,6 +1193,13 @@ void Service_DeleteNodes(UA_Server *server, UA_Session *session,
                          UA_DeleteNodesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing DeleteNodesRequest");
+
+    if(server->config.maxNodesPerNodeManagement != 0 &&
+       request->nodesToDeleteSize > server->config.maxNodesPerNodeManagement) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult =
         UA_Server_processServiceOperations(server, session,
                                            (UA_ServiceOperation)deleteNodeOperation,
@@ -1274,6 +1288,13 @@ void Service_AddReferences(UA_Server *server, UA_Session *session,
                            UA_AddReferencesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing AddReferencesRequest");
+
+    if(server->config.maxNodesPerNodeManagement != 0 &&
+       request->referencesToAddSize > server->config.maxNodesPerNodeManagement) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult =
         UA_Server_processServiceOperations(server, session,
                                            (UA_ServiceOperation) addReference,
@@ -1340,6 +1361,13 @@ Service_DeleteReferences(UA_Server *server, UA_Session *session,
                          UA_DeleteReferencesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing DeleteReferencesRequest");
+
+    if(server->config.maxNodesPerNodeManagement != 0 &&
+       request->referencesToDeleteSize > server->config.maxNodesPerNodeManagement) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult =
         UA_Server_processServiceOperations(server, session,
                                            (UA_ServiceOperation) deleteReference,

+ 24 - 0
src/server/ua_services_subscription.c

@@ -279,6 +279,12 @@ Service_CreateMonitoredItems(UA_Server *server, UA_Session *session,
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing CreateMonitoredItemsRequest");
 
+    if(server->config.maxMonitoredItemsPerCall != 0 &&
+       request->itemsToCreateSize > server->config.maxMonitoredItemsPerCall) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     /* Check if the timestampstoreturn is valid */
     op_timestampsToReturn2 = request->timestampsToReturn;
     if(op_timestampsToReturn2 > UA_TIMESTAMPSTORETURN_NEITHER) {
@@ -327,6 +333,12 @@ void Service_ModifyMonitoredItems(UA_Server *server, UA_Session *session,
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing ModifyMonitoredItemsRequest");
 
+    if(server->config.maxMonitoredItemsPerCall != 0 &&
+       request->itemsToModifySize > server->config.maxMonitoredItemsPerCall) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     /* Check if the timestampstoreturn is valid */
     if(request->timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID;
@@ -380,6 +392,12 @@ void Service_SetMonitoringMode(UA_Server *server, UA_Session *session,
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing SetMonitoringMode");
 
+    if(server->config.maxMonitoredItemsPerCall != 0 &&
+       request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     /* Get the subscription */
     op_sub = UA_Session_getSubscriptionByID(session, request->subscriptionId);
     if(!op_sub) {
@@ -558,6 +576,12 @@ void Service_DeleteMonitoredItems(UA_Server *server, UA_Session *session,
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing DeleteMonitoredItemsRequest");
 
+    if(server->config.maxMonitoredItemsPerCall != 0 &&
+       request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     /* Get the subscription */
     op_sub = UA_Session_getSubscriptionByID(session, request->subscriptionId);
     if(!op_sub) {

+ 38 - 2
src/server/ua_services_view.c

@@ -72,8 +72,17 @@ browseReferences(UA_Server *server, const UA_Node *node,
 
     /* How many references can we return at most? */
     size_t maxrefs = cp->maxReferences;
-    if(maxrefs == 0)
-        maxrefs = UA_INT32_MAX;
+    if(maxrefs == 0) {
+        if(server->config.maxReferencesPerNode != 0) {
+            maxrefs = server->config.maxReferencesPerNode;
+        } else {
+            maxrefs = UA_INT32_MAX;
+        }
+    } else {
+        if(server->config.maxReferencesPerNode != 0 && maxrefs > server->config.maxReferencesPerNode) {
+            maxrefs = server->config.maxReferencesPerNode;
+        }
+    }
 
     /* Allocate the results array */
     size_t refs_size = 2; /* True size of the array */
@@ -127,6 +136,8 @@ browseReferences(UA_Server *server, const UA_Node *node,
             /* Make enough space in the array */
             if(result->referencesSize >= refs_size) {
                 refs_size *= 2;
+                if(refs_size > maxrefs)
+                    refs_size = maxrefs;
                 UA_ReferenceDescription *rd = (UA_ReferenceDescription*)
                     UA_realloc(result->references, sizeof(UA_ReferenceDescription) * refs_size);
                 if(!rd) {
@@ -296,6 +307,12 @@ void Service_Browse(UA_Server *server, UA_Session *session,
         return;
     }
 
+    if(server->config.maxNodesPerBrowse != 0 &&
+       request->nodesToBrowseSize > server->config.maxNodesPerBrowse) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     size_t size = request->nodesToBrowseSize;
     response->results =
         (UA_BrowseResult*)UA_Array_new(size, &UA_TYPES[UA_TYPES_BROWSERESULT]);
@@ -679,6 +696,13 @@ Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
                                       UA_TranslateBrowsePathsToNodeIdsResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
                          "Processing TranslateBrowsePathsToNodeIdsRequest");
+
+    if(server->config.maxNodesPerTranslateBrowsePathsToNodeIds != 0 &&
+       request->browsePathsSize > server->config.maxNodesPerTranslateBrowsePathsToNodeIds) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
                   (UA_ServiceOperation)Operation_TranslateBrowsePathToNodeIds,
@@ -698,6 +722,12 @@ void Service_RegisterNodes(UA_Server *server, UA_Session *session,
         return;
     }
 
+    if(server->config.maxNodesPerRegisterNodes != 0 &&
+       request->nodesToRegisterSize > server->config.maxNodesPerRegisterNodes) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
+
     response->responseHeader.serviceResult =
         UA_Array_copy(request->nodesToRegister, request->nodesToRegisterSize,
                       (void**)&response->registeredNodeIds, &UA_TYPES[UA_TYPES_NODEID]);
@@ -714,4 +744,10 @@ void Service_UnregisterNodes(UA_Server *server, UA_Session *session,
     //TODO: remove the nodeids from the session if really needed
     if(request->nodesToUnregisterSize == 0)
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
+
+    if(server->config.maxNodesPerRegisterNodes != 0 &&
+       request->nodesToUnregisterSize > server->config.maxNodesPerRegisterNodes) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
+        return;
+    }
 }

+ 186 - 10
tools/schema/Opc.Ua.NodeSet2.Minimal.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
-<UANodeSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" LastModified="2013-12-02T00:00:00Z" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd">
+<UANodeSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" LastModified="2016-12-31T00:00:00Z" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd">
   <Models>
-    <Model ModelUri="http://opcfoundation.org/UA/" Version="1.03" PublicationDate="2013-12-02T00:00:00Z" />
+    <Model ModelUri="http://opcfoundation.org/UA/" Version="1.04" PublicationDate="2016-12-31T00:00:00Z" />
   </Models>
   <Aliases>
     <Alias Alias="Boolean">i=1</Alias>
@@ -255,16 +255,16 @@
       <Reference ReferenceType="HasSubtype" IsForward="false">i=24</Reference>
     </References>
   </UADataType>
-  <UADataType NodeId="i=30" BrowseName="Image">
+  <UADataType NodeId="i=30" BrowseName="Image" IsAbstract="true">
     <DisplayName>Image</DisplayName>
     <Description>Describes a value that is an image encoded as a string of bytes.</Description>
     <References>
       <Reference ReferenceType="HasSubtype" IsForward="false">i=15</Reference>
     </References>
   </UADataType>
-  <UADataType NodeId="i=121" BrowseName="Decimal128">
-    <DisplayName>Decimal128</DisplayName>
-    <Description>Describes a 128-bit decimal value.</Description>
+  <UADataType NodeId="i=50" BrowseName="Decimal">
+    <DisplayName>Decimal</DisplayName>
+    <Description>Describes an arbitrary precision decimal value.</Description>
     <References>
       <Reference ReferenceType="HasSubtype" IsForward="false">i=26</Reference>
     </References>
@@ -290,7 +290,7 @@
     </References>
     <InverseName>HierarchicalReferences</InverseName>
   </UAReferenceType>
-  <UAReferenceType NodeId="i=34" BrowseName="HasChild">
+  <UAReferenceType NodeId="i=34" BrowseName="HasChild" IsAbstract="true">
     <DisplayName>HasChild</DisplayName>
     <Description>The abstract base type for all non-looping hierarchical references.</Description>
     <References>
@@ -352,9 +352,9 @@
     <References>
       <Reference ReferenceType="HasSubtype" IsForward="false">i=32</Reference>
     </References>
-    <InverseName>GeneratesEvent</InverseName>
+    <InverseName>GeneratedBy</InverseName>
   </UAReferenceType>
-  <UAReferenceType NodeId="i=44" BrowseName="Aggregates">
+  <UAReferenceType NodeId="i=44" BrowseName="Aggregates" IsAbstract="true">
     <DisplayName>Aggregates</DisplayName>
     <Description>The type for non-looping hierarchical references that are used to aggregate nodes into complex types.</Description>
     <References>
@@ -777,6 +777,15 @@
       <Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
     </References>
   </UAObjectType>
+  <UAObject NodeId="i=11551" BrowseName="OperationLimits" ParentNodeId="i=2013">
+    <DisplayName>OperationLimits</DisplayName>
+    <Description>Defines the limits supported by the server for different operations.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=11564</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=2013</Reference>
+    </References>
+  </UAObject>
   <UAObjectType NodeId="i=2020" BrowseName="ServerDiagnosticsType">
     <DisplayName>ServerDiagnosticsType</DisplayName>
     <Description>The diagnostics information for a server.</Description>
@@ -801,6 +810,93 @@
       <Reference ReferenceType="HasProperty" IsForward="false">i=2034</Reference>
     </References>
   </UAVariable>
+  <UAObjectType NodeId="i=11564" BrowseName="OperationLimitsType">
+    <DisplayName>OperationLimitsType</DisplayName>
+    <Description>Identifies the operation limits imposed by the server.</Description>
+    <References>
+      <Reference ReferenceType="HasProperty">i=11565</Reference>
+      <Reference ReferenceType="HasProperty">i=11567</Reference>
+      <Reference ReferenceType="HasProperty">i=11569</Reference>
+      <Reference ReferenceType="HasProperty">i=11570</Reference>
+      <Reference ReferenceType="HasProperty">i=11571</Reference>
+      <Reference ReferenceType="HasProperty">i=11572</Reference>
+      <Reference ReferenceType="HasProperty">i=11573</Reference>
+      <Reference ReferenceType="HasProperty">i=11574</Reference>
+      <Reference ReferenceType="HasSubtype" IsForward="false">i=61</Reference>
+    </References>
+  </UAObjectType>
+  <UAVariable NodeId="i=11565" BrowseName="MaxNodesPerRead" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxNodesPerRead</DisplayName>
+    <Description>The maximum number of operations in a single Read request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11567" BrowseName="MaxNodesPerWrite" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxNodesPerWrite</DisplayName>
+    <Description>The maximum number of operations in a single Write request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11569" BrowseName="MaxNodesPerMethodCall" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxNodesPerMethodCall</DisplayName>
+    <Description>The maximum number of operations in a single Call request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11570" BrowseName="MaxNodesPerBrowse" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxNodesPerBrowse</DisplayName>
+    <Description>The maximum number of operations in a single Browse request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11571" BrowseName="MaxNodesPerRegisterNodes" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxNodesPerRegisterNodes</DisplayName>
+    <Description>The maximum number of operations in a single RegisterNodes request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11572" BrowseName="MaxNodesPerTranslateBrowsePathsToNodeIds" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxNodesPerTranslateBrowsePathsToNodeIds</DisplayName>
+    <Description>The maximum number of operations in a single TranslateBrowsePathsToNodeIds request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11573" BrowseName="MaxNodesPerNodeManagement" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxNodesPerNodeManagement</DisplayName>
+    <Description>The maximum number of operations in a single AddNodes, AddReferences, DeleteNodes or DeleteReferences request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11574" BrowseName="MaxMonitoredItemsPerCall" ParentNodeId="i=11564" DataType="UInt32">
+    <DisplayName>MaxMonitoredItemsPerCall</DisplayName>
+    <Description>The maximum number of operations in a single MonitoredItem related request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11564</Reference>
+    </References>
+  </UAVariable>
   <UAVariableType NodeId="i=2138" BrowseName="ServerStatusType" DataType="i=862">
     <DisplayName>ServerStatusType</DisplayName>
     <References>
@@ -1138,6 +1234,86 @@
       <Reference ReferenceType="HasProperty" IsForward="false">i=2268</Reference>
     </References>
   </UAVariable>
+  <UAObject NodeId="i=11704" BrowseName="OperationLimits" ParentNodeId="i=2268">
+    <DisplayName>OperationLimits</DisplayName>
+    <Description>Defines the limits supported by the server for different operations.</Description>
+    <References>
+      <Reference ReferenceType="HasProperty">i=11705</Reference>
+      <Reference ReferenceType="HasProperty">i=11707</Reference>
+      <Reference ReferenceType="HasProperty">i=11709</Reference>
+      <Reference ReferenceType="HasProperty">i=11710</Reference>
+      <Reference ReferenceType="HasProperty">i=11711</Reference>
+      <Reference ReferenceType="HasProperty">i=11712</Reference>
+      <Reference ReferenceType="HasProperty">i=11713</Reference>
+      <Reference ReferenceType="HasProperty">i=11714</Reference>
+      <Reference ReferenceType="HasTypeDefinition">i=11564</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=2268</Reference>
+    </References>
+  </UAObject>
+  <UAVariable NodeId="i=11705" BrowseName="MaxNodesPerRead" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxNodesPerRead</DisplayName>
+    <Description>The maximum number of operations in a single Read request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11707" BrowseName="MaxNodesPerWrite" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxNodesPerWrite</DisplayName>
+    <Description>The maximum number of operations in a single Write request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11709" BrowseName="MaxNodesPerMethodCall" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxNodesPerMethodCall</DisplayName>
+    <Description>The maximum number of operations in a single Call request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11710" BrowseName="MaxNodesPerBrowse" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxNodesPerBrowse</DisplayName>
+    <Description>The maximum number of operations in a single Browse request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11711" BrowseName="MaxNodesPerRegisterNodes" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxNodesPerRegisterNodes</DisplayName>
+    <Description>The maximum number of operations in a single RegisterNodes request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11712" BrowseName="MaxNodesPerTranslateBrowsePathsToNodeIds" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxNodesPerTranslateBrowsePathsToNodeIds</DisplayName>
+    <Description>The maximum number of operations in a single TranslateBrowsePathsToNodeIds request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11713" BrowseName="MaxNodesPerNodeManagement" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxNodesPerNodeManagement</DisplayName>
+    <Description>The maximum number of operations in a single AddNodes, AddReferences, DeleteNodes or DeleteReferences request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=11714" BrowseName="MaxMonitoredItemsPerCall" ParentNodeId="i=11704" DataType="UInt32">
+    <DisplayName>MaxMonitoredItemsPerCall</DisplayName>
+    <Description>The maximum number of operations in a single MonitoredItem related request.</Description>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=11704</Reference>
+    </References>
+  </UAVariable>
   <UAObject NodeId="i=2274" BrowseName="ServerDiagnostics" ParentNodeId="i=2253">
     <DisplayName>ServerDiagnostics</DisplayName>
     <Description>Reports diagnostics about the server.</Description>
@@ -1252,7 +1428,7 @@
       <Reference ReferenceType="HasComponent" IsForward="false">i=2275</Reference>
     </References>
   </UAVariable>
-  <UAVariable NodeId="i=2294" BrowseName="EnabledFlag" ParentNodeId="i=2274" DataType="Boolean" AccessLevel="3" UserAccessLevel="3">
+  <UAVariable NodeId="i=2294" BrowseName="EnabledFlag" ParentNodeId="i=2274" DataType="Boolean" AccessLevel="3">
     <DisplayName>EnabledFlag</DisplayName>
     <Description>If TRUE the diagnostics collection is enabled.</Description>
     <References>