Browse Source

improve documentation and html/latex generation

Julius Pfrommer 8 years ago
parent
commit
392217167f

+ 13 - 2
doc/CMakeLists.txt

@@ -8,8 +8,20 @@ set(DOC_SRC_DIR   ${PROJECT_BINARY_DIR}/doc_src)
 make_directory(${DOC_SRC_DIR})
 make_directory(${DOC_SRC_DIR})
 file(GLOB DOC_SRC "${PROJECT_SOURCE_DIR}/doc/*")
 file(GLOB DOC_SRC "${PROJECT_SOURCE_DIR}/doc/*")
 list(REMOVE_ITEM DOC_SRC "${PROJECT_SOURCE_DIR}/doc/conf.py")
 list(REMOVE_ITEM DOC_SRC "${PROJECT_SOURCE_DIR}/doc/conf.py")
-configure_file("${PROJECT_SOURCE_DIR}/doc/conf.py" "${DOC_SRC_DIR}/conf.py")
+list(REMOVE_ITEM DOC_SRC "${PROJECT_SOURCE_DIR}/doc/tutorial_server_variables.rst")
+list(REMOVE_ITEM DOC_SRC "${PROJECT_SOURCE_DIR}/doc/tutorial_server_method.rst")
+list(REMOVE_ITEM DOC_SRC "${PROJECT_SOURCE_DIR}/doc/tutorial_server_firstSteps.rst")
+list(REMOVE_ITEM DOC_SRC "${PROJECT_SOURCE_DIR}/doc/tutorial_client_firstSteps.rst")
 file(COPY ${DOC_SRC} DESTINATION ${DOC_SRC_DIR})
 file(COPY ${DOC_SRC} DESTINATION ${DOC_SRC_DIR})
+configure_file("${PROJECT_SOURCE_DIR}/doc/conf.py" "${DOC_SRC_DIR}/conf.py")
+configure_file("${PROJECT_SOURCE_DIR}/doc/tutorial_server_variables.rst"
+               "${DOC_SRC_DIR}/tutorial_server_variables.rst")
+configure_file("${PROJECT_SOURCE_DIR}/doc/tutorial_server_method.rst"
+               "${DOC_SRC_DIR}/tutorial_server_method.rst")
+configure_file("${PROJECT_SOURCE_DIR}/doc/tutorial_server_firstSteps.rst"
+               "${DOC_SRC_DIR}/tutorial_server_firstSteps.rst")
+configure_file("${PROJECT_SOURCE_DIR}/doc/tutorial_client_firstSteps.rst"
+               "${DOC_SRC_DIR}/tutorial_client_firstSteps.rst")
 
 
 function(generate_rst in out)
 function(generate_rst in out)
   add_custom_command(OUTPUT ${out} DEPENDS ${PROJECT_SOURCE_DIR}/tools/c2rst.py ${in}
   add_custom_command(OUTPUT ${out} DEPENDS ${PROJECT_SOURCE_DIR}/tools/c2rst.py ${in}
@@ -37,7 +49,6 @@ add_custom_target(doc_latex ${SPHINX_EXECUTABLE}
   COMMENT "Building LaTeX sources for documentation with Sphinx")
   COMMENT "Building LaTeX sources for documentation with Sphinx")
 add_dependencies(doc_latex open62541)
 add_dependencies(doc_latex open62541)
 
 
-
 add_custom_target(doc_pdf ${PDFLATEX_COMPILER} -q "open62541.tex"
 add_custom_target(doc_pdf ${PDFLATEX_COMPILER} -q "open62541.tex"
   WORKING_DIRECTORY ${DOC_LATEX_DIR}
   WORKING_DIRECTORY ${DOC_LATEX_DIR}
   # compile it twice so that the contents pages are correct
   # compile it twice so that the contents pages are correct

+ 11 - 11
doc/building.rst

@@ -1,10 +1,10 @@
 .. _building:
 .. _building:
 
 
 Building open62541
 Building open62541
-^^^^^^^^^^^^^^^^^^
+==================
 
 
 Building the Examples
 Building the Examples
-=====================
+---------------------
 
 
 Using the GCC compiler, the following calls build the examples on Linux.
 Using the GCC compiler, the following calls build the examples on Linux.
 
 
@@ -15,10 +15,10 @@ Using the GCC compiler, the following calls build the examples on Linux.
    gcc -std=c99 open62541.c server_variable.c -o server
    gcc -std=c99 open62541.c server_variable.c -o server
 
 
 Building the Library
 Building the Library
-====================
+--------------------
 
 
 Building with CMake on Ubuntu or Debian
 Building with CMake on Ubuntu or Debian
----------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 .. code-block:: bash
 .. code-block:: bash
 
 
@@ -41,7 +41,7 @@ Building with CMake on Ubuntu or Debian
    make
    make
 
 
 Building with CMake on Windows
 Building with CMake on Windows
-------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 Here we explain the build process for Visual Studio (2013 or newer). To build
 Here we explain the build process for Visual Studio (2013 or newer). To build
 with MinGW, just replace the compiler selection in the call to CMake.
 with MinGW, just replace the compiler selection in the call to CMake.
@@ -66,7 +66,7 @@ with MinGW, just replace the compiler selection in the call to CMake.
 - Then open :file:`build\open62541.sln` in Visual Studio 2015 and build as usual
 - Then open :file:`build\open62541.sln` in Visual Studio 2015 and build as usual
 
 
 Building on OS X
 Building on OS X
-----------------
+^^^^^^^^^^^^^^^^
 
 
 - Download and install
 - Download and install
 
 
@@ -88,10 +88,10 @@ Building on OS X
 Follow Ubuntu instructions without the ``apt-get`` commands as these are taken care of by the above packages.
 Follow Ubuntu instructions without the ``apt-get`` commands as these are taken care of by the above packages.
 
 
 Build Options
 Build Options
-=============
+-------------
 
 
 Build Type and Logging
 Build Type and Logging
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
 
 
 **CMAKE_BUILD_TYPE**
 **CMAKE_BUILD_TYPE**
   - ``RelWithDebInfo`` -O2 optimization with debug symbols
   - ``RelWithDebInfo`` -O2 optimization with debug symbols
@@ -113,7 +113,7 @@ Further options that are not inherited from the CMake configuration are defined
 in :file:`ua_config.h`. Usually there is no need to adjust them.
 in :file:`ua_config.h`. Usually there is no need to adjust them.
 
 
 UA_BUILD_* group
 UA_BUILD_* group
-----------------
+^^^^^^^^^^^^^^^^
 
 
 By default only the shared object libopen62541.so or the library open62541.dll
 By default only the shared object libopen62541.so or the library open62541.dll
 and open62541.dll.a resp. open62541.lib are build. Additional artifacts can be
 and open62541.dll.a resp. open62541.lib are build. Additional artifacts can be
@@ -139,7 +139,7 @@ specified by the following options:
    Generate a self-signed certificate for the server (openSSL required)
    Generate a self-signed certificate for the server (openSSL required)
 
 
 UA_ENABLE_* group
 UA_ENABLE_* group
------------------
+^^^^^^^^^^^^^^^^^
 
 
 This group contains build options related to the supported OPC UA features.
 This group contains build options related to the supported OPC UA features.
 
 
@@ -174,7 +174,7 @@ be visible in the cmake GUIs.
    Enable udp extension
    Enable udp extension
 
 
 Building a shared library
 Building a shared library
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 open62541 is small enough that most users will want to statically link the library into their programs. If a shared library (.dll, .so) is required, this can be enabled in CMake with the `BUILD_SHARED_LIBS` option.
 open62541 is small enough that most users will want to statically link the library into their programs. If a shared library (.dll, .so) is required, this can be enabled in CMake with the `BUILD_SHARED_LIBS` option.
 Note that this option modifies the :file:`ua_config.h` file that is also included in :file:`open62541.h` for the single-file distribution.
 Note that this option modifies the :file:`ua_config.h` file that is also included in :file:`open62541.h` for the single-file distribution.

+ 0 - 132
doc/in_a_nutshell.rst

@@ -1,132 +0,0 @@
-.. _introduction:
-
-Introduction to OPC UA
-======================
-
-OPC UA, a collection of services
---------------------------------
-
-In OPC UA, all communication is based on service calls, each consisting of a request and a response
-message. Be careful to note the difference between services and methods. Services are pre-defined in
-the standard and cannot be changed. But you can use the *Call* service to invoke user-defined
-methods on the server.
-
-For completeness, the following tables contain all services defined in the standard. Do not bother
-with their details yet. We will introduce the different services later in the text. In open62541,
-each service is implemented in a single function. See the :ref:`services` section for details.
-
-**Establishing communication**
-
-+-----------------------------+-----------------------------+------------------------------+
-| Discovery Service Set       | SecureChannel Service Set   | Session Service Set          |
-+=============================+=============================+==============================+
-| FindServers                 | OpenSecureChannel           | CreateSession                |
-+-----------------------------+-----------------------------+------------------------------+
-| GetEndpoints                | CloseSecureChannel          | ActivateSession              |
-+-----------------------------+-----------------------------+------------------------------+
-| RegisterServer              |                             | CloseSession                 |
-+-----------------------------+-----------------------------+------------------------------+
-|                             |                             | Cancel                       |
-+-----------------------------+-----------------------------+------------------------------+
-
-**Interaction with the information model**
-
-+-----------------------------+-------------------------------+------------------------------+------------------------------+----------------------+
-| Attribute Service Set       | View Service Set              | Method Service Set           | NodeManagement Service Set   | Query Service Set    |
-+=============================+===============================+==============================+==============================+======================+
-| Read                        | Browse                        | Call                         | AddNodes                     | QueryFirst           |
-+-----------------------------+-------------------------------+------------------------------+------------------------------+----------------------+
-| HistoryRead                 | BrowseNext                    |                              | AddReferences                | QueryNext            |
-+-----------------------------+-------------------------------+------------------------------+------------------------------+----------------------+
-| Write                       | TranslateBrowsePathsToNodeids |                              | DeleteNodes                  |                      |
-+-----------------------------+-------------------------------+------------------------------+------------------------------+----------------------+
-| HistoryUpdate               | RegisterNodes                 |                              | DeleteReferences             |                      |
-+-----------------------------+-------------------------------+------------------------------+------------------------------+----------------------+
-|                             | UnregisterNodes               |                              |                              |                      |
-+-----------------------------+-------------------------------+------------------------------+------------------------------+----------------------+
-
-**Notifications**
-
-+-----------------------------+-------------------------------+
-| MonitoredItem Service Set   | Subscription Service Set      |
-+=============================+===============================+
-| CreateMonitoredItems        | CreateSubscription            |
-+-----------------------------+-------------------------------+
-| ModifyMonitoreditems        | ModifySubscription            |
-+-----------------------------+-------------------------------+
-| SetMonitoringMode           | SetPublishingMode             |
-+-----------------------------+-------------------------------+
-| SetTriggering               | Publish                       |
-+-----------------------------+-------------------------------+
-| DeleteMonitoredItems        | Republish                     |
-+-----------------------------+-------------------------------+
-|                             | TransferSubscription          |
-+-----------------------------+-------------------------------+
-|                             | DeleteSubscription            |
-+-----------------------------+-------------------------------+
-
-OPC UA, a web of nodes
-----------------------
-
-The information model in each OPC UA server is a web of interconnected nodes.
-There are eight different types of nodes.
-
-+-----------------------+-------------------+
-| ReferenceTypeNode     | MethodNode        |
-+-----------------------+-------------------+
-| DataTypeNode          | ObjectTypeNode    |
-+-----------------------+-------------------+
-| VariableTypeNode      | ObjectNode        |
-+-----------------------+-------------------+
-| VariableNode          | ViewNode          |
-+-----------------------+-------------------+
-
-Depending on its type, every node contains different attributes. Some
-attributes, are contained in all node types:
-
-+----------------+---------------+
-| Name           | Type          |
-+================+===============+
-| nodeID         | NodeId        |
-+----------------+---------------+
-| nodeClass      | NodeClass     |
-+----------------+---------------+
-| browseName     | QualifiedName |
-+----------------+---------------+
-| displayName    | LocalizedText |
-+----------------+---------------+
-| description    | LocalizedText |
-+----------------+---------------+
-| writeMask      | UInt32        |
-+----------------+---------------+
-| userWriteMask  | UInt32        |
-+----------------+---------------+
-| referencesSize | Int32         |
-+----------------+---------------+
-| references     |ReferenceNode[]|
-+----------------+---------------+
-
-Nodes are interconnected by directed reference-triples of the form ``(nodeid,
-referencetype, target-nodeid)``. Therefore an OPC UA information model is
-easiest imagined as a *web of nodes*. Reference types can be
-
-- standard- or user-defined and
-- either non-hierarchical (e.g., indicating the type of a variable-node) or
-  hierarchical (e.g., indicating a parent-child relationship).
-
-OPC UA, a protocol
-------------------
-
-The OPC UA protocol (both binary and XML-based) is based on 25 *built-in*
-datatypes. In open62541, these are defined in ua_types.h.
-
-The builtin datatypes are combined to more complex structures. When the structure contains an array,
-then the size of the array is stored in an Int32 value just before the array itself. A size of -1
-indicates an undefined array. Positive sizes (and zero) have the usual semantics.
-
-Most importantly, every service has a request and a response message defined as such a data
-structure. The entire OPC UA protocol revolves around the exchange of these request and response
-messages. Their exact definitions can be looked up here:
-https://opcfoundation.org/UA/schemas/Opc.Ua.Types.bsd.xml. In open62541, we autogenerate the
-C-structs to handle the standard-defined structures automatically. See ua_types_generated.h for
-comparison.

File diff suppressed because it is too large
+ 15 - 160
doc/index.rst


+ 15 - 0
doc/index_html.rst

@@ -0,0 +1,15 @@
+.. include:: introduction.rst
+
+.. toctree::
+    :hidden:
+
+    self
+    building
+    tutorials
+    types
+    information_modelling
+    services
+    server
+    client
+    constants
+    internal

+ 5 - 6
doc/internal.rst

@@ -1,9 +1,8 @@
 Internals
 Internals
-#########
+=========
 
 
-.. toctree::
+.. include:: nodestore.rst
 
 
-   nodestore
-   connection
-   log
-   types_generated
+.. include:: connection.rst
+
+.. include:: log.rst

File diff suppressed because it is too large
+ 67 - 0
doc/introduction.rst


+ 7 - 7
doc/tutorial_client_firstSteps.rst

@@ -1,5 +1,5 @@
-5. Building a simple client
-===========================
+Building a simple client
+------------------------
 
 
 You should already have a basic server from the previous tutorials. open62541
 You should already have a basic server from the previous tutorials. open62541
 provides both a server- and clientside API, so creating a client is as easy as
 provides both a server- and clientside API, so creating a client is as easy as
@@ -29,24 +29,24 @@ Compilation is very much similar to the server example.
    $ gcc -std=c99 open6251.c myClient.c -o myClient
    $ gcc -std=c99 open6251.c myClient.c -o myClient
 
 
 Reading a node attibute
 Reading a node attibute
------------------------
+^^^^^^^^^^^^^^^^^^^^^^^
 
 
 In this example we are going to connect to the server from the second tutorial
 In this example we are going to connect to the server from the second tutorial
 and read the value-attribute of the added variable node.
 and read the value-attribute of the added variable node.
 
 
-.. literalinclude:: ../../examples/client_firstSteps.c
+.. literalinclude:: ${PROJECT_SOURCE_DIR}/examples/client_firstSteps.c
    :language: c
    :language: c
    :linenos:
    :linenos:
    :lines: 4,5,12,14-
    :lines: 4,5,12,14-
 
 
 
 
 Further tasks
 Further tasks
--------------
+^^^^^^^^^^^^^
 * Try to connect to some other OPC UA server by changing
 * Try to connect to some other OPC UA server by changing
-  "opc.tcp://localhost:16664" to an appropriate address (remember that the
+  ``opc.tcp://localhost:16664`` to an appropriate address (remember that the
   queried node is contained in any OPC UA server).
   queried node is contained in any OPC UA server).
 * Try to set the value of the variable node (ns=1,i="the.answer") containing an
 * Try to set the value of the variable node (ns=1,i="the.answer") containing an
-  "Int32" from the example server (which is built in
+  ``Int32`` from the example server (which is built in
   :doc:`tutorial_server_firstSteps`) using "UA_Client_write" function. The
   :doc:`tutorial_server_firstSteps`) using "UA_Client_write" function. The
   example server needs some more modifications, i.e., changing request types.
   example server needs some more modifications, i.e., changing request types.
   The answer can be found in "examples/exampleClient.c".
   The answer can be found in "examples/exampleClient.c".

File diff suppressed because it is too large
+ 27 - 167
doc/tutorial_noderelations.rst


+ 3 - 3
doc/tutorial_server_firstSteps.rst

@@ -1,5 +1,5 @@
-1. Building a simple server
-===========================
+Building a simple server
+------------------------
 
 
 This series of tutorial guide you through your first steps with open62541. For
 This series of tutorial guide you through your first steps with open62541. For
 compiling the examples, you need a compiler (MS Visual Studio 2015 or newer,
 compiling the examples, you need a compiler (MS Visual Studio 2015 or newer,
@@ -17,7 +17,7 @@ have the ``open62541.c/.h`` files in the current folder.
 
 
 Now create a new C source-file called ``myServer.c`` with the following content:
 Now create a new C source-file called ``myServer.c`` with the following content:
 
 
-.. literalinclude:: ../../examples/server_firstSteps.c
+.. literalinclude:: ${PROJECT_SOURCE_DIR}/examples/server_firstSteps.c
    :language: c
    :language: c
    :linenos:
    :linenos:
    :lines: 4,12,14-34
    :lines: 4,12,14-34

+ 3 - 3
doc/tutorial_server_method.rst

@@ -1,5 +1,5 @@
-3. Adding a server-side method
-==============================
+Adding a server-side method
+---------------------------
 
 
 This tutorial demonstrates how to add method nodes to the server. Use an UA
 This tutorial demonstrates how to add method nodes to the server. Use an UA
 client, e.g., UaExpert to call the method (right-click on the method node ->
 client, e.g., UaExpert to call the method (right-click on the method node ->
@@ -16,7 +16,7 @@ The last example presents a way to bind a new method callback to an already
 instantiated method node.
 instantiated method node.
 
 
 
 
-.. literalinclude:: ../../examples/server_method.c
+.. literalinclude:: ${PROJECT_SOURCE_DIR}/examples/server_method.c
    :language: c
    :language: c
    :linenos:
    :linenos:
    :lines: 4,5,14,16-
    :lines: 4,5,14,16-

+ 21 - 70
doc/tutorial_server_variables.rst

@@ -1,30 +1,27 @@
 .. role:: ccode(code)
 .. role:: ccode(code)
       :language: c
       :language: c
 
 
-2. Adding variables to a server
-===============================
+Adding variables to a server
+----------------------------
 
 
 This tutorial shows how to add variable nodes to a server and how these can be
 This tutorial shows how to add variable nodes to a server and how these can be
-connected to a physical process in the background. Make sure to read the
-:ref:`introduction <introduction>` first.
+connected to a physical process in the background.
 
 
 This is the code for a server with a single variable node holding an integer. We
 This is the code for a server with a single variable node holding an integer. We
 will take this example to explain some of the fundamental concepts of open62541.
 will take this example to explain some of the fundamental concepts of open62541.
 
 
-.. literalinclude:: ../../examples/server_variable.c
+.. literalinclude:: ${PROJECT_SOURCE_DIR}/examples/server_variable.c
    :language: c
    :language: c
    :linenos:
    :linenos:
    :lines: 4,13,15-
    :lines: 4,13,15-
 
 
-
 Variants and Datatypes
 Variants and Datatypes
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
 
 
-The datatype *variant* belongs to the built-in datatypes of OPC UA and is used
-as a container type. A variant can hold any other datatype as a scalar (except
-variant) or as an array. Array variants can additionally denote the
+The datatype :ref:`variant` belongs to the built-in datatypes of OPC UA and is
+used as a container type. A variant can hold any other datatype as a scalar
+(except variant) or as an array. Array variants can additionally denote the
 dimensionality of the data (e.g. a 2x3 matrix) in an additional integer array.
 dimensionality of the data (e.g. a 2x3 matrix) in an additional integer array.
-You can find the code that defines the variant datatype :ref:`here <variant>`.
 
 
 The `UA_VariableAttributes` type contains a variant member `value`. The command
 The `UA_VariableAttributes` type contains a variant member `value`. The command
 :ccode:`UA_Variant_setScalar(&attr.value, &myInteger,
 :ccode:`UA_Variant_setScalar(&attr.value, &myInteger,
@@ -33,20 +30,9 @@ this does not make a copy of the integer (for which `UA_Variant_setScalarCopy`
 can be used). The variant (and its content) is then copied into the newly
 can be used). The variant (and its content) is then copied into the newly
 created node.
 created node.
 
 
-Since it is a bit involved to set variants by hand, there are four basic
-functions you should be aware of:
-
-  * **UA_Variant_setScalar** will set the contents of the variant to a pointer
-    to the object that you pass with the call. Make sure to never deallocate
-    that object while the variant exists!
-  * **UA_Variant_setScalarCopy** will copy the object pointed to into a new
-    object of the same type and attach that to the variant.
-  * **UA_Variant_setArray** will set the contents of the variant to be an array
-    and point to the exact pointer/object that you passed the call.
-  * **UA_Variant_setArrayCopy** will create a copy of the array passed with the
-    call.
-
-The equivalent code using allocations is as follows:
+The above code could have used allocations by making copies of all entries of
+the attribute variant. Then, of course, the variant content needs to be deleted
+to prevent memleaks.
 
 
 .. code-block:: c
 .. code-block:: c
 
 
@@ -65,25 +51,11 @@ information model. For that, we state the NodeId of the parent node and the
 (hierarchical) reference to the parent node.
 (hierarchical) reference to the parent node.
 
 
 NodeIds
 NodeIds
--------
-
-A node ID is a unique identifier in server's context. It is composed of two members:
-
-+-------------+-----------------+---------------------------+
-| Type        | Name            | Notes                     |
-+=============+=================+===========================+
-| UInt16      | namespaceIndex  |  Number of the namespace  |
-+-------------+-----------------+---------------------------+
-| Union       | identifier      |  One idenifier of the     |
-|             |  * String       |  listed types             |
-|             |  * Integer      |                           |
-|             |  * GUID         |                           |
-|             |  * ByteString   |                           |
-+-------------+-----------------+---------------------------+
-
-The first parameter is the number of node's namespace, the second one may be a
-numeric, a string or a GUID (Globally Unique ID) identifier. The following are
-some examples for their usage.
+^^^^^^^
+
+A :ref:`nodeid` is a unique identifier in server's context. It contains the
+number of node's namespace and either a numeric, string or GUID (Globally
+Unique ID) identifier. The following are some examples for their usage.
 
 
 .. code-block:: c
 .. code-block:: c
 
 
@@ -91,33 +63,12 @@ some examples for their usage.
 
 
    UA_NodeId id2 = UA_NODEID_STRING(1, "testid"); /* points to the static string */
    UA_NodeId id2 = UA_NODEID_STRING(1, "testid"); /* points to the static string */
 
 
-   UA_NodeId id3 = UA_NODEID_STRING_ALLOC(1, "testid");
+   UA_NodeId id3 = UA_NODEID_STRING_ALLOC(1, "testid"); /* copy to memory */
    UA_NodeId_deleteMembers(&id3); /* free the allocated string */
    UA_NodeId_deleteMembers(&id3); /* free the allocated string */
 
 
 
 
-What is UA_NODEID_STRING_ALLOC for?
-
-
-Adding a variable node to the server that contains a user-defined callback
---------------------------------------------------------------------------
-
-The latter case allows to define callback functions that are executed on read or
-write of the node. In this case an "UA_DataSource" containing the respective
-callback pointer is intserted into the node.
-
-Consider ``examples/server_datasource.c`` in the repository. The examples are
-compiled if the Cmake option UA_BUILD_EXAMPLE is turned on.
-
-
-UA_Server_addVariableNode vs. UA_Server_addDataSourceVariableNode
-UA_ValueCallback
-UA_DataSource
-
-
-Asserting success/failure
--------------------------
+Adding a Variable with an external Data Source
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
-Almost all functions of the open62541 API will return a `StatusCode` 32-bit
-integer. The actual statuscodes are defined :ref:`here <statuscodes>`. Normally,
-the functions should return `UA_STATUSCODE_GOOD`, which maps to the zero
-integer.
+In order to couple a running process to a variable, a :ref:`datasource` is used.
+Consider ``examples/server_datasource.c`` in the repository for an example.

+ 8 - 6
doc/tutorials.rst

@@ -1,10 +1,12 @@
 Tutorials
 Tutorials
 =========
 =========
 
 
-.. toctree::
+.. include:: tutorial_server_firstSteps.rst
 
 
-   tutorial_server_firstSteps
-   tutorial_server_variables
-   tutorial_server_method
-   tutorial_noderelations
-   tutorial_client_firstSteps
+.. include:: tutorial_server_variables.rst
+
+.. include:: tutorial_server_method.rst
+
+.. include:: tutorial_noderelations.rst
+
+.. include:: tutorial_client_firstSteps.rst

+ 4 - 3
examples/server_firstSteps.c

@@ -22,13 +22,14 @@ int main(void) {
     signal(SIGTERM, stopHandler);
     signal(SIGTERM, stopHandler);
 
 
     UA_ServerConfig config = UA_ServerConfig_standard;
     UA_ServerConfig config = UA_ServerConfig_standard;
-    UA_ServerNetworkLayer nl = UA_ServerNetworkLayerTCP(UA_ConnectionConfig_standard, 16664);
+    UA_ServerNetworkLayer nl;
+    nl = UA_ServerNetworkLayerTCP(UA_ConnectionConfig_standard, 16664);
     config.networkLayers = &nl;
     config.networkLayers = &nl;
     config.networkLayersSize = 1;
     config.networkLayersSize = 1;
     UA_Server *server = UA_Server_new(config);
     UA_Server *server = UA_Server_new(config);
 
 
-    UA_StatusCode retval = UA_Server_run(server, &running);
+    UA_Server_run(server, &running);
     UA_Server_delete(server);
     UA_Server_delete(server);
     nl.deleteMembers(&nl);
     nl.deleteMembers(&nl);
-    return (int)retval;
+    return 0;
 }
 }

+ 1 - 1
include/ua_client.h

@@ -35,7 +35,7 @@ extern "C" {
  * convenience, some functionality has been wrapped in :ref:`high-level
  * convenience, some functionality has been wrapped in :ref:`high-level
  * abstractions <client-highlevel>`.
  * abstractions <client-highlevel>`.
  *
  *
- * **However**: At this point, the client does not yet contain its own thread or
+ * **However**: At this time, the client does not yet contain its own thread or
  * event-driven main-loop. So the client will not perform any actions
  * event-driven main-loop. So the client will not perform any actions
  * automatically in the background. This is especially relevant for
  * automatically in the background. This is especially relevant for
  * subscriptions. The user will have to periodically call
  * subscriptions. The user will have to periodically call

+ 11 - 13
include/ua_client_highlevel.h

@@ -27,22 +27,19 @@ extern "C" {
  *
  *
  * Highlevel Client Functionality
  * Highlevel Client Functionality
  * ------------------------------
  * ------------------------------
- * The following definitions are convenience functions making use of the
- * standard OPC UA services in the background.
- *
- * The high level abstractions concetrate on getting the job done in a simple
- * manner for the user. This is a less flexible way of handling the stack,
- * because at many places sensible defaults are presumed; at the same time using
- * these functions is the easiest way of implementing an OPC UA application, as
- * you will not have to consider all the details that go into the OPC UA
- * services. A concept of how nodes and datatypes are used are completely
- * sufficient to use OPC UA with this layer.
  *
  *
- * If more flexibility is needed, you can always achieve the same functionality
- * using the raw :ref:`OPC UA services <client-services>`.
+ * The following definitions are convenience functions making use of the
+ * standard OPC UA services in the background. This is a less flexible way of
+ * handling the stack, because at many places sensible defaults are presumed; at
+ * the same time using these functions is the easiest way of implementing an OPC
+ * UA application, as you will not have to consider all the details that go into
+ * the OPC UA services. If more flexibility is needed, you can always achieve
+ * the same functionality using the raw :ref:`OPC UA services
+ * <client-services>`.
  *
  *
  * Read Attributes
  * Read Attributes
  * ^^^^^^^^^^^^^^^
  * ^^^^^^^^^^^^^^^
+ *
  * The following functions can be used to retrieve a single node attribute. Use
  * The following functions can be used to retrieve a single node attribute. Use
  * the regular service to read several attributes at once. */
  * the regular service to read several attributes at once. */
 /* Don't call this function, use the typed versions */
 /* Don't call this function, use the typed versions */
@@ -221,6 +218,7 @@ UA_Client_readUserExecutableAttribute(UA_Client *client, const UA_NodeId nodeId,
 /**
 /**
  * Write Attributes
  * Write Attributes
  * ^^^^^^^^^^^^^^^^
  * ^^^^^^^^^^^^^^^^
+ *
  * The following functions can be use to write a single node attribute at a
  * The following functions can be use to write a single node attribute at a
  * time. Use the regular write service to write several attributes at once. */
  * time. Use the regular write service to write several attributes at once. */
 /* Don't call this function, use the typed versions */
 /* Don't call this function, use the typed versions */
@@ -555,7 +553,7 @@ UA_Client_addMethodNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
  *
  *
  * Subscriptions Handling
  * Subscriptions Handling
  * ^^^^^^^^^^^^^^^^^^^^^^
  * ^^^^^^^^^^^^^^^^^^^^^^
- * At this point, the client does not yet contain its own thread or event-driven
+ * At this time, the client does not yet contain its own thread or event-driven
  * main-loop. So the client will not perform any actions automatically in the
  * main-loop. So the client will not perform any actions automatically in the
  * background. This is especially relevant for subscriptions. The user will have
  * background. This is especially relevant for subscriptions. The user will have
  * to periodically call `UA_Client_Subscriptions_manuallySendPublishRequest`.
  * to periodically call `UA_Client_Subscriptions_manuallySendPublishRequest`.

+ 4 - 3
include/ua_connection.h

@@ -43,7 +43,7 @@ typedef struct UA_SecureChannel UA_SecureChannel;
  * without being aware of the underlying transport technology.
  * without being aware of the underlying transport technology.
  *
  *
  * Connection Config
  * Connection Config
- * ================= */
+ * ^^^^^^^^^^^^^^^^^ */
 typedef struct UA_ConnectionConfig {
 typedef struct UA_ConnectionConfig {
     UA_UInt32 protocolVersion;
     UA_UInt32 protocolVersion;
     UA_UInt32 sendBufferSize;
     UA_UInt32 sendBufferSize;
@@ -56,7 +56,7 @@ extern const UA_EXPORT UA_ConnectionConfig UA_ConnectionConfig_standard;
 
 
 /**
 /**
  * Connection Structure
  * Connection Structure
- * ==================== */
+ * ^^^^^^^^^^^^^^^^^^^^ */
 typedef enum UA_ConnectionState {
 typedef enum UA_ConnectionState {
     UA_CONNECTION_OPENING,     /* The socket is open, but the HEL/ACK handshake
     UA_CONNECTION_OPENING,     /* The socket is open, but the HEL/ACK handshake
                                   is not done */
                                   is not done */
@@ -119,7 +119,8 @@ void UA_EXPORT UA_Connection_deleteMembers(UA_Connection *connection);
 
 
 
 
 /**
 /**
- * EndpointURL helper
+ * EndpointURL Helper
+ * ^^^^^^^^^^^^^^^^^^
  */
  */
 
 
 /**
 /**

+ 2 - 1
include/ua_log.h

@@ -25,6 +25,7 @@ extern "C" {
 /**
 /**
  * Logging
  * Logging
  * -------
  * -------
+ *
  * Servers and clients may contain a logger. Every logger needs to implement the
  * Servers and clients may contain a logger. Every logger needs to implement the
  * `UA_Logger` signature. An example logger that writes to stdout is provided in
  * `UA_Logger` signature. An example logger that writes to stdout is provided in
  * the plugins folder.
  * the plugins folder.
@@ -105,7 +106,7 @@ typedef void (*UA_Logger)(UA_LogLevel level, UA_LogCategory category,
 
 
 /**
 /**
  * Convenience macros for complex types
  * Convenience macros for complex types
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
 #define UA_PRINTF_GUID_FORMAT "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"
 #define UA_PRINTF_GUID_FORMAT "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"
 #define UA_PRINTF_GUID_DATA(GUID) (GUID).data1, (GUID).data2, (GUID).data3, \
 #define UA_PRINTF_GUID_DATA(GUID) (GUID).data1, (GUID).data2, (GUID).data3, \
         (GUID).data4[0], (GUID).data4[1], (GUID).data4[2], (GUID).data4[3], \
         (GUID).data4[0], (GUID).data4[1], (GUID).data4[2], (GUID).data4[3], \

+ 4 - 0
include/ua_server.h

@@ -555,6 +555,8 @@ UA_Server_call(UA_Server *server, const UA_CallMethodRequest *request);
  * - Method callbacks, where a user-defined method is exposed in the information
  * - Method callbacks, where a user-defined method is exposed in the information
  *   model
  *   model
  *
  *
+ * .. _datasource:
+ *
  * Data Source Callback
  * Data Source Callback
  * ~~~~~~~~~~~~~~~~~~~~
  * ~~~~~~~~~~~~~~~~~~~~
  *
  *
@@ -627,6 +629,8 @@ UA_Server_setVariableNode_valueCallback(UA_Server *server, const UA_NodeId nodeI
                                         const UA_ValueCallback callback);
                                         const UA_ValueCallback callback);
 
 
 /**
 /**
+ * .. _object-lifecycle:
+ *
  * Object Lifecycle Management Callbacks
  * Object Lifecycle Management Callbacks
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  * Lifecycle management adds constructor and destructor callbacks to
  * Lifecycle management adds constructor and destructor callbacks to

+ 7 - 10
include/ua_types.h

@@ -28,20 +28,17 @@ extern "C" {
  * ==========
  * ==========
  *
  *
  * The OPC UA protocol defines 25 builtin data types and three ways of combining
  * The OPC UA protocol defines 25 builtin data types and three ways of combining
- * them into higher-order types: arrays, structures and unions. When the type of
- * a value can be decided at runtime, it is be wrapped into a :ref:`variant`
- * together with a description of the content. This metadata is used to decode
- * the value on the receiving end. In open62541, the builtin data types are
- * defined manually. Higher-order data types are generated from standard XML
- * definitions. Their exact definitions can be looked up at
- * https://opcfoundation.org/UA/schemas/Opc.Ua.Types.bsd.xml.
+ * them into higher-order types: arrays, structures and unions. In open62541,
+ * the builtin data types are defined manually. All other data types are
+ * generated from standard XML definitions. Their exact definitions can be
+ * looked up at https://opcfoundation.org/UA/schemas/Opc.Ua.Types.bsd.xml.
  *
  *
  * Note that arrays can only be part of a scalar data type and never constitute
  * Note that arrays can only be part of a scalar data type and never constitute
  * a data type on their own. Also, open62541 does not implement unions so far.
  * a data type on their own. Also, open62541 does not implement unions so far.
  * They are a recent addition to the protocol (since OPC UA v1.03). And so far,
  * They are a recent addition to the protocol (since OPC UA v1.03). And so far,
  * no service definition makes of unions in the request / response message
  * no service definition makes of unions in the request / response message
- * definition. Instead, :ref:`Variants <variant>` are used where several member
- * value types are possible.
+ * definition. Instead, :ref:`Variants <variant>` are used when values of
+ * different types are possible.
  *
  *
  * All data types ``T`` (builtin and generated) share the same basic API for
  * All data types ``T`` (builtin and generated) share the same basic API for
  * creation, copying and deletion:
  * creation, copying and deletion:
@@ -49,7 +46,7 @@ extern "C" {
  * - ``void T_init(T *ptr)``: Initialize the data type. This is synonymous with
  * - ``void T_init(T *ptr)``: Initialize the data type. This is synonymous with
  *   zeroing out the memory, i.e. ``memset(ptr, 0, sizeof(T))``.
  *   zeroing out the memory, i.e. ``memset(ptr, 0, sizeof(T))``.
  * - ``T* T_new()``: Allocate and return the memory for the data type. The
  * - ``T* T_new()``: Allocate and return the memory for the data type. The
- *   memory is already initialized.
+ *   value is already initialized.
  * - ``UA_StatusCode T_copy(const T *src, T *dst)``: Copy the content of the
  * - ``UA_StatusCode T_copy(const T *src, T *dst)``: Copy the content of the
  *   data type. Returns ``UA_STATUSCODE_GOOD`` or
  *   data type. Returns ``UA_STATUSCODE_GOOD`` or
  *   ``UA_STATUSCODE_BADOUTOFMEMORY``.
  *   ``UA_STATUSCODE_BADOUTOFMEMORY``.

+ 9 - 4
src/server/ua_nodes.h

@@ -8,6 +8,8 @@ extern "C" {
 #include "ua_server.h"
 #include "ua_server.h"
 
 
 /**
 /**
+ * .. _information-modelling:
+ *
  * Information Modelling
  * Information Modelling
  * =====================
  * =====================
  *
  *
@@ -224,7 +226,9 @@ typedef struct {
  * ObjectTypeNode
  * ObjectTypeNode
  * --------------
  * --------------
  *
  *
- * ObjectTypes provide definitions for Objects. */
+ * ObjectTypes provide definitions for Objects. Abstract objects cannot be
+ * instantiated. See :ref:`object-lifecycle` for the use of constructor and
+ * destructor callbacks. */
 typedef struct {
 typedef struct {
     UA_NODE_BASEATTRIBUTES
     UA_NODE_BASEATTRIBUTES
     UA_Boolean isAbstract;
     UA_Boolean isAbstract;
@@ -254,9 +258,10 @@ typedef struct {
  * DataTypeNode
  * DataTypeNode
  * ------------
  * ------------
  *
  *
- * DataTypes represent simple and structured data types (for scalar values). In
- * open62541, DataTypeNodes in the hierarchy are matched to `UA_DataType` type
- * descriptions for :ref:`generic-types` via their NodeId.
+ * DataTypes represent simple and structured data types. DataTypes may contain
+ * arrays. But they always describe the structure of a single instance. In
+ * open62541, DataTypeNodes in the information model hierarchy are matched to
+ * ``UA_DataType`` type descriptions for :ref:`generic-types` via their NodeId.
  *
  *
  * Abstract DataTypes (e.g. ``Number``) cannot be the type of actual values.
  * Abstract DataTypes (e.g. ``Number``) cannot be the type of actual values.
  * They are used to constrain values to possible child DataTypes (e.g.
  * They are used to constrain values to possible child DataTypes (e.g.

+ 5 - 5
src/server/ua_nodestore.h

@@ -10,7 +10,7 @@ extern "C" {
 
 
 /**
 /**
  * Nodestore
  * Nodestore
- * =========
+ * ---------
  * Stores nodes that can be indexed by their NodeId. Internally, it is based on
  * Stores nodes that can be indexed by their NodeId. Internally, it is based on
  * a hash-map implementation. */
  * a hash-map implementation. */
 struct UA_NodeStore;
 struct UA_NodeStore;
@@ -18,7 +18,7 @@ typedef struct UA_NodeStore UA_NodeStore;
 
 
 /**
 /**
  * Nodestore Lifecycle
  * Nodestore Lifecycle
- * ------------------- */
+ * ^^^^^^^^^^^^^^^^^^^ */
 /* Create a new nodestore */
 /* Create a new nodestore */
 UA_NodeStore * UA_NodeStore_new(void);
 UA_NodeStore * UA_NodeStore_new(void);
 
 
@@ -28,7 +28,7 @@ void UA_NodeStore_delete(UA_NodeStore *ns);
 
 
 /**
 /**
  * Node Lifecycle
  * Node Lifecycle
- * ---------------
+ * ^^^^^^^^^^^^^^
  *
  *
  * The following definitions are used to create empty nodes of the different
  * The following definitions are used to create empty nodes of the different
  * node types. The memory is managed by the nodestore. Therefore, the node has
  * node types. The memory is managed by the nodestore. Therefore, the node has
@@ -58,7 +58,7 @@ void UA_NodeStore_deleteNode(UA_Node *node);
 
 
 /**
 /**
  * Insert / Get / Replace / Remove
  * Insert / Get / Replace / Remove
- * ------------------------------- */
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
 /* Inserts a new node into the nodestore. If the nodeid is zero, then a fresh
 /* Inserts a new node into the nodestore. If the nodeid is zero, then a fresh
  * numeric nodeid from namespace 1 is assigned. If insertion fails, the node is
  * numeric nodeid from namespace 1 is assigned. If insertion fails, the node is
  * deleted. */
  * deleted. */
@@ -83,7 +83,7 @@ UA_StatusCode UA_NodeStore_remove(UA_NodeStore *ns, const UA_NodeId *nodeid);
 
 
 /**
 /**
  * Iteration
  * Iteration
- * ---------
+ * ^^^^^^^^^
  * The following definitions are used to call a callback for every node in the
  * The following definitions are used to call a callback for every node in the
  * nodestore. */
  * nodestore. */
 typedef void (*UA_NodeStore_nodeVisitor)(const UA_Node *node);
 typedef void (*UA_NodeStore_nodeVisitor)(const UA_Node *node);

+ 0 - 1
src/server/ua_services_nodemanagement.c

@@ -461,7 +461,6 @@ Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
     return retval;
     return retval;
 }
 }
 
 
-
 /***********************************************/
 /***********************************************/
 /* Create a node from an attribute description */
 /* Create a node from an attribute description */
 /***********************************************/
 /***********************************************/