ソースを参照

Renamen UA_Server_attachMethod_toNode to UA_Server_setAttribute_method; added UA_Server_getAttribute_method; Replaced attribute getter|setter functions with aliases to UA_Server_get|setAttributeValue (which is now manditorily exported).

Chris Iatrou 8 年 前
コミット
20ae4add72
共有3 個のファイルを変更した123 個の追加152 個の削除を含む
  1. 2 2
      examples/server.c
  2. 58 60
      include/ua_server.h
  3. 63 90
      src/server/ua_server_addressspace.c

+ 2 - 2
examples/server.c

@@ -387,10 +387,10 @@ int main(int argc, char** argv) {
                           1, &inputArguments, 1, &outputArguments, &methodId);
   
   // Dettach the method from the methodNode
-  UA_Server_attachMethod_toNode(server, UA_NODEID_NUMERIC(1,62541), NULL, NULL);
+  UA_Server_setAttribute_method(server, UA_NODEID_NUMERIC(1,62541), NULL, NULL);
   
   // Reaettach the method from the methodNode
-  UA_Server_attachMethod_toNode(server, UA_NODEID_NUMERIC(1,62541), &getMonitoredItems, (void *) server);
+  UA_Server_setAttribute_method(server, UA_NODEID_NUMERIC(1,62541), &getMonitoredItems, (void *) server);
 #endif
    
   // Example for iterating over all nodes referenced by "Objects":

+ 58 - 60
include/ua_server.h

@@ -326,10 +326,6 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId nodeId, const UA_Qual
                         UA_MethodCallback method, void *handle, UA_Int32 inputArgumentsSize, const UA_Argument *inputArguments, 
                         UA_Int32 outputArgumentsSize, const UA_Argument *outputArguments,
                         UA_NodeId *createdNodeId);
-
-
-UA_StatusCode UA_EXPORT
-UA_Server_attachMethod_toNode(UA_Server *server, UA_NodeId methodNodeId, UA_MethodCallback method, void *handle);
 #endif
 
 #ifndef _HAVE_UA_NODEITERATORCALLBACK_D
@@ -349,69 +345,71 @@ typedef UA_StatusCode (*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean i
  */
 UA_StatusCode UA_EXPORT UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId, UA_NodeIteratorCallback callback, void *handle);
 
-UA_StatusCode UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, UA_AttributeId attributeId, void *value);
+UA_StatusCode UA_EXPORT UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, UA_AttributeId attributeId, void *value);
+// Attribute specific macros for setAttribute_are defined in ua_server_addressspace.c
+#define UA_Server_setAttribute_nodeId(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_NODEID, (UA_NodeId *) VALUE);
+#define UA_Server_setAttribute_nodeClass(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_NODECLASS, (UA_NodeClass *) VALUE);
+#define UA_Server_setAttribute_browseName(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_BROWSENAME, (UA_QualifiedName *) VALUE);
+#define UA_Server_setAttribute_displayName(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_DISPLAYNAME, (UA_LocalizedText *) VALUE);
+#define UA_Server_setAttribute_description(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_DESCRIPTION, (UA_LocalizedText *) VALUE);
+#define UA_Server_setAttribute_writeMask(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_WRITEMASK, (UA_UInt32 *) VALUE);
+#define UA_Server_setAttribute_userWriteMask(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_USERWRITEMASK, (UA_UInt32 *) VALUE);
+#define UA_Server_setAttribute_isAbstract(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_ISABSTRACT, (UA_Boolean *) VALUE);
+#define UA_Server_setAttribute_symmetric(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_SYMMETRIC, (UA_Boolean *) VALUE);
+#define UA_Server_setAttribute_inverseName(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_INVERSENAME, (UA_LocalizedText *) VALUE);
+#define UA_Server_setAttribute_containsNoLoops(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_CONTAINSNOLOOPS, (UA_Boolean *) VALUE);
+#define UA_Server_setAttribute_eventNotifier(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_EVENTNOTIFIER, (UA_Byte *) VALUE);
+#define UA_Server_setAttribute_value(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_VALUE, (UA_Variant *) VALUE);
+#define UA_Server_setAttribute_dataType(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_DATATYPE, (UA_NodeId *) VALUE);
+#define UA_Server_setAttribute_valueRank(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_VALUERANK, (UA_Int32 *) VALUE);
+#define UA_Server_setAttribute_arrayDimensions(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_ARRAYDIMENSIONS, (UA_Int32 *) VALUE);
+#define UA_Server_setAttribute_accessLevel(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_ACCESSLEVEL, (UA_UInt32 *) VALUE);
+#define UA_Server_setAttribute_userAccessLevel(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_USERACCESSLEVEL, (UA_UInt32 *) VALUE);
+#define UA_Server_setAttribute_minimumSamplingInterval(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, (UA_Double *) VALUE);
+#define UA_Server_setAttribute_historizing(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_HISTORIZING, (UA_Boolean *) VALUE);
+#define UA_Server_setAttribute_executable(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_EXECUTABLE, (UA_Boolean *) VALUE);
+#define UA_Server_setAttribute_userExecutable(SERVER, NODEID, VALUE) UA_Server_setAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_USEREXECUTABLE, (UA_Boolean *) VALUE);
+
+#ifdef ENABLE_METHODCALLS
+UA_StatusCode UA_EXPORT
+UA_Server_setAttribute_method(UA_Server *server, UA_NodeId methodNodeId, UA_MethodCallback method, void *handle);
+#endif
 
 UA_StatusCode UA_EXPORT
 UA_Server_setAttribute_DataSource(UA_Server *server, UA_NodeId nodeId, UA_DataSource *value);
 
-#define UA_SERVER_SETATTRIBUTEDECL(ATTRIBUTEID, ATTRIBUTEIDNAME, ATTRIBUTETYPE) \
-UA_StatusCode UA_EXPORT \
-UA_Server_setAttribute_##ATTRIBUTEIDNAME(UA_Server *server, UA_NodeId nodeId, ATTRIBUTETYPE *value); \
-
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_NODEID, nodeId, UA_NodeId)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_NODECLASS, nodeClass, UA_NodeClass)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_BROWSENAME, browseName, UA_QualifiedName)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_DISPLAYNAME, displayName, UA_LocalizedText)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_DESCRIPTION, description, UA_LocalizedText)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_WRITEMASK, writeMask, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_USERWRITEMASK, userWriteMask, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_ISABSTRACT, isAbstract, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_SYMMETRIC, symmetric, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_INVERSENAME, inverseName, UA_LocalizedText)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_CONTAINSNOLOOPS, containsNoLoops, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_EVENTNOTIFIER, eventNotifier, UA_Byte)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_VALUE, value, UA_Variant)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_DATATYPE, dataType, UA_NodeId)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_VALUERANK, valueRank, UA_Int32)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_ARRAYDIMENSIONS, arrayDimensions, UA_Int32)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_ACCESSLEVEL, accessLevel, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_USERACCESSLEVEL, userAccessLevel, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, minimumSamplingInterval, UA_Double)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_HISTORIZING, historizing, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_EXECUTABLE, executable, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDECL(UA_ATTRIBUTEID_USEREXECUTABLE, userExecutable, UA_Boolean)
-
-UA_StatusCode UA_Server_getAttributeValue(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);
+#define UA_Server_getAttribute_nodeId(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_NODEID, (UA_NodeId **) VALUE);
+#define UA_Server_getAttribute_nodeClass(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_NODECLASS, (UA_NodeClass **) VALUE);
+#define UA_Server_getAttribute_browseName(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_BROWSENAME, (UA_QualifiedName **) VALUE);
+#define UA_Server_getAttribute_displayName(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_DISPLAYNAME, (UA_LocalizedText **) VALUE);
+#define UA_Server_getAttribute_description(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_DESCRIPTION, (UA_LocalizedText **) VALUE);
+#define UA_Server_getAttribute_writeMask(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_WRITEMASK, (UA_UInt32 **) VALUE);
+#define UA_Server_getAttribute_userWriteMask(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_USERWRITEMASK, (UA_UInt32 **) VALUE);
+#define UA_Server_getAttribute_isAbstract(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_ISABSTRACT, (UA_Boolean **) VALUE);
+#define UA_Server_getAttribute_symmetric(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_SYMMETRIC, (UA_Boolean **) VALUE);
+#define UA_Server_getAttribute_inverseName(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_INVERSENAME, (UA_LocalizedText **) VALUE);
+#define UA_Server_getAttribute_containsNoLoops(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_CONTAINSNOLOOPS, (UA_Boolean **) VALUE);
+#define UA_Server_getAttribute_eventNotifier(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_EVENTNOTIFIER, (UA_Byte **) VALUE);
+#define UA_Server_getAttribute_value(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_VALUE, (UA_Variant **) VALUE);
+#define UA_Server_getAttribute_dataType(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_DATATYPE, (UA_NodeId **) VALUE);
+#define UA_Server_getAttribute_valueRank(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_VALUERANK, (UA_Int32 **) VALUE);
+#define UA_Server_getAttribute_arrayDimensions(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_ARRAYDIMENSIONS, (UA_Int32 **) VALUE);
+#define UA_Server_getAttribute_accessLevel(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_ACCESSLEVEL, (UA_UInt32 **) VALUE);
+#define UA_Server_getAttribute_userAccessLevel(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_USERACCESSLEVEL, (UA_UInt32 **) VALUE);
+#define UA_Server_getAttribute_minimumSamplingInterval(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, (UA_Double **) VALUE);
+#define UA_Server_getAttribute_historizing(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_HISTORIZING, (UA_Boolean **) VALUE);
+#define UA_Server_getAttribute_executable(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_EXECUTABLE, (UA_Boolean **) VALUE);
+#define UA_Server_getAttribute_userExecutable(SERVER, NODEID, VALUE) UA_Server_getAttributeValue(SERVER, NODEID, UA_ATTRIBUTEID_USEREXECUTABLE, (UA_Boolean **) VALUE);
 
+#ifdef ENABLE_METHODCALLS
 UA_StatusCode UA_EXPORT
-UA_Server_getAttribute_DataSource(UA_Server *server, UA_NodeId nodeId, UA_DataSource **value);
+UA_Server_getAttribute_method(UA_Server *server, UA_NodeId methodNodeId, UA_MethodCallback *method);
+#endif
 
-#define UA_SERVER_GETATTRIBUTEDECL(ATTRIBUTEID, ATTRIBUTEIDNAME, ATTRIBUTETYPE) \
-UA_StatusCode UA_EXPORT \
-UA_Server_getAttribute_##ATTRIBUTEIDNAME(UA_Server *server, UA_NodeId nodeId, ATTRIBUTETYPE **value); \
-
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_NODEID, nodeId, UA_NodeId)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_NODECLASS, nodeClass, UA_NodeClass)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_BROWSENAME, browseName, UA_QualifiedName)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_DISPLAYNAME, displayName, UA_LocalizedText)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_DESCRIPTION, description, UA_LocalizedText)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_WRITEMASK, writeMask, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_USERWRITEMASK, userWriteMask, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_ISABSTRACT, isAbstract, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_SYMMETRIC, symmetric, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_INVERSENAME, inverseName, UA_LocalizedText)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_CONTAINSNOLOOPS, containsNoLoops, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_EVENTNOTIFIER, eventNotifier, UA_Byte)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_VALUE, value, UA_Variant)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_DATATYPE, dataType, UA_NodeId)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_VALUERANK, valueRank, UA_Int32)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_ARRAYDIMENSIONS, arrayDimensions, UA_Int32)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_ACCESSLEVEL, accessLevel, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_USERACCESSLEVEL, userAccessLevel, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, minimumSamplingInterval, UA_Double)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_HISTORIZING, historizing, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_EXECUTABLE, executable, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDECL(UA_ATTRIBUTEID_USEREXECUTABLE, userExecutable, UA_Boolean)
+UA_StatusCode UA_EXPORT
+UA_Server_getAttribute_DataSource(UA_Server *server, UA_NodeId nodeId, UA_DataSource **value);
 
 /** Jobs describe work that is executed once or repeatedly. */
 typedef struct {

+ 63 - 90
src/server/ua_server_addressspace.c

@@ -893,40 +893,6 @@ UA_Server_addMethodNode(UA_Server* server, const UA_NodeId nodeId, const UA_Qual
     UA_AddNodesResult_deleteMembers(&addRes);
     return retval;
 }
-
-/* Allow userspace to attach a method to one defined via XML or to switch an attached method for another */
-UA_StatusCode
-UA_Server_attachMethod_toNode(UA_Server *server, UA_NodeId methodNodeId, UA_MethodCallback method, void *handle) {
-  UA_StatusCode retval = UA_STATUSCODE_GOOD;
-  const UA_Node *attachToMethod = UA_NULL;
-  UA_MethodNode *replacementMethod = UA_NULL;
-  
-  if (!method)
-    return UA_STATUSCODE_BADMETHODINVALID;
-
-  if (!server)
-    return UA_STATUSCODE_BADSERVERINDEXINVALID;
-  
-  attachToMethod =  UA_NodeStore_get(server->nodestore, &methodNodeId);
-  if (!attachToMethod)
-    return UA_STATUSCODE_BADNODEIDINVALID;
-  
-  if (attachToMethod->nodeClass != UA_NODECLASS_METHOD){
-    UA_NodeStore_release(attachToMethod);
-    return UA_STATUSCODE_BADNODEIDINVALID;
-  }
-  
-  replacementMethod = UA_MethodNode_new();
-
-  UA_MethodNode_copy((const UA_MethodNode *) attachToMethod, replacementMethod);
-  
-  replacementMethod->attachedMethod = method;
-  replacementMethod->methodHandle   = handle;
-  UA_NodeStore_replace(server->nodestore, attachToMethod, (UA_Node *) replacementMethod, UA_NULL);
-  UA_NodeStore_release(attachToMethod);
-
-  return retval;
-}
 #endif
 
 #define SETATTRIBUTE_ASSERTNODECLASS(CLASS) {                   \
@@ -1120,6 +1086,42 @@ UA_StatusCode UA_Server_setAttributeValue(UA_Server *server, UA_NodeId nodeId, U
   return retval;
 }
 
+#ifdef ENABLE_METHODCALLS
+/* Allow userspace to attach a method to one defined via XML or to switch an attached method for another */
+UA_StatusCode
+UA_Server_setAttribute_method(UA_Server *server, UA_NodeId methodNodeId, UA_MethodCallback method, void *handle) {
+  UA_StatusCode retval = UA_STATUSCODE_GOOD;
+  const UA_Node *attachToMethod = UA_NULL;
+  UA_MethodNode *replacementMethod = UA_NULL;
+  
+  if (!method)
+    return UA_STATUSCODE_BADMETHODINVALID;
+
+  if (!server)
+    return UA_STATUSCODE_BADSERVERINDEXINVALID;
+  
+  attachToMethod =  UA_NodeStore_get(server->nodestore, &methodNodeId);
+  if (!attachToMethod)
+    return UA_STATUSCODE_BADNODEIDINVALID;
+  
+  if (attachToMethod->nodeClass != UA_NODECLASS_METHOD){
+    UA_NodeStore_release(attachToMethod);
+    return UA_STATUSCODE_BADNODEIDINVALID;
+  }
+  
+  replacementMethod = UA_MethodNode_new();
+
+  UA_MethodNode_copy((const UA_MethodNode *) attachToMethod, replacementMethod);
+  
+  replacementMethod->attachedMethod = method;
+  replacementMethod->methodHandle   = handle;
+  UA_NodeStore_replace(server->nodestore, attachToMethod, (UA_Node *) replacementMethod, UA_NULL);
+  UA_NodeStore_release(attachToMethod);
+
+  return retval;
+}
+#endif
+
 UA_StatusCode
 UA_Server_setAttribute_DataSource(UA_Server *server, UA_NodeId nodeId, UA_DataSource *value) {
   union {
@@ -1165,34 +1167,6 @@ UA_Server_setAttribute_DataSource(UA_Server *server, UA_NodeId nodeId, UA_DataSo
   return retval;
 }
 
-#define UA_SERVER_SETATTRIBUTEDEF(ATTRIBUTEID, ATTRIBUTEIDNAME, ATTRIBUTETYPE) \
-UA_StatusCode \
-UA_Server_setAttribute_##ATTRIBUTEIDNAME (UA_Server *server, UA_NodeId nodeId, ATTRIBUTETYPE *value) { \
-  return UA_Server_setAttributeValue(server, nodeId, ATTRIBUTEID , (void *) value);\
-}
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_NODEID, nodeId, UA_NodeId)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_NODECLASS, nodeClass, UA_NodeClass)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_BROWSENAME, browseName, UA_QualifiedName)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_DISPLAYNAME, displayName, UA_LocalizedText)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_DESCRIPTION, description, UA_LocalizedText)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_WRITEMASK, writeMask, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_USERWRITEMASK, userWriteMask, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_ISABSTRACT, isAbstract, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_SYMMETRIC, symmetric, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_INVERSENAME, inverseName, UA_LocalizedText)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_CONTAINSNOLOOPS, containsNoLoops, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_EVENTNOTIFIER, eventNotifier, UA_Byte)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_VALUE, value, UA_Variant)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_DATATYPE, dataType, UA_NodeId)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_VALUERANK, valueRank, UA_Int32)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_ARRAYDIMENSIONS, arrayDimensions, UA_Int32)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_ACCESSLEVEL, accessLevel, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_USERACCESSLEVEL, userAccessLevel, UA_UInt32)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, minimumSamplingInterval, UA_Double)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_HISTORIZING, historizing, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_EXECUTABLE, executable, UA_Boolean)
-UA_SERVER_SETATTRIBUTEDEF(UA_ATTRIBUTEID_USEREXECUTABLE, userExecutable, UA_Boolean)
-
 #define SERVER_GETATTRIBUTE_COPYTYPEVALUE(TYPE, SRC) \
   *value = (void *) UA_##TYPE##_new();               \
   UA_##TYPE##_copy( SRC, (UA_##TYPE *) *value  );    \
@@ -1360,6 +1334,33 @@ UA_StatusCode UA_Server_getAttributeValue(UA_Server *server, UA_NodeId nodeId, U
   return retval;
 }
 
+#ifdef ENABLE_METHODCALLS
+UA_StatusCode UA_Server_getAttribute_method(UA_Server *server, UA_NodeId methodNodeId, UA_MethodCallback *method) {
+  union {
+    UA_Node *anyNode;
+    UA_MethodNode *mNode;
+  } node;
+  UA_StatusCode retval;
+  *method= UA_NULL;
+  
+  retval = UA_Server_getNodeCopy(server, methodNodeId, (void **) &node.anyNode);
+  if (retval != UA_STATUSCODE_GOOD || node.anyNode == UA_NULL)
+    return retval;
+  
+  if (node.anyNode->nodeClass != UA_NODECLASS_METHOD) {
+    UA_Server_deleteNodeCopy(server, (void **) &node);
+    return UA_STATUSCODE_BADNODECLASSINVALID;
+  }
+  
+  if (node.mNode->attachedMethod != UA_NULL) {
+    method = &node.mNode->attachedMethod;
+  }
+  
+  retval |= UA_Server_deleteNodeCopy(server, (void **) &node);
+  return retval;
+}
+#endif
+
 UA_StatusCode
 UA_Server_getAttribute_DataSource(UA_Server *server, UA_NodeId nodeId, UA_DataSource **value) {
   union {
@@ -1404,34 +1405,6 @@ UA_Server_getAttribute_DataSource(UA_Server *server, UA_NodeId nodeId, UA_DataSo
   return retval;
 }
 
-#define UA_SERVER_GETATTRIBUTEDEF(ATTRIBUTEID, ATTRIBUTEIDNAME, ATTRIBUTETYPE) \
-UA_StatusCode \
-UA_Server_getAttribute_##ATTRIBUTEIDNAME (UA_Server *server, UA_NodeId nodeId, ATTRIBUTETYPE **value) { \
-  return UA_Server_getAttributeValue(server, nodeId, ATTRIBUTEID , (void **) value);\
-}
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_NODEID, nodeId, UA_NodeId)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_NODECLASS, nodeClass, UA_NodeClass)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_BROWSENAME, browseName, UA_QualifiedName)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_DISPLAYNAME, displayName, UA_LocalizedText)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_DESCRIPTION, description, UA_LocalizedText)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_WRITEMASK, writeMask, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_USERWRITEMASK, userWriteMask, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_ISABSTRACT, isAbstract, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_SYMMETRIC, symmetric, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_INVERSENAME, inverseName, UA_LocalizedText)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_CONTAINSNOLOOPS, containsNoLoops, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_EVENTNOTIFIER, eventNotifier, UA_Byte)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_VALUE, value, UA_Variant)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_DATATYPE, dataType, UA_NodeId)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_VALUERANK, valueRank, UA_Int32)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_ARRAYDIMENSIONS, arrayDimensions, UA_Int32)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_ACCESSLEVEL, accessLevel, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_USERACCESSLEVEL, userAccessLevel, UA_UInt32)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, minimumSamplingInterval, UA_Double)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_HISTORIZING, historizing, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_EXECUTABLE, executable, UA_Boolean)
-UA_SERVER_GETATTRIBUTEDEF(UA_ATTRIBUTEID_USEREXECUTABLE, userExecutable, UA_Boolean)
-
 UA_StatusCode UA_Server_getAttributeValue(UA_Server *server, UA_NodeId nodeId, UA_AttributeId attributeId, void **value);
 #define arrayOfNodeIds_addNodeId(ARRAYNAME, NODEID) { \
   ARRAYNAME.size++; \