Selaa lähdekoodia

Created Serverside UA_Server_getAttributeValue() function; we now have symmetric get|set proxies for all attributes on server|client.

ichrispa 9 vuotta sitten
vanhempi
commit
c263c4335e
2 muutettua tiedostoa jossa 179 lisäystä ja 6 poistoa
  1. 2 0
      include/ua_server.h
  2. 177 6
      src/server/ua_server_addressspace.c

+ 2 - 0
include/ua_server.h

@@ -305,6 +305,8 @@ UA_StatusCode UA_EXPORT UA_Server_forEachChildNodeCall(UA_Server *server, UA_Nod
 
 UA_StatusCode UA_EXPORT UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, UA_AttributeId attributeId, void *value);
 
+UA_StatusCode UA_EXPORT UA_Server_getAttributeValue(UA_Server *server, UA_NodeId nodeId, UA_AttributeId attributeId, void **value);
+
 /** Jobs describe work that is executed once or repeatedly. */
 typedef struct {
     enum {

+ 177 - 6
src/server/ua_server_addressspace.c

@@ -866,7 +866,7 @@ UA_StatusCode UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, U
   
   UA_UInt32  *nInt;
   UA_Boolean *nBool;
-  UA_Boolean *nByte;
+  UA_Byte    *nByte;
   UA_Variant *nVariant;
   UA_Double  *nDouble;
   switch(attributeId) {
@@ -937,7 +937,7 @@ UA_StatusCode UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, U
       break;
     case UA_ATTRIBUTEID_EVENTNOTIFIER:
       SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT)
-      nByte = value;
+      nByte = (UA_Byte *) value;
       switch(anyTypeNode.node->nodeClass) {
         case UA_NODECLASS_VIEW:
           anyTypeNode.vwObj->eventNotifier = *nByte;
@@ -975,13 +975,13 @@ UA_StatusCode UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, U
       break;
     case UA_ATTRIBUTEID_ACCESSLEVEL:
       SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE)
-      nInt = (UA_UInt32*) value;
-      anyTypeNode.node->userWriteMask = *nInt;
+      nByte = (UA_Byte*) value;
+      anyTypeNode.vObj->accessLevel = *nByte;
       break;
     case UA_ATTRIBUTEID_USERACCESSLEVEL:
       SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE)
-      nInt = (UA_UInt32*) value;
-      anyTypeNode.node->userWriteMask = *nInt;
+      nByte = (UA_Byte*) value;
+      anyTypeNode.vObj->userAccessLevel = *nByte;
       break;
     case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
       SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE)
@@ -1003,6 +1003,10 @@ UA_StatusCode UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, U
       nBool = (UA_Boolean *) value;
       anyTypeNode.mObj->userExecutable= *nBool;
       break;
+    default:
+      UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+      return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+      break;
   }
   
   const UA_Node *oldNode = UA_NodeStore_get(server->nodestore, &nodeId);
@@ -1014,4 +1018,171 @@ UA_StatusCode UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, U
   //UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
   return retval;
 }
+
+#define SERVER_GETATTRIBUTE_COPYTYPEVALUE(TYPE, SRC) \
+  *value = (void *) UA_##TYPE##_new();               \
+  UA_##TYPE##_copy( SRC, (UA_##TYPE *) *value  );    \
+  
+UA_StatusCode UA_Server_getAttributeValue(UA_Server *server, UA_NodeId nodeId, UA_AttributeId attributeId, void **value) {
+  union {
+    UA_Node *node;
+    UA_ObjectNode *oObj;
+    UA_ObjectTypeNode *otObj;
+    UA_VariableNode *vObj;
+    UA_VariableTypeNode *vtObj;
+    UA_ReferenceTypeNode *rtObj;
+    UA_MethodNode *mObj;
+    UA_DataTypeNode *dtObj;
+    UA_ViewNode *vwObj;
+  } anyTypeNode;
+  
+  UA_StatusCode retval = UA_Server_getNodeCopy(server, nodeId, (void **) &anyTypeNode.node);
+  if (retval != UA_STATUSCODE_GOOD)
+    return retval;
+  
+  switch(attributeId) {
+    case UA_ATTRIBUTEID_NODEID:
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(NodeId, &anyTypeNode.node->nodeId);
+      break;
+    case UA_ATTRIBUTEID_NODECLASS:
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(NodeClass, &anyTypeNode.node->nodeClass);
+      break;
+    case UA_ATTRIBUTEID_BROWSENAME:
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(QualifiedName, &anyTypeNode.node->browseName);
+      break;
+    case UA_ATTRIBUTEID_DISPLAYNAME:
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(LocalizedText, &anyTypeNode.node->displayName);
+      break;
+    case UA_ATTRIBUTEID_DESCRIPTION:
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(LocalizedText, &anyTypeNode.node->description);
+      break;
+    case UA_ATTRIBUTEID_WRITEMASK:
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(UInt32, &anyTypeNode.node->writeMask);
+      break;
+    case UA_ATTRIBUTEID_USERWRITEMASK:
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(UInt32, &anyTypeNode.node->userWriteMask);
+      break;    
+    case UA_ATTRIBUTEID_ISABSTRACT:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_OBJECTTYPE | UA_NODECLASS_REFERENCETYPE | UA_NODECLASS_VARIABLETYPE | UA_NODECLASS_DATATYPE)
+      switch(anyTypeNode.node->nodeClass) {
+        case UA_NODECLASS_OBJECTTYPE:
+          SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.otObj->isAbstract);
+          break;
+        case UA_NODECLASS_REFERENCETYPE:
+          SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.rtObj->isAbstract);
+          break;
+        case UA_NODECLASS_VARIABLETYPE:
+          SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.vtObj->isAbstract);
+          break;
+        case UA_NODECLASS_DATATYPE:
+          SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.dtObj->isAbstract);
+          break;
+        default:
+          UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+          return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+          break;
+      }
+      break;
+    case UA_ATTRIBUTEID_SYMMETRIC:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_REFERENCETYPE)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.rtObj->symmetric);
+      break;
+    case UA_ATTRIBUTEID_INVERSENAME:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_REFERENCETYPE)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(LocalizedText, &anyTypeNode.rtObj->inverseName);
+      break;
+    case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VIEW)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.vwObj->containsNoLoops);
+      break;
+    case UA_ATTRIBUTEID_EVENTNOTIFIER:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT)
+      switch(anyTypeNode.node->nodeClass) {
+        case UA_NODECLASS_VIEW:
+          SERVER_GETATTRIBUTE_COPYTYPEVALUE(Byte, &anyTypeNode.vwObj->eventNotifier);
+          break;
+        case UA_NODECLASS_OBJECT:
+          SERVER_GETATTRIBUTE_COPYTYPEVALUE(Byte, &anyTypeNode.oObj->eventNotifier);
+          break;
+        default:
+          UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+          return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+          break;
+      }
+      break;
+    case UA_ATTRIBUTEID_VALUE:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE)
+      switch(anyTypeNode.node->nodeClass) {
+        case UA_NODECLASS_VARIABLE:
+          *value = UA_Variant_new();
+          if(anyTypeNode.vObj->valueSource == UA_VALUESOURCE_VARIANT) {
+            retval |= UA_Variant_copy(&anyTypeNode.vObj->value.variant, *value);
+          } else {
+            UA_DataValue ds;
+            UA_DataValue_init(&ds);
+            retval |= anyTypeNode.vObj->value.dataSource.read(anyTypeNode.vObj->value.dataSource.handle, UA_FALSE, UA_NULL, &ds);
+            UA_Variant_copy(&ds.value, *value);
+          }
+          break;
+        case UA_NODECLASS_VARIABLETYPE:
+          // Note: Precicely the same as variableNode above!
+          *value = UA_Variant_new();
+          if(anyTypeNode.vtObj->valueSource == UA_VALUESOURCE_VARIANT) {
+            retval |= UA_Variant_copy(&anyTypeNode.vtObj->value.variant, *value);
+          } else {
+            UA_DataValue ds;
+            UA_DataValue_init(&ds);
+            retval |= anyTypeNode.vtObj->value.dataSource.read(anyTypeNode.vtObj->value.dataSource.handle, UA_FALSE, UA_NULL, &ds);
+            UA_Variant_copy(&ds.value, *value);
+          }
+          break;
+        default:
+          UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+          return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+      }
+      break;
+    case UA_ATTRIBUTEID_DATATYPE:
+      UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+      return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+      break;
+    case UA_ATTRIBUTEID_VALUERANK:
+      UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+      return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+      break;
+    case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
+      UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+      return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+      break;
+    case UA_ATTRIBUTEID_ACCESSLEVEL:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Byte, &anyTypeNode.vObj->accessLevel);
+      break;
+    case UA_ATTRIBUTEID_USERACCESSLEVEL:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Byte, &anyTypeNode.vObj->userAccessLevel);
+      break;
+    case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Double, &anyTypeNode.vObj->minimumSamplingInterval);
+      break;
+    case UA_ATTRIBUTEID_HISTORIZING:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_VARIABLE)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.vObj->historizing);
+      break;
+    case UA_ATTRIBUTEID_EXECUTABLE:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_METHOD)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.mObj->executable);
+      break;
+    case UA_ATTRIBUTEID_USEREXECUTABLE:
+      SETATTRIBUTE_ASSERTNODECLASS(UA_NODECLASS_METHOD)
+      SERVER_GETATTRIBUTE_COPYTYPEVALUE(Boolean, &anyTypeNode.mObj->userExecutable);
+      break;
+    default:
+      UA_Server_deleteNodeCopy(server, (void **) &anyTypeNode.node);
+      return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+      break;
+  }
+  
+  return retval;
+}
 #endif