Procházet zdrojové kódy

generate documentation for ua_server.h

Julius Pfrommer před 8 roky
rodič
revize
e30e0f306b
3 změnil soubory, kde provedl 377 přidání a 268 odebrání
  1. 3 0
      doc/CMakeLists.txt
  2. 1 0
      doc/index.rst
  3. 373 268
      include/ua_server.h

+ 3 - 0
doc/CMakeLists.txt

@@ -14,12 +14,14 @@ endfunction()
 generate_rst(${PROJECT_SOURCE_DIR}/include/ua_types.h ${PROJECT_BINARY_DIR}/doc_src/types.rst)
 generate_rst(${PROJECT_SOURCE_DIR}/include/ua_constants.h ${PROJECT_BINARY_DIR}/doc_src/constants.rst)
 generate_rst(${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h ${PROJECT_BINARY_DIR}/doc_src/types_generated.rst)
+generate_rst(${PROJECT_SOURCE_DIR}/include/ua_server.h ${PROJECT_BINARY_DIR}/doc_src/server.rst)
 
 add_custom_target(doc_latex ${SPHINX_EXECUTABLE}
   -b latex -c "${PROJECT_BINARY_DIR}/doc_src" "${PROJECT_BINARY_DIR}/doc_src" "${PROJECT_BINARY_DIR}/doc_latex"
   DEPENDS ${PROJECT_BINARY_DIR}/doc_src/types.rst
   DEPENDS ${PROJECT_BINARY_DIR}/doc_src/constants.rst
   DEPENDS ${PROJECT_BINARY_DIR}/doc_src/types_generated.rst
+  DEPENDS ${PROJECT_BINARY_DIR}/doc_src/server.rst
   COMMENT "Building LaTeX sources for documentation with Sphinx")
 add_dependencies(doc_latex open62541)
 
@@ -29,5 +31,6 @@ add_custom_target(doc ${SPHINX_EXECUTABLE}
   DEPENDS ${PROJECT_BINARY_DIR}/doc_src/types.rst
   DEPENDS ${PROJECT_BINARY_DIR}/doc_src/constants.rst
   DEPENDS ${PROJECT_BINARY_DIR}/doc_src/types_generated.rst
+  DEPENDS ${PROJECT_BINARY_DIR}/doc_src/server.rst
   COMMENT "Building HTML documentation with Sphinx")
 add_dependencies(doc open62541)

+ 1 - 0
doc/index.rst

@@ -25,5 +25,6 @@ standard.
    tutorials
    types
    constants
+   server
    types_generated
 

+ 373 - 268
include/ua_server.h

@@ -28,13 +28,56 @@ extern "C" {
 #include "ua_job.h"
 #include "ua_connection.h"
 
-/*****************/
-/* Server Config */
-/*****************/
-
-struct UA_ServerNetworkLayer; // forwards declaration
+/**
+ * Server
+ * ======
+ *
+ * Network Layer
+ * -------------
+ * Interface to the binary network layers. The functions in the network layer
+ * are never called in parallel but only sequentially from the server's main
+ * loop. So the network layer does not need to be thread-safe. */
+struct UA_ServerNetworkLayer;
 typedef struct UA_ServerNetworkLayer UA_ServerNetworkLayer;    
 
+struct UA_ServerNetworkLayer {
+    void *handle; // pointer to internal data
+    UA_String discoveryUrl;
+
+    /* Starts listening on the the networklayer.
+     *
+     * @param nl The network layer
+     * @param logger The logger
+     * @return Returns UA_STATUSCODE_GOOD or an error code. */
+    UA_StatusCode (*start)(UA_ServerNetworkLayer *nl, UA_Logger logger);
+    
+    /* Gets called from the main server loop and returns the jobs (accumulated
+     * messages and close events) for dispatch.
+     *
+     * @param nl The network layer
+     * @param jobs When the returned integer is >0, *jobs points to an array of UA_Job of the
+     *             returned size.
+     * @param timeout The timeout during which an event must arrive in microseconds
+     * @return The size of the jobs array. If the result is negative, an error has occurred. */
+    size_t (*getJobs)(UA_ServerNetworkLayer *nl, UA_Job **jobs, UA_UInt16 timeout);
+
+    /* Closes the network connection and returns all the jobs that need to be
+     * finished before the network layer can be safely deleted.
+     *
+     * @param nl The network layer
+     * @param jobs When the returned integer is >0, jobs points to an array of UA_Job of the
+     *             returned size.
+     * @return The size of the jobs array. If the result is negative, an error has occurred. */
+    size_t (*stop)(UA_ServerNetworkLayer *nl, UA_Job **jobs);
+
+    /** Deletes the network content. Call only after stopping. */
+    void (*deleteMembers)(UA_ServerNetworkLayer *nl);
+};
+
+/**
+ * Server Configuration
+ * --------------------
+ * The following structure is passed to a new server for configuration. */
 typedef struct {
     UA_String username;
     UA_String password;
@@ -59,152 +102,117 @@ typedef struct {
 
 extern UA_EXPORT const UA_ServerConfig UA_ServerConfig_standard;
 
-/*********************************/
-/* Initialize and run the server */
-/*********************************/
-
+/**
+ * Server Lifecycle
+ * ---------------- */
 UA_Server UA_EXPORT * UA_Server_new(const UA_ServerConfig config);
 void UA_EXPORT UA_Server_delete(UA_Server *server);
 
-/**
- * Runs the main loop of the server. In each iteration, this calls into the
+/* Runs the main loop of the server. In each iteration, this calls into the
  * networklayers to see if jobs have arrived and checks if repeated jobs need to
  * be triggered.
  *
  * @param server The server object.
  * @param running The loop is run as long as *running is true. Otherwise, the server shuts down.
- * @return Returns the statuscode of the UA_Server_run_shutdown method
- */
+ * @return Returns the statuscode of the UA_Server_run_shutdown method */
 UA_StatusCode UA_EXPORT UA_Server_run(UA_Server *server, volatile UA_Boolean *running);
 
-/** The prologue part of UA_Server_run (no need to use if you call UA_Server_run) */
+/* The prologue part of UA_Server_run (no need to use if you call UA_Server_run) */
 UA_StatusCode UA_EXPORT UA_Server_run_startup(UA_Server *server);
 
-/** The epilogue part of UA_Server_run (no need to use if you call UA_Server_run) */
-UA_StatusCode UA_EXPORT UA_Server_run_shutdown(UA_Server *server);
-
-/**
- * Executes a single iteration of the server's main loop.
+/* Executes a single iteration of the server's main loop.
  *
  * @param server The server object.
  * @param waitInternal Should we wait for messages in the networklayer?
  *        Otherwise, the timouts for the networklayers are set to zero.
  *        The default max wait time is 50millisec.
- * @return Returns how long we can wait until the next scheduled job (in millisec)
- */
+ * @return Returns how long we can wait until the next scheduled job (in millisec) */
 UA_UInt16 UA_EXPORT UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal);
 
+/* The epilogue part of UA_Server_run (no need to use if you call UA_Server_run) */
+UA_StatusCode UA_EXPORT UA_Server_run_shutdown(UA_Server *server);
+
 /**
+ * Modify a running server
+ * ----------------------- */
+/* Add a job for cyclic repetition to the server.
+ *
  * @param server The server object.
  * @param job The job that shall be added.
- * @param interval The job shall be repeatedly executed with the given interval (in ms). The
- *        interval must be larger than 5ms. The first execution occurs at now() + interval at the
- *        latest.
- * @param jobId Set to the guid of the repeated job. This can be used to cancel the job later on. If
- *        the pointer is null, the guid is not set.
- * @return Upon success, UA_STATUSCODE_GOOD is returned. An error code otherwise.
- */
+ * @param interval The job shall be repeatedly executed with the given interval
+ *        (in ms). The interval must be larger than 5ms. The first execution
+ *        occurs at now() + interval at the latest.
+ * @param jobId Set to the guid of the repeated job. This can be used to cancel
+ *        the job later on. If the pointer is null, the guid is not set.
+ * @return Upon success, UA_STATUSCODE_GOOD is returned. An error code otherwise. */
 UA_StatusCode UA_EXPORT UA_Server_addRepeatedJob(UA_Server *server, UA_Job job,
                                                  UA_UInt32 interval, UA_Guid *jobId);
 
-/**
- * Remove repeated job. The entry will be removed asynchronously during the next iteration of the
- * server main loop.
+/* Remove repeated job. The entry will be removed asynchronously during the next
+ * iteration of the server main loop.
  *
  * @param server The server object.
  * @param jobId The id of the job that shall be removed.
- * @return Upon sucess, UA_STATUSCODE_GOOD is returned. An error code otherwise.
- */
+ * @return Upon sucess, UA_STATUSCODE_GOOD is returned. An error code otherwise. */
 UA_StatusCode UA_EXPORT UA_Server_removeRepeatedJob(UA_Server *server, UA_Guid jobId);
 
-/** @brief Add a new namespace to the server. Returns the index of the new namespace */
+/* Add a new namespace to the server. Returns the index of the new namespace */
 UA_UInt16 UA_EXPORT UA_Server_addNamespace(UA_Server *server, const char* name);
 
 /**
- * Interface to the binary network layers. This structure is returned from the
- * function that initializes the network layer. The layer is already bound to a
- * specific port and listening. The functions in the structure are never called
- * in parallel but only sequentially from the server's main loop. So the network
- * layer does not need to be thread-safe.
- */
-struct UA_ServerNetworkLayer {
-    void *handle; // pointer to internal data
-    UA_String discoveryUrl;
-
-    /**
-     * Starts listening on the the networklayer.
-     *
-     * @param nl The network layer
-     * @param logger The logger
-     * @return Returns UA_STATUSCODE_GOOD or an error code.
-     */
-    UA_StatusCode (*start)(UA_ServerNetworkLayer *nl, UA_Logger logger);
-    
-    /**
-     * Gets called from the main server loop and returns the jobs (accumulated messages and close
-     * events) for dispatch.
-     *
-     * @param nl The network layer
-     * @param jobs When the returned integer is >0, *jobs points to an array of UA_Job of the
-     * returned size.
-     * @param timeout The timeout during which an event must arrive in microseconds
-     * @return The size of the jobs array. If the result is negative, an error has occurred.
-     */
-    size_t (*getJobs)(UA_ServerNetworkLayer *nl, UA_Job **jobs, UA_UInt16 timeout);
-
-    /**
-     * Closes the network connection and returns all the jobs that need to be finished before the
-     * network layer can be safely deleted.
-     *
-     * @param nl The network layer
-     * @param jobs When the returned integer is >0, jobs points to an array of UA_Job of the
-     * returned size.
-     * @return The size of the jobs array. If the result is negative, an error has occurred.
-     */
-    size_t (*stop)(UA_ServerNetworkLayer *nl, UA_Job **jobs);
-
-    /** Deletes the network content. Call only after stopping. */
-    void (*deleteMembers)(UA_ServerNetworkLayer *nl);
-};
-
-/**********************/
-/* Set Node Callbacks */
-/**********************/
-
-/**
+ * Node Management
+ * ---------------
+ *
+ * Callback Mechanisms
+ * ^^^^^^^^^^^^^^^^^^^
+ * There are four mechanisms for callbacks from the node-based information model
+ * into userspace:
+ *
+ * - Datasources for variable nodes, where the variable content is managed
+ *   externally
+ * - Value-callbacks for variable nodes, where userspace is notified when a
+ *   read/write occurs
+ * - Object lifecycle management, where a user-defined constructor and
+ *   destructor is added to an object type
+ * - Method callbacks, where a user-defined method is exposed in the information
+ *   model
+ *
+ * Data Source Callback
+ * ~~~~~~~~~~~~~~~~~~~~
  * Datasources are the interface to local data providers. It is expected that
  * the read and release callbacks are implemented. The write callback can be set
- * to null. The read callback is set to null will result in a BADINTERNALERROR.
- */
+ * to a null-pointer. */
 typedef struct {
-    void *handle; ///> A custom pointer to reuse the same datasource functions for multiple sources
-
-    /**
-     * Copies the data from the source into the provided value.
+    void *handle; /* A custom pointer to reuse the same datasource functions for
+                     multiple sources */
+    /* Copies the data from the source into the provided value.
      *
      * @param handle An optional pointer to user-defined data for the specific data source
      * @param nodeid Id of the read node
      * @param includeSourceTimeStamp If true, then the datasource is expected to set the source
      *        timestamp in the returned value
-     * @param range If not null, then the datasource shall return only a selection of the (nonscalar)
-     *        data. Set UA_STATUSCODE_BADINDEXRANGEINVALID in the value if this does not apply.
-     * @param value The (non-null) DataValue that is returned to the client. The data source sets the
-     *        read data, the result status and optionally a sourcetimestamp.
-     * @return Returns a status code for logging. Error codes intended for the original caller are set
-     *         in the value. If an error is returned, then no releasing of the value is done.
-     */
-    UA_StatusCode (*read)(void *handle, const UA_NodeId nodeid, UA_Boolean includeSourceTimeStamp,
-                          const UA_NumericRange *range, UA_DataValue *value);
-
-    /**
-     * Write into a data source. The write member of UA_DataSource can be empty if the operation
-     * is unsupported.
+     * @param range If not null, then the datasource shall return only a
+     *        selection of the (nonscalar) data. Set
+     *        UA_STATUSCODE_BADINDEXRANGEINVALID in the value if this does not
+     *        apply.
+     * @param value The (non-null) DataValue that is returned to the client. The
+     *        data source sets the read data, the result status and optionally a
+     *        sourcetimestamp.
+     * @return Returns a status code for logging. Error codes intended for the
+     *         original caller are set in the value. If an error is returned,
+     *         then no releasing of the value is done. */
+    UA_StatusCode (*read)(void *handle, const UA_NodeId nodeid,
+                          UA_Boolean includeSourceTimeStamp, const UA_NumericRange *range,
+                          UA_DataValue *value);
+
+    /* Write into a data source. The write member of UA_DataSource can be empty
+     * if the operation is unsupported.
      *
      * @param handle An optional pointer to user-defined data for the specific data source
      * @param nodeid Id of the node being written to
      * @param data The data to be written into the data source
-     * @param range An optional data range. If the data source is scalar or does not support writing
-     *        of ranges, then an error code is returned.
+     * @param range An optional data range. If the data source is scalar or does
+     *        not support writing of ranges, then an error code is returned.
      * @return Returns a status code that is returned to the user
      */
     UA_StatusCode (*write)(void *handle, const UA_NodeId nodeid,
@@ -215,8 +223,11 @@ UA_StatusCode UA_EXPORT
 UA_Server_setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
                                      const UA_DataSource dataSource);
 
-/* Value Callbacks can be attach to variable and variable type nodes. If
-   not-null, they are called before reading and after writing respectively */
+/**
+ * Value Callback
+ * ~~~~~~~~~~~~~~
+ * Value Callbacks can be attached to variable and variable type nodes. If
+ * not-null, they are called before reading and after writing respectively. */
 typedef struct {
     void *handle;
     void (*onRead)(void *handle, const UA_NodeId nodeid,
@@ -229,10 +240,14 @@ UA_StatusCode UA_EXPORT
 UA_Server_setVariableNode_valueCallback(UA_Server *server, const UA_NodeId nodeId,
                                         const UA_ValueCallback callback);
 
-/* The lifecycle management allows to track the instantiation and deletion of
-   object nodes derived from object types. */
+/**
+ * Object Lifecycle Management Callbacks
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Lifecycle management adds constructor and destructor callbacks to
+ * object types. */
 typedef struct {
-    void * (*constructor)(const UA_NodeId instance); ///< Returns the instance handle attached to the node
+    /* Returns the instance handle that is then attached to the node */
+    void * (*constructor)(const UA_NodeId instance);
     void (*destructor)(const UA_NodeId instance, void *instanceHandle);
 } UA_ObjectLifecycleManagement;
 
@@ -240,126 +255,143 @@ UA_StatusCode UA_EXPORT
 UA_Server_setObjectTypeNode_lifecycleManagement(UA_Server *server, UA_NodeId nodeId,
                                                 UA_ObjectLifecycleManagement olm);
 
-#ifndef HAVE_NODEITER_CALLBACK
-#define HAVE_NODEITER_CALLBACK
-/* Iterate over all nodes referenced by parentNodeId by calling the callback
-   function for each child node (in ifdef because GCC/CLANG handle include order differently)*/
-typedef UA_StatusCode (*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean isInverse,
-                                                 UA_NodeId referenceTypeId, void *handle);
-#endif
+/**
+ * Method Callbacks
+ * ~~~~~~~~~~~~~~~~ */
+typedef UA_StatusCode (*UA_MethodCallback)(void *methodHandle, const UA_NodeId objectId,
+                                           size_t inputSize, const UA_Variant *input,
+                                           size_t outputSize, UA_Variant *output);
 
+#ifdef UA_ENABLE_METHODCALLS
 UA_StatusCode UA_EXPORT
-UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
-                               UA_NodeIteratorCallback callback, void *handle);
-
-/*******************/
-/* Node Management */
-/*******************/
+UA_Server_setMethodNode_callback(UA_Server *server, const UA_NodeId methodNodeId,
+                                 UA_MethodCallback method, void *handle);
+#endif
 
+/**
+ * Node Addition and Deletion
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^ */
+UA_StatusCode UA_EXPORT
+UA_Server_deleteNode(UA_Server *server, const UA_NodeId nodeId, UA_Boolean deleteReferences);
+    
+/**
+ * The instantiation callback is used to track the addition of new nodes. It is
+ * also called for all sub-nodes contained in an object or variable type node
+ * that is instantiated.
+ */
 typedef struct UA_InstantiationCallback_s {
   UA_StatusCode (*method)(UA_NodeId objectId, UA_NodeId definitionId, void *handle);
   void *handle;
 } UA_InstantiationCallback;
 
-UA_StatusCode UA_EXPORT
-UA_Server_addReference(UA_Server *server, const UA_NodeId sourceId, const UA_NodeId refTypeId,
-                       const UA_ExpandedNodeId targetId, UA_Boolean isForward);
-
-UA_StatusCode UA_EXPORT
-UA_Server_deleteNode(UA_Server *server, const UA_NodeId nodeId, UA_Boolean deleteReferences);
-    
-UA_StatusCode UA_EXPORT
-UA_Server_deleteReference(UA_Server *server, const UA_NodeId sourceNodeId, const UA_NodeId referenceTypeId,
-                          UA_Boolean isForward, const UA_ExpandedNodeId targetNodeId,
-                          UA_Boolean deleteBidirectional);
-
 /* Don't use this function. There are typed versions as inline functions. */
 UA_StatusCode UA_EXPORT
-__UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass, const UA_NodeId requestedNewNodeId,
-                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                    const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
-                    const UA_NodeAttributes *attr, const UA_DataType *attributeType, 
+__UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
+                    const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
+                    const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
+                    const UA_NodeId typeDefinition, const UA_NodeAttributes *attr,
+                    const UA_DataType *attributeType,
                     UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId);
 
 static UA_INLINE UA_StatusCode
 UA_Server_addVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                           const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
                           const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
-                          const UA_VariableAttributes attr, UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId) {
+                          const UA_VariableAttributes attr,
+                          UA_InstantiationCallback *instantiationCallback,
+                          UA_NodeId *outNewNodeId) {
     return __UA_Server_addNode(server, UA_NODECLASS_VARIABLE, requestedNewNodeId, parentNodeId,
-                               referenceTypeId, browseName, typeDefinition, (const UA_NodeAttributes*)&attr,
-                               &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], instantiationCallback, outNewNodeId); }
+                               referenceTypeId, browseName, typeDefinition,
+                               (const UA_NodeAttributes*)&attr,
+                               &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
+                               instantiationCallback, outNewNodeId); }
 
 static UA_INLINE UA_StatusCode
 UA_Server_addVariableTypeNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                               const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                              const UA_QualifiedName browseName, const UA_VariableTypeAttributes attr,
-                              UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_VARIABLETYPE, requestedNewNodeId, parentNodeId,
-                               referenceTypeId, browseName, UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
-                               &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], instantiationCallback, outNewNodeId); }
+                              const UA_QualifiedName browseName,
+                              const UA_VariableTypeAttributes attr,
+                              UA_InstantiationCallback *instantiationCallback,
+                              UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode(server, UA_NODECLASS_VARIABLETYPE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr,
+                               &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
+                               instantiationCallback, outNewNodeId); }
 
 static UA_INLINE UA_StatusCode
 UA_Server_addObjectNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                         const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
                         const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
-                        const UA_ObjectAttributes attr, UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId) {
+                        const UA_ObjectAttributes attr,
+                        UA_InstantiationCallback *instantiationCallback,
+                        UA_NodeId *outNewNodeId) {
     return __UA_Server_addNode(server, UA_NODECLASS_OBJECT, requestedNewNodeId, parentNodeId,
-                               referenceTypeId, browseName, typeDefinition, (const UA_NodeAttributes*)&attr,
-                               &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], instantiationCallback, outNewNodeId); }
+                               referenceTypeId, browseName, typeDefinition,
+                               (const UA_NodeAttributes*)&attr,
+                               &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
+                               instantiationCallback, outNewNodeId); }
 
 static UA_INLINE UA_StatusCode
 UA_Server_addObjectTypeNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                             const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                            const UA_QualifiedName browseName, const UA_ObjectTypeAttributes attr,
-                            UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_OBJECTTYPE, requestedNewNodeId, parentNodeId,
-                               referenceTypeId, browseName, UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
-                               &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], instantiationCallback, outNewNodeId); }
+                            const UA_QualifiedName browseName,
+                            const UA_ObjectTypeAttributes attr,
+                            UA_InstantiationCallback *instantiationCallback,
+                            UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode(server, UA_NODECLASS_OBJECTTYPE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr,
+                               &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],
+                               instantiationCallback, outNewNodeId); }
 
 static UA_INLINE UA_StatusCode
 UA_Server_addViewNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                       const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
                       const UA_QualifiedName browseName, const UA_ViewAttributes attr,
-                      UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId) {
+                      UA_InstantiationCallback *instantiationCallback,
+                      UA_NodeId *outNewNodeId) {
     return __UA_Server_addNode(server, UA_NODECLASS_VIEW, requestedNewNodeId, parentNodeId,
-                               referenceTypeId, browseName, UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
-                               &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], instantiationCallback, outNewNodeId); }
+                               referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr,
+                               &UA_TYPES[UA_TYPES_VIEWATTRIBUTES],
+                               instantiationCallback, outNewNodeId); }
 
 static UA_INLINE UA_StatusCode
 UA_Server_addReferenceTypeNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                                const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                               const UA_QualifiedName browseName, const UA_ReferenceTypeAttributes attr,
-                               UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_REFERENCETYPE, requestedNewNodeId, parentNodeId,
-                               referenceTypeId, browseName, UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
-                               &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], instantiationCallback, outNewNodeId); }
+                               const UA_QualifiedName browseName,
+                               const UA_ReferenceTypeAttributes attr,
+                               UA_InstantiationCallback *instantiationCallback,
+                               UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode(server, UA_NODECLASS_REFERENCETYPE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr,
+                               &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],
+                               instantiationCallback, outNewNodeId); }
 
 static UA_INLINE UA_StatusCode
 UA_Server_addDataTypeNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                           const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
                           const UA_QualifiedName browseName, const UA_DataTypeAttributes attr,
-                          UA_InstantiationCallback *instantiationCallback, UA_NodeId *outNewNodeId) {
+                          UA_InstantiationCallback *instantiationCallback,
+                          UA_NodeId *outNewNodeId) {
     return __UA_Server_addNode(server, UA_NODECLASS_DATATYPE, requestedNewNodeId, parentNodeId,
-                               referenceTypeId, browseName, UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
-                               &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], instantiationCallback, outNewNodeId); }
+                               referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr,
+                               &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],
+                               instantiationCallback, outNewNodeId); }
 
 UA_StatusCode UA_EXPORT
 UA_Server_addDataSourceVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
-                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                                    const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
-                                    const UA_VariableAttributes attr, const UA_DataSource dataSource,
-                                    UA_NodeId *outNewNodeId);
-
-typedef UA_StatusCode (*UA_MethodCallback)(void *methodHandle, const UA_NodeId objectId,
-                                           size_t inputSize, const UA_Variant *input,
-                                           size_t outputSize, UA_Variant *output);
+                                    const UA_NodeId parentNodeId,
+                                    const UA_NodeId referenceTypeId,
+                                    const UA_QualifiedName browseName,
+                                    const UA_NodeId typeDefinition,
+                                    const UA_VariableAttributes attr,
+                                    const UA_DataSource dataSource, UA_NodeId *outNewNodeId);
 
 #ifdef UA_ENABLE_METHODCALLS
-UA_StatusCode UA_EXPORT
-UA_Server_setMethodNode_callback(UA_Server *server, const UA_NodeId methodNodeId,
-				 UA_MethodCallback method, void *handle);
-
 UA_StatusCode UA_EXPORT
 UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                         const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
@@ -370,183 +402,256 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                         UA_NodeId *outNewNodeId);
 #endif
 
-/*************************/
-/* Write Node Attributes */
-/*************************/
-
-/* The following node attributes cannot be written
-   - NodeClass
-   - NodeId
-   - Symmetric
-   - ContainsNoLoop
-   
-   The following attributes cannot be written from the server, as there is no "user" in the server
-   - UserWriteMask
-   - UserAccessLevel
-   - UserExecutable
-
-   The following attributes are currently taken from the value variant:
-   TODO: Handle them independent from the variable, ensure that the implicit constraints hold
-   - DataType
-   - ValueRank
-   - ArrayDimensions
-   
-   - Historizing is currently unsupported
-  */
-
+/**
+ * Write Node Attributes
+ * ^^^^^^^^^^^^^^^^^^^^^
+ * The following node attributes cannot be written
+ *
+ * - NodeClass
+ * - NodeId
+ * - Symmetric
+ * - ContainsNoLoop
+ *  
+ * The following attributes cannot be written from the server, as there is no "user" in the server
+ *
+ * - UserWriteMask
+ * - UserAccessLevel
+ * - UserExecutable
+ *
+ * The following attributes are currently taken from the value variant:
+ * TODO: Handle them independent from the variable, ensure that the implicit constraints hold
+ *
+ * - DataType
+ * - ValueRank
+ * - ArrayDimensions
+ * 
+ * - Historizing is currently unsupported */
 /* Don't use this function. There are typed versions with no additional overhead. */
 UA_StatusCode UA_EXPORT
-__UA_Server_write(UA_Server *server, const UA_NodeId *nodeId, const UA_AttributeId attributeId,
+__UA_Server_write(UA_Server *server, const UA_NodeId *nodeId,
+                  const UA_AttributeId attributeId,
                   const UA_DataType *type, const void *value);
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeBrowseName(UA_Server *server, const UA_NodeId nodeId, const UA_QualifiedName browseName) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_BROWSENAME, &UA_TYPES[UA_TYPES_QUALIFIEDNAME], &browseName); }
+UA_Server_writeBrowseName(UA_Server *server, const UA_NodeId nodeId,
+                          const UA_QualifiedName browseName) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_BROWSENAME,
+                             &UA_TYPES[UA_TYPES_QUALIFIEDNAME], &browseName); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeDisplayName(UA_Server *server, const UA_NodeId nodeId, const UA_LocalizedText displayName) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &displayName); }
+UA_Server_writeDisplayName(UA_Server *server, const UA_NodeId nodeId,
+                           const UA_LocalizedText displayName) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME,
+                             &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &displayName); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeDescription(UA_Server *server, const UA_NodeId nodeId, const UA_LocalizedText description) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DESCRIPTION, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &description); }
+UA_Server_writeDescription(UA_Server *server, const UA_NodeId nodeId,
+                           const UA_LocalizedText description) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DESCRIPTION,
+                             &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &description); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeWriteMask(UA_Server *server, const UA_NodeId nodeId, const UA_UInt32 writeMask) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_WRITEMASK, &UA_TYPES[UA_TYPES_UINT32], &writeMask); }
+UA_Server_writeWriteMask(UA_Server *server, const UA_NodeId nodeId,
+                         const UA_UInt32 writeMask) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_WRITEMASK,
+                             &UA_TYPES[UA_TYPES_UINT32], &writeMask); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeIsAbstract(UA_Server *server, const UA_NodeId nodeId, const UA_Boolean isAbstract) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ISABSTRACT, &UA_TYPES[UA_TYPES_BOOLEAN], &isAbstract); }
+UA_Server_writeIsAbstract(UA_Server *server, const UA_NodeId nodeId,
+                          const UA_Boolean isAbstract) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ISABSTRACT,
+                             &UA_TYPES[UA_TYPES_BOOLEAN], &isAbstract); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeInverseName(UA_Server *server, const UA_NodeId nodeId, const UA_LocalizedText inverseName) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_INVERSENAME, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &inverseName); }
+UA_Server_writeInverseName(UA_Server *server, const UA_NodeId nodeId,
+                           const UA_LocalizedText inverseName) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_INVERSENAME,
+                             &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &inverseName); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeEventNotifier(UA_Server *server, const UA_NodeId nodeId, const UA_Byte eventNotifier) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER, &UA_TYPES[UA_TYPES_BYTE], &eventNotifier); }
+UA_Server_writeEventNotifier(UA_Server *server, const UA_NodeId nodeId,
+                             const UA_Byte eventNotifier) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER,
+                             &UA_TYPES[UA_TYPES_BYTE], &eventNotifier); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeValue(UA_Server *server, const UA_NodeId nodeId, const UA_Variant value) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUE, &UA_TYPES[UA_TYPES_VARIANT], &value); }
+UA_Server_writeValue(UA_Server *server, const UA_NodeId nodeId,
+                     const UA_Variant value) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUE,
+                             &UA_TYPES[UA_TYPES_VARIANT], &value); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeAccessLevel(UA_Server *server, const UA_NodeId nodeId, const UA_UInt32 accessLevel) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL, &UA_TYPES[UA_TYPES_UINT32], &accessLevel); }
+UA_Server_writeAccessLevel(UA_Server *server, const UA_NodeId nodeId,
+                           const UA_UInt32 accessLevel) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL,
+                             &UA_TYPES[UA_TYPES_UINT32], &accessLevel); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId, const UA_Double miniumSamplingInterval) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, &UA_TYPES[UA_TYPES_DOUBLE], &miniumSamplingInterval); }
+UA_Server_writeMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId,
+                                       const UA_Double miniumSamplingInterval) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
+                             &UA_TYPES[UA_TYPES_DOUBLE], &miniumSamplingInterval); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_writeExecutable(UA_Server *server, const UA_NodeId nodeId, const UA_Boolean executable) {
-    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EXECUTABLE, &UA_TYPES[UA_TYPES_BOOLEAN], &executable); }
-
-/************************/
-/* Read Node Attributes */
-/************************/
-
-/* The following attributes cannot be read, since the "admin" user always has all rights.
-   - UserWriteMask
-   - UserAccessLevel
-   - UserExecutable
-*/
+UA_Server_writeExecutable(UA_Server *server, const UA_NodeId nodeId,
+                          const UA_Boolean executable) {
+    return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EXECUTABLE,
+                             &UA_TYPES[UA_TYPES_BOOLEAN], &executable); }
 
+/**
+ * Read Node Attributes
+ * ^^^^^^^^^^^^^^^^^^^^
+ * The following attributes cannot be read, since the local "admin" user always has
+ * full rights.
+ *
+ * - UserWriteMask
+ * - UserAccessLevel
+ * - UserExecutable */
 /* Don't use this function. There are typed versions for every supported attribute. */
 UA_StatusCode UA_EXPORT
-__UA_Server_read(UA_Server *server, const UA_NodeId *nodeId, UA_AttributeId attributeId, void *v);
+__UA_Server_read(UA_Server *server, const UA_NodeId *nodeId,
+                 UA_AttributeId attributeId, void *v);
   
 static UA_INLINE UA_StatusCode
-UA_Server_readNodeId(UA_Server *server, const UA_NodeId nodeId, UA_NodeId *outNodeId) {
+UA_Server_readNodeId(UA_Server *server, const UA_NodeId nodeId,
+                     UA_NodeId *outNodeId) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_NODEID, outNodeId); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readNodeClass(UA_Server *server, const UA_NodeId nodeId, UA_NodeClass *outNodeClass) {
+UA_Server_readNodeClass(UA_Server *server, const UA_NodeId nodeId,
+                        UA_NodeClass *outNodeClass) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_NODECLASS, outNodeClass); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readBrowseName(UA_Server *server, const UA_NodeId nodeId, UA_QualifiedName *outBrowseName) {
+UA_Server_readBrowseName(UA_Server *server, const UA_NodeId nodeId,
+                         UA_QualifiedName *outBrowseName) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_BROWSENAME, outBrowseName); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readDisplayName(UA_Server *server, const UA_NodeId nodeId, UA_LocalizedText *outDisplayName) {
+UA_Server_readDisplayName(UA_Server *server, const UA_NodeId nodeId,
+                          UA_LocalizedText *outDisplayName) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME, outDisplayName); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readDescription(UA_Server *server, const UA_NodeId nodeId, UA_LocalizedText *outDescription) {
+UA_Server_readDescription(UA_Server *server, const UA_NodeId nodeId,
+                          UA_LocalizedText *outDescription) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DESCRIPTION, outDescription); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readWriteMask(UA_Server *server, const UA_NodeId nodeId, UA_UInt32 *outWriteMask) {
+UA_Server_readWriteMask(UA_Server *server, const UA_NodeId nodeId,
+                        UA_UInt32 *outWriteMask) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_WRITEMASK, outWriteMask); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readIsAbstract(UA_Server *server, const UA_NodeId nodeId, UA_Boolean *outIsAbstract) {
+UA_Server_readIsAbstract(UA_Server *server, const UA_NodeId nodeId,
+                         UA_Boolean *outIsAbstract) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ISABSTRACT, outIsAbstract); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readSymmetric(UA_Server *server, const UA_NodeId nodeId, UA_Boolean *outSymmetric) {
+UA_Server_readSymmetric(UA_Server *server, const UA_NodeId nodeId,
+                        UA_Boolean *outSymmetric) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_SYMMETRIC, outSymmetric); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readInverseName(UA_Server *server, const UA_NodeId nodeId, UA_LocalizedText *outInverseName) {
+UA_Server_readInverseName(UA_Server *server, const UA_NodeId nodeId,
+                          UA_LocalizedText *outInverseName) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_INVERSENAME, outInverseName); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readContainsNoLoop(UA_Server *server, const UA_NodeId nodeId, UA_Boolean *outContainsNoLoops) {
-    return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_CONTAINSNOLOOPS, outContainsNoLoops); }
+UA_Server_readContainsNoLoop(UA_Server *server, const UA_NodeId nodeId,
+                             UA_Boolean *outContainsNoLoops) {
+    return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_CONTAINSNOLOOPS,
+                            outContainsNoLoops); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readEventNotifier(UA_Server *server, const UA_NodeId nodeId, UA_Byte *outEventNotifier) {
+UA_Server_readEventNotifier(UA_Server *server, const UA_NodeId nodeId,
+                            UA_Byte *outEventNotifier) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER, outEventNotifier); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readValue(UA_Server *server, const UA_NodeId nodeId, UA_Variant *outValue) {
+UA_Server_readValue(UA_Server *server, const UA_NodeId nodeId,
+                    UA_Variant *outValue) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_VALUE, outValue); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readDataType(UA_Server *server, const UA_NodeId nodeId, UA_NodeId *outDataType) {
+UA_Server_readDataType(UA_Server *server, const UA_NodeId nodeId,
+                       UA_NodeId *outDataType) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DATATYPE, outDataType); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readValueRank(UA_Server *server, const UA_NodeId nodeId, UA_Int32 *outValueRank) {
+UA_Server_readValueRank(UA_Server *server, const UA_NodeId nodeId,
+                        UA_Int32 *outValueRank) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_VALUERANK, outValueRank); }
 
 /* Returns a variant with an int32 array */
 static UA_INLINE UA_StatusCode
-UA_Server_readArrayDimensions(UA_Server *server, const UA_NodeId nodeId, UA_Variant *outArrayDimensions) {
-    return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ARRAYDIMENSIONS, outArrayDimensions); }
+UA_Server_readArrayDimensions(UA_Server *server, const UA_NodeId nodeId,
+                              UA_Variant *outArrayDimensions) {
+    return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ARRAYDIMENSIONS,
+                            outArrayDimensions); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readAccessLevel(UA_Server *server, const UA_NodeId nodeId, UA_UInt32 *outAccessLevel) {
+UA_Server_readAccessLevel(UA_Server *server, const UA_NodeId nodeId,
+                          UA_UInt32 *outAccessLevel) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL, outAccessLevel); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId, UA_Double *outMinimumSamplingInterval) {
-    return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, outMinimumSamplingInterval); }
+UA_Server_readMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId,
+                                      UA_Double *outMinimumSamplingInterval) {
+    return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
+                            outMinimumSamplingInterval); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readHistorizing(UA_Server *server, const UA_NodeId nodeId, UA_Boolean *outHistorizing) {
+UA_Server_readHistorizing(UA_Server *server, const UA_NodeId nodeId,
+                          UA_Boolean *outHistorizing) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_HISTORIZING, outHistorizing); }
 
 static UA_INLINE UA_StatusCode
-UA_Server_readExecutable(UA_Server *server, const UA_NodeId nodeId, UA_Boolean *outExecutable) {
+UA_Server_readExecutable(UA_Server *server, const UA_NodeId nodeId,
+                         UA_Boolean *outExecutable) {
     return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_EXECUTABLE, outExecutable); }
 
-/****************/
-/* Browse Nodes */
-/****************/
+/**
+ * Reference Management
+ * -------------------- */
+UA_StatusCode UA_EXPORT
+UA_Server_addReference(UA_Server *server, const UA_NodeId sourceId, const UA_NodeId refTypeId,
+                       const UA_ExpandedNodeId targetId, UA_Boolean isForward);
+
+UA_StatusCode UA_EXPORT
+UA_Server_deleteReference(UA_Server *server, const UA_NodeId sourceNodeId,
+                          const UA_NodeId referenceTypeId, UA_Boolean isForward,
+                          const UA_ExpandedNodeId targetNodeId, UA_Boolean deleteBidirectional);
 
-UA_BrowseResult UA_EXPORT UA_Server_browse(UA_Server *server, UA_UInt32 maxrefs, const UA_BrowseDescription *descr);
-UA_BrowseResult UA_Server_browseNext(UA_Server *server, UA_Boolean releaseContinuationPoint, const UA_ByteString *continuationPoint);
+/**
+ * Browsing
+ * -------- */
+UA_BrowseResult UA_EXPORT
+UA_Server_browse(UA_Server *server, UA_UInt32 maxrefs, const UA_BrowseDescription *descr);
+
+UA_BrowseResult UA_EXPORT
+UA_Server_browseNext(UA_Server *server, UA_Boolean releaseContinuationPoint,
+                     const UA_ByteString *continuationPoint);
+
+#ifndef HAVE_NODEITER_CALLBACK
+#define HAVE_NODEITER_CALLBACK
+/* Iterate over all nodes referenced by parentNodeId by calling the callback
+ * function for each child node (in ifdef because GCC/CLANG handle include order
+ * differently) */
+typedef UA_StatusCode (*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean isInverse,
+                                                 UA_NodeId referenceTypeId, void *handle);
+#endif
 
-/***************/
-/* Call Method */
-/***************/
+UA_StatusCode UA_EXPORT
+UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
+                               UA_NodeIteratorCallback callback, void *handle);
 
+/**
+ * Method Call
+ * ----------- */
 #ifdef UA_ENABLE_METHODCALLS
-UA_CallMethodResult UA_EXPORT UA_Server_call(UA_Server *server, const UA_CallMethodRequest *request);
+UA_CallMethodResult UA_EXPORT
+UA_Server_call(UA_Server *server, const UA_CallMethodRequest *request);
 #endif
 
 #ifdef __cplusplus