Browse Source

Merge remote-tracking branch 'origin/master' into connection_secureChannel

Conflicts:
	Makefile.am
	examples/src/networklayer.c
	examples/src/networklayer.h
	examples/src/opcuaServerACPLT.c
	include/ua_basictypes.h
	src/Makefile.am
	src/ua_basictypes.c
	src/ua_services.h
	src/ua_services_attribute.c
	src/ua_services_discovery.c
	src/ua_services_nodemanagement.c
	src/ua_services_securechannel.c
	src/ua_services_session.c
	src/ua_services_view.c
	src/ua_transport_binary.c
	src/ua_transport_binary.h
	src/ua_transport_binary_secure.c
	src/ua_transport_binary_secure.h
FlorianPalm 10 years ago
parent
commit
c62be40cef
96 changed files with 8956 additions and 5774 deletions
  1. 12 3
      .travis.yml
  2. 25 7
      Makefile.am
  3. 23 7
      README.md
  4. 43 3
      configure.ac
  5. 6 6
      doc/Doxyfile.in
  6. 194 0
      doc/DoxygenLayout.xml
  7. 1 0
      doc/style/load-style.js
  8. 4 0
      examples/src/Makefile.am
  9. 20 24
      examples/src/generateSam.c
  10. 43 19
      examples/src/networklayer.c
  11. 5 5
      examples/src/networklayer.h
  12. 148 2
      examples/src/opcuaServer.c
  13. 3 8
      examples/src/opcuaServerACPLT.c
  14. 65 0
      examples/src/raspberrypi_io.c
  15. 22 0
      examples/src/raspberrypi_io.h
  16. 36 47
      examples/src/xml2ns0.c
  17. 0 8
      include/Makefile.am
  18. 0 434
      include/ua_basictypes.h
  19. 0 66
      include/ua_types.h
  20. 0 0
      schema/NodeIds.csv
  21. 0 0
      schema/Opc.Ua.NodeSet2.Part3.xml
  22. 0 0
      schema/Opc.Ua.NodeSet2.Part4.xml
  23. 0 0
      schema/Opc.Ua.NodeSet2.Part5.xml
  24. 0 0
      schema/Opc.Ua.NodeSet2.xml
  25. 0 0
      schema/Opc.Ua.Types.bsd
  26. 0 0
      schema/UA_stackInternalTypes.bsd
  27. 46 25
      src/Makefile.am
  28. 606 32
      src/ua_application.c
  29. 2 2
      src/ua_application.h
  30. 0 1694
      src/ua_basictypes.c
  31. 2 7
      src/ua_namespace.c
  32. 9 6
      src/ua_namespace.h
  33. 85 0
      src/ua_namespace_xml.c
  34. 41 0
      src/ua_namespace_xml.h
  35. 30 14
      src/ua_services.h
  36. 358 118
      src/ua_services_attribute.c
  37. 18 15
      src/ua_services_discovery.c
  38. 16 0
      src/ua_services_internal.h
  39. 19 8
      src/ua_services_monitoreditems.c
  40. 70 13
      src/ua_services_nodemanagement.c
  41. 6 8
      src/ua_services_securechannel.c
  42. 19 17
      src/ua_services_session.c
  43. 30 0
      src/ua_services_subscription.c
  44. 228 15
      src/ua_services_view.c
  45. 17 5
      src/ua_stack_channel.c
  46. 2 2
      src/ua_stack_channel.h
  47. 5 4
      src/ua_stack_session.c
  48. 1 1
      src/ua_stack_session.h
  49. 2 2
      src/ua_stack_session_manager.h
  50. 1 1
      include/ua_statuscodes.h
  51. 312 237
      src/ua_transport.c
  52. 35 91
      src/ua_transport.h
  53. 11 10
      src/ua_transport_binary.c
  54. 2 1
      src/ua_transport_binary.h
  55. 132 34
      src/ua_transport_binary_secure.c
  56. 3 3
      src/ua_transport_binary_secure.h
  57. 15 1
      src/ua_transport_connection.c
  58. 9 5
      src/ua_transport_connection.h
  59. 1175 0
      src/ua_types.c
  60. 516 0
      src/ua_types.h
  61. 987 0
      src/ua_types_encoding_binary.c
  62. 112 0
      src/ua_types_encoding_binary.h
  63. 447 0
      src/ua_types_encoding_xml.c
  64. 77 0
      src/ua_types_encoding_xml.h
  65. 657 887
      src/ua_xml.c
  66. 68 59
      src/ua_xml.h
  67. 153 0
      src/util/ua_base64.c
  68. 20 0
      src/util/ua_base64.h
  69. 1 0
      src/util/ua_indexedList.c
  70. 1 1
      include/ua_indexedList.h
  71. 2 0
      src/util/ua_list.c
  72. 0 1
      include/ua_list.h
  73. 29 0
      src/util/ua_util.c
  74. 38 0
      src/util/ua_util.h
  75. 4 0
      tests/.gitignore
  76. 3 3
      tests/Makefile.am
  77. 115 0
      tests/check_base64.c
  78. 822 995
      tests/check_builtin.c
  79. 28 2
      tests/check_indexedList.c
  80. 2 1
      tests/check_list.c
  81. 109 105
      tests/check_memory.c
  82. 1 1
      tests/check_namespace.c
  83. 14 12
      tests/check_services_view.c
  84. 294 290
      tests/check_stack.c
  85. 8 17
      tests/check_xml.c
  86. 2 2
      tools/.coverity.sh
  87. 0 25
      tools/Makefile.am
  88. 215 228
      tools/generate_builtin.py
  89. 115 95
      tools/generate_namespace.py
  90. 4 40
      tools/indent.sh
  91. 95 0
      tools/uncrustify.cfg
  92. 11 0
      wrappers/Makefile.am
  93. 20 0
      wrappers/lua/Makefile.am
  94. 2 0
      wrappers/open62541.h
  95. 9 0
      wrappers/open62541.i
  96. 18 0
      wrappers/python/Makefile.am

+ 12 - 3
.travis.yml

@@ -10,7 +10,7 @@ addons:
     project:
       name: acplt/open62541
       description: Open-source OPC UA
-    notification_email: 
+    notification_email: null@plt.rwth-aachen.de
     build_command_prepend: ./autogen.sh && ./configure
     build_command: make
     branch_pattern: coverity_scan
@@ -28,9 +28,17 @@ before_install:
 - sudo ldconfig
 - cd ..
 - rm -rf check-code
-script: ./autogen.sh && ./configure --enable-doxygen && make && make check
+- sudo pip install cpp-coveralls
+script: 
+   - ./autogen.sh 
+   - ./configure 
+   - echo "Production build + checks"
+   - make && make check && make clean
+   - echo "Extended debug build + checks + coverage + doxygen"
+   - ./configure --enable-debug --enable-coverage --enable-doxygen
+   - make all && make check
 after_success:
-   - git clone -b gh-pages https://$GITAUTH@github.com/acplt/open62541
+   - git clone --depth=50 -b gh-pages https://$GITAUTH@github.com/acplt/open62541
    - rm -rf open62541/doxygen
    - cp -r doc/html open62541/doxygen
    - cd open62541/doxygen
@@ -44,3 +52,4 @@ after_success:
    - cd ..
    - rm -rf open62541
    - ./tools/.coverity.sh
+   - coveralls -b src --exclude doc --exclude examples --exclude tests --exclude wrappers --exclude src/.libs --exclude src/util/.libs -E '.*\.h' 

+ 25 - 7
Makefile.am

@@ -1,15 +1,21 @@
-AM_CFLAGS  = -std=c99 -pedantic -pipe -fPIC -fno-exceptions -fstack-protector -Wl,-z,relro -Wl,-z,now -fvisibility=hidden -W -Wall -Wno-unused-parameter -Wno-unused-function -Wno-unused-label -Wpointer-arith -Wformat -Wreturn-type -Wsign-compare -Wmultichar -Wformat-nonliteral -Winit-self -Wuninitialized -Wno-deprecated -Wformat-security -Werror
+AM_CFLAGS = -std=c99 -pedantic -pipe -fstack-protector -Wall -Wextra -Wno-unused-parameter -Wno-unused-function -Wno-unused-label -Wpointer-arith -Wformat -Wreturn-type -Wsign-compare -Wmultichar -Wformat-nonliteral -Winit-self -Wuninitialized -Wno-deprecated -Wformat-security -Werror -ffunction-sections -fdata-sections -Wl,--gc-sections
 AM_LDFLAGS =
 AM_LDADD =
 
+if TARGET_WIN
+else
+AM_CFLAGS += -fPIC
+endif
+
+
 if DEBUG
 AM_CFLAGS += -g3 -O0
 else
-AM_CFLAGS += -O2 
+AM_CFLAGS += -O2
 endif
 
 if COVERAGE
-AM_CFLAGS  += --coverage
+AM_CFLAGS += --coverage
 AM_LDFLAGS += --coverage
 endif
 
@@ -20,12 +26,24 @@ endif
 export GLOBAL_AM_CFLAGS = $(AM_CFLAGS)
 export GLOBAL_AM_LDADD = $(AM_LDADD)
 
-SUBS=tools include src
+SUBDIRS=src
 if HAVE_CHECK
-	SUBS+= tests
+SUBDIRS+= tests
 endif
 
 if ENABLE_DOXYGEN
-	SUBS+= doc
+SUBDIRS+= doc
+endif
+
+if TARGET_WIN
+else
+SUBDIRS += examples/src
 endif
-SUBDIRS = $(SUBS) examples/src	
+
+if PYTHON_WRAPPER
+SUBDIRS += wrappers wrappers/python
+endif
+
+if LUA_WRAPPER
+SUBDIRS += wrappers wrappers/lua
+endif

+ 23 - 7
README.md

@@ -1,15 +1,15 @@
-Open62541
+open62541
 =========
 
 An open-source communication stack implementation of OPC UA (OPC Unified Architecture) licensed under LGPL + static linking exception.
 
 [![Ohloh Project Status](https://www.ohloh.net/p/open62541/widgets/project_thin_badge.gif)](https://www.ohloh.net/p/open62541)
 [![Build Status](https://travis-ci.org/acplt/open62541.png?branch=master)](https://travis-ci.org/acplt/open62541)
+[![Coverage Status](https://coveralls.io/repos/acplt/open62541/badge.png?branch=master)](https://coveralls.io/r/acplt/open62541?branch=master)
 [![Coverity Scan Build Status](https://scan.coverity.com/projects/1864/badge.svg)](https://scan.coverity.com/projects/1864)
 
 ### Documentation
-Documentation is generated from Doxygen annotations in the source code. The current version can be accessed at http://acplt.github.io/open62541/doxygen/.
-
+Documentation is generated from Doxygen annotations in the source code. The current version can be accessed at [http://open62541.org/doxygen/](http://open62541.org/doxygen/).
 
 ## Getting dependencies
 ### Ubuntu
@@ -63,18 +63,28 @@ $ make all
 ##### Get expat
 * start MinGW Installation Manager
 * choose all Packages, mark mingw32-expat and install
+* Open MinGW\msys\1.0\msys.bat
+```bash
+$ mingw-get install libexpat
+```
 
 ##### Get Python and lxml:
-* download Python at https://python.org/downloads
+* download Python (Windows x86 MSI Installer) at https://python.org/downloads (necessary version: 2.7.x)
 * install the executable
-* add the install directory (e. g. "c:\python27") to your windows path variable 
+* add the install directory (e. g. "c:\python27") to your windows path variable [Selectable in the setup-options]
 * restart mingw console
-* install lxml by either downloading and installing http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml (choose the version which fits    to your python installation) or by following the instructions
-  given here: http://lxml.de/installation.html
+* install lxml by either downloading and installing http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml (choose the version which fits    to your python installation (x86 version)) or by following the instructions
+  given here: http://lxml.de/installation.html 
+* add ("C:\Python27\Tools\Scripts") to your windows path variable
+
 
 ##### Get git (IMPORTANT: get 1.8.4, since 1.8.5.2 has a bug):
 * http://code.google.com/p/msysgit/downloads/detail?name=Git-1.8.4-preview20130916.exe&can=2&q=
 
+##### SVN:
+* download: http://tortoisesvn.net/downloads.html
+* install svn @ c:\MinGW\
+
 ##### Getting and installing *check* as unit testing framework (http://check.sourceforge.net/):
 * Open MinGW\msys\1.0\msys.bat
 
@@ -87,6 +97,11 @@ $ make
 $ make install
 ```
 
+##### Adjusting MinGW
+* open the file c:\MinGW\include\io.h and replace every off64_t with _off64_t (4x should off64_t appear)
+* open the file c:\MinGW\include\unistd.h and replace every off_t with _off_t (2x should off_t appear)
+* download the queue.h header @ http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/queue.h and copy it to c:\MinGW\include\sys
+
 ## Building 
 * use autogen.sh only first time and whenever aclocal.m4 or configure.ac were modified
 ```bash
@@ -98,6 +113,7 @@ $ make check
 ```
 
 ### Configure Options 
+
 * --enable-debug=(yes|no|verbose) - omit/include debug code
 * --enable-multithreading - enable pthreads (for examples/src/opcuaServerMT)
 * --enable-doxygen - make documentation as well

+ 43 - 3
configure.ac

@@ -9,7 +9,7 @@ AC_PROG_MAKE_SET
 #default CFLAGS is -g -02
 #reset it just to -g and make optimization dependend on --enable-debug
 if test -z $CFLAGS; then
-    CFLAGS='-g'
+   CFLAGS=''
 fi
 AM_PATH_PYTHON
 AC_PROG_CC
@@ -29,6 +29,7 @@ AM_COND_IF([TARGET_WIN],
 AM_COND_IF([TARGET_LINUX],
     AC_DEFINE([LINUX]))
    
+#debugging
 AC_ARG_ENABLE(debug,
 AS_HELP_STRING([--enable-debug],
                [enable debugging, default: no]),
@@ -46,6 +47,7 @@ AM_CONDITIONAL(VERBOSE, test x"$verbose" = x"true")
 AM_COND_IF([VERBOSE],
     AC_DEFINE([VERBOSE])) #define VERBOSE is accessible from pre-processor
 
+#multithreading
 AC_ARG_ENABLE(multithreading,
 AS_HELP_STRING([--enable-multithreading],
                [enable multithreading, default: yes]),
@@ -58,6 +60,7 @@ AM_CONDITIONAL(MULTITHREADING, test x"$multithreading" = x"true")
 AM_COND_IF([MULTITHREADING],
     AC_DEFINE([MULTITHREADING])) #define MULTITHREADING is accessible from pre-processor
 
+#coverage
 AC_ARG_ENABLE(coverage,
 AS_HELP_STRING([--enable-coverage],
                [enable coverage, default: no]),
@@ -69,6 +72,19 @@ AS_HELP_STRING([--enable-coverage],
 AM_CONDITIONAL(COVERAGE, test x"$coverage" = x"true")
 AM_COND_IF([COVERAGE],
     AC_DEFINE([COVERAGE])) #define MULTITHREADING is accessible from pre-processor
+    
+#raspberry pi
+AC_ARG_ENABLE(raspi,
+AS_HELP_STRING([--enable-raspi],
+               [enable raspi, default: no]),
+	[case "${enableval}" in
+		yes) raspi=true ;;
+		no)  raspi=false ;;
+		*)   AC_MSG_ERROR([bad value ${enableval} for --enable-raspi]) ;; 
+	esac],[raspi=false])
+AM_CONDITIONAL(RASPI, test x"$raspi" = x"true")
+AM_COND_IF([RASPI],
+    AC_DEFINE([RASPI]))
 
 #doxygen start
 AC_ARG_ENABLE(doxygen,
@@ -96,10 +112,34 @@ fi
 AM_COND_IF([ENABLE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])])
 #doxygen end
 
-   
+#language wrappers
+AC_ARG_ENABLE(python_wrapper,
+AS_HELP_STRING([--enable-python-wrapper],
+               [build python-wrapper, default: no]),
+	[case "${enableval}" in
+		yes) python_wrapper=true ;;
+		no)  python_wrapper=false ;;
+		*)   AC_MSG_ERROR([bad value ${enableval} for --enable-python-wrapper]) ;; 
+	esac],[python_wrapper=false])
+AM_CONDITIONAL(PYTHON_WRAPPER, test x"$python_wrapper" = x"true")
+AM_COND_IF([PYTHON_WRAPPER],
+    AC_DEFINE([PYTHON_WRAPPER]))
+
+AC_ARG_ENABLE(lua_wrapper,
+AS_HELP_STRING([--enable-lua-wrapper],
+               [build lua-wrapper, default: no]),
+	[case "${enableval}" in
+		yes) lua_wrapper=true ;;
+		no)  lua_wrapper=false ;;
+		*)   AC_MSG_ERROR([bad value ${enableval} for --enable-lua-wrapper]) ;; 
+	esac],[lua_wrapper=false])
+AM_CONDITIONAL(LUA_WRAPPER, test x"$lua_wrapper" = x"true")
+AM_COND_IF([LUA_WRAPPER],
+    AC_DEFINE([LUA_WRAPPER]))
+
 AC_LIBTOOL_WIN32_DLL
 AC_PROG_LIBTOOL
 AC_CONFIG_MACRO_DIR([m4])
-AC_CONFIG_FILES(Makefile include/Makefile src/Makefile tools/Makefile tests/Makefile examples/src/Makefile doc/Makefile)
+AC_CONFIG_FILES(Makefile src/Makefile tests/Makefile examples/src/Makefile doc/Makefile wrappers/Makefile wrappers/python/Makefile wrappers/lua/Makefile)
 AC_OUTPUT
 

+ 6 - 6
doc/Doxyfile.in

@@ -796,7 +796,7 @@ EXCLUDE                =
 # from the input.
 # The default value is: NO.
 
-EXCLUDE_SYMLINKS       = NO
+EXCLUDE_SYMLINKS       = YES
 
 # If the value of the INPUT tag contains directories, you can use the
 # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
@@ -1903,7 +1903,7 @@ ENABLE_PREPROCESSING   = YES
 # The default value is: NO.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-MACRO_EXPANSION        = NO
+MACRO_EXPANSION        = YES
 
 # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
 # the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -1925,7 +1925,7 @@ SEARCH_INCLUDES        = YES
 # preprocessor.
 # This tag requires that the tag SEARCH_INCLUDES is set to YES.
 
-INCLUDE_PATH           =
+INCLUDE_PATH           = src
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1943,7 +1943,7 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             =
+PREDEFINED             = 
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
@@ -1962,7 +1962,7 @@ EXPAND_AS_DEFINED      =
 # The default value is: YES.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-SKIP_FUNCTION_MACROS   = YES
+SKIP_FUNCTION_MACROS   = NO
 
 #---------------------------------------------------------------------------
 # Configuration options related to external references
@@ -2115,7 +2115,7 @@ COLLABORATION_GRAPH    = NO
 # The default value is: YES.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-GROUP_GRAPHS           = YES
+GROUP_GRAPHS           = NO
 
 # If the UML_LOOK tag is set to YES doxygen will generate inheritance and
 # collaboration diagrams in a style similar to the OMG's Unified Modeling

+ 194 - 0
doc/DoxygenLayout.xml

@@ -0,0 +1,194 @@
+<doxygenlayout version="1.0">
+  <!-- Generated by doxygen 1.8.6 -->
+  <!-- Navigation index tabs for HTML output -->
+  <navindex>
+    <tab type="mainpage" visible="yes" title=""/>
+    <tab type="pages" visible="yes" title="" intro=""/>
+    <tab type="modules" visible="yes" title="" intro=""/>
+    <tab type="namespaces" visible="no" title="">
+      <tab type="namespacelist" visible="yes" title="" intro=""/>
+      <tab type="namespacemembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="classes" visible="no" title="">
+      <tab type="classlist" visible="yes" title="" intro=""/>
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 
+      <tab type="hierarchy" visible="yes" title="" intro=""/>
+      <tab type="classmembers" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="files" visible="yes" title="">
+      <tab type="filelist" visible="yes" title="" intro=""/>
+      <tab type="globals" visible="yes" title="" intro=""/>
+    </tab>
+    <tab type="examples" visible="no" title="" intro=""/>  
+  </navindex>
+
+  <!-- Layout definition for a class page -->
+  <class>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <inheritancegraph visible="$CLASS_GRAPH"/>
+    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
+    <memberdecl>
+      <nestedclasses visible="yes" title=""/>
+      <publictypes title=""/>
+      <services title=""/>
+      <interfaces title=""/>
+      <publicslots title=""/>
+      <signals title=""/>
+      <publicmethods title=""/>
+      <publicstaticmethods title=""/>
+      <publicattributes title=""/>
+      <publicstaticattributes title=""/>
+      <protectedtypes title=""/>
+      <protectedslots title=""/>
+      <protectedmethods title=""/>
+      <protectedstaticmethods title=""/>
+      <protectedattributes title=""/>
+      <protectedstaticattributes title=""/>
+      <packagetypes title=""/>
+      <packagemethods title=""/>
+      <packagestaticmethods title=""/>
+      <packageattributes title=""/>
+      <packagestaticattributes title=""/>
+      <properties title=""/>
+      <events title=""/>
+      <privatetypes title=""/>
+      <privateslots title=""/>
+      <privatemethods title=""/>
+      <privatestaticmethods title=""/>
+      <privateattributes title=""/>
+      <privatestaticattributes title=""/>
+      <friends title=""/>
+      <related title="" subtitle=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <inlineclasses title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <services title=""/>
+      <interfaces title=""/>
+      <constructors title=""/>
+      <functions title=""/>
+      <related title=""/>
+      <variables title=""/>
+      <properties title=""/>
+      <events title=""/>
+    </memberdef>
+    <allmemberslink visible="yes"/>
+    <usedfiles visible="$SHOW_USED_FILES"/>
+    <authorsection visible="yes"/>
+  </class>
+
+  <!-- Layout definition for a namespace page -->
+  <namespace>
+    <briefdescription visible="yes"/>
+    <memberdecl>
+      <nestednamespaces visible="yes" title=""/>
+      <constantgroups visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <inlineclasses title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection visible="yes"/>
+  </namespace>
+
+  <!-- Layout definition for a file page -->
+  <file>
+    <briefdescription visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <includegraph visible="$INCLUDE_GRAPH"/>
+    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
+    <sourcelink visible="yes"/>
+    <memberdecl>
+      <classes visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <constantgroups visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+    <memberdef>
+      <inlineclasses title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <functions title=""/>
+      <variables title=""/>
+    </memberdef>
+    <authorsection/>
+  </file>
+
+  <!-- Layout definition for a group page -->
+  <group>
+    <briefdescription visible="no"/>
+    <groupgraph visible="$GROUP_GRAPHS"/>
+    <detaileddescription title=""/>
+    <memberdecl>
+      <nestedgroups visible="yes" title=""/>
+      <dirs visible="yes" title=""/>
+      <files visible="yes" title=""/>
+      <namespaces visible="yes" title=""/>
+      <classes visible="yes" title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+      <membergroups visible="yes"/>
+    </memberdecl>
+    <memberdef>
+      <pagedocs/>
+      <inlineclasses title=""/>
+      <defines title=""/>
+      <typedefs title=""/>
+      <enums title=""/>
+      <enumvalues title=""/>
+      <functions title=""/>
+      <variables title=""/>
+      <signals title=""/>
+      <publicslots title=""/>
+      <protectedslots title=""/>
+      <privateslots title=""/>
+      <events title=""/>
+      <properties title=""/>
+      <friends title=""/>
+    </memberdef>
+    <authorsection visible="no"/>
+  </group>
+
+  <!-- Layout definition for a directory page -->
+  <directory>
+    <briefdescription visible="yes"/>
+    <directorygraph visible="yes"/>
+    <memberdecl>
+      <dirs visible="yes"/>
+      <files visible="yes"/>
+    </memberdecl>
+    <detaileddescription title=""/>
+  </directory>
+</doxygenlayout>

+ 1 - 0
doc/style/load-style.js

@@ -13,6 +13,7 @@ $( document ).ready(function() {
 	$("ul.tablist").css("margin-bottom", "0.5em");
 	$("li.current").addClass("active");
 	$(".contents").wrapInner("<div class='panel panel-default' style='margin-top:1em;'><div class='panel-body'></div></div>");
+	$(".contents").find("h2.groupheader:first").remove();
 
 	$("iframe").attr("scrolling", "yes");
 	

+ 4 - 0
examples/src/Makefile.am

@@ -27,6 +27,10 @@ bin_PROGRAMS += $(top_builddir)/bin/exampleServer $(top_builddir)/bin/exampleSer
 __top_builddir__bin_exampleServer_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_exampleServer_SOURCES = opcuaServer.c networklayer.c
 __top_builddir__bin_exampleServer_LDADD= $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
+if RASPI
+__top_builddir__bin_exampleServer_LDFLAGS = -lwiringPi
+__top_builddir__bin_exampleServer_SOURCES += raspberrypi_io.c
+endif
 
 __top_builddir__bin_exampleServerACPLT_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_exampleServerACPLT_SOURCES = opcuaServerACPLT.c networklayer.c

+ 20 - 24
examples/src/generateSam.c

@@ -1,11 +1,7 @@
-/*
- * xml2ns0.c
- *
- *  Created on: 21.04.2014
- *      Author: mrt
- */
-
 #include "ua_xml.h"
+#include "ua_namespace.h"
+#include "ua_namespace_xml.h"
+#include "ua_types_generated.h"
 #include <ctype.h> // tolower
 
 /** @brief we need a variable global to the module to make it possible for the visitors to access the namespace */
@@ -13,20 +9,20 @@ static Namespace* theNamespace;
 
 UA_Int32 UA_Node_getParent(const UA_Node* node, const UA_Node** parent) {
 	UA_Int32 i = 0;
-	DBG(printf("// UA_Node_getParent - node={i=%d}",UA_NodeId_getIdentifier(&(node->nodeId))));
+	DBG(printf("// UA_Node_getParent - node={i=%d}",node->nodeId.identifier.numeric));
 	// FIXME: the data model is crap! we should have a single memory location which holds the parent NodeId
 	for (; i < node->referencesSize; i++ ) {
-		UA_Int32 refId = UA_NodeId_getIdentifier(&(node->references[i]->referenceTypeId));
-		UA_Int32 isInverse = node->references[i]->isInverse;
+		UA_Int32 refId = node->references[i].referenceTypeId.identifier.numeric;
+		UA_Int32 isInverse = node->references[i].isInverse;
 		if (isInverse && (refId == 47 || refId == 46)) {
 			Namespace_Entry_Lock* lock = UA_NULL;
 			UA_Int32 retval;
-			retval = Namespace_get(theNamespace, &(node->references[i]->targetId.nodeId),parent,&lock);
+			retval = Namespace_get(theNamespace, &(node->references[i].targetId.nodeId),parent,&lock);
 			Namespace_Entry_Lock_release(lock);
 			if (retval == UA_SUCCESS) {
-				DBG(printf(" has parent={i=%d}\n",UA_NodeId_getIdentifier(&((*parent)->nodeId))));
+				DBG(printf(" has parent={i=%d}\n",(*parent)->nodeId.identifier.numeric));
 			} else {
-				DBG(printf(" has non-existing parent={i=%d}\n",UA_NodeId_getIdentifier(&(node->references[i]->targetId.nodeId))));
+				DBG(printf(" has non-existing parent={i=%d}\n", node->references[i].targetId.nodeId.identifier.numeric));
 			}
 			return retval;
 		}
@@ -80,13 +76,13 @@ UA_Int32 UA_Node_getPath(const UA_Node* node, UA_list_List* list) {
 			// and add our own name when we come back
 			if (retval == UA_SUCCESS) {
 				UA_list_addPayloadToBack(list,(void*)&(node->browseName.name));
-				DBG(printf("// UA_Node_getPath - add id={i=%d},class=%d",UA_NodeId_getIdentifier(&(node->nodeId)),node->nodeClass));
+				DBG(printf("// UA_Node_getPath - add id={i=%d},class=%d",node->nodeId.identifier.numeric,node->nodeClass));
 				DBG(UA_String_printf(",name=",&(node->browseName.name)));
 			}
 		} else {
 			// node is root, terminate recursion by adding own name
 			UA_list_addPayloadToBack(list,(void*)&node->browseName.name);
-			DBG(printf("// UA_Node_getPath - add id={i=%d},class=%d",UA_NodeId_getIdentifier(&(node->nodeId)),node->nodeClass));
+			DBG(printf("// UA_Node_getPath - add id={i=%d},class=%d",node->nodeId.identifier.numeric,node->nodeClass));
 			DBG(UA_String_printf(",name=",&(node->browseName.name)));
 		}
 	}
@@ -112,7 +108,7 @@ void sam_declareAttribute(UA_Node const * node) {
 		UA_Int32 retval = UA_Node_getPath(node,&list);
 		if (retval == UA_SUCCESS) {
 			UA_VariableNode* vn = (UA_VariableNode*) node;
-			printf("\t%s ", UA_[UA_ns0ToVTableIndex(vn->dataType.identifier.numeric)].name);
+			printf("\t%s ", UA_.types[UA_ns0ToVTableIndex(&vn->nodeId)].name);
 			UA_list_iteratePayload(&list,listPrintName);
 			printf("; // i=%d\n", node->nodeId.identifier.numeric);
 		} else {
@@ -167,7 +163,7 @@ void sam_assignBuffer(UA_Node const * node) {
 void sam_attachToNamespace(UA_Node const * node) {
 	if (node != UA_NULL && node->nodeClass == UA_NODECLASS_VARIABLE) {
 		UA_VariableNode* vn = (UA_VariableNode*) node;
-		printf("\tsam_attach(ns,%d,%s,&sam." F_cls ");\n",node->nodeId.identifier.numeric,UA_[UA_ns0ToVTableIndex(vn->dataType.identifier.numeric)].name, LC_cls(vn->browseName.name));
+		printf("\tsam_attach(ns,%d,%s,&sam." F_cls ");\n",node->nodeId.identifier.numeric,UA_.types[UA_ns0ToVTableIndex(&vn->dataType)].name, LC_cls(vn->browseName.name));
 	}
 }
 
@@ -180,7 +176,7 @@ UA_Int32 Namespace_getNumberOfComponents(Namespace const * ns, UA_NodeId const *
 		return UA_ERR_INVALID_VALUE;
 	UA_Int32 i, n;
 	for (i = 0, n = 0; i < node->referencesSize; i++ ) {
-		if (node->references[i]->referenceTypeId.identifier.numeric == 47 && node->references[i]->isInverse != UA_TRUE) {
+		if (node->references[i].referenceTypeId.identifier.numeric == 47 && node->references[i].isInverse != UA_TRUE) {
 			n++;
 		}
 	}
@@ -197,10 +193,10 @@ UA_Int32 Namespace_getComponent(Namespace const * ns, UA_NodeId const * id, UA_I
 
 	UA_Int32 i, n;
 	for (i = 0, n = 0; i < node->referencesSize; i++ ) {
-		if (node->references[i]->referenceTypeId.identifier.numeric == 47 && node->references[i]->isInverse != UA_TRUE) {
+		if (node->references[i].referenceTypeId.identifier.numeric == 47 && node->references[i].isInverse != UA_TRUE) {
 			n++;
 			if (n == idx) {
-				*result = &(node->references[i]->targetId.nodeId);
+				*result = &(node->references[i].targetId.nodeId);
 				return retval;
 			}
 		}
@@ -209,13 +205,13 @@ UA_Int32 Namespace_getComponent(Namespace const * ns, UA_NodeId const * id, UA_I
 }
 
 
-UA_Int32 UAX_NodeId_encodeBinaryByMetaData(Namespace const * ns, UA_NodeId const * id, UA_Int32* pos, UA_ByteString *dst) {
+UA_Int32 UAX_NodeId_encodeBinaryByMetaData(Namespace const * ns, UA_NodeId const * id, UA_UInt32* pos, UA_ByteString *dst) {
 	UA_Int32 i, retval = UA_SUCCESS;
 	if (UA_NodeId_isBasicType(id)) {
 		UA_Node const * result;
 		Namespace_Entry_Lock* lock;
 		if ((retval = Namespace_get(ns,id,&result,&lock)) == UA_SUCCESS)
-			UA_Variant_encodeBinary(&((UA_VariableNode *) result)->value,pos,dst);
+			UA_Variant_encodeBinary(&((UA_VariableNode *) result)->value,dst,pos);
 	} else {
 		UA_Int32 nComp = 0;
 		if ((retval = Namespace_getNumberOfComponents(ns,id,&nComp)) == UA_SUCCESS) {
@@ -229,14 +225,14 @@ UA_Int32 UAX_NodeId_encodeBinaryByMetaData(Namespace const * ns, UA_NodeId const
 	return retval;
 }
 
-UA_Int32 UAX_NodeId_encodeBinary(Namespace const * ns, UA_NodeId const * id, UA_Int32* pos, UA_ByteString *dst) {
+UA_Int32 UAX_NodeId_encodeBinary(Namespace const * ns, UA_NodeId const * id, UA_ByteString *dst, UA_UInt32* offset) {
 	UA_Int32 retval = UA_SUCCESS;
 	UA_Node const * node;
 	Namespace_Entry_Lock* lock;
 
 	if ((retval = Namespace_get(ns,id,&node,&lock)) == UA_SUCCESS) {
 		if (node->nodeClass == UA_NODECLASS_VARIABLE) {
-			retval = UA_Variant_encodeBinary(&((UA_VariableNode*) node)->value,pos,dst);
+			retval = UA_Variant_encodeBinary(&((UA_VariableNode*) node)->value,dst,offset);
 		}
 		Namespace_Entry_Lock_release(lock);
 	}

+ 43 - 19
examples/src/networklayer.c

@@ -16,7 +16,7 @@ NL_Description NL_Description_TcpBinary  = {
 	NL_UA_ENCODING_BINARY,
 	NL_CONNECTIONTYPE_TCPV4,
 	NL_MAXCONNECTIONS_DEFAULT,
-	{-1,8192,8192,16384,1}
+	{0,8192,8192,16384,1}
 };
 
 /* If we do not have multitasking, we implement a dispatcher-Pattern. All Connections
@@ -28,7 +28,11 @@ NL_Description NL_Description_TcpBinary  = {
 _Bool NL_ConnectionComparer(void *p1, void* p2) {
 	NL_Connection* c1 = (NL_Connection*) p1;
 	NL_Connection* c2 = (NL_Connection*) p2;
-	return (c1->connectionHandle == c2->connectionHandle);
+	UA_UInt32 h1,h2;
+	UA_TL_Connection_getHandle(c1->connection,&h1);
+	UA_TL_Connection_getHandle(c2->connection,&h2);
+
+	return (h1 == h2);
 }
 int NL_TCP_SetNonBlocking(int sock) {
 	int opts = fcntl(sock,F_GETFL);
@@ -55,16 +59,17 @@ void NL_addHandleToSet(UA_Int32 handle, NL_data* nl) {
 	nl->maxReaderHandle = (handle > nl->maxReaderHandle) ? handle : nl->maxReaderHandle;
 }
 void NL_setFdSet(void* payload) {
-  UA_UInt32 id;
+  UA_UInt32 h;
   NL_Connection* c = (NL_Connection*) payload;
-  UA_TL_Connection_getHandle(c->connection,&id);
-  NL_addHandleToSet(id, c->networkLayer);
+  UA_TL_Connection_getHandle(c->connection,&h);
+
+  NL_addHandleToSet(h, c->networkLayer);
 }
 void NL_checkFdSet(void* payload) {
-	  UA_UInt32 id;
+  UA_UInt32 h;
   NL_Connection* c = (NL_Connection*) payload;
-  UA_TL_Connection_getHandle(c->connection,&id);
-  if (FD_ISSET(id, &(c->networkLayer->readerHandles))) {
+  UA_TL_Connection_getHandle(c->connection,&h);
+  if (FD_ISSET(h, &(c->networkLayer->readerHandles))) {
 	  c->reader((void*)c);
   }
 }
@@ -73,6 +78,7 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 	while (UA_TRUE) {
 		// determine the largest handle
 		nl->maxReaderHandle = 0;
+
 		UA_list_iteratePayload(&(nl->connections),NL_setFdSet);
 		DBG_VERBOSE(printf("\n------------\nUA_Stack_msgLoop - maxHandle=%d\n", nl->maxReaderHandle));
 
@@ -82,7 +88,7 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 
 		// and wait
 		DBG_VERBOSE(printf("UA_Stack_msgLoop - enter select sec=%d,usec=%d\n",(UA_Int32) tmptv.tv_sec, (UA_Int32) tmptv.tv_usec));
-		result = select(nl->maxReaderHandle + 1, &(nl->readerHandles), UA_NULL, UA_NULL,&tmptv);
+		result = select(nl->maxReaderHandle + 1, &(nl->readerHandles), UA_NULL, UA_NULL, &tmptv);
 		DBG_VERBOSE(printf("UA_Stack_msgLoop - leave select result=%d,sec=%d,usec=%d\n",result, (UA_Int32) tmptv.tv_sec, (UA_Int32) tmptv.tv_usec));
 		if (result == 0) {
 			int err = errno;
@@ -103,8 +109,12 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 		} else { // activity on listener or client ports
 			DBG_VERBOSE(printf("UA_Stack_msgLoop - activities on %d handles\n",result));
 			UA_list_iteratePayload(&(nl->connections),NL_checkFdSet);
+
 		}
+		worker(arg);
+
 	}
+
 	return UA_SUCCESS;
 }
 #endif
@@ -113,19 +123,20 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 /** the tcp reader function */
 void* NL_TCP_reader(NL_Connection *c) {
 
+
 	UA_ByteString readBuffer;
 
 	TL_Buffer localBuffers;
-
-	UA_UInt32 connectionId;
+	UA_Int32 connectionState;
+	UA_UInt32 connectionHandle;
 	UA_TL_Connection_getLocalConfiguration(c->connection, &localBuffers);
-	UA_TL_Connection_getHandle(c->connection, &connectionId);
+	UA_TL_Connection_getHandle(c->connection, &connectionHandle);
 	UA_alloc((void**)&(readBuffer.data),localBuffers.recvBufferSize);
 
 
 	if (c->state  != CONNECTIONSTATE_CLOSE) {
 		DBG_VERBOSE(printf("NL_TCP_reader - enter read\n"));
-		readBuffer.length = read(connectionId, readBuffer.data, localBuffers.recvBufferSize);
+		readBuffer.length = read(connectionHandle, readBuffer.data, localBuffers.recvBufferSize);
 		DBG_VERBOSE(printf("NL_TCP_reader - leave read\n"));
 
 		DBG_VERBOSE(printf("NL_TCP_reader - src={%*.s}, ",c->connection.remoteEndpointUrl.length,c->connection.remoteEndpointUrl.data));
@@ -141,26 +152,33 @@ void* NL_TCP_reader(NL_Connection *c) {
 			perror("ERROR reading from socket1");
 		}
 	}
-
-	if (c->state == CONNECTIONSTATE_CLOSE) {
+	UA_TL_Connection_getState(c->connection, &connectionState);
+	if (connectionState == CONNECTIONSTATE_CLOSE) {
 		DBG_VERBOSE(printf("NL_TCP_reader - enter shutdown\n"));
-		shutdown(connectionId,2);
+		shutdown(connectionHandle,2);
 		DBG_VERBOSE(printf("NL_TCP_reader - enter close\n"));
-		close(connectionId);
+		close(connectionHandle);
 		DBG_VERBOSE(printf("NL_TCP_reader - leave close\n"));
-		c->state  = CONNECTIONSTATE_CLOSED;
+		UA_TL_Connection_setState(c->connection,CONNECTIONSTATE_CLOSED);
+
+		//c->state  = CONNECTIONSTATE_CLOSED;
 
-		UA_ByteString_deleteMembers(&readBuffer);
 
 #ifndef MULTITHREADING
+		//connection list before deletion
+		//UA_list_iteratePayload(&(c->networkLayer->connections),NL_Connection_printf);
 		DBG_VERBOSE(printf("NL_TCP_reader - search element to remove\n"));
 		UA_list_Element* lec = UA_list_search(&(c->networkLayer->connections),NL_ConnectionComparer,c);
+
 		DBG_VERBOSE(printf("NL_TCP_reader - remove connection for handle=%d\n",((NL_Connection*)lec->payload)->connection.connectionHandle));
 		UA_list_removeElement(lec,UA_NULL);
 		DBG_VERBOSE(UA_list_iteratePayload(&(c->networkLayer->connections),NL_Connection_printf));
+		//connection list after deletion
+		//UA_list_iteratePayload(&(c->networkLayer->connections),NL_Connection_printf);
 		UA_free(c);
 #endif
 	}
+	UA_ByteString_deleteMembers(&readBuffer);
 	return UA_NULL;
 }
 
@@ -176,6 +194,7 @@ void* NL_TCP_readerThread(NL_Connection *c) {
 	pthread_exit(UA_NULL);
 }
 #endif
+
 /** write message provided in the gather buffers to a tcp transport layer connection */
 UA_Int32 NL_TCP_writer(UA_Int32 connectionHandle, UA_ByteString const * const * gather_buf, UA_UInt32 gather_len) {
 
@@ -226,10 +245,14 @@ void* NL_Connection_init(NL_Connection* c, NL_data* tld, UA_Int32 connectionHand
 	//create new connection object
 	UA_TL_Connection_new(&connection, tld->tld->localConf,writer);
 	//add connection object to list, so stack is aware of its connections
+	UA_TL_Connection_setConnectionHandle(connection,connectionHandle);
 
 	UA_TL_ConnectionManager_addConnection(&connection);
 
 	// connection layer of UA stackwriteLock
+	c->connection = connection;
+	c->connectionHandle = connectionHandle;
+
 
 	//c->connection.connectionHandle = connectionHandle;
 	//c->connection.connectionState = CONNECTIONSTATE_CLOSED;
@@ -252,6 +275,7 @@ void* NL_TCP_listen(NL_Connection* c) {
 	NL_data* tld = c->networkLayer;
 
 	DBG_VERBOSE(printf("NL_TCP_listen - enter listen\n"));
+
 	int retval = listen(c->connectionHandle, tld->tld->maxConnections);
 	DBG_VERBOSE(printf("NL_TCP_listen - leave listen, retval=%d\n",retval));
 

+ 5 - 5
examples/src/networklayer.h

@@ -1,10 +1,10 @@
 #ifndef NETWORKLAYER_H_
 #define NETWORKLAYER_H_
 
-#include "opcua.h"
+#include "ua_types.h"
 #include "ua_transport.h"
 #include "ua_transport_binary.h"
-#include "ua_list.h"
+#include "util/ua_list.h"
 #include "ua_transport_connection_manager.h"
 
 #ifdef MULTITHREADING
@@ -42,9 +42,9 @@ typedef struct NL_data {
 	int maxReaderHandle;
 } NL_data;
 
-struct NL_Connection_T;
-typedef void* (*NL_Reader)(struct NL_Connection_T *c);
-typedef struct NL_Connection_T {
+struct NL_Connection;
+typedef void* (*NL_Reader)(struct NL_Connection *c);
+typedef struct NL_Connection {
 	UA_TL_Connection1 connection;
 	UA_Int32 state;
 	UA_UInt32 connectionHandle;

+ 148 - 2
examples/src/opcuaServer.c

@@ -7,6 +7,10 @@
  Description : lala
  ============================================================================
  */
+#ifdef RASPI
+	#define _POSIX_C_SOURCE 199309L //to use nanosleep
+	#include <pthread.h>
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -14,16 +18,158 @@
 #include "networklayer.h"
 #include "ua_application.h"
 
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include "ua_stack_channel_manager.h"
+#include "ua_stack_session_manager.h"
+
+#ifdef RASPI
+	#include "raspberrypi_io.h"
+#endif
+
+
 UA_Int32 serverCallback(void * arg) {
 	char *name = (char *) arg;
 	printf("%s does whatever servers do\n",name);
+
+	Namespace* ns0 = (Namespace*)UA_indexedList_find(appMockup.namespaces, 0)->payload;
+	UA_Int32 retval;
+	UA_Node const * node;
+	UA_ExpandedNodeId serverStatusNodeId = NS0EXPANDEDNODEID(2256);
+	retval = Namespace_get(ns0, &(serverStatusNodeId.nodeId),&node, UA_NULL);
+	if(retval == UA_SUCCESS){
+		((UA_ServerStatusDataType*)(((UA_VariableNode*)node)->value.data))->currentTime = UA_DateTime_now();
+	}
+
+	const UA_Node *foundNode1 = UA_NULL;
+
+	Namespace_Entry_Lock *lock;
+	//node which should be filled with data (float value)
+	UA_NodeId tmpNodeId1;
+
+
+	tmpNodeId1.encodingByte = UA_NODEIDTYPE_TWOBYTE;
+	tmpNodeId1.identifier.numeric = 108;
+	tmpNodeId1.namespace =  0;
+
+
+	if(Namespace_get(ns0,&tmpNodeId1, &foundNode1,&lock) != UA_SUCCESS){
+		return UA_ERROR;
+	}
+
+
+#ifdef RASPI
+#else
+	*((float*)((UA_VariableNode *)foundNode1)->value.data) = *((float*)((UA_VariableNode *)foundNode1)->value.data) + 0.2f;
+#endif
+
+
+
 	return UA_SUCCESS;
 }
 
+#ifdef RASPI
+
+static float sharedTemperature = 0;
+static UA_Boolean sharedLED1 = 0;
+static UA_Boolean sharedLED2 = 0;
+
+static void* ioloop(void* ptr){
+    {
+	if(initIO())
+	{
+		printf("ERROR while initializing the IO \n");
+	}
+	else
+	{
+	        struct timespec t = {0, 50*1000*1000};
+		int j = 0;
+		for(;j<25;j++){
+		writePin(j%2,0);
+		writePin((j+1)%2,2);
+		nanosleep(&t, NULL);
+		}
+		writePin(0,0);
+		writePin(0,2);
+
+		printf("IO successfully initalized \n");
+	}
+
+	printf("done - io init \n");
+
+  
+
+        struct timespec t = {0, 50*1000*1000};
+    	while(1){
+		readTemp(&sharedTemperature);
+		writePin(sharedLED1,0);
+		writePin(sharedLED2,2);
+		nanosleep(&t, NULL);
+    	}
+    }
+	return UA_NULL;
+}
+#endif
+
 int main(int argc, char** argv) {
 	appMockup_init();
 	NL_data* nl = NL_init(&NL_Description_TcpBinary,16664);
 
-	struct timeval tv = {20, 0}; // 20 seconds
-	NL_msgLoop(nl, &tv,serverCallback,argv[0]);
+	struct timeval tv = {1, 0}; // 1 second
+#ifdef RASPI
+  	Namespace* ns0 = (Namespace*)UA_indexedList_find(appMockup.namespaces, 0)->payload;
+		const UA_Node *foundNode1 = UA_NULL;
+		const UA_Node *foundNode2 = UA_NULL;
+		const UA_Node *foundNode3 = UA_NULL;
+		Namespace_Entry_Lock *lock;
+		//node which should be filled with data (float value)
+		UA_NodeId tmpNodeId1;
+		UA_NodeId tmpNodeId2;
+		UA_NodeId tmpNodeId3;
+
+		tmpNodeId1.encodingByte = UA_NODEIDTYPE_TWOBYTE;
+		tmpNodeId1.identifier.numeric = 108;
+		tmpNodeId1.namespace =  0;
+
+		tmpNodeId2.encodingByte = UA_NODEIDTYPE_TWOBYTE;
+		tmpNodeId2.identifier.numeric = 109;
+		tmpNodeId2.namespace =  0;
+
+		tmpNodeId3.encodingByte = UA_NODEIDTYPE_TWOBYTE;
+		tmpNodeId3.identifier.numeric = 110;
+		tmpNodeId3.namespace =  0;
+            	
+			if(Namespace_get(ns0,&tmpNodeId1, &foundNode1,&lock) != UA_SUCCESS){
+				_exit(1);
+			}
+
+			if(Namespace_get(ns0,&tmpNodeId2, &foundNode2,&lock) != UA_SUCCESS){
+				_exit(1);
+			}
+
+			if(Namespace_get(ns0,&tmpNodeId3, &foundNode3,&lock) != UA_SUCCESS){
+				_exit(1);
+			}
+
+		((UA_VariableNode *)foundNode1)->value.data = &sharedTemperature;
+		((UA_VariableNode *)foundNode2)->value.data = &sharedLED1;
+		((UA_VariableNode *)foundNode3)->value.data = &sharedLED2;
+
+		pthread_t t;
+		pthread_create(&t, NULL, &ioloop, UA_NULL);
+
+	printf("raspi enabled \n");	
+  	//pid_t i = fork();
+	//printf("process id i=%d \n",i);
+#endif    
+
+	SL_ChannelManager_init(2,3600000, 873, 23, &nl->endpointUrl);
+	UA_SessionManager_init(2,300000,5);
+
+  	NL_msgLoop(nl, &tv, serverCallback, argv[0]);
+
 }

+ 3 - 8
examples/src/opcuaServerACPLT.c

@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include <memory.h>
 
-#include "opcua.h"
+#include "ua_types.h"
 #include "ua_transport.h"
 #include "ua_transport_binary.h"
 #include "networklayer.h"
@@ -60,13 +60,8 @@ void server_run() {
 	UA_String endpointUrl;
 	UA_String_copycstring("open62541.org",&endpointUrl);
 	SL_ChannelManager_init(2,3600000, 873, 23, &endpointUrl);
-
 	UA_SessionManager_init(2,300000,5);
 
-
-
-
-
 	UA_ByteString slMessage = { -1, UA_NULL };
 
 	int optval = 1;
@@ -100,8 +95,6 @@ void server_run() {
 		exit(1);
 	}
 
-	//UA_TL_Connection_new(&connection, localBuffers, (TL_Writer)NL_TCP_writer);
-
 	/* Now start listening for the clients, here process will
 	 * go in sleep mode and will wait for the incoming connection
 	 */
@@ -133,6 +126,7 @@ void server_run() {
 			if (n > 0) {
                 slMessage.data = (UA_Byte*) buffer;
 				slMessage.length = n;
+#ifdef DEBUG
 				UA_ByteString_printx("server_run - received=",&slMessage);
 				TL_Process(connection, &slMessage);
 			} else if (n <= 0) {
@@ -151,3 +145,4 @@ void server_run() {
 }
 
 #endif
+#endif

+ 65 - 0
examples/src/raspberrypi_io.c

@@ -0,0 +1,65 @@
+/*
+ * raspberrypi_io.c
+ *
+ *  Created on: 23.06.2014
+ *      Author: root
+ */
+
+#include "raspberrypi_io.h"
+
+
+
+#ifdef RASPI
+static _Bool initialized = 0;
+int initIO()
+{
+	if (wiringPiSetup() == -1){
+		initialized = 0;
+		return 1;
+	}
+	initialized = 1;
+	return 0;
+}
+int readTemp(float *temp){
+	FILE *ptr_file;
+	char buf[1000];
+	char delimiter[] = "=";
+	char *ptr_temp;
+	long temperaturInmC;
+
+	ptr_file =fopen("/sys/bus/w1/devices/10-000802c607f3/w1_slave","r");
+	if (!ptr_file){
+		puts("ERROR: no sensor");
+		return 1;
+	}
+
+	fgets(buf, 1000, ptr_file);
+
+	fgets(buf, 1000, ptr_file);
+
+	ptr_temp = strtok(buf, (char*) delimiter);
+
+	ptr_temp = strtok((void*)0, (char*) delimiter);
+
+	temperaturInmC = atol(ptr_temp);
+
+	fclose(ptr_file);
+
+	*temp = (float)temperaturInmC/1000;
+	return 0;
+}
+
+int writePin(_Bool state, int pin){
+	if(initialized)
+	{
+		pinMode(0, OUTPUT);
+		if(state==(1==1)){
+			digitalWrite(pin, 1);
+		}else{
+			digitalWrite(pin, 0);
+		}
+		return 0;
+	}
+	return 1; //ERROR
+}
+#endif

+ 22 - 0
examples/src/raspberrypi_io.h

@@ -0,0 +1,22 @@
+/*
+ * raspberrypi_io.h
+ *
+ *  Created on: 23.06.2014
+ *      Author: root
+ */
+
+#ifndef RASPBERRYPI_IO_H_
+#define RASPBERRYPI_IO_H_
+
+#include <wiringPi.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "string.h"
+int readTemp(float *temp);
+int writePin(_Bool state, int pin);
+int initIO();
+
+#endif /* RASPBERRYPI_IO_H_ */

+ 36 - 47
examples/src/xml2ns0.c

@@ -1,11 +1,11 @@
-/*
- * xml2ns0.c
- *
- *  Created on: 21.04.2014
- *      Author: mrt
- */
-
+#include <fcntl.h> // open, O_RDONLY
+#include "ua_types.h"
+//#include "ua_types_generated.h"
+#include "ua_namespace.h"
 #include "ua_xml.h"
+#include "ua_namespace_xml.h"
+#include "ua_types_encoding_xml.h"
+#include "util/ua_util.h"
 
 // FIXME: most of the following code should be generated as a template from the ns0-defining xml-files
 /** @brief sam (abbr. for server_application_memory) is a flattened memory structure of the UAVariables in ns0 */
@@ -36,43 +36,32 @@ void sam_attach(Namespace *ns,UA_UInt32 ns0id,UA_Int32 type, void* p) {
 		if (result->nodeId.identifier.numeric == ns0id) {
 			if (result->nodeClass == UA_NODECLASS_VARIABLE) {
 				UA_VariableNode* variable = (UA_VariableNode*) result;
-				if (variable->dataType.identifier.numeric == UA_[type].ns0Id) {
+				if (variable->dataType.identifier.numeric == UA_.types[type].typeId.identifier.numeric) {
 					variable->value.arrayLength = 1;
-					if (variable->value.data == UA_NULL) {
-						UA_alloc((void**)&(variable->value.data), sizeof(void*));
-						variable->value.data[0] = UA_NULL;
-					}
-					if (UA_NodeId_isBuiltinType(&variable->dataType)) {
-						variable->value.data[0] = p;
-					} else {
-						if (variable->value.vt->ns0Id != UA_EXTENSIONOBJECT_NS0) {
-							printf("nodeId for id=%d, type=%d\n should be an extension object", ns0id, type);
-						} else {
-							if (variable->value.data[0] == UA_NULL) {
-								UA_alloc((void**)&(variable->value.data[0]), sizeof(UA_ExtensionObject));
-							}
-							UA_ExtensionObject* eo = (UA_ExtensionObject*) variable->value.data[0];
-							eo->typeId = variable->dataType;
-							eo->encoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
-							// FIXME: This code is valid for ns0 and numeric identifiers only
-							eo->body.length = UA_[UA_ns0ToVTableIndex(variable->dataType.identifier.numeric)].memSize;
-							eo->body.data = p;
-						}
-					}
+					variable->value.data = p;
 				} else {
-					printf("wrong datatype for id=%d, expected=%d, retrieved=%d\n", ns0id, UA_[type].ns0Id, variable->dataType.identifier.numeric);
+					UA_alloc((void**)&variable->value.data, sizeof(UA_ExtensionObject));
+					UA_ExtensionObject* eo = (UA_ExtensionObject*) variable->value.data;
+					eo->typeId = variable->dataType;
+					eo->encoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
+					// FIXME: This code is valid for ns0 and numeric identifiers only
+					eo->body.length = UA_.types[UA_ns0ToVTableIndex(&variable->dataType)].memSize;
+					eo->body.data = p;
 				}
-			} else {
-				perror("Namespace_getWritable returned wrong node class");
 			}
-		} else {
-			printf("retrieving node={i=%d} returned node={i=%d}\n", ns0id, result->nodeId.identifier.numeric);
 		}
-		Namespace_Entry_Lock_release(lock);
-	} else {
-		printf("retrieving node={i=%d} returned error code %d\n",ns0id,retval);
 	}
 }
+	/* 	} else { */
+	/* 		perror("Namespace_getWritable returned wrong node class"); */
+	/* 	} */
+	/* } else { */
+	/* 	printf("retrieving node={i=%d} returned node={i=%d}\n", ns0id, result->nodeId.identifier.numeric); */
+	/* } */
+	/*        Namespace_Entry_Lock_release(lock); */
+	/* 	} else { */
+	/* 	printf("retrieving node={i=%d} returned error code %d\n",ns0id,retval); */
+	/* } */
 
 void sam_init(Namespace* ns) {
 	// Initialize the strings
@@ -108,7 +97,7 @@ UA_Int32 Namespace_getNumberOfComponents(Namespace const * ns, UA_NodeId const *
 		return UA_ERR_INVALID_VALUE;
 	UA_Int32 i, n;
 	for (i = 0, n = 0; i < node->referencesSize; i++ ) {
-		if (node->references[i]->referenceTypeId.identifier.numeric == 47 && node->references[i]->isInverse != UA_TRUE) {
+		if (node->references[i].referenceTypeId.identifier.numeric == 47 && node->references[i].isInverse != UA_TRUE) {
 			n++;
 		}
 	}
@@ -125,10 +114,10 @@ UA_Int32 Namespace_getComponent(Namespace const * ns, UA_NodeId const * id, UA_I
 
 	UA_Int32 i, n;
 	for (i = 0, n = 0; i < node->referencesSize; i++ ) {
-		if (node->references[i]->referenceTypeId.identifier.numeric == 47 && node->references[i]->isInverse != UA_TRUE) {
+		if (node->references[i].referenceTypeId.identifier.numeric == 47 && node->references[i].isInverse != UA_TRUE) {
 			n++;
 			if (n == idx) {
-				*result = &(node->references[i]->targetId.nodeId);
+				*result = &(node->references[i].targetId.nodeId);
 				return retval;
 			}
 		}
@@ -137,34 +126,34 @@ UA_Int32 Namespace_getComponent(Namespace const * ns, UA_NodeId const * id, UA_I
 }
 
 
-UA_Int32 UAX_NodeId_encodeBinaryByMetaData(Namespace const * ns, UA_NodeId const * id, UA_Int32* pos, UA_ByteString *dst) {
+UA_Int32 UAX_NodeId_encodeBinaryByMetaData(Namespace const * ns, UA_NodeId const * id, UA_ByteString *dst, UA_UInt32* offset) {
 	UA_Int32 i, retval = UA_SUCCESS;
 	if (UA_NodeId_isBasicType(id)) {
 		UA_Node const * result;
 		Namespace_Entry_Lock* lock;
 		if ((retval = Namespace_get(ns,id,&result,&lock)) == UA_SUCCESS)
-			UA_Variant_encodeBinary(&((UA_VariableNode *) result)->value,pos,dst);
+			UA_Variant_encodeBinary(&((UA_VariableNode *) result)->value,dst,offset);
 	} else {
 		UA_Int32 nComp = 0;
 		if ((retval = Namespace_getNumberOfComponents(ns,id,&nComp)) == UA_SUCCESS) {
 			for (i=0; i < nComp; i++) {
 				UA_NodeId* comp = UA_NULL;
 				Namespace_getComponent(ns,id,i,&comp);
-				UAX_NodeId_encodeBinaryByMetaData(ns,comp, pos, dst);
+				UAX_NodeId_encodeBinaryByMetaData(ns,comp, dst, offset);
 			}
 		}
 	}
 	return retval;
 }
 
-UA_Int32 UAX_NodeId_encodeBinary(Namespace const * ns, UA_NodeId const * id, UA_Int32* pos, UA_ByteString *dst) {
+UA_Int32 UAX_NodeId_encodeBinary(Namespace const * ns, UA_NodeId const * id, UA_ByteString *dst, UA_UInt32* offset) {
 	UA_Int32 retval = UA_SUCCESS;
 	UA_Node const * node;
 	Namespace_Entry_Lock* lock;
 
 	if ((retval = Namespace_get(ns,id,&node,&lock)) == UA_SUCCESS) {
 		if (node->nodeClass == UA_NODECLASS_VARIABLE) {
-			retval = UA_Variant_encodeBinary(&((UA_VariableNode*) node)->value,pos,dst);
+			retval = UA_Variant_encodeBinary(&((UA_VariableNode*) node)->value,dst,offset);
 		}
 		Namespace_Entry_Lock_release(lock);
 	}
@@ -183,7 +172,7 @@ int main() {
 	// encoding buffer
 	char buf[1024];
 	UA_ByteString buffer = { 1024, (UA_Byte*) buf };
-	UA_Int32 pos = 0;
+	UA_UInt32 pos = 0;
 
 	UA_NodeId nodeid;
 	nodeid.encodingByte = UA_NODEIDTYPE_FOURBYTE;
@@ -197,7 +186,7 @@ int main() {
 	for (i=0;i<1E5 && retval == UA_SUCCESS;i++) {
 		pos = 0;
 		sam.serverStatus.currentTime = UA_DateTime_now();
-		retval |= UAX_NodeId_encodeBinary(ns,&nodeid,&pos,&buffer);
+		retval |= UAX_NodeId_encodeBinary(ns,&nodeid,&buffer,&pos);
 	}
 	UA_DateTime tEnd = UA_DateTime_now();
 	// tStart, tEnd count in 100 ns steps, so 10 steps = 1 µs

+ 0 - 8
include/Makefile.am

@@ -1,8 +0,0 @@
-TOOL_DIR = ../tools
-
-all-local: opcua.h ua_namespace_0.h
-
-opcua.h: $(TOOL_DIR)/opcua.hgen
-	cp $< $@
-ua_namespace_0.h: $(TOOL_DIR)/ua_namespace_0.hgen
-	cp $< $@

+ 0 - 434
include/ua_basictypes.h

@@ -1,434 +0,0 @@
-#ifndef OPCUA_BASICTYPES_H_
-#define OPCUA_BASICTYPES_H_
-
-#include "ua_types.h"
-#include "ua_list.h"
-
-/* Stop decoding at the first failure. Free members that were already allocated.
-   It is assumed that retval is already defined. */
-#define CHECKED_DECODE(DECODE, CLEAN_UP) do { \
-	retval |= DECODE; \
-	if(retval != UA_SUCCESS) { \
-		CLEAN_UP; \
-		return retval; \
-	} } while(0) \
-
-/* Array operations */
-UA_Int32 UA_Array_calcSize(UA_Int32 noElements, UA_Int32 type, void const * const * ptr);
-UA_Int32 UA_Array_encodeBinary(void const * const *src, UA_Int32 noElements, UA_Int32 type, UA_Int32* pos, UA_ByteString * dst);
-UA_Int32 UA_Array_decodeBinary(UA_ByteString const * src,UA_Int32 noElements, UA_Int32 type, UA_Int32* pos, void *** dst);
-UA_Int32 UA_Array_delete(void ***p,UA_Int32 noElements, UA_Int32 type);
-UA_Int32 UA_Array_init(void **p,UA_Int32 noElements, UA_Int32 type);
-UA_Int32 UA_Array_new(void ***p,UA_Int32 noElements, UA_Int32 type);
-UA_Int32 UA_Array_copy(void const * const *src,UA_Int32 noElements, UA_Int32 type, void ***dst);
-
-/* XML preliminaries */
-struct XML_Stack;
-typedef char const * const XML_Attr;
-typedef char const * cstring;
-#define XML_STACK_MAX_DEPTH 10
-#define XML_STACK_MAX_CHILDREN 40
-typedef UA_Int32 (*XML_decoder)(struct XML_Stack* s, XML_Attr* attr, void* dst, UA_Boolean isStart);
-
-#define UA_TYPE_METHOD_PROTOTYPES(TYPE) \
-	UA_Int32 TYPE##_calcSize(TYPE const * ptr);							\
-	UA_Int32 TYPE##_encodeBinary(TYPE const * src, UA_Int32* pos, UA_ByteString * dst);	\
-	UA_Int32 TYPE##_decodeBinary(UA_ByteString const * src, UA_Int32* pos, TYPE * dst);	\
-	UA_Int32 TYPE##_decodeXML(struct XML_Stack* s, XML_Attr* attr, TYPE* dst, UA_Boolean isStart); \
-	UA_Int32 TYPE##_delete(TYPE * p);									\
-	UA_Int32 TYPE##_deleteMembers(TYPE * p);							\
-	UA_Int32 TYPE##_init(TYPE * p);										\
-	UA_Int32 TYPE##_new(TYPE ** p); 									\
-	UA_Int32 TYPE##_copy(TYPE const *src, TYPE *dst);
-
-#define UA_TYPE_METHOD_CALCSIZE_SIZEOF(TYPE) \
-UA_Int32 TYPE##_calcSize(TYPE const * p) { return sizeof(TYPE); }
-
-#define UA_TYPE_METHOD_CALCSIZE_AS(TYPE, TYPE_AS) \
-UA_Int32 TYPE##_calcSize(TYPE const * p) { return TYPE_AS##_calcSize((TYPE_AS*) p); }
-
-#define UA_TYPE_METHOD_DELETE_FREE(TYPE) \
-UA_Int32 TYPE##_delete(TYPE * p) { return UA_free(p); }
-
-#define UA_TYPE_METHOD_DELETE_AS(TYPE, TYPE_AS) \
-UA_Int32 TYPE##_delete(TYPE * p) { return TYPE_AS##_delete((TYPE_AS*) p);}
-
-#define UA_TYPE_METHOD_DELETE_STRUCT(TYPE) \
-UA_Int32 TYPE##_delete(TYPE *p) { \
-	UA_Int32 retval = UA_SUCCESS; \
-	retval |= TYPE##_deleteMembers(p); \
-	retval |= UA_free(p); \
-	return retval; \
-}
-
-#define UA_TYPE_METHOD_COPY(TYPE) \
-UA_Int32 TYPE##_copy(TYPE const *src, TYPE *dst) { \
-	UA_Int32 retval = UA_SUCCESS; \
-	retval |= UA_memcpy(dst, src, TYPE##_calcSize(UA_NULL)); \
-	return retval; \
-}
-
-#define UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(TYPE) \
-UA_Int32 TYPE##_deleteMembers(TYPE * p) { return UA_SUCCESS; }
-
-#define UA_TYPE_METHOD_DELETEMEMBERS_AS(TYPE, TYPE_AS) \
-UA_Int32 TYPE##_deleteMembers(TYPE * p) { return TYPE_AS##_deleteMembers((TYPE_AS*) p);}
-
-#define UA_TYPE_METHOD_DECODEBINARY_AS(TYPE,TYPE_AS) \
-UA_Int32 TYPE##_decodeBinary(UA_ByteString const * src, UA_Int32* pos, TYPE *dst) { \
-	return TYPE_AS##_decodeBinary(src,pos,(TYPE_AS*) dst); \
-}
-
-#define UA_TYPE_METHOD_DECODEXML_NOTIMPL(TYPE) \
-	UA_Int32 TYPE##_decodeXML(XML_Stack* s, XML_Attr* attr, TYPE* dst, _Bool isStart) { \
-		DBG_VERBOSE(printf(#TYPE "_decodeXML entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); \
-		return UA_ERR_NOT_IMPLEMENTED;\
-	}
-
-#define UA_TYPE_METHOD_DECODEXML_AS(TYPE,TYPE_AS) \
-	UA_Int32 TYPE##_decodeXML(struct XML_Stack* s, XML_Attr* attr, TYPE* dst, _Bool isStart) { \
-		return TYPE_AS##_decodeXML(s,attr,(TYPE_AS*) dst,isStart); \
-	}
-
-#define UA_TYPE_METHOD_ENCODEBINARY_AS(TYPE,TYPE_AS) \
-UA_Int32 TYPE##_encodeBinary(TYPE const * src, UA_Int32* pos, UA_ByteString *dst) { \
-	return TYPE_AS##_encodeBinary((TYPE_AS*) src,pos,dst); \
-}
-
-#define UA_TYPE_METHOD_INIT_AS(TYPE, TYPE_AS) \
-UA_Int32 TYPE##_init(TYPE * p) { \
-	return TYPE_AS##_init((TYPE_AS*)p); \
-}
-#define UA_TYPE_METHOD_COPY_AS(TYPE, TYPE_AS) \
-UA_Int32 TYPE##_copy(TYPE const *src, TYPE *dst) {return TYPE_AS##_copy((TYPE_AS*) src,(TYPE_AS*)dst); \
-}
-
-#define UA_TYPE_METHOD_PROTOTYPES_AS_WOXML(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_CALCSIZE_AS(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_ENCODEBINARY_AS(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_DECODEBINARY_AS(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_DELETE_AS(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_DELETEMEMBERS_AS(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_INIT_AS(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_COPY_AS(TYPE, TYPE_AS)
-
-#define UA_TYPE_METHOD_PROTOTYPES_AS(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_PROTOTYPES_AS_WOXML(TYPE, TYPE_AS) \
-	UA_TYPE_METHOD_DECODEXML_AS(TYPE, TYPE_AS)
-
-#define UA_TYPE_METHOD_NEW_DEFAULT(TYPE) \
-UA_Int32 TYPE##_new(TYPE ** p) { \
-	UA_Int32 retval = UA_SUCCESS;\
-	retval |= UA_alloc((void**)p, TYPE##_calcSize(UA_NULL));\
-	retval |= TYPE##_init(*p);\
-	return retval;\
-}
-
-#define UA_TYPE_METHOD_INIT_DEFAULT(TYPE) \
-UA_Int32 TYPE##_init(TYPE * p) { \
-	if(p==UA_NULL)return UA_ERROR;\
-	*p = (TYPE)0;\
-	return UA_SUCCESS;\
-}
-//#define UA_TYPE_COPY_METHOD_PROTOTYPE(TYPE) \  UA_Int32 TYPE##_copy(TYPE const *src, TYPE *dst);
-
-/*** Prototypes for basic types **/
-UA_TYPE_METHOD_PROTOTYPES (UA_Boolean)
-UA_TYPE_METHOD_PROTOTYPES (UA_Byte)
-UA_TYPE_METHOD_PROTOTYPES (UA_SByte)
-UA_TYPE_METHOD_PROTOTYPES (UA_Int16)
-UA_TYPE_METHOD_PROTOTYPES (UA_UInt16)
-UA_TYPE_METHOD_PROTOTYPES (UA_Int32)
-UA_TYPE_METHOD_PROTOTYPES (UA_UInt32)
-UA_TYPE_METHOD_PROTOTYPES (UA_Int64)
-UA_TYPE_METHOD_PROTOTYPES (UA_UInt64)
-UA_TYPE_METHOD_PROTOTYPES (UA_Float)
-UA_TYPE_METHOD_PROTOTYPES (UA_Double)
-
-/**
-* StatusCodeBinaryEncoding
-* Part: 6
-* Chapter: 5.2.2.11
-* Page: 20
-* 
-* StatusCodes aren't an enum (=int), since 32 unsigned bits are needed.
-* See also ua_statuscodes.h
-*/
-typedef UA_UInt32 UA_StatusCode;
-UA_TYPE_METHOD_PROTOTYPES (UA_StatusCode)
-
-/** IntegerId - Part: 4, Chapter: 7.13, Page: 118 */
-typedef float UA_IntegerId;
-UA_TYPE_METHOD_PROTOTYPES (UA_IntegerId)
-
-/** @brief String Object
- *
- *  String - Part: 6, Chapter: 5.2.2.4, Page: 16
- */
-typedef struct UA_String {
-	UA_Int32 	length;
-	UA_Byte*	data;
-} UA_String;
-UA_TYPE_METHOD_PROTOTYPES (UA_String)
-//UA_Int32 UA_String_copy(UA_String const * src, UA_String* dst);
-UA_Int32 UA_String_copycstring(char const * src, UA_String* dst);
-UA_Int32 UA_String_copyprintf(char const * fmt, UA_String* dst, ...);
-UA_Int32 UA_String_compare(const UA_String *string1, const UA_String *string2);
-void UA_String_printf(char const * label, const UA_String* string);
-void UA_String_printx(char const * label, const UA_String* string);
-void UA_String_printx_hex(char const * label, const UA_String* string);
-
-/* ByteString - Part: 6, Chapter: 5.2.2.7, Page: 17 */
-UA_TYPE_METHOD_PROTOTYPES (UA_ByteString)
-UA_Int32 UA_ByteString_compare(const UA_ByteString *string1, const UA_ByteString *string2);
-//UA_Int32 UA_ByteString_copy(UA_ByteString const * src, UA_ByteString* dst);
-UA_Int32 UA_ByteString_newMembers(UA_ByteString* p, UA_Int32 length);
-extern UA_ByteString UA_ByteString_securityPoliceNone;
-
-/* LocalizedTextBinaryEncoding - Part: 6, Chapter: 5.2.2.14, Page: 21 */
-enum UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_enum {
-	UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE = 0x01,
-	UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT = 0x02
-};
-
-typedef struct UA_LocalizedText {
-	UA_Byte encodingMask;
-	UA_String locale;
-	UA_String text;
-} UA_LocalizedText;
-UA_TYPE_METHOD_PROTOTYPES (UA_LocalizedText)
-
-UA_Int32 UA_LocalizedText_copycstring(char const * src, UA_LocalizedText* dst);
-void UA_ByteString_printf(char* label, const UA_ByteString* string);
-void UA_ByteString_printx(char* label, const UA_ByteString* string);
-void UA_ByteString_printx_hex(char* label, const UA_ByteString* string);
-
-/* GuidType - Part: 6, Chapter: 5.2.2.6 Page: 17 */
-typedef struct UA_Guid {
-	UA_UInt32 data1;
-	UA_UInt16 data2;
-	UA_UInt16 data3;
-	UA_Byte data4[8];
-} UA_Guid;
-UA_TYPE_METHOD_PROTOTYPES (UA_Guid)
-UA_Int32 UA_Guid_compare(const UA_Guid *g1, const UA_Guid *g2);
-
-/* DateTime - Part: 6, Chapter: 5.2.2.5, Page: 16 */
-typedef UA_Int64 UA_DateTime; //100 nanosecond resolution
-UA_TYPE_METHOD_PROTOTYPES (UA_DateTime)
-
-UA_DateTime UA_DateTime_now();
-typedef struct UA_DateTimeStruct {
-	UA_Int16 nanoSec;
-	UA_Int16 microSec;
-	UA_Int16 milliSec;
-	UA_Int16 sec;
-	UA_Int16 min;
-	UA_Int16 hour;
-	UA_Int16 day;
-	UA_Int16 mounth;
-	UA_Int16 year;
-} UA_DateTimeStruct;
-UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time);
-UA_Int32 UA_DateTime_difference_ms(UA_DateTime time1, UA_DateTime time2);
-UA_Int32 UA_DateTime_toString(UA_DateTime time, UA_String* timeString);
-
-typedef struct UA_NodeId {
-	UA_Byte   encodingByte; //enum BID_NodeIdEncodingValuesType
-	UA_UInt16 namespace;
-    union {
-        UA_UInt32 numeric;
-        UA_String string;
-        UA_Guid guid;
-        UA_ByteString byteString;
-    } identifier;
-} UA_NodeId;
-UA_TYPE_METHOD_PROTOTYPES (UA_NodeId)
-
-UA_Int32 UA_NodeId_compare(const UA_NodeId *n1, const UA_NodeId *n2);
-void UA_NodeId_printf(char* label, const UA_NodeId* node);
-UA_Boolean UA_NodeId_isNull(const UA_NodeId* p);
-UA_Int16 UA_NodeId_getNamespace(UA_NodeId const * id);
-UA_Int16 UA_NodeId_getIdentifier(UA_NodeId const * id);
-_Bool UA_NodeId_isBasicType(UA_NodeId const * id);
-
-
-/* XmlElement - Part: 6, Chapter: 5.2.2.8, Page: 17 */
-typedef struct UA_XmlElement {
-	//TODO Überlegung ob man es direkt als ByteString speichert oder als String
-	UA_ByteString data;
-} UA_XmlElement;
-UA_TYPE_METHOD_PROTOTYPES (UA_XmlElement)
-
-/* ExpandedNodeId - Part: 6, Chapter: 5.2.2.10, Page: 19 */
-// 62541-6 Chapter 5.2.2.9, Table 5
-#define UA_NODEIDTYPE_NAMESPACE_URI_FLAG 0x80
-#define UA_NODEIDTYPE_SERVERINDEX_FLAG   0x40
-#define UA_NODEIDTYPE_MASK (~(UA_NODEIDTYPE_NAMESPACE_URI_FLAG | UA_NODEIDTYPE_SERVERINDEX_FLAG))
-typedef struct UA_ExpandedNodeId {
-	UA_NodeId nodeId;
-	UA_String namespaceUri;
-	UA_UInt32 serverIndex;
-} UA_ExpandedNodeId;
-UA_TYPE_METHOD_PROTOTYPES(UA_ExpandedNodeId)
-UA_Boolean UA_ExpandedNodeId_isNull(const UA_ExpandedNodeId* p);
-
-/* IdentifierType */
-typedef UA_Int32 UA_IdentifierType;
-UA_TYPE_METHOD_PROTOTYPES(UA_IdentifierType)
-
-/* ExtensionObjectBinaryEncoding - Part: 6, Chapter: 5.2.2.15, Page: 21 */
-typedef struct UA_ExtensionObject {
-	UA_NodeId typeId;
-	UA_Byte encoding; //Type of the enum UA_ExtensionObjectEncodingMaskType
-	UA_ByteString body; // contains either the bytestring or a pointer to the memory-object
-} UA_ExtensionObject;
-UA_TYPE_METHOD_PROTOTYPES(UA_ExtensionObject)
-
-enum UA_ExtensionObject_EncodingMaskType_enum {
-	UA_EXTENSIONOBJECT_ENCODINGMASK_NOBODYISENCODED =   0x00,
-	UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING = 	0x01,
-	UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML =         0x02
-};
-
-/* QualifiedNameBinaryEncoding - Part: 6, Chapter: 5.2.2.13, Page: 20 */
-typedef struct UA_QualifiedName {
-	UA_UInt16 namespaceIndex;
-	/*UA_UInt16 reserved; removed by Sten since unclear origin*/
-	UA_String name;
-} UA_QualifiedName;
-UA_TYPE_METHOD_PROTOTYPES(UA_QualifiedName)
-
-/* XML Decoding */
-
-/** @brief A readable shortcut for NodeIds. A list of aliases is intensively used in the namespace0-xml-files */
-typedef struct UA_NodeSetAlias {
-	UA_String alias;
-	UA_String value;
-} UA_NodeSetAlias;
-UA_TYPE_METHOD_PROTOTYPES (UA_NodeSetAlias)
-
-/** @brief UA_NodeSetAliases - a list of aliases */
-typedef struct UA_NodeSetAliases {
-	UA_Int32 size;
-	UA_NodeSetAlias** aliases;
-} UA_NodeSetAliases;
-UA_TYPE_METHOD_PROTOTYPES (UA_NodeSetAliases)
-
-typedef struct XML_child {
-	cstring name;
-	UA_Int32 length;
-	UA_Int32 type;
-	XML_decoder elementHandler;
-	void* obj;
-} XML_child;
-
-typedef struct XML_Parent {
-	cstring name;
-	int textAttribIdx; // -1 - not set
-	cstring textAttrib;
-	int activeChild; // -1 - no active child
-	int totalGatherLength;
-	UA_list_List textGatherList;
-	int len; // -1 - empty set
-	XML_child children[XML_STACK_MAX_CHILDREN];
-} XML_Parent;
-
-typedef struct XML_Stack {
-	int depth;
-	XML_Parent parent[XML_STACK_MAX_DEPTH];
-	UA_Int32 nsid;
-	UA_NodeSetAliases* aliases; // shall point to the aliases of the NodeSet after reading
-} XML_Stack;
-
-typedef struct UA_VTable {
-	UA_UInt32 ns0Id;
-	UA_Int32 (*calcSize)(void const * ptr);
-	UA_Int32 (*decodeBinary)(UA_ByteString const * src, UA_Int32* pos, void* dst);
-	UA_Int32 (*encodeBinary)(void const * src, UA_Int32* pos, UA_ByteString* dst);
-	UA_Int32 (*decodeXML)(XML_Stack* s, XML_Attr* attr, void* dst, UA_Boolean isStart);
-	UA_Int32 (*init)(void * p);
-	UA_Int32 (*new)(void ** p);
-	UA_Int32 (*copy)(void const *src,void *dst);
-	UA_Int32 (*delete)(void * p);
-	UA_UInt32 memSize; // size of the struct only in memory (no dynamic components)
-	UA_Byte* name;
-} UA_VTable;
-
-/* VariantBinaryEncoding - Part: 6, Chapter: 5.2.2.16, Page: 22 */
-enum UA_VARIANT_ENCODINGMASKTYPE_enum {
-	UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK = 0x3F,	// bits 0:5
-	UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS =  (0x01 << 6), // bit 6
-	UA_VARIANT_ENCODINGMASKTYPE_ARRAY =       (0x01 << 7) // bit 7
-};
-
-typedef struct UA_Variant {
-	UA_VTable* vt;		// internal entry into vTable
-	UA_Byte encodingMask; 	// Type of UA_Variant_EncodingMaskType_enum
-	UA_Int32 arrayLength;	// total number of elements
-	UA_Int32 arrayDimensionsLength;
-	UA_Int32 **arrayDimensions;
-	void** data;
-} UA_Variant;
-UA_TYPE_METHOD_PROTOTYPES (UA_Variant)
-
-UA_Int32 UA_Variant_copySetValue(UA_Variant *v, UA_Int32 type, const void* data);
-UA_Int32 UA_Variant_copySetArray(UA_Variant *v, UA_Int32 type_id, UA_Int32 arrayLength, UA_UInt32 elementSize, const void* array);
-
-/**
-   @brief Functions UA_Variant_borrowSetValue and ..Array allow to define
- variants whose payload will not be deleted. This is achieved by a second
- vtable. The functionality can be used e.g. when UA_VariableNodes point into a
- "father" structured object that is stored in an UA_VariableNode itself. */
-UA_Int32 UA_Variant_borrowSetValue(UA_Variant *v, UA_Int32 type, const void* data); // Take care not to free the data before the variant.
-UA_Int32 UA_Variant_borrowSetArray(UA_Variant *v, UA_Int32 type, UA_Int32 arrayLength, const void* data); // Take care not to free the data before the variant.
-
-/* DataValue - Part: 6, Chapter: 5.2.2.17, Page: 23 */
-typedef struct UA_DataValue {
-	UA_Byte encodingMask;
-	UA_Variant value;
-	UA_StatusCode status;
-	UA_DateTime sourceTimestamp;
-	UA_Int16 sourcePicoseconds;
-	UA_DateTime serverTimestamp;
-	UA_Int16 serverPicoseconds;
-} UA_DataValue;
-UA_TYPE_METHOD_PROTOTYPES(UA_DataValue)
-
-/** 62541-6, §5.2.2.17, Table 15 */
-enum UA_DATAVALUE_ENCODINGMASKTYPE_enum {
-	UA_DATAVALUE_ENCODINGMASK_VARIANT = 	        0x01,
-	UA_DATAVALUE_ENCODINGMASK_STATUSCODE = 	        0x02,
-	UA_DATAVALUE_ENCODINGMASK_SOURCETIMESTAMP = 	0x04,
-	UA_DATAVALUE_ENCODINGMASK_SERVERTIMESTAMP = 	0x08,
-	UA_DATAVALUE_ENCODINGMASK_SOURCEPICOSECONDS = 	0x10,
-	UA_DATAVALUE_ENCODINGMASK_SERVERPICOSECONDS = 	0x20
-};
-
-/* DiagnosticInfo - Part: 6, Chapter: 5.2.2.12, Page: 20 */
-typedef struct UA_DiagnosticInfo {
-	UA_Byte encodingMask; //Type of the Enum UA_DIAGNOSTICINFO_ENCODINGMASKTYPE
-	UA_Int32 symbolicId;
-	UA_Int32 namespaceUri;
-	UA_Int32 localizedText;
-	UA_Int32 locale;
-	UA_String additionalInfo;
-	UA_StatusCode innerStatusCode;
-	struct UA_DiagnosticInfo* innerDiagnosticInfo;
-} UA_DiagnosticInfo;
-UA_TYPE_METHOD_PROTOTYPES(UA_DiagnosticInfo)
-
-enum UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_enum {
-	UA_DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID = 		 0x01,
-	UA_DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE = 		     0x02,
-	UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT = 	     0x04,
-	UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALE = 			 0x08,
-	UA_DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO =      0x10,
-	UA_DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE =     0x20,
-	UA_DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO = 0x40
-};
-
-typedef void UA_InvalidType;
-UA_TYPE_METHOD_PROTOTYPES (UA_InvalidType)
-
-#endif /* OPCUA_BASICTYPES_H_ */

+ 0 - 66
include/ua_types.h

@@ -1,66 +0,0 @@
-#ifndef OPCUA_TYPES_H_
-#define OPCUA_TYPES_H_
-
-#include <stdint.h>
-
-#define DBG_VERBOSE(expression) // omit debug code
-#define DBG_ERR(expression) // omit debug code
-#define DBG(expression) // omit debug code
-#if defined(DEBUG) 		// --enable-debug=(yes|verbose)
-# undef DBG
-# define DBG(expression) expression
-# undef DBG_ERR
-# define DBG_ERR(expression) expression
-# if defined(VERBOSE) 	// --enable-debug=verbose
-#  undef DBG_VERBOSE
-#  define DBG_VERBOSE(expression) expression
-# endif
-#endif
-
-/* Basic types */
-typedef _Bool UA_Boolean;
-typedef uint8_t UA_Byte;
-typedef int8_t UA_SByte;
-typedef int16_t UA_Int16;
-typedef uint16_t UA_UInt16;
-typedef int32_t UA_Int32;
-typedef uint32_t UA_UInt32;
-typedef int64_t UA_Int64;
-typedef uint64_t UA_UInt64;
-typedef float UA_Float;
-typedef double UA_Double;
-
-/* ByteString - Part: 6, Chapter: 5.2.2.7, Page: 17 */
-typedef struct UA_ByteString {
-	UA_Int32 	length;
-	UA_Byte*	data;
-} UA_ByteString;
-
-/* Function return values */
-#define UA_SUCCESS 0
-#define UA_NO_ERROR UA_SUCCESS
-#define UA_ERROR (0x01 << 31)
-#define UA_ERR_INCONSISTENT  (UA_ERROR | (0x01 << 1))
-#define UA_ERR_INVALID_VALUE (UA_ERROR | (0x01 << 2))
-#define UA_ERR_NO_MEMORY     (UA_ERROR | (0x01 << 3))
-#define UA_ERR_NOT_IMPLEMENTED (UA_ERROR | (0x01 << 4))
-
-/* Boolean values and null */
-#define UA_TRUE (42==42)
-#define TRUE UA_TRUE
-#define UA_FALSE (!UA_TRUE)
-#define FALSE UA_FALSE
-
-/* Compare values */
-#define UA_EQUAL 0
-#define UA_NOT_EQUAL (!UA_EQUAL)
-
-/* heap memory functions */
-#define UA_NULL ((void*)0)
-extern void const * UA_alloc_lastptr;
-#define UA_free(ptr) _UA_free(ptr,#ptr,__FILE__,__LINE__)
-UA_Int32 _UA_free(void * ptr,char*,char*,int);
-UA_Int32 UA_memcpy(void *dst, void const *src, int size);
-#define UA_alloc(ptr,size) _UA_alloc(ptr,size,#ptr,#size,__FILE__,__LINE__)
-UA_Int32 _UA_alloc(void ** dst, int size,char*,char*,char*,int);
-#endif

tools/NodeIds.csv → schema/NodeIds.csv


examples/src/Opc.Ua.NodeSet2.Part3.xml → schema/Opc.Ua.NodeSet2.Part3.xml


examples/src/Opc.Ua.NodeSet2.Part4.xml → schema/Opc.Ua.NodeSet2.Part4.xml


examples/src/Opc.Ua.NodeSet2.Part5.xml → schema/Opc.Ua.NodeSet2.Part5.xml


examples/src/Opc.Ua.NodeSet2.xml → schema/Opc.Ua.NodeSet2.xml


tools/Opc.Ua.Types.bsd → schema/Opc.Ua.Types.bsd


tools/UA_stackInternalTypes.bsd → schema/UA_stackInternalTypes.bsd


+ 46 - 25
src/Makefile.am

@@ -1,30 +1,47 @@
-AM_CFLAGS = $(GLOBAL_AM_CFLAGS) -I$(top_builddir)/include -I$(top_builddir)/src -I. -I$(top_builddir)/src/util
-TOOL_DIR = ../tools
+AM_CFLAGS = $(GLOBAL_AM_CFLAGS) -I$(top_builddir)/src -I. -I$(top_builddir)/src/util
+TOOL_DIR = $(top_builddir)/tools
+SCHEMA_DIR = $(top_builddir)/schema
 lib_LTLIBRARIES = libopen62541.la
+lib_LTLIBRARIES: generate_types generate_namespace_0
 libopen62541_la_LDFLAGS = -avoid-version -no-undefined
-libopen62541_la_SOURCES = opcua.c \
-			ua_basictypes.c \
-			ua_namespace_0.c \
-			util/ua_list.c \
-			util/ua_indexedList.c \
-			ua_transport.c \
-			ua_transport_binary.c \
-			ua_transport_binary_secure.c \
-			ua_namespace.c \
-			ua_services_attribute.c \
-			ua_services_session.c \
-			ua_services_discovery.c \
-			ua_services_securechannel.c \
-			ua_services_nodemanagement.c \
-			ua_services_view.c \
-			ua_application.c \
-			ua_xml.c\
-			ua_stack_session.c\
-			ua_stack_session_manager.c\
-			ua_stack_channel.c \
-			ua_stack_channel_manager.c \
-			ua_transport_connection_manager.c \
-			ua_transport_connection.c
+libopen62541_la_SOURCES = ua_types.c \
+						  ua_types_encoding_binary.c \
+						  ua_types_generated.c \
+						  ua_types_encoding_xml.c \
+						  ua_namespace_0.c \
+						  util/ua_util.c \
+						  util/ua_list.c \
+						  util/ua_indexedList.c \
+						  util/ua_base64.c \
+						  ua_transport.c \
+						  ua_transport_binary.c \
+						  ua_transport_binary_secure.c \
+						  ua_namespace.c \
+						  ua_namespace_xml.c \
+						  ua_services_attribute.c \
+						  ua_services_session.c \
+						  ua_services_discovery.c \
+						  ua_services_securechannel.c \
+						  ua_services_nodemanagement.c \
+						  ua_services_view.c \
+						  ua_services_subscription.c\
+						  ua_services_monitoreditems.c\
+						  ua_application.c \
+			              ua_stack_session.c\
+			              ua_stack_session_manager.c\
+			              ua_stack_channel.c \
+						  ua_stack_channel_manager.c \
+						  ua_transport_connection_manager.c \
+						  ua_transport_connection.c\
+						  ua_xml.c
+ua_types.c: ua_namespace_0.h
+ua_namespace_0.h: ua_types_generated.h
+
+ua_types_generated.c ua_types_generated.h: $(SCHEMA_DIR)/Opc.Ua.Types.bsd $(TOOL_DIR)/generate_builtin.py
+	python $(TOOL_DIR)/generate_builtin.py $(SCHEMA_DIR)/Opc.Ua.Types.bsd ua_types_generated
+
+ua_namespace_0.c ua_namespace_0.h: $(SCHEMA_DIR)/NodeIds.csv $(TOOL_DIR)/generate_namespace.py
+	python $(TOOL_DIR)/generate_namespace.py $(SCHEMA_DIR)/NodeIds.csv ua_namespace_0
 
 .PHONY: convenience-link clean-convenience-link
 
@@ -51,3 +68,7 @@ clean-convenience-link:
 all-local: convenience-link
 
 clean-local: clean-convenience-link
+	rm -rf ua_types_generated.c ua_types_generated.h || true;
+	rm -rf ua_namespace_0.c ua_namespace_0.h || true;
+	rm -rf *.gcov || true;
+	rm -rf util/*.gcov || true;

+ 606 - 32
src/ua_application.c

@@ -1,5 +1,6 @@
 #include "ua_application.h"
 #include "ua_namespace.h"
+#include "ua_services_internal.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -11,21 +12,25 @@ Application appMockup = {
 };
 
 UA_Node* create_node_ns0(UA_Int32 class, UA_Int32 nodeClass, UA_Int32 const id, char const * qn, char const * dn, char const * desc) {
-	UA_Node* n; UA_[class].new((void **)&n);
+	UA_Node* n; UA_.types[class].new((void **)&n);
 	n->nodeId.encodingByte = UA_NODEIDTYPE_FOURBYTE;
 	n->nodeId.namespace = 0;
 	n->nodeId.identifier.numeric = id;
 	UA_String_copycstring(qn,&(n->browseName.name));
-	n->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
-	UA_String_copycstring(dn,&(n->displayName.text));
-	n->description.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
-	UA_String_copycstring(desc,&(n->description.text));
+	UA_String_copycstring(dn,&n->displayName.text);
+	UA_String_copycstring(desc,&n->description.text);
 	n->nodeClass = nodeClass;
 	return n;
 }
 
-#define C2UA_STRING(s) (UA_String) { sizeof(s)-1, (UA_Byte*) s }
 void appMockup_init() {
+	//fill the UA_borrowed_ table that has been declaed in ua_namespace.c
+	for(UA_Int32 i=0;i<SIZE_UA_VTABLE;i++){
+		UA_borrowed_.types[i] = UA_.types[i];
+		UA_borrowed_.types[i].delete=(UA_Int32(*)(void *))phantom_delete;
+		UA_borrowed_.types[i].deleteMembers=(UA_Int32(*)(void *))phantom_delete;
+	}
+
 	// create namespaces
 	// TODO: A table that maps the namespaceUris to Ids
 	Namespace* ns0;
@@ -39,36 +44,605 @@ void appMockup_init() {
 	UA_indexedList_addValueToFront(appMockup.namespaces,0,ns0);
 	UA_indexedList_addValueToFront(appMockup.namespaces,1,local);
 
-	UA_Node* np;
-	np = create_node_ns0(UA_OBJECTNODE, UA_NODECLASS_OBJECT, 2253, "Server", "open62541", "...");
-	Namespace_insert(ns0,np);
-	UA_ObjectNode* o = (UA_ObjectNode*)np;
-	o->eventNotifier = UA_FALSE;
-
-	np = create_node_ns0(UA_VARIABLENODE, UA_NODECLASS_VARIABLE, 2255, "Server_NamespaceArray", "open62541", "..." );
-	UA_VariableNode* v = (UA_VariableNode*)np;
-	UA_Array_new((void***)&v->value.data,2,UA_STRING);
-	v->value.vt = &UA_[UA_STRING];
-	v->value.arrayLength = 2;
-	v->value.encodingMask = UA_VARIANT_ENCODINGMASKTYPE_ARRAY | UA_STRING_NS0;
-	UA_String_copycstring("http://opcfoundation.org/UA/",((UA_String **)(((v)->value).data))[0]);
-	UA_String_copycstring("http://localhost:16664/open62541/",((UA_String **)(((v)->value).data))[1]);
-	v->dataType.encodingByte = UA_NODEIDTYPE_FOURBYTE;
-	v->dataType.identifier.numeric = UA_STRING_NS0;
-	v->valueRank = 1;
-	v->minimumSamplingInterval = 1.0;
-	v->historizing = UA_FALSE;
-
-	Namespace_insert(ns0,np);
+	/**************/
+	/* References */
+	/**************/
+
+	// ReferenceType Ids
+	UA_NodeId RefTypeId_References = NS0NODEID(31);
+	UA_NodeId RefTypeId_NonHierarchicalReferences = NS0NODEID(32);
+	UA_NodeId RefTypeId_HierarchicalReferences = NS0NODEID(33);
+	UA_NodeId RefTypeId_HasChild = NS0NODEID(34);
+	UA_NodeId RefTypeId_Organizes = NS0NODEID(35);
+	UA_NodeId RefTypeId_HasEventSource = NS0NODEID(36);
+	UA_NodeId RefTypeId_HasModellingRule = NS0NODEID(37);
+	UA_NodeId RefTypeId_HasEncoding = NS0NODEID(38);
+	UA_NodeId RefTypeId_HasDescription = NS0NODEID(39);
+	UA_NodeId RefTypeId_HasTypeDefinition = NS0NODEID(40);
+	UA_NodeId RefTypeId_GeneratesEvent = NS0NODEID(41);
+	UA_NodeId RefTypeId_Aggregates = NS0NODEID(44);
+	UA_NodeId RefTypeId_HasSubtype = NS0NODEID(45);
+	UA_NodeId RefTypeId_HasProperty = NS0NODEID(46);
+	UA_NodeId RefTypeId_HasComponent = NS0NODEID(47);
+	UA_NodeId RefTypeId_HasNotifier = NS0NODEID(48);
+	UA_NodeId RefTypeId_HasOrderedComponent = NS0NODEID(49);
+	UA_NodeId RefTypeId_HasModelParent = NS0NODEID(50);
+	UA_NodeId RefTypeId_FromState = NS0NODEID(51);
+	UA_NodeId RefTypeId_ToState = NS0NODEID(52);
+	UA_NodeId RefTypeId_HasCause = NS0NODEID(53);
+	UA_NodeId RefTypeId_HasEffect = NS0NODEID(54);
+	UA_NodeId RefTypeId_HasHistoricalConfiguration = NS0NODEID(56);
+
+	UA_ReferenceTypeNode *references;
+	UA_ReferenceTypeNode_new(&references);
+	references->nodeId = RefTypeId_References;
+	references->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	references->browseName = UA_QUALIFIEDNAME_STATIC("References");
+	references->displayName = UA_LOCALIZEDTEXT_STATIC("References");
+	references->description = UA_LOCALIZEDTEXT_STATIC("References");
+	references->isAbstract = UA_TRUE;
+	references->symmetric = UA_TRUE;
+	Namespace_insert(ns0,(UA_Node*)references);
+
+	UA_ReferenceTypeNode *hierarchicalreferences;
+	UA_ReferenceTypeNode_new(&hierarchicalreferences);
+	hierarchicalreferences->nodeId = RefTypeId_HierarchicalReferences;
+	hierarchicalreferences->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hierarchicalreferences->browseName = UA_QUALIFIEDNAME_STATIC("HierarchicalReferences");
+	hierarchicalreferences->displayName = UA_LOCALIZEDTEXT_STATIC("HierarchicalReferences");
+	hierarchicalreferences->description = UA_LOCALIZEDTEXT_STATIC("HierarchicalReferences");
+	hierarchicalreferences->isAbstract = UA_TRUE;
+	hierarchicalreferences->symmetric = UA_FALSE;
+	AddReference((UA_Node*)hierarchicalreferences, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_References, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hierarchicalreferences);
+
+	UA_ReferenceTypeNode *nonhierarchicalreferences;
+	UA_ReferenceTypeNode_new(&nonhierarchicalreferences);
+	nonhierarchicalreferences->nodeId = RefTypeId_NonHierarchicalReferences;
+	nonhierarchicalreferences->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	nonhierarchicalreferences->browseName = UA_QUALIFIEDNAME_STATIC("NonHierarchicalReferences");
+	nonhierarchicalreferences->displayName = UA_LOCALIZEDTEXT_STATIC("NonHierarchicalReferences");
+	nonhierarchicalreferences->description = UA_LOCALIZEDTEXT_STATIC("NonHierarchicalReferences");
+	nonhierarchicalreferences->isAbstract = UA_TRUE;
+	nonhierarchicalreferences->symmetric = UA_FALSE;
+	AddReference((UA_Node*)nonhierarchicalreferences, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_References, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)nonhierarchicalreferences);
+
+	UA_ReferenceTypeNode *haschild;
+	UA_ReferenceTypeNode_new(&haschild);
+	haschild->nodeId = RefTypeId_HasChild;
+	haschild->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	haschild->browseName = UA_QUALIFIEDNAME_STATIC("HasChild");
+	haschild->displayName = UA_LOCALIZEDTEXT_STATIC("HasChild");
+	haschild->description = UA_LOCALIZEDTEXT_STATIC("HasChild");
+	haschild->isAbstract = UA_TRUE;
+	haschild->symmetric = UA_FALSE;
+	AddReference((UA_Node*)haschild, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_HierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)haschild);
+
+	UA_ReferenceTypeNode *organizes;
+	UA_ReferenceTypeNode_new(&organizes);
+	organizes->nodeId = RefTypeId_Organizes;
+	organizes->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	organizes->browseName = UA_QUALIFIEDNAME_STATIC("Organizes");
+	organizes->displayName = UA_LOCALIZEDTEXT_STATIC("Organizes");
+	organizes->description = UA_LOCALIZEDTEXT_STATIC("Organizes");
+	organizes->isAbstract = UA_FALSE;
+	organizes->symmetric = UA_FALSE;
+	organizes->inverseName = UA_LOCALIZEDTEXT_STATIC("OrganizedBy");
+	AddReference((UA_Node*)organizes, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_HierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)organizes);
+
+	UA_ReferenceTypeNode *haseventsource;
+	UA_ReferenceTypeNode_new(&haseventsource);
+	haseventsource->nodeId = RefTypeId_HasEventSource;
+	haseventsource->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	haseventsource->browseName = UA_QUALIFIEDNAME_STATIC("HasEventSource");
+	haseventsource->displayName = UA_LOCALIZEDTEXT_STATIC("HasEventSource");
+	haseventsource->description = UA_LOCALIZEDTEXT_STATIC("HasEventSource");
+	haseventsource->isAbstract = UA_FALSE;
+	haseventsource->symmetric = UA_FALSE;
+	haseventsource->inverseName = UA_LOCALIZEDTEXT_STATIC("EventSourceOf");
+	AddReference((UA_Node*)haseventsource, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_HierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)haseventsource);
+
+	UA_ReferenceTypeNode *hasmodellingrule;
+	UA_ReferenceTypeNode_new(&hasmodellingrule);
+	hasmodellingrule->nodeId = RefTypeId_HasModellingRule;
+	hasmodellingrule->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hasmodellingrule->browseName = UA_QUALIFIEDNAME_STATIC("HasModellingRule");
+	hasmodellingrule->displayName = UA_LOCALIZEDTEXT_STATIC("HasModellingRule");
+	hasmodellingrule->description = UA_LOCALIZEDTEXT_STATIC("HasModellingRule");
+	hasmodellingrule->isAbstract = UA_FALSE;
+	hasmodellingrule->symmetric = UA_FALSE;
+	hasmodellingrule->inverseName = UA_LOCALIZEDTEXT_STATIC("ModellingRuleOf");
+	AddReference((UA_Node*)hasmodellingrule, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hasmodellingrule);
+
+	UA_ReferenceTypeNode *hasencoding;
+	UA_ReferenceTypeNode_new(&hasencoding);
+	hasencoding->nodeId = RefTypeId_HasEncoding;
+	hasencoding->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hasencoding->browseName = UA_QUALIFIEDNAME_STATIC("HasEncoding");
+	hasencoding->displayName = UA_LOCALIZEDTEXT_STATIC("HasEncoding");
+	hasencoding->description = UA_LOCALIZEDTEXT_STATIC("HasEncoding");
+	hasencoding->isAbstract = UA_FALSE;
+	hasencoding->symmetric = UA_FALSE;
+	hasencoding->inverseName = UA_LOCALIZEDTEXT_STATIC("EncodingOf");
+	AddReference((UA_Node*)hasencoding, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hasencoding);
+
+	UA_ReferenceTypeNode *hasdescription;
+	UA_ReferenceTypeNode_new(&hasdescription);
+	hasdescription->nodeId = RefTypeId_HasDescription;
+	hasdescription->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hasdescription->browseName = UA_QUALIFIEDNAME_STATIC("HasDescription");
+	hasdescription->displayName = UA_LOCALIZEDTEXT_STATIC("HasDescription");
+	hasdescription->description = UA_LOCALIZEDTEXT_STATIC("HasDescription");
+	hasdescription->isAbstract = UA_FALSE;
+	hasdescription->symmetric = UA_FALSE;
+	hasdescription->inverseName = UA_LOCALIZEDTEXT_STATIC("DescriptionOf");
+	AddReference((UA_Node*)hasdescription, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hasdescription);
+
+	UA_ReferenceTypeNode *hastypedefinition;
+	UA_ReferenceTypeNode_new(&hastypedefinition);
+	hastypedefinition->nodeId = RefTypeId_HasTypeDefinition;
+	hastypedefinition->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hastypedefinition->browseName = UA_QUALIFIEDNAME_STATIC("HasTypeDefinition");
+	hastypedefinition->displayName = UA_LOCALIZEDTEXT_STATIC("HasTypeDefinition");
+	hastypedefinition->description = UA_LOCALIZEDTEXT_STATIC("HasTypeDefinition");
+	hastypedefinition->isAbstract = UA_FALSE;
+	hastypedefinition->symmetric = UA_FALSE;
+	hastypedefinition->inverseName = UA_LOCALIZEDTEXT_STATIC("TypeDefinitionOf");
+	AddReference((UA_Node*)hastypedefinition, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hastypedefinition);
+
+	UA_ReferenceTypeNode *generatesevent;
+	UA_ReferenceTypeNode_new(&generatesevent);
+	generatesevent->nodeId = RefTypeId_GeneratesEvent;
+	generatesevent->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	generatesevent->browseName = UA_QUALIFIEDNAME_STATIC("GeneratesEvent");
+	generatesevent->displayName = UA_LOCALIZEDTEXT_STATIC("GeneratesEvent");
+	generatesevent->description = UA_LOCALIZEDTEXT_STATIC("GeneratesEvent");
+	generatesevent->isAbstract = UA_FALSE;
+	generatesevent->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("GeneratedBy");
+	AddReference((UA_Node*)generatesevent, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)generatesevent);
+
+	UA_ReferenceTypeNode *aggregates;
+	UA_ReferenceTypeNode_new(&aggregates);
+	aggregates->nodeId = RefTypeId_Aggregates;
+	aggregates->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	aggregates->browseName = UA_QUALIFIEDNAME_STATIC("Aggregates");
+	aggregates->displayName = UA_LOCALIZEDTEXT_STATIC("Aggregates");
+	aggregates->description = UA_LOCALIZEDTEXT_STATIC("Aggregates");
+	aggregates->isAbstract = UA_TRUE;
+	aggregates->symmetric = UA_FALSE;
+	AddReference((UA_Node*)aggregates, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_HasChild, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)aggregates);
+
+	UA_ReferenceTypeNode *hassubtype;
+	UA_ReferenceTypeNode_new(&hassubtype);
+	hassubtype->nodeId = RefTypeId_HasSubtype;
+	hassubtype->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hassubtype->browseName = UA_QUALIFIEDNAME_STATIC("HasSubtype");
+	hassubtype->displayName = UA_LOCALIZEDTEXT_STATIC("HasSubtype");
+	hassubtype->description = UA_LOCALIZEDTEXT_STATIC("HasSubtype");
+	hassubtype->isAbstract = UA_FALSE;
+	hassubtype->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("SubtypeOf");
+	AddReference((UA_Node*)hassubtype, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_HasChild, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hassubtype);
+
+	UA_ReferenceTypeNode *hasproperty;
+	UA_ReferenceTypeNode_new(&hasproperty);
+	hasproperty->nodeId = RefTypeId_HasProperty;
+	hasproperty->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hasproperty->browseName = UA_QUALIFIEDNAME_STATIC("HasProperty");
+	hasproperty->displayName = UA_LOCALIZEDTEXT_STATIC("HasProperty");
+	hasproperty->description = UA_LOCALIZEDTEXT_STATIC("HasProperty");
+	hasproperty->isAbstract = UA_FALSE;
+	hasproperty->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("PropertyOf");
+	AddReference((UA_Node*)hasproperty, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_Aggregates, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hasproperty);
+
+	UA_ReferenceTypeNode *hascomponent;
+	UA_ReferenceTypeNode_new(&hascomponent);
+	hascomponent->nodeId = RefTypeId_HasComponent;
+	hascomponent->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hascomponent->browseName = UA_QUALIFIEDNAME_STATIC("HasComponent");
+	hascomponent->displayName = UA_LOCALIZEDTEXT_STATIC("HasComponent");
+	hascomponent->description = UA_LOCALIZEDTEXT_STATIC("HasComponent");
+	hascomponent->isAbstract = UA_FALSE;
+	hascomponent->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("ComponentOf");
+	AddReference((UA_Node*)hascomponent, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_Aggregates, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hascomponent);
+
+	UA_ReferenceTypeNode *hasnotifier;
+	UA_ReferenceTypeNode_new(&hasnotifier);
+	hasnotifier->nodeId = RefTypeId_HasNotifier;
+	hasnotifier->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hasnotifier->browseName = UA_QUALIFIEDNAME_STATIC("HasNotifier");
+	hasnotifier->displayName = UA_LOCALIZEDTEXT_STATIC("HasNotifier");
+	hasnotifier->description = UA_LOCALIZEDTEXT_STATIC("HasNotifier");
+	hasnotifier->isAbstract = UA_FALSE;
+	hasnotifier->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("NotifierOf");
+	AddReference((UA_Node*)hasnotifier, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_HasEventSource, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hasnotifier);
+
+	UA_ReferenceTypeNode *hasorderedcomponent;
+	UA_ReferenceTypeNode_new(&hasorderedcomponent);
+	hasorderedcomponent->nodeId = RefTypeId_HasOrderedComponent;
+	hasorderedcomponent->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hasorderedcomponent->browseName = UA_QUALIFIEDNAME_STATIC("HasOrderedComponent");
+	hasorderedcomponent->displayName = UA_LOCALIZEDTEXT_STATIC("HasOrderedComponent");
+	hasorderedcomponent->description = UA_LOCALIZEDTEXT_STATIC("HasOrderedComponent");
+	hasorderedcomponent->isAbstract = UA_FALSE;
+	hasorderedcomponent->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("OrderedComponentOf");
+	AddReference((UA_Node*)hasorderedcomponent, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_HasComponent, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hasorderedcomponent);
+
+	UA_ReferenceTypeNode *hasmodelparent;
+	UA_ReferenceTypeNode_new(&hasmodelparent);
+	hasmodelparent->nodeId = RefTypeId_HasModelParent;
+	hasmodelparent->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hasmodelparent->browseName = UA_QUALIFIEDNAME_STATIC("HasModelParent");
+	hasmodelparent->displayName = UA_LOCALIZEDTEXT_STATIC("HasModelParent");
+	hasmodelparent->description = UA_LOCALIZEDTEXT_STATIC("HasModelParent");
+	hasmodelparent->isAbstract = UA_FALSE;
+	hasmodelparent->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("ModelParentOf");
+	AddReference((UA_Node*)hasmodelparent, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hasmodelparent);
+
+	UA_ReferenceTypeNode *fromstate;
+	UA_ReferenceTypeNode_new(&fromstate);
+	fromstate->nodeId = RefTypeId_FromState;
+	fromstate->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	fromstate->browseName = UA_QUALIFIEDNAME_STATIC("FromState");
+	fromstate->displayName = UA_LOCALIZEDTEXT_STATIC("FromState");
+	fromstate->description = UA_LOCALIZEDTEXT_STATIC("FromState");
+	fromstate->isAbstract = UA_FALSE;
+	fromstate->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("ToTransition");
+	AddReference((UA_Node*)fromstate, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)fromstate);
+
+	UA_ReferenceTypeNode *tostate;
+	UA_ReferenceTypeNode_new(&tostate);
+	tostate->nodeId = RefTypeId_ToState;
+	tostate->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	tostate->browseName = UA_QUALIFIEDNAME_STATIC("ToState");
+	tostate->displayName = UA_LOCALIZEDTEXT_STATIC("ToState");
+	tostate->description = UA_LOCALIZEDTEXT_STATIC("ToState");
+	tostate->isAbstract = UA_FALSE;
+	tostate->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("FromTransition");
+	AddReference((UA_Node*)tostate, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)tostate);
+
+	UA_ReferenceTypeNode *hascause;
+	UA_ReferenceTypeNode_new(&hascause);
+	hascause->nodeId = RefTypeId_HasCause;
+	hascause->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hascause->browseName = UA_QUALIFIEDNAME_STATIC("HasCause");
+	hascause->displayName = UA_LOCALIZEDTEXT_STATIC("HasCause");
+	hascause->description = UA_LOCALIZEDTEXT_STATIC("HasCause");
+	hascause->isAbstract = UA_FALSE;
+	hascause->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("MayBeCausedBy");
+	AddReference((UA_Node*)hascause, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hascause);
+
+	UA_ReferenceTypeNode *haseffect;
+	UA_ReferenceTypeNode_new(&haseffect);
+	haseffect->nodeId = RefTypeId_HasEffect;
+	haseffect->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	haseffect->browseName = UA_QUALIFIEDNAME_STATIC("HasEffect");
+	haseffect->displayName = UA_LOCALIZEDTEXT_STATIC("HasEffect");
+	haseffect->description = UA_LOCALIZEDTEXT_STATIC("HasEffect");
+	haseffect->isAbstract = UA_FALSE;
+	haseffect->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("MayBeEffectedBy");
+	AddReference((UA_Node*)haseffect, &(UA_ReferenceNode){RefTypeId_HasSubtype, UA_TRUE,
+		(UA_ExpandedNodeId){RefTypeId_NonHierarchicalReferences, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)haseffect);
+
+	UA_ReferenceTypeNode *hashistoricalconfiguration;
+	UA_ReferenceTypeNode_new(&hashistoricalconfiguration);
+	hashistoricalconfiguration->nodeId = RefTypeId_HasHistoricalConfiguration;
+	hashistoricalconfiguration->nodeClass = UA_NODECLASS_REFERENCETYPE;
+	hashistoricalconfiguration->browseName = UA_QUALIFIEDNAME_STATIC("HasHistoricalConfiguration");
+	hashistoricalconfiguration->displayName = UA_LOCALIZEDTEXT_STATIC("HasHistoricalConfiguration");
+	hashistoricalconfiguration->description = UA_LOCALIZEDTEXT_STATIC("HasHistoricalConfiguration");
+	hashistoricalconfiguration->isAbstract = UA_FALSE;
+	hashistoricalconfiguration->symmetric = UA_FALSE;
+	generatesevent->inverseName = UA_LOCALIZEDTEXT_STATIC("HistoricalConfigurationOf");
+	AddReference((UA_Node*)hashistoricalconfiguration, &(UA_ReferenceNode){RefTypeId_HasSubtype,
+		UA_TRUE, (UA_ExpandedNodeId){RefTypeId_Aggregates, UA_STRING_NULL, 0}}, ns0);
+	Namespace_insert(ns0,(UA_Node*)hashistoricalconfiguration);
+
+
+	// ObjectTypes (Ids only)
+	UA_ExpandedNodeId ObjTypeId_FolderType = NS0EXPANDEDNODEID(61);
+
+	// Objects (Ids only)
+	UA_ExpandedNodeId ObjId_ObjectsFolder = NS0EXPANDEDNODEID(85);
+	UA_ExpandedNodeId ObjId_TypesFolder = NS0EXPANDEDNODEID(86);
+	UA_ExpandedNodeId ObjId_ViewsFolder = NS0EXPANDEDNODEID(87);
+	UA_ExpandedNodeId ObjId_Server = NS0EXPANDEDNODEID(2253);
+	UA_ExpandedNodeId ObjId_ServerArray = NS0EXPANDEDNODEID(2254);
+	UA_ExpandedNodeId ObjId_NamespaceArray = NS0EXPANDEDNODEID(2255);
+	UA_ExpandedNodeId ObjId_ServerStatus = NS0EXPANDEDNODEID(2256);
+	UA_ExpandedNodeId ObjId_ServerCapabilities = NS0EXPANDEDNODEID(2268);
+	UA_ExpandedNodeId ObjId_State = NS0EXPANDEDNODEID(2259);
+
+	// FolderType
+	UA_ObjectNode *folderType;
+	UA_ObjectNode_new(&folderType);
+	folderType->nodeId = NS0NODEID(61);
+	folderType->nodeClass = UA_NODECLASS_OBJECTTYPE; // I should not have to set this manually
+	folderType->browseName = UA_QUALIFIEDNAME_STATIC("FolderType");
+	folderType->displayName = UA_LOCALIZEDTEXT_STATIC("FolderType");
+	folderType->description = UA_LOCALIZEDTEXT_STATIC("FolderType");
+	Namespace_insert(ns0,(UA_Node*)folderType);
+
+	// Root
+	UA_ObjectNode *root;
+	UA_ObjectNode_new(&root);
+	root->nodeId = NS0NODEID(84);
+	root->nodeClass = UA_NODECLASS_OBJECT; // I should not have to set this manually
+	root->browseName = UA_QUALIFIEDNAME_STATIC("Root");
+	root->displayName = UA_LOCALIZEDTEXT_STATIC("Root");
+	root->description = UA_LOCALIZEDTEXT_STATIC("Root");
+	AddReference((UA_Node*)root, &(UA_ReferenceNode){RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType}, ns0);
+	AddReference((UA_Node*)root, &(UA_ReferenceNode){RefTypeId_Organizes, UA_FALSE, ObjId_ObjectsFolder}, ns0);
+	AddReference((UA_Node*)root, &(UA_ReferenceNode){RefTypeId_Organizes, UA_FALSE, ObjId_TypesFolder}, ns0);
+	AddReference((UA_Node*)root, &(UA_ReferenceNode){RefTypeId_Organizes, UA_FALSE, ObjId_ViewsFolder}, ns0);
+	Namespace_insert(ns0,(UA_Node*)root);
+
+	// Objects
+	UA_ObjectNode *objects;
+	UA_ObjectNode_new(&objects);
+	objects->nodeId = ObjId_ObjectsFolder.nodeId;
+	objects->nodeClass = UA_NODECLASS_OBJECT;
+	objects->browseName = UA_QUALIFIEDNAME_STATIC("Objects");
+	objects->displayName = UA_LOCALIZEDTEXT_STATIC("Objects");
+	objects->description = UA_LOCALIZEDTEXT_STATIC("Objects");
+	AddReference((UA_Node*)objects, &(UA_ReferenceNode){RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType}, ns0);
+	AddReference((UA_Node*)objects, &(UA_ReferenceNode){RefTypeId_Organizes, UA_FALSE, ObjId_Server}, ns0);
+	Namespace_insert(ns0,(UA_Node*)objects);
+
+	// Types
+	UA_ObjectNode *types;
+	UA_ObjectNode_new(&types);
+	types->nodeId = ObjId_TypesFolder.nodeId;
+	types->nodeClass = UA_NODECLASS_OBJECT;
+	types->browseName = UA_QUALIFIEDNAME_STATIC("Types");
+	types->displayName = UA_LOCALIZEDTEXT_STATIC("Types");
+	types->description = UA_LOCALIZEDTEXT_STATIC("Types");
+	AddReference((UA_Node*)types, &(UA_ReferenceNode){RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType}, ns0);
+	Namespace_insert(ns0,(UA_Node*)types);
+
+	// Views
+	UA_ObjectNode *views;
+	UA_ObjectNode_new(&views);
+	views->nodeId = ObjId_ViewsFolder.nodeId;
+	views->nodeClass = UA_NODECLASS_OBJECT;
+	views->browseName = UA_QUALIFIEDNAME_STATIC("Views");
+	views->displayName = UA_LOCALIZEDTEXT_STATIC("Views");
+	views->description = UA_LOCALIZEDTEXT_STATIC("Views");
+	AddReference((UA_Node*)views, &(UA_ReferenceNode){RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType}, ns0);
+	Namespace_insert(ns0,(UA_Node*)views);
+
+	// Server
+	UA_ObjectNode *server;
+	UA_ObjectNode_new(&server);
+	server->nodeId = ObjId_Server.nodeId;
+	server->nodeClass = UA_NODECLASS_OBJECT;
+	server->browseName = UA_QUALIFIEDNAME_STATIC("Server");
+	server->displayName = UA_LOCALIZEDTEXT_STATIC("Server");
+	server->description = UA_LOCALIZEDTEXT_STATIC("Server");
+	AddReference((UA_Node*)server, &(UA_ReferenceNode){RefTypeId_HasComponent, UA_FALSE, ObjId_ServerCapabilities}, ns0);
+	AddReference((UA_Node*)server, &(UA_ReferenceNode){RefTypeId_HasComponent, UA_FALSE, ObjId_NamespaceArray}, ns0);
+	AddReference((UA_Node*)server, &(UA_ReferenceNode){RefTypeId_HasProperty, UA_FALSE, ObjId_ServerStatus}, ns0);
+	AddReference((UA_Node*)server, &(UA_ReferenceNode){RefTypeId_HasProperty, UA_FALSE, ObjId_ServerArray}, ns0);
+	Namespace_insert(ns0,(UA_Node*)server);
+
+	// NamespaceArray
+	UA_VariableNode *namespaceArray;
+	UA_VariableNode_new(&namespaceArray);
+	namespaceArray->nodeId = ObjId_NamespaceArray.nodeId;
+	namespaceArray->nodeClass = UA_NODECLASS_VARIABLE; //FIXME: this should go into _new?
+	namespaceArray->browseName = UA_QUALIFIEDNAME_STATIC("NamespaceArray");
+	namespaceArray->displayName = UA_LOCALIZEDTEXT_STATIC("NamespaceArray");
+	namespaceArray->description = UA_LOCALIZEDTEXT_STATIC("NamespaceArray");
+	UA_Array_new((void**)&namespaceArray->value.data, 2, &UA_.types[UA_STRING]);
+	namespaceArray->value.vt = &UA_.types[UA_STRING];
+	namespaceArray->value.arrayLength = 2;
+	UA_String_copycstring("http://opcfoundation.org/UA/",&((UA_String *)((namespaceArray->value).data))[0]);
+	UA_String_copycstring("http://localhost:16664/open62541/",&((UA_String *)(((namespaceArray)->value).data))[1]);
+	namespaceArray->arrayDimensionsSize = 1;
+	UA_UInt32* dimensions = UA_NULL;
+	UA_alloc((void**)&dimensions, sizeof(UA_UInt32));
+	*dimensions = 2;
+	namespaceArray->arrayDimensions = dimensions;
+	namespaceArray->dataType = NS0NODEID(UA_STRING_NS0);
+	namespaceArray->valueRank = 1;
+	namespaceArray->minimumSamplingInterval = 1.0;
+	namespaceArray->historizing = UA_FALSE;
+	Namespace_insert(ns0,(UA_Node*)namespaceArray);
+
+	// ServerStatus
+	UA_VariableNode *serverstatus;
+	UA_VariableNode_new(&serverstatus);
+	serverstatus->nodeId = ObjId_ServerStatus.nodeId;
+	serverstatus->nodeClass = UA_NODECLASS_VARIABLE;
+	serverstatus->browseName = UA_QUALIFIEDNAME_STATIC("ServerStatus");
+	serverstatus->displayName = UA_LOCALIZEDTEXT_STATIC("ServerStatus");
+	serverstatus->description = UA_LOCALIZEDTEXT_STATIC("ServerStatus");
+	UA_ServerStatusDataType *status;
+	UA_ServerStatusDataType_new(&status);
+	status->startTime = UA_DateTime_now();
+	status->currentTime = UA_DateTime_now();
+	status->state = UA_SERVERSTATE_RUNNING;
+	status->buildInfo = (UA_BuildInfo){
+		.productUri = UA_STRING_STATIC("open62541.org"),
+				.manufacturerName = UA_STRING_STATIC("open62541"),
+				.productName = UA_STRING_STATIC("open62541"),
+				.softwareVersion = UA_STRING_STATIC("0.0"),
+				.buildNumber = UA_STRING_STATIC("0.0"),
+				.buildDate = UA_DateTime_now()};
+	status->secondsTillShutdown = 99999999;
+	status->shutdownReason = UA_LOCALIZEDTEXT_STATIC("because");
+	serverstatus->value.vt = &UA_.types[UA_SERVERSTATUSDATATYPE]; // gets encoded as an extensionobject
+	serverstatus->value.arrayLength = 1;
+	serverstatus->value.data = status;
+	Namespace_insert(ns0,(UA_Node*)serverstatus);
+
+	// State (Component of ServerStatus)
+	UA_Int32 *stateVal;
+	UA_Int32_new(&stateVal);
+	UA_VariableNode *state;
+	UA_VariableNode_new(&state);
+	state->nodeId = ObjId_State.nodeId;
+	state->nodeClass = UA_NODECLASS_VARIABLE;
+	state->browseName = UA_QUALIFIEDNAME_STATIC("State");
+	state->displayName = UA_LOCALIZEDTEXT_STATIC("State");
+	state->description = UA_LOCALIZEDTEXT_STATIC("State");
+	state->value.vt = &UA_borrowed_.types[UA_SERVERSTATE];
+	state->value.arrayLength = 1;
+	state->value.data = &status->state; // points into the other object.
+	Namespace_insert(ns0,(UA_Node*)state);
+
+	//TODO: free(namespaceArray->value.data) later or forget it
+
+
+	/* UA_VariableNode* v = (UA_VariableNode*)np; */
+	/* UA_Array_new((void**)&v->value.data, 2, &UA_.types[UA_STRING]); */
+	/* v->value.vt = &UA_.types[UA_STRING]; */
+	/* v->value.arrayLength = 2; */
+	/* UA_String_copycstring("http://opcfoundation.org/UA/",&((UA_String *)((v->value).data))[0]); */
+	/* UA_String_copycstring("http://localhost:16664/open62541/",&((UA_String *)(((v)->value).data))[1]); */
+	/* v->dataType.encodingByte = UA_NODEIDTYPE_FOURBYTE; */
+	/* v->dataType.identifier.numeric = UA_STRING_NS0; */
+	/* v->valueRank = 1; */
+	/* v->minimumSamplingInterval = 1.0; */
+	/* v->historizing = UA_FALSE; */
+	/* Namespace_insert(ns0,np); */
+
+	/*******************/
+	/* Namespace local */
+	/*******************/
+
+	// WORKS
+	UA_ExpandedNodeId ObjId_temperature1 = (UA_ExpandedNodeId){.nodeId = (UA_NodeId){.encodingByte = UA_NODEIDTYPE_TWOBYTE, .namespace = 0, .identifier.numeric = 108}, .namespaceUri = {-1, ((void *)0)}, .serverIndex = 0};
+
+	// temperature sensor
+	UA_VariableNode *temperature1;
+	UA_VariableNode_new(&temperature1);
+	temperature1->nodeId = ObjId_temperature1.nodeId;
+	temperature1->nodeClass = UA_NODECLASS_VARIABLE;
+	temperature1->browseName = UA_QUALIFIEDNAME_STATIC("temperature1");
+	temperature1->displayName = UA_LOCALIZEDTEXT_STATIC("temperature1");
+	temperature1->description = UA_LOCALIZEDTEXT_STATIC("temperature1");
+
+	//Set node value
+	UA_Variant *tmpNodeValue = &temperature1->value;
+	UA_Variant_init(tmpNodeValue);
+	UA_Float *tmpFloat;
+	UA_Float_new(&tmpFloat);
+	*tmpFloat = -273.15f;
+	tmpNodeValue->arrayDimensionsLength = 0;
+	tmpNodeValue->arrayLength = 1;
+	tmpNodeValue->data = (void*)tmpFloat;
+	tmpNodeValue->vt = &UA_.types[UA_FLOAT];
+
+	AddReference((UA_Node*)root, &(UA_ReferenceNode){RefTypeId_Organizes, UA_FALSE, ObjId_temperature1}, ns0);
+	Namespace_insert(ns0,(UA_Node*)temperature1);
+
+
+	UA_ExpandedNodeId ObjId_redLED = (UA_ExpandedNodeId){.nodeId = (UA_NodeId){.encodingByte = UA_NODEIDTYPE_TWOBYTE, .namespace = 0, .identifier.numeric = 109}, .namespaceUri = {-1, ((void *)0)}, .serverIndex = 0};
+	// redLED sensor
+	UA_VariableNode *redLED;
+	UA_VariableNode_new(&redLED);
+	redLED->nodeId = ObjId_redLED.nodeId;
+	redLED->nodeClass = UA_NODECLASS_VARIABLE;
+	redLED->browseName = UA_QUALIFIEDNAME_STATIC("redLED");
+	redLED->displayName = UA_LOCALIZEDTEXT_STATIC("redLED");
+	redLED->description = UA_LOCALIZEDTEXT_STATIC("redLED");
+
+	//Set node value
+	UA_Variant *tmpNodeValue1 = &redLED->value;
+	UA_Variant_init(tmpNodeValue1);
+	UA_Boolean *ledVal;
+	UA_Boolean_new(&ledVal);
+	*ledVal = UA_FALSE;
+	tmpNodeValue1->arrayDimensionsLength = 0;
+	tmpNodeValue1->arrayLength = 1;
+	tmpNodeValue1->data = (void*)ledVal;
+	tmpNodeValue1->vt = &UA_.types[UA_BOOLEAN];
+
+	AddReference((UA_Node*)root, &(UA_ReferenceNode){RefTypeId_Organizes, UA_FALSE, ObjId_redLED}, ns0);
+	Namespace_insert(ns0,(UA_Node*)redLED);
+
+
+	UA_ExpandedNodeId ObjId_yellowLED = (UA_ExpandedNodeId){.nodeId = (UA_NodeId){.encodingByte = UA_NODEIDTYPE_TWOBYTE, .namespace = 0, .identifier.numeric = 110}, .namespaceUri = {-1, ((void *)0)}, .serverIndex = 0};
+	// yellowLED sensor
+	UA_VariableNode *yellowLED;
+	UA_VariableNode_new(&yellowLED);
+	yellowLED->nodeId = ObjId_yellowLED.nodeId;
+	yellowLED->nodeClass = UA_NODECLASS_VARIABLE;
+	yellowLED->browseName = UA_QUALIFIEDNAME_STATIC("yellowLED");
+	yellowLED->displayName = UA_LOCALIZEDTEXT_STATIC("yellowLED");
+	yellowLED->description = UA_LOCALIZEDTEXT_STATIC("yellowLED");
+
+	//Set node value
+	UA_Variant *tmpNodeValue2 = &yellowLED->value;
+	UA_Variant_init(tmpNodeValue2);
+	UA_Boolean *ledVal1;
+	UA_Boolean_new(&ledVal1);
+	*ledVal1 = UA_FALSE;
+	tmpNodeValue2->arrayDimensionsLength = 0;
+	tmpNodeValue2->arrayLength = 1;
+	tmpNodeValue2->data = (void*)ledVal1;
+	tmpNodeValue2->vt = &UA_.types[UA_BOOLEAN];
+
+	AddReference((UA_Node*)root, &(UA_ReferenceNode){RefTypeId_Organizes, UA_FALSE, ObjId_yellowLED}, ns0);
+	Namespace_insert(ns0,(UA_Node*)yellowLED);
 
 #if defined(DEBUG) && defined(VERBOSE)
-	uint32_t i, j;
-	for (i=0, j=0; i < ns0->size && j < ns0->count; i++) {
+	uint32_t i;
+	for (i=0;i < ns0->size;i++) {
 		if (ns0->entries[i].node != UA_NULL) {
 			printf("appMockup_init - entries[%d]={",i);
-			UA_NodeId_printf("nodeId=",&(ns0->entries[i].node->nodeId));
-			UA_String_printf(",browseName=",&(ns0->entries[i].node->browseName.name));
-			j++;
+			UA_Node_print(ns0->entries[i].node, stdout);
 			printf("}\n");
 		}
 	}

+ 2 - 2
src/ua_application.h

@@ -1,9 +1,9 @@
 #ifndef OPCUA_APPLICATION_H_
 #define OPCUA_APPLICATION_H_
 
-#include "opcua.h"
+#include "ua_types.h"
 #include "ua_namespace.h"
-#include "ua_indexedList.h"
+#include "util/ua_indexedList.h"
 
 typedef struct Application {
 	UA_ApplicationDescription *description;

File diff suppressed because it is too large
+ 0 - 1694
src/ua_basictypes.c


+ 2 - 7
src/ua_namespace.c

@@ -6,11 +6,6 @@
 /* Internal (not exported) functionality */
 /*****************************************/
 
-struct Namespace_Entry {
-	UA_UInt64 status;	/* 2 bits status | 14 bits checkout count | 48 bits timestamp */
-	const UA_Node *node;	/* Nodes are immutable. It is not recommended to change nodes in place */
-};
-
 struct Namespace_Entry_Lock {
 	Namespace_Entry *entry;
 };
@@ -242,7 +237,7 @@ static inline UA_Int32 find_entry(const Namespace * ns, const UA_NodeId * nodeid
 		return UA_ERROR;
 	}
 
-	if(UA_NodeId_compare(&e->node->nodeId, nodeid) == UA_EQUAL) {
+	if(UA_NodeId_equal(&e->node->nodeId, nodeid) == UA_EQUAL) {
 		*entry = e;
 		return UA_SUCCESS;
 	}
@@ -260,7 +255,7 @@ static inline UA_Int32 find_entry(const Namespace * ns, const UA_NodeId * nodeid
 			return UA_ERROR;
 		}
 
-		if(UA_NodeId_compare(&e->node->nodeId, nodeid) == UA_EQUAL) {
+		if(UA_NodeId_equal(&e->node->nodeId, nodeid) == UA_EQUAL) {
 			*entry = e;
 			return UA_SUCCESS;
 		}

+ 9 - 6
src/ua_namespace.h

@@ -1,9 +1,9 @@
 #ifndef __NAMESPACE_H__
 #define __NAMESPACE_H__
 
-#include "ua_basictypes.h"
-#include "opcua.h"
-#include "ua_list.h"
+#include "ua_types.h"
+#include "ua_types_generated.h"
+#include "util/ua_list.h"
 
 #ifdef MULTITHREADING
 #define _XOPEN_SOURCE 500
@@ -13,8 +13,11 @@
 
 /** @brief Namespace entries point to an UA_Node. But the actual data structure
 	is opaque outside of ua_namespace.c */
-struct Namespace_Entry;
-typedef struct Namespace_Entry Namespace_Entry;
+
+typedef struct Namespace_Entry {
+	UA_UInt64 status;	/* 2 bits status | 14 bits checkout count | 48 bits timestamp */
+	const UA_Node *node;	/* Nodes are immutable. It is not recommended to change nodes in place */
+} Namespace_Entry;
 
 /** @brief Namespace datastructure. It mainly serves as a hashmap to UA_Nodes. */
 typedef struct Namespace {
@@ -46,7 +49,7 @@ void Namespace_delete(Namespace * ns);
 UA_Int32 Namespace_insert(Namespace * ns, const UA_Node * node);
 
 /** @brief Insert a new node or replace an existing node if an entry has the same NodeId. */
-UA_Int32 Namespace_insertOrReplace(Namespace * ns, const UA_Node * node);
+// UA_Int32 Namespace_insertOrReplace(Namespace * ns, const UA_Node * node);
 
 /** @brief Find an unused (numeric) NodeId in the namespace and insert the node.
 	The node is modified to contain the new nodeid after insertion. */

+ 85 - 0
src/ua_namespace_xml.c

@@ -0,0 +1,85 @@
+#include "ua_namespace_xml.h"
+#include <fcntl.h> // open, O_RDONLY
+
+typedef UA_Int32 (*XML_Stack_Loader) (char* buf, int len);
+
+#define XML_BUFFER_LEN 1024
+UA_Int32 Namespace_loadXml(Namespace **ns,UA_UInt32 nsid,const char* rootName, XML_Stack_Loader getNextBufferFull) {
+	UA_Int32 retval = UA_SUCCESS;
+	char buf[XML_BUFFER_LEN];
+	int len; /* len is the number of bytes in the current bufferful of data */
+
+	XML_Stack s;
+	XML_Stack_init(&s, 0, rootName);
+
+	UA_NodeSet n;
+	UA_NodeSet_init(&n, 0);
+	*ns = n.ns;
+
+	XML_Stack_addChildHandler(&s, "UANodeSet", strlen("UANodeSet"), (XML_decoder) UA_NodeSet_decodeXmlFromStack, UA_INVALIDTYPE, &n);
+	XML_Parser parser = XML_ParserCreate(NULL);
+	XML_SetUserData(parser, &s);
+	XML_SetElementHandler(parser, XML_Stack_startElement, XML_Stack_endElement);
+	XML_SetCharacterDataHandler(parser, XML_Stack_handleText);
+	while ((len = getNextBufferFull(buf, XML_BUFFER_LEN)) > 0) {
+		if (XML_Parse(parser, buf, len, (len < XML_BUFFER_LEN)) == XML_STATUS_ERROR) {
+			retval = UA_ERR_INVALID_VALUE;
+			break;
+		}
+	}
+	XML_ParserFree(parser);
+
+	DBG_VERBOSE(printf("Namespace_loadXml - aliases addr=%p, size=%d\n", (void*) &(n.aliases), n.aliases.size));
+	DBG_VERBOSE(UA_NodeSetAliases_println("Namespace_loadXml - elements=", &n.aliases));
+
+	return retval;
+}
+
+static int theFile = 0;
+UA_Int32 readFromTheFile(char*buf,int len) {
+	return read(theFile,buf,len);
+}
+
+/** @brief load a namespace from an XML-File
+ *
+ * @param[in/out] ns the address of the namespace ptr
+ * @param[in] namespaceId the numeric id of the namespace
+ * @param[in] rootName the name of the root element of the hierarchy (not used?)
+ * @param[in] fileName the name of an existing file, e.g. Opc.Ua.NodeSet2.xml
+ */
+UA_Int32 Namespace_loadFromFile(Namespace **ns,UA_UInt32 nsid,const char* rootName,const char* fileName) {
+	if (fileName == UA_NULL)
+		theFile = 0; // stdin
+	else if ((theFile = open(fileName, O_RDONLY)) == -1)
+		return UA_ERR_INVALID_VALUE;
+
+	UA_Int32 retval = Namespace_loadXml(ns,nsid,rootName,readFromTheFile);
+	close(theFile);
+	return retval;
+}
+
+static const char* theBuffer = UA_NULL;
+static const char* theBufferEnd = UA_NULL;
+UA_Int32 readFromTheBuffer(char*buf,int len) {
+	if (len == 0) return 0;
+	if (theBuffer + XML_BUFFER_LEN > theBufferEnd)
+		len = theBufferEnd - theBuffer + 1;
+	else
+		len = XML_BUFFER_LEN;
+	memcpy(buf,theBuffer,len);
+	theBuffer = theBuffer + len;
+	return len;
+}
+
+/** @brief load a namespace from a string
+ *
+ * @param[in/out] ns the address of the namespace ptr
+ * @param[in] namespaceId the numeric id of the namespace
+ * @param[in] rootName the name of the root element of the hierarchy (not used?)
+ * @param[in] buffer the xml string
+ */
+UA_Int32 Namespace_loadFromString(Namespace **ns,UA_UInt32 nsid,const char* rootName,const char* buffer) {
+	theBuffer = buffer;
+	theBufferEnd = buffer + strlen(buffer) - 1;
+	return Namespace_loadXml(ns,nsid,rootName,readFromTheBuffer);
+}

+ 41 - 0
src/ua_namespace_xml.h

@@ -0,0 +1,41 @@
+#ifndef __UA_NAMESPACE_XML_H
+#define __UA_NAMESPACE_XML_H
+
+#include "ua_xml.h"
+#include "ua_types_generated.h"
+#include "ua_namespace.h"
+
+void print_node(UA_Node const * node);
+UA_Int32 UA_NodeSetAlias_init(UA_NodeSetAlias* p);
+UA_Int32 UA_NodeSetAlias_new(UA_NodeSetAlias** p);
+//UA_Int32 UA_NodeSetAlias_decodeXML(XML_Stack* s, XML_Attr* attr, UA_NodeSetAlias* dst, _Bool isStart);
+
+UA_Int32 UA_NodeSetAliases_init(UA_NodeSetAliases* p);
+UA_Int32 UA_NodeSetAliases_new(UA_NodeSetAliases** p);
+UA_Int32 UA_NodeSetAliases_println(cstring label, UA_NodeSetAliases *p);
+//UA_Int32 UA_NodeSetAliases_decodeXML(XML_Stack* s, XML_Attr* attr, UA_NodeSetAliases* dst, _Bool isStart);
+
+typedef struct UA_NodeSet {
+	Namespace* ns;
+	UA_NodeSetAliases aliases;
+} UA_NodeSet;
+
+/** @brief init typed array with size=-1 and an UA_INVALIDTYPE */
+UA_Int32 UA_NodeSet_init(UA_NodeSet* p, UA_UInt32 nsid);
+UA_Int32 UA_NodeSet_new(UA_NodeSet** p, UA_UInt32 nsid);
+UA_Int32 UA_NodeId_copycstring(cstring src, UA_NodeId* dst, UA_NodeSetAliases* aliases);
+UA_Int32 UA_NodeSet_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_NodeSet* dst, _Bool isStart);
+
+UA_Int32 UA_ExpandedNodeId_copycstring(cstring src, UA_ExpandedNodeId* dst, UA_NodeSetAliases* aliases);
+
+/** @brief load a namespace from an XML-File
+ *
+ * @param[in/out] ns the address of the namespace ptr
+ * @param[in] namespaceId the numeric id of the namespace
+ * @param[in] rootName the name of the root element of the hierarchy (not used?)
+ * @param[in] fileName the name of an existing file, e.g. Opc.Ua.NodeSet2.xml
+ */
+UA_Int32 Namespace_loadFromFile(Namespace **ns,UA_UInt32 namespaceId,const char* rootName,const char* fileName);
+UA_Int32 Namespace_loadFromString(Namespace **ns,UA_UInt32 nsid,const char* rootName,const char* buffer);
+
+#endif /* __UA_NAMESPACE_XML_H */

+ 30 - 14
src/ua_services.h

@@ -7,7 +7,7 @@
 #ifndef UA_SERVICES_H_
 #define UA_SERVICES_H_
 
-#include "opcua.h"
+#include "ua_types.h"
 #include "ua_application.h"
 #include "ua_transport_binary_secure.h"
 #include "ua_stack_session.h"
@@ -53,12 +53,12 @@ UA_Int32 Service_GetEndpoints(SL_secureChannel channel, const UA_GetEndpointsReq
  * to ensure Confidentiality and Integrity for Message exchange during a
  * Session.
  */
-UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel,const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response);
+UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel, const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response);
 
 /**
  * @brief This Service is used to terminate a SecureChannel.
  */
-UA_Int32 Service_CloseSecureChannel(const UA_CloseSecureChannelRequest *request, UA_CloseSecureChannelResponse *response);
+UA_Int32 Service_CloseSecureChannel(SL_secureChannel channel, const UA_CloseSecureChannelRequest *request, UA_CloseSecureChannelResponse *response);
 /** @} */
 
 /**
@@ -77,7 +77,7 @@ UA_Int32 Service_CloseSecureChannel(const UA_CloseSecureChannelRequest *request,
  * logs and in the Server’s address space. The second is the authenticationToken
  * which is used to associate an incoming request with a Session.
  */
-UA_Int32 Service_CreateSession(UA_Session *session, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
+UA_Int32 Service_CreateSession(SL_secureChannel channel, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
 
 /**
  * @brief This Service is used by the Client to submit its SoftwareCertificates
@@ -86,12 +86,12 @@ UA_Int32 Service_CreateSession(UA_Session *session, const UA_CreateSessionReques
  * Client before it issues any other Service request after CreateSession.
  * Failure to do so shall cause the Server to close the Session.
  */
-UA_Int32 Service_ActivateSession(SL_secureChannel channel, UA_Session *session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
+UA_Int32 Service_ActivateSession(SL_secureChannel channel, UA_Session session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
 
 /**
  * @brief This Service is used to terminate a Session.
  */
-UA_Int32 Service_CloseSession(UA_Session *session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
+UA_Int32 Service_CloseSession(UA_Session session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
 // Service_Cancel
 /** @} */
 
@@ -108,8 +108,13 @@ UA_Int32 Service_CloseSession(UA_Session *session, const UA_CloseSessionRequest
 /**
  * @brief This Service is used to add one or more Nodes into the AddressSpace hierarchy.
  */
-UA_Int32 Service_AddNodes(UA_Session *session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
-// Service_AddReferences
+UA_Int32 Service_AddNodes(UA_Session session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
+
+/**
+ * @brief This Service is used to add one or more References to one or more Nodes
+ */
+UA_Int32 Service_AddReferences(UA_Session session, const UA_AddReferencesRequest *request, UA_AddReferencesResponse *response);
+
 // Service_DeleteNodes
 // Service_DeleteReferences
 /** @} */
@@ -128,12 +133,12 @@ UA_Int32 Service_AddNodes(UA_Session *session, const UA_AddNodesRequest *request
  * The browse can be further limited by the use of a View. This Browse Service
  * also supports a primitive filtering capability.
  */ 
-UA_Int32 Service_Browse(UA_Session *session, const UA_BrowseRequest *request, UA_BrowseResponse *response);
+UA_Int32 Service_Browse(UA_Session session, const UA_BrowseRequest *request, UA_BrowseResponse *response);
 
 /**
  * @brief This Service is used to translate textual node paths to their respective ids.
  */
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session *session,  const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response);
+UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session session, const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response);
 // Service_BrowseNext
 // Service_TranslateBrowsePathsToNodeIds
 // Service_RegisterNodes
@@ -176,9 +181,16 @@ UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session *session,  const UA_Tr
  * values as a composite, to read individual elements or to read ranges of
  * elements of the composite.
  */
-UA_Int32 Service_Read(UA_Session *session, const UA_ReadRequest *request, UA_ReadResponse *response);
+UA_Int32 Service_Read(UA_Session session, const UA_ReadRequest *request, UA_ReadResponse *response);
 // Service_HistoryRead
-// Service_Write
+/**
+ * @brief This Service is used to write one or more Attributes of one or more
+ *  Nodes. For constructed Attribute values whose elements are indexed, such as
+ *  an array, this Service allows Clients to write the entire set of indexed
+ *  values as a composite, to write individual elements or to write ranges of
+ *  elements of the composite.
+ */
+UA_Int32 Service_Write(UA_Session session, const UA_WriteRequest *request,UA_WriteResponse *response);
 // Service_HistoryUpdate
 /** @} */
 
@@ -210,7 +222,7 @@ a component of an Object.
  * triggered item links to be deleted, but has no effect on the MonitoredItems
  * referenced by the triggered items.
  */
-UA_Int32 Service_CreateMonitoredItems(UA_Session *session, const UA_CreateMonitoredItemsRequest *request, UA_CreateMonitoredItemsResponse *response);
+UA_Int32 Service_CreateMonitoredItems(UA_Session session, const UA_CreateMonitoredItemsRequest *request, UA_CreateMonitoredItemsResponse *response);
 // Service_ModifyMonitoredItems
 // Service_SetMonitoringMode
 // Service_SetTriggering
@@ -225,9 +237,13 @@ UA_Int32 Service_CreateMonitoredItems(UA_Session *session, const UA_CreateMonito
  * @{
  */
 // Service_CreateSubscription
+UA_Int32 Service_CreateSubscription(UA_Session session, const UA_CreateSubscriptionRequest *request,
+                                   UA_CreateSubscriptionResponse *response);
 // Service_ModifySubscription
 // Service_SetPublishingMode
-// Service_Publish
+UA_Int32 Service_Publish(UA_Session session, const UA_PublishRequest *request,
+                                   UA_PublishResponse *response);
+
 // Service_Republish
 // Service_TransferSubscription
 // Service_DeleteSubscription

+ 358 - 118
src/ua_services_attribute.c

@@ -2,52 +2,52 @@
 #include "ua_statuscodes.h"
 
 enum UA_AttributeId {
-	UA_ATTRIBUTEID_NODEID = 1,
-	UA_ATTRIBUTEID_NODECLASS = 2,
-	UA_ATTRIBUTEID_BROWSENAME = 3,
-	UA_ATTRIBUTEID_DISPLAYNAME = 4,
-	UA_ATTRIBUTEID_DESCRIPTION = 5,
-	UA_ATTRIBUTEID_WRITEMASK = 6,
-	UA_ATTRIBUTEID_USERWRITEMASK = 7,
-	UA_ATTRIBUTEID_ISABSTRACT = 8,
-	UA_ATTRIBUTEID_SYMMETRIC = 9,
-	UA_ATTRIBUTEID_INVERSENAME = 10,
-	UA_ATTRIBUTEID_CONTAINSNOLOOPS = 11,
-	UA_ATTRIBUTEID_EVENTNOTIFIER = 12,
-	UA_ATTRIBUTEID_VALUE = 13,
-	UA_ATTRIBUTEID_DATATYPE = 14,
-	UA_ATTRIBUTEID_VALUERANK = 15,
-	UA_ATTRIBUTEID_ARRAYDIMENSIONS = 16,
-	UA_ATTRIBUTEID_ACCESSLEVEL = 17,
-	UA_ATTRIBUTEID_USERACCESSLEVEL = 18,
+	UA_ATTRIBUTEID_NODEID                  = 1,
+	UA_ATTRIBUTEID_NODECLASS               = 2,
+	UA_ATTRIBUTEID_BROWSENAME              = 3,
+	UA_ATTRIBUTEID_DISPLAYNAME             = 4,
+	UA_ATTRIBUTEID_DESCRIPTION             = 5,
+	UA_ATTRIBUTEID_WRITEMASK               = 6,
+	UA_ATTRIBUTEID_USERWRITEMASK           = 7,
+	UA_ATTRIBUTEID_ISABSTRACT              = 8,
+	UA_ATTRIBUTEID_SYMMETRIC               = 9,
+	UA_ATTRIBUTEID_INVERSENAME             = 10,
+	UA_ATTRIBUTEID_CONTAINSNOLOOPS         = 11,
+	UA_ATTRIBUTEID_EVENTNOTIFIER           = 12,
+	UA_ATTRIBUTEID_VALUE                   = 13,
+	UA_ATTRIBUTEID_DATATYPE                = 14,
+	UA_ATTRIBUTEID_VALUERANK               = 15,
+	UA_ATTRIBUTEID_ARRAYDIMENSIONS         = 16,
+	UA_ATTRIBUTEID_ACCESSLEVEL             = 17,
+	UA_ATTRIBUTEID_USERACCESSLEVEL         = 18,
 	UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL = 19,
-	UA_ATTRIBUTEID_HISTORIZING = 20,
-	UA_ATTRIBUTEID_EXECUTABLE = 21,
-	UA_ATTRIBUTEID_USEREXECUTABLE = 22
+	UA_ATTRIBUTEID_HISTORIZING             = 20,
+	UA_ATTRIBUTEID_EXECUTABLE              = 21,
+	UA_ATTRIBUTEID_USEREXECUTABLE          = 22
 };
 
-#define CHECK_NODECLASS(CLASS) do {									\
-		if((node->nodeClass & (CLASS)) != 0x00) {					\
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;		\
-			v->status = UA_STATUSCODE_BADNOTREADABLE;				\
-		}															\
-		break;														\
-	} while(0)
+#define CHECK_NODECLASS(CLASS) do {                                \
+		if((node->nodeClass & (CLASS)) != 0x00) {                  \
+			v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE; \
+			v.status       = UA_STATUSCODE_BADNOTREADABLE;         \
+		}                                                          \
+		break;                                                     \
+} while(0)
 
-static UA_DataValue *service_read_node(Application * app, const UA_ReadValueId * id) {
-	UA_DataValue *v;
-	UA_DataValue_new(&v);
+static UA_DataValue service_read_node(Application *app, const UA_ReadValueId *id) {
+	UA_DataValue v;
+	UA_DataValue_init(&v);
 
-	DBG(printf("service_read_node - entered with ns=%d,id=%d,attr=%i\n", id->nodeId.namespace, id->nodeId.identifier.numeric, id->attributeId));
+	DBG(printf("service_read_node - entered with ns=%d,id=%d,attr=%i\n", id->nodeId.namespace,
+	           id->nodeId.identifier.numeric, id->attributeId));
 	Namespace *ns = UA_indexedList_findValue(app->namespaces, id->nodeId.namespace);
 
 	if(ns == UA_NULL) {
 		DBG_VERBOSE(printf("service_read_node - unknown namespace %d\n", id->nodeId.namespace));
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-		v->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v.status       = UA_STATUSCODE_BADNODEIDUNKNOWN;
 		return v;
 	}
-	DBG_VERBOSE(UA_String_printf(",namespaceUri=", &(ns->namespaceUri)));
 
 	UA_Node const *node = UA_NULL;
 	Namespace_Entry_Lock *lock = UA_NULL;
@@ -55,173 +55,413 @@ static UA_DataValue *service_read_node(Application * app, const UA_ReadValueId *
 	DBG_VERBOSE(UA_NodeId_printf("service_read_node - search for ", &(id->nodeId)));
 	UA_Int32 result = Namespace_get(ns, &(id->nodeId), &node, &lock);
 	if(result != UA_SUCCESS || node == UA_NULL) {
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-		v->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v.status       = UA_STATUSCODE_BADNODEIDUNKNOWN;
 		return v;
 	}
 	DBG_VERBOSE(UA_NodeId_printf("service_read_node - found node=", &(node->nodeId)));
 
 	UA_Int32 retval = UA_SUCCESS;
 
-	switch (id->attributeId) {
+	switch(id->attributeId) {
 	case UA_ATTRIBUTEID_NODEID:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_NODEID, &node->nodeId);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_NODEID], &node->nodeId);
 		break;
+
 	case UA_ATTRIBUTEID_NODECLASS:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_UINT32, &node->nodeClass);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_INT32], &node->nodeClass);
 		break;
+
 	case UA_ATTRIBUTEID_BROWSENAME:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_QUALIFIEDNAME, &node->browseName);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_QUALIFIEDNAME], &node->browseName);
 		break;
+
 	case UA_ATTRIBUTEID_DISPLAYNAME:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_LOCALIZEDTEXT, &node->displayName);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_LOCALIZEDTEXT],
+		                                  &node->displayName);
 		break;
+
 	case UA_ATTRIBUTEID_DESCRIPTION:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_LOCALIZEDTEXT],
+		                                  &node->description);
 		break;
+
 	case UA_ATTRIBUTEID_WRITEMASK:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_UINT32, &node->writeMask);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_UINT32], &node->writeMask);
 		break;
+
 	case UA_ATTRIBUTEID_USERWRITEMASK:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_UINT32, &node->userWriteMask);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_UINT32], &node->userWriteMask);
 		break;
+
 	case UA_ATTRIBUTEID_ISABSTRACT:
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BOOLEAN, &((UA_ReferenceTypeNode *) node)->isAbstract);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |=
+		    UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN],
+		                            &((UA_ReferenceTypeNode *)node)->isAbstract);
 		break;
+
 	case UA_ATTRIBUTEID_SYMMETRIC:
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BOOLEAN, &((UA_ReferenceTypeNode *) node)->symmetric);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN],
+		                                  &((UA_ReferenceTypeNode *)node)->symmetric);
 		break;
+
 	case UA_ATTRIBUTEID_INVERSENAME:
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_LOCALIZEDTEXT, &((UA_ReferenceTypeNode *) node)->inverseName);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_LOCALIZEDTEXT],
+		                                  &((UA_ReferenceTypeNode *)node)->inverseName);
 		break;
+
 	case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
 		CHECK_NODECLASS(UA_NODECLASS_VIEW);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BOOLEAN, &((UA_ViewNode *) node)->containsNoLoops);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN],
+		                                  &((UA_ViewNode *)node)->containsNoLoops);
 		break;
+
 	case UA_ATTRIBUTEID_EVENTNOTIFIER:
 		CHECK_NODECLASS(UA_NODECLASS_VIEW);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BYTE, &((UA_ViewNode *) node)->eventNotifier);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BYTE],
+		                                  &((UA_ViewNode *)node)->eventNotifier);
 		break;
+
 	case UA_ATTRIBUTEID_VALUE:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		// TODO: Ensure that the borrowed value is not freed prematurely (multithreading)
-		retval |= UA_Variant_borrowSetValue(&v->value, UA_VARIANT, &((UA_VariableNode *) node)->value);
+		/* retval |= UA_Variant_borrowSetValue(&v.value, &UA_.types[UA_VARIANT], */
+		/*                                     &((UA_VariableNode *)node)->value); */
+		retval |= UA_Variant_copy(&((UA_VariableNode *)node)->value, &v.value);
 		break;
+
 	case UA_ATTRIBUTEID_DATATYPE:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_NODEID, &((UA_VariableTypeNode *) node)->dataType);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_NODEID],
+		                                  &((UA_VariableTypeNode *)node)->dataType);
 		break;
+
 	case UA_ATTRIBUTEID_VALUERANK:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_INT32, &((UA_VariableTypeNode *) node)->valueRank);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_INT32],
+		                                  &((UA_VariableTypeNode *)node)->valueRank);
 		break;
+
 	case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		UA_Variant_copySetArray(&v->value, UA_UINT32, ((UA_VariableTypeNode *) node)->arrayDimensionsSize, sizeof(UA_UInt32),
-								&((UA_VariableTypeNode *) node)->arrayDimensions);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		UA_Variant_copySetArray(&v.value, &UA_.types[UA_UINT32],
+		                        ((UA_VariableTypeNode *)node)->arrayDimensionsSize,
+		                        &((UA_VariableTypeNode *)node)->arrayDimensions);
 		break;
+
 	case UA_ATTRIBUTEID_ACCESSLEVEL:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BYTE, &((UA_VariableNode *) node)->accessLevel);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BYTE],
+		                                  &((UA_VariableNode *)node)->accessLevel);
 		break;
+
 	case UA_ATTRIBUTEID_USERACCESSLEVEL:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BYTE, &((UA_VariableNode *) node)->userAccessLevel);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BYTE],
+		                                  &((UA_VariableNode *)node)->userAccessLevel);
 		break;
+
 	case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_DOUBLE, &((UA_VariableNode *) node)->minimumSamplingInterval);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_DOUBLE],
+		                                  &((UA_VariableNode *)node)->minimumSamplingInterval);
 		break;
+
 	case UA_ATTRIBUTEID_HISTORIZING:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BOOLEAN, &((UA_VariableNode *) node)->historizing);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN],
+		                                  &((UA_VariableNode *)node)->historizing);
 		break;
+
 	case UA_ATTRIBUTEID_EXECUTABLE:
 		CHECK_NODECLASS(UA_NODECLASS_METHOD);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BOOLEAN, &((UA_MethodNode *) node)->executable);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN],
+		                                  &((UA_MethodNode *)node)->executable);
 		break;
+
 	case UA_ATTRIBUTEID_USEREXECUTABLE:
 		CHECK_NODECLASS(UA_NODECLASS_METHOD);
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v->value, UA_BOOLEAN, &((UA_MethodNode *) node)->userExecutable);
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN],
+		                                  &((UA_MethodNode *)node)->userExecutable);
 		break;
+
 	default:
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-		v->status = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v.status       = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
 		break;
 	}
 
 	Namespace_Entry_Lock_release(lock);
 
 	if(retval != UA_SUCCESS) {
-		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v.status       = UA_STATUSCODE_BADNOTREADABLE;
 	}
 
 	return v;
 }
+UA_Int32 Service_Read(UA_Session session, const UA_ReadRequest *request,
+                      UA_ReadResponse *response) {
+	Application *application = UA_NULL;
+	if(session == UA_NULL)
+	{
+		return UA_ERROR;
+	}
+	UA_Session_getApplicationPointer(session,&application);
+	if( application == UA_NULL)
+		return UA_ERROR;    // TODO: Return error message
+
+	UA_Int32 readsize = request->nodesToReadSize;
+	/* NothingTodo */
+	if(readsize <= 0) {
+		response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
+		response->resultsSize = 0;
+		return UA_SUCCESS;
+	}
+
+	response->resultsSize = readsize;
+	UA_alloc((void **)&response->results, sizeof(UA_DataValue) * readsize);
+	for(UA_Int32 i = 0;i < readsize;i++) {
+		DBG_VERBOSE(printf("service_read - attributeId=%d\n", request->nodesToRead[i].attributeId));
+		DBG_VERBOSE(UA_NodeId_printf("service_read - nodeId=", &(request->nodesToRead[i].nodeId)));
+		response->results[i] = service_read_node(application,
+		                                         &request->nodesToRead[i]);
+	}
+	response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
+	response->diagnosticInfosSize = 0;
+	return UA_SUCCESS;
+}
 
-UA_Int32 Service_Read(UA_Session *session, const UA_ReadRequest * request, UA_ReadResponse * response) {
-	if(session)
+UA_Int32 Service_Write_writeNode(Application *app, UA_WriteValue *writeValue, UA_StatusCode *result)
+{
+	UA_Int32 retval = UA_SUCCESS;
+	Namespace *ns = UA_indexedList_findValue(app->namespaces, writeValue->nodeId.namespace);
+	if(ns==UA_NULL)
 	{
+		*result = UA_STATUSCODE_BADNODEIDINVALID;
+		return UA_ERROR;
+	}
+	Namespace_Entry_Lock *lock;
+	const UA_Node *node;
+
+	if(Namespace_get(ns, &writeValue->nodeId,&node, &lock) != UA_SUCCESS){
+		return UA_ERROR;
+	}
+
+
+
+	switch(writeValue->attributeId) {
+	case UA_ATTRIBUTEID_NODEID:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){
 
-		//if(channel->session == UA_NULL || channel->session->application == UA_NULL)
-		//	return UA_ERROR;	// TODO: Return error message
-		Application *application = UA_NULL;
-		int readsize = request->nodesToReadSize;
-		/* NothingTodo */
-		if(readsize <= 0) {
-			response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
-			response->resultsSize = 0;
-			return UA_SUCCESS;
 		}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
 
-		response->resultsSize = readsize;
-		UA_alloc((void **)&response->results, sizeof(void *)*readsize);
-		for(int i=0;i<readsize;i++) {
-			DBG_VERBOSE(printf("service_read - attributeId=%d\n",request->nodesToRead[i]->attributeId));
-			DBG_VERBOSE(UA_NodeId_printf("service_read - nodeId=",&(request->nodesToRead[i]->nodeId)));
-
-			UA_Session_getApplicationPointer(*session,&application);
-			if(application){
-				response->results[i] = service_read_node(application, request->nodesToRead[i]);
-			}
-			else
-			{
-				printf("Service_Read - ERROR: no valid application pointer");
-				return UA_ERROR;
-			}
+	case UA_ATTRIBUTEID_NODECLASS:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){
 
 		}
-		response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
-		response->diagnosticInfosSize = -1;
-		return UA_SUCCESS;
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_BROWSENAME:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_DISPLAYNAME:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){
+		}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_DESCRIPTION:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_WRITEMASK:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		break;
+
+	case UA_ATTRIBUTEID_USERWRITEMASK:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_ISABSTRACT:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_SYMMETRIC:
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_INVERSENAME:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_EVENTNOTIFIER:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_VALUE:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){
+		// TODO: Ensure that the borrowed value is not freed prematurely (multithreading)
+		/* retval |= UA_Variant_borrowSetValue(&v.value, &UA_.types[UA_VARIANT], */
+		/*                                     &((UA_VariableNode *)node)->value); */
+
+#ifdef RASPI
+		//Sten: this is  highly hacked to cope with pthreads
+		//tested only with raspberrypi and boolean
+		*((UA_Boolean*)((UA_VariableNode *)node)->value.data) = *((UA_Boolean*)(writeValue->value.value.data));
+		//it seems that UA_Variant_copy copies the value out of the shared memory
+#else
+		retval |= UA_Variant_copy(&writeValue->value.value, &((UA_VariableNode *)node)->value);
+#endif
+		*result = UA_STATUSCODE_GOOD;
+		}
+
+		break;
+
+	case UA_ATTRIBUTEID_DATATYPE:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_VALUERANK:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_ACCESSLEVEL:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_USERACCESSLEVEL:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+		return UA_ERROR;
+		break;
+
+	case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_HISTORIZING:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_EXECUTABLE:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	case UA_ATTRIBUTEID_USEREXECUTABLE:
+
+		if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){}
+		*result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+
+		break;
+
+	default:
+
+		*result      = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+		break;
 	}
-	printf("Service_Read - ERROR: no valid session object");
-	return UA_ERROR;
+
+	Namespace_Entry_Lock_release(lock);
+	return retval;
+
 }
+UA_Int32 Service_Write(UA_Session session, const UA_WriteRequest *request,
+                      UA_WriteResponse *response) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_Int32 i;
+	Application *application = UA_NULL;
+	UA_Session_getApplicationPointer(session, &application);
+	if(session == UA_NULL || application == UA_NULL)
+		return UA_ERROR;    // TODO: Return error message
+	response->resultsSize = request->nodesToWriteSize;
+	//TODO evalutate diagnostic info within the request
+	UA_Array_new((void**)&response->results,response->resultsSize,&UA_.types[UA_STATUSCODE]);
+	for(i=0; i < request->nodesToWriteSize; i++){
+		retval |= Service_Write_writeNode(application, &request->nodesToWrite[i], &response->results[i]);
+	}
 
+	return retval;
+}

+ 18 - 15
src/ua_services_discovery.c

@@ -1,36 +1,39 @@
 #include "ua_services.h"
 UA_Int32 Service_GetEndpoints(SL_secureChannel channel, const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response) {
+#ifdef DEBUG
 	UA_String_printx("endpointUrl=", &request->endpointUrl);
+#endif
+
 	response->endpointsSize = 1;
-	UA_Array_new((void***) &response->endpoints,response->endpointsSize,UA_ENDPOINTDESCRIPTION);
+	UA_Array_new((void**) &response->endpoints,response->endpointsSize,&UA_.types[UA_ENDPOINTDESCRIPTION]);
 
 	//Security issues:
 	//The policy should be 'http://opcfoundation.org/UA/SecurityPolicy#None'
 	//FIXME String or ByteString
-//TODO get Channel by SessionManager / Session
-//UA_SessionManager_getSession(request->requestHeader->authenticationToken);
-//channel = UA_Session_getChannel(session);
-//UA_String_copy((UA_String*)&channel->localAsymAlgSettings.securityPolicyUri,&response->endpoints[0]->securityPolicyUri);
+	UA_AsymmetricAlgorithmSecurityHeader *asymSettings;
+	SL_Channel_getLocalAsymAlgSettings(channel, &asymSettings);
+	UA_String_copy((UA_String *)&(asymSettings->securityPolicyUri), &response->endpoints[0].securityPolicyUri);
 	//FIXME hard-coded code
-	response->endpoints[0]->securityMode = UA_MESSAGESECURITYMODE_NONE;
-	UA_String_copycstring("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary", &response->endpoints[0]->transportProfileUri);
+	response->endpoints[0].securityMode = UA_MESSAGESECURITYMODE_NONE;
+	UA_String_copycstring("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary", &response->endpoints[0].transportProfileUri);
 
-	response->endpoints[0]->userIdentityTokensSize = 1;
-	UA_Array_new((void***) &response->endpoints[0]->userIdentityTokens, response->endpoints[0]->userIdentityTokensSize, UA_USERTOKENPOLICY);
-	UA_UserTokenPolicy *token = response->endpoints[0]->userIdentityTokens[0];
+	response->endpoints[0].userIdentityTokensSize = 1;
+	UA_Array_new((void**) &response->endpoints[0].userIdentityTokens, response->endpoints[0].userIdentityTokensSize,
+				 &UA_.types[UA_USERTOKENPOLICY]);
+	UA_UserTokenPolicy *token = &response->endpoints[0].userIdentityTokens[0];
 	UA_String_copycstring("my-anonymous-policy", &token->policyId); // defined per server
 	token->tokenType = UA_USERTOKENTYPE_ANONYMOUS;
 	token->issuerEndpointUrl = (UA_String) {-1, UA_NULL};
 	token->issuedTokenType = (UA_String) {-1, UA_NULL};
 	token->securityPolicyUri = (UA_String) {-1, UA_NULL};
 
-	UA_String_copy(&request->endpointUrl,&response->endpoints[0]->endpointUrl);
-	UA_String_copycstring("http://open62541.info/product/release",&(response->endpoints[0]->server.productUri));
+	UA_String_copy(&request->endpointUrl,&response->endpoints[0].endpointUrl);
+	UA_String_copycstring("http://open62541.info/product/release",&(response->endpoints[0].server.productUri));
 	// FIXME: This information should be provided by the application, preferably in the address space
-	UA_String_copycstring("http://open62541.info/applications/4711",&(response->endpoints[0]->server.applicationUri));
-	UA_LocalizedText_copycstring("The open62541 application",&(response->endpoints[0]->server.applicationName));
+	UA_String_copycstring("http://open62541.info/applications/4711",&(response->endpoints[0].server.applicationUri));
+	UA_LocalizedText_copycstring("The open62541 application",&(response->endpoints[0].server.applicationName));
 	// FIXME: This should be a feature of the application and an enum
-	response->endpoints[0]->server.applicationType = UA_APPLICATIONTYPE_SERVER;
+	response->endpoints[0].server.applicationType = UA_APPLICATIONTYPE_SERVER;
 	// all the other strings are empty by initialization
 	
 	return UA_SUCCESS;

+ 16 - 0
src/ua_services_internal.h

@@ -0,0 +1,16 @@
+/**
+ * @brief This files contains helper functions for the UA-Services that are used
+ * internally as well (with a simplified API as no access rights are checked).
+ */
+
+#include "ua_namespace.h"
+#include "ua_types.h"
+#include "ua_types_generated.h"
+
+/* @brief Add a reference (and the inverse reference to the target node).
+ *
+ * @param The node to which the reference shall be added
+ * @param The reference itself
+ * @param The namespace where the target node is looked up for the reverse reference (this is omitted if targetns is UA_NULL)
+ */
+UA_Int32 AddReference(UA_Node *node, UA_ReferenceNode *reference, Namespace *targetns);

+ 19 - 8
src/ua_services_monitoreditems.c

@@ -1,24 +1,35 @@
 #include "ua_services.h"
+#include "ua_statuscodes.h"
 
-#if 0
+//#if 0
 /* Activate once the infrastructure for pushing events is in place. */
 
 UA_Int32 Service_CreateMonitoredItems(UA_Session session, const UA_CreateMonitoredItemsRequest *request, UA_CreateMonitoredItemsResponse *response) {
 	if (request->itemsToCreateSize > 0) {
 		response->resultsSize = request->itemsToCreateSize;
-		UA_Array_new((void**)&(response->results),response->resultsSize,UA_MONITOREDITEMCREATERESULT);
+
+		UA_Array_new((void**)&(response->results),response->resultsSize,&UA_.types[UA_MONITOREDITEMCREATERESULT]);
 		for (int i=0;request->itemsToCreateSize > 0 && i < request->itemsToCreateSize;i++) {
-			UA_NodeId_printf("CreateMonitoredItems - itemToCreate=",&(request->itemsToCreate[i]->itemToMonitor.nodeId));
+#ifdef DEBUG
+			UA_NodeId_printf("CreateMonitoredItems - itemToCreate=",&(request->itemsToCreate[i].itemToMonitor.nodeId));
+#endif
 			//FIXME: search the object in the namespace
-			if (request->itemsToCreate[i]->itemToMonitor.nodeId.identifier.numeric == 2253) { // server
-				response->results[i]->statusCode = UA_STATUSCODE_GOOD;
-				response->results[i]->monitoredItemId = 1024;
+
+			if (request->itemsToCreate[i].itemToMonitor.nodeId.identifier.numeric == 2253) { // server
+
+				response->results[i].statusCode = UA_STATUSCODE_GOOD;
+				response->results[i].monitoredItemId = 1;
+				response->results[i].revisedSamplingInterval = 4294967295;
+				response->results[i].revisedQueueSize = 0;
 			} else {
 				// response->results[i]->statusCode = UA_STATUSCODE_BAD_NODEIDUNKNOWN;
-				response->results[i]->statusCode = -1;
+
+				response->results[i].statusCode = -1;
 			}
 		}
 	}
+	//mock up
+	return UA_SUCCESS;
 }
 
-#endif
+//#endif

+ 70 - 13
src/ua_services_nodemanagement.c

@@ -1,7 +1,8 @@
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 #include "ua_namespace.h"
-
+#include "ua_services_internal.h"
+#include "ua_stack_session.h"
 #define CHECKED_ACTION(ACTION, CLEAN_UP, GOTO) do {	\
 	status |= ACTION; \
 	if(status != UA_SUCCESS) { \
@@ -9,14 +10,14 @@
 		goto GOTO; \
 	} } while(0) \
 
-static UA_AddNodesResult * addSingleNode(Application *app, UA_AddNodesItem *item) {
-	UA_AddNodesResult *result;
-	UA_AddNodesResult_new(&result);
+static UA_AddNodesResult addSingleNode(Application *app, UA_AddNodesItem *item) {
+	UA_AddNodesResult result;
+	UA_AddNodesResult_init(&result);
 
 	Namespace *parent_ns = UA_indexedList_findValue(app->namespaces, item->parentNodeId.nodeId.namespace);
 	// TODO: search for namespaceUris and not only ns-ids.
 	if(parent_ns == UA_NULL) {
-		result->statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID;
+		result.statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID;
 		return result;
 	}
 
@@ -27,7 +28,7 @@ static UA_AddNodesResult * addSingleNode(Application *app, UA_AddNodesItem *item
 	else ns = UA_indexedList_findValue(app->namespaces, item->requestedNewNodeId.nodeId.namespace);
 
 	if(ns == UA_NULL || item->requestedNewNodeId.nodeId.namespace == 0) {
-		result->statusCode = UA_STATUSCODE_BADNODEIDREJECTED;
+		result.statusCode = UA_STATUSCODE_BADNODEIDREJECTED;
 		return result;
 	}
 
@@ -36,10 +37,10 @@ static UA_AddNodesResult * addSingleNode(Application *app, UA_AddNodesItem *item
 	Namespace_Entry_Lock *parent_lock = UA_NULL;
 
 	CHECKED_ACTION(Namespace_get(parent_ns, &item->parentNodeId.nodeId, &parent, &parent_lock),
-				   result->statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID, ret);
+				   result.statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID, ret);
 
 	if(!nodeid_isnull && Namespace_contains(ns, &item->requestedNewNodeId.nodeId)) {
-		result->statusCode = UA_STATUSCODE_BADNODEIDEXISTS;
+		result.statusCode = UA_STATUSCODE_BADNODEIDEXISTS;
 		goto ret;
 	}
 
@@ -66,9 +67,14 @@ static UA_AddNodesResult * addSingleNode(Application *app, UA_AddNodesItem *item
 	return result;
 }
 
-UA_Int32 Service_AddNodes(UA_Session *session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
-//TODO GET SESSION HERE	if(channel->session == UA_NULL || channel->session->application == UA_NULL)
-//		return UA_ERROR;	// TODO: Return error message
+UA_Int32 Service_AddNodes(UA_Session session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
+
+	Application *application;
+	if(session == UA_NULL)
+		return UA_ERROR;	// TODO: Return error message
+	UA_Session_getApplicationPointer(session,&application);
+	if(application == UA_NULL)
+		return UA_ERROR;
 
 	UA_Int32 nodestoaddsize = request->nodesToAddSize;
 	if(nodestoaddsize <= 0) {
@@ -80,11 +86,62 @@ UA_Int32 Service_AddNodes(UA_Session *session, const UA_AddNodesRequest *request
 	response->resultsSize = nodestoaddsize;
 	UA_alloc((void **)&response->results, sizeof(void *) * nodestoaddsize);
 	for(int i = 0; i < nodestoaddsize; i++) {
-		DBG_VERBOSE(UA_QualifiedName_printf("service_addnodes - name=", &(request->nodesToAdd[i]->browseName)));
-//TODO GET SESSION HERE		response->results[i] = addSingleNode(channel->session->application, request->nodesToAdd[i]);
+		DBG_VERBOSE(UA_QualifiedName_printf("service_addnodes - name=", &(request->nodesToAdd[i].browseName)));
+		response->results[i] = addSingleNode(application, &request->nodesToAdd[i]);
 	}
 	response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
 	response->diagnosticInfosSize = -1;
 	return UA_SUCCESS;
 	
 }
+
+static UA_Int32 AddSingleReference(UA_Node *node, UA_ReferenceNode *reference) {
+	// TODO: Check if reference already exists
+
+	UA_Int32 count = node->referencesSize;
+	if(count < 0) count = 0;
+	UA_ReferenceNode *old_refs = node->references;
+	UA_ReferenceNode *new_refs;
+
+	UA_Int32 retval = UA_alloc((void **)&new_refs, sizeof(UA_ReferenceNode)*(count+1));
+	if(retval != UA_SUCCESS)
+		return UA_ERROR;
+	UA_memcpy(new_refs, old_refs, sizeof(UA_ReferenceNode)*count);
+	retval |= UA_ReferenceNode_copy(reference, &new_refs[count]);
+
+	if(retval != UA_SUCCESS) {
+		UA_free(new_refs);
+		return retval;
+	}
+	
+	node->references = new_refs;
+	node->referencesSize = count+1;
+	UA_free(old_refs);
+	return retval;
+}
+
+UA_Int32 AddReference(UA_Node *node, UA_ReferenceNode *reference, Namespace *targetns) {
+	UA_Int32 retval = AddSingleReference(node, reference);
+	if(retval != UA_SUCCESS || targetns == UA_NULL)
+		return retval;
+
+	UA_Node *targetnode;
+	Namespace_Entry_Lock *lock;
+	// TODO: Nodes in the namespace are immutable (for lockless multithreading).
+	// Do a copy every time?
+	if(Namespace_get(targetns, &reference->targetId.nodeId, (const UA_Node**)&targetnode, &lock) != UA_SUCCESS)
+		return UA_ERROR;
+
+	UA_ReferenceNode inversereference;
+	inversereference.referenceTypeId = reference->referenceTypeId;
+	inversereference.isInverse = !reference->isInverse;
+	inversereference.targetId = (UA_ExpandedNodeId){node->nodeId, UA_STRING_NULL, 0};	
+	retval = AddSingleReference(targetnode, &inversereference);
+	Namespace_Entry_Lock_release(lock);
+
+	return retval;
+}
+
+UA_Int32 Service_AddReferences(UA_Session session, const UA_AddReferencesRequest *request, UA_AddReferencesResponse *response) {
+	return UA_ERROR;
+}

+ 6 - 8
src/ua_services_securechannel.c

@@ -1,11 +1,9 @@
 #include "ua_services.h"
 #include "ua_transport_binary_secure.h"
 
-
-
 UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel,
-		const UA_OpenSecureChannelRequest* request,
-		UA_OpenSecureChannelResponse* response)
+const UA_OpenSecureChannelRequest* request,
+UA_OpenSecureChannelResponse* response)
 {
 	UA_Int32 retval = UA_SUCCESS;
 
@@ -18,12 +16,12 @@ UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel,
 	return retval;
 }
 
-UA_Int32 Service_CloseSecureChannel(const UA_CloseSecureChannelRequest *request,
-		UA_CloseSecureChannelResponse *response)
+UA_Int32 Service_CloseSecureChannel(SL_secureChannel channel, const UA_CloseSecureChannelRequest *request,
+UA_CloseSecureChannelResponse *response)
 {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 retval = UA_SUCCESS;
 
 // 62451 Part 6 Chapter 7.1.4 - The server does not send a CloseSecureChannel response
 
-	return retval;
+return retval;
 }

+ 19 - 17
src/ua_services_session.c

@@ -2,23 +2,23 @@
 #include "ua_stack_session_manager.h"
 #include "ua_application.h"
 
-Session sessionMockup = {
-		(UA_Int32) 0,
-		&appMockup
-};
+//Session sessionMockup = {
+//		(UA_Int32) 0,
+//		&appMockup
+//};
 
-UA_Int32 Service_CreateSession(UA_Session *session, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) {
-	UA_String_printf("CreateSession Service - endpointUrl=", &(request->endpointUrl));
+UA_Int32 Service_CreateSession(SL_secureChannel channel, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) {
+UA_String_printf("CreateSession Service - endpointUrl=", &(request->endpointUrl));
 
 	UA_Session *newSession;
 
 	UA_Session_new(&newSession);
 	//TODO get maxResponseMessageSize
 	UA_Session_init(*newSession, (UA_String*)&request->sessionName,
-			request->requestedSessionTimeout,
-			request->maxResponseMessageSize,
-			9999,
-			(UA_Session_idProvider)UA_SessionManager_generateSessionId);
+	request->requestedSessionTimeout,
+	request->maxResponseMessageSize,
+	9999,
+	(UA_Session_idProvider)UA_SessionManager_generateSessionId);
 
 	UA_SessionManager_addSession(newSession);
 	UA_Session_getId(*newSession, &response->sessionId);
@@ -28,11 +28,13 @@ UA_Int32 Service_CreateSession(UA_Session *session, const UA_CreateSessionReques
 	return UA_SUCCESS;
 }
 
-UA_Int32 Service_ActivateSession(SL_secureChannel channel, UA_Session *session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) {
+UA_Int32 Service_ActivateSession(SL_secureChannel channel,UA_Session session,
+		const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response)
+{
 
+	UA_Session_bind(session, channel);
 
-	UA_Session_bind(*session,channel);
-	UA_Session_setApplicationPointer(*session,&appMockup);
+	UA_Session_setApplicationPointer(session, &appMockup);
 
 	UA_NodeId_printf("ActivateSession - authToken=", &(request->requestHeader.authenticationToken));
 	// 321 == AnonymousIdentityToken_Encoding_DefaultBinary
@@ -42,8 +44,8 @@ UA_Int32 Service_ActivateSession(SL_secureChannel channel, UA_Session *session,
 	return UA_SUCCESS;
 }
 
-UA_Int32 Service_CloseSession(UA_Session *session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) {
-	//FIXME channel->session = UA_NULL;
-	// FIXME: set response
-	return UA_SUCCESS;
+UA_Int32 Service_CloseSession(UA_Session session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) {
+//FIXME channel->session = UA_NULL;
+// FIXME: set response
+return UA_SUCCESS;
 }

+ 30 - 0
src/ua_services_subscription.c

@@ -0,0 +1,30 @@
+/*
+ * ua_services_subscription.c
+ *
+ *  Created on: 18.06.2014
+ *      Author: root
+ */
+#include "ua_services.h"
+#include "ua_statuscodes.h"
+
+UA_Int32 Service_CreateSubscription(UA_Session session, const UA_CreateSubscriptionRequest *request,
+                                   UA_CreateSubscriptionResponse *response)
+{
+
+	response->subscriptionId = 42;
+	response->revisedPublishingInterval = 100000;
+	response->revisedLifetimeCount = 120000;
+	response->revisedMaxKeepAliveCount = 50;
+	return UA_SUCCESS;
+}
+
+UA_Int32 Service_Publish(UA_Session session, const UA_PublishRequest *request,
+                                   UA_PublishResponse *response)
+{
+
+	response->subscriptionId = 42;
+	response->notificationMessage.sequenceNumber = 1;
+	response->notificationMessage.publishTime = UA_DateTime_now();
+	return UA_SUCCESS;
+}
+

+ 228 - 15
src/ua_services_view.c

@@ -1,32 +1,245 @@
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 
-UA_Int32 Service_Browse(UA_Session *session, const UA_BrowseRequest *request, UA_BrowseResponse *response) {
+UA_Int32 Service_Browse_getReferenceDescription(Namespace *ns, UA_ReferenceNode* reference, UA_UInt32 nodeClassMask,
+												UA_UInt32 resultMask, UA_ReferenceDescription* referenceDescription) {
+	const UA_Node* foundNode;
+	Namespace_Entry_Lock *lock;
+
+	if(Namespace_get(ns,&reference->targetId.nodeId,&foundNode, &lock) != UA_SUCCESS)
+		return UA_ERROR;
+
+	UA_NodeId_copy(&foundNode->nodeId, &referenceDescription->nodeId.nodeId);
+	//TODO ExpandedNodeId is a mockup
+	referenceDescription->nodeId.serverIndex = 0;
+	referenceDescription->nodeId.namespaceUri.length = -1;
+
+	UA_UInt32 mask = 0;
+	for (mask = 0x01; mask <= 0x40; mask *= 2) {
+		switch (mask & (resultMask)) {
+		case UA_BROWSERESULTMASK_REFERENCETYPEID:
+			UA_NodeId_copy(&reference->referenceTypeId, &referenceDescription->referenceTypeId);
+			break;
+		case UA_BROWSERESULTMASK_ISFORWARD:
+			referenceDescription->isForward = !reference->isInverse;
+			break;
+		case UA_BROWSERESULTMASK_NODECLASS:
+			UA_NodeClass_copy(&foundNode->nodeClass, &referenceDescription->nodeClass);
+			break;
+		case UA_BROWSERESULTMASK_BROWSENAME:
+			UA_QualifiedName_copy(&foundNode->browseName, &referenceDescription->browseName);
+			break;
+		case UA_BROWSERESULTMASK_DISPLAYNAME:
+			UA_LocalizedText_copy(&foundNode->displayName, &referenceDescription->displayName);
+			break;
+		case UA_BROWSERESULTMASK_TYPEDEFINITION:
+			if (foundNode->nodeClass != UA_NODECLASS_OBJECT &&
+				foundNode->nodeClass != UA_NODECLASS_VARIABLE)
+				break;
+
+			for(UA_Int32 i = 0;i<foundNode->referencesSize;i++) {
+				UA_ReferenceNode *ref = &foundNode->references[i];
+				if(ref->referenceTypeId.identifier.numeric == 40 /* hastypedefinition */) {
+					UA_ExpandedNodeId_copy(&ref->targetId, &referenceDescription->typeDefinition);
+					break;
+				}
+			}
+			break;
+		}
+	}
+	
+	Namespace_Entry_Lock_release(lock);
+	return UA_SUCCESS;
+}
+
+/* singly-linked list */
+struct SubRefTypeId {
+	UA_NodeId id;
+	UA_SLIST_ENTRY(SubRefTypeId) next;
+};
+UA_SLIST_HEAD(SubRefTypeIdList, SubRefTypeId);
+
+UA_UInt32 walkReferenceTree(Namespace *ns, UA_ReferenceTypeNode *current, struct SubRefTypeIdList *list) {
+	// insert the current referencetype
+	struct SubRefTypeId *element;
+	UA_alloc((void**)&element, sizeof(struct SubRefTypeId));
+	element->id = current->nodeId;
+	UA_SLIST_INSERT_HEAD(list, element, next);
+
+	UA_UInt32 count = 1; // the current element
+
+	// walk the tree
+	for(UA_Int32 i = 0;i < current->referencesSize;i++) {
+		if(current->references[i].referenceTypeId.identifier.numeric == 45 /* HasSubtype */ &&
+		   current->references[i].isInverse == UA_FALSE) {
+			const UA_Node *node;
+			Namespace_Entry_Lock *lock;
+			if(Namespace_get(ns, &current->references[i].targetId.nodeId, &node, &lock) == UA_SUCCESS &&
+			   node->nodeClass == UA_NODECLASS_REFERENCETYPE) {
+				count += walkReferenceTree(ns,(UA_ReferenceTypeNode*)node, list);
+				Namespace_Entry_Lock_release(lock);
+			}
+		}
+	}
+	return count;
+}
+
+/* We do not search across namespaces so far. The id of the father-referencetype is returned in the array also. */
+static UA_Int32 findSubReferenceTypes(Namespace *ns, UA_NodeId *rootReferenceType, UA_NodeId **ids, UA_UInt32 *idcount) {
+	struct SubRefTypeIdList list;
+	UA_SLIST_INIT(&list);
+
+	// walk the tree
+	UA_ReferenceTypeNode *root;
+	Namespace_Entry_Lock *lock;
+	if(Namespace_get(ns, rootReferenceType, (const UA_Node**)&root, &lock) != UA_SUCCESS ||
+	   root->nodeClass != UA_NODECLASS_REFERENCETYPE)
+		return UA_ERROR;
+	UA_UInt32 count = walkReferenceTree(ns, root, &list);
+	Namespace_Entry_Lock_release(lock);
+
+	// copy results into an array
+	UA_alloc((void**) ids, sizeof(UA_NodeId)*count);
+	for(UA_UInt32 i = 0; i < count;i++) {
+		struct SubRefTypeId *element = UA_SLIST_FIRST(&list);
+		UA_NodeId_copy(&element->id, &(*ids)[i]);
+		UA_SLIST_REMOVE_HEAD(&list, next);
+		UA_free(element);
+	}
+	*idcount = count;
+
+	return UA_SUCCESS;
+}
+
+/* is this a relevant reference? */
+static inline UA_Boolean Service_Browse_returnReference(UA_BrowseDescription *browseDescription, UA_ReferenceNode* reference,
+														UA_NodeId *relevantRefTypes, UA_UInt32 relevantRefTypesCount) {
+	if (reference->isInverse == UA_TRUE && browseDescription->browseDirection == UA_BROWSEDIRECTION_FORWARD)
+		return UA_FALSE;
+	else if (reference->isInverse == UA_FALSE && browseDescription->browseDirection == UA_BROWSEDIRECTION_INVERSE)
+		return UA_FALSE;
+	for(UA_UInt32 i = 0; i<relevantRefTypesCount;i++) {
+		if(UA_NodeId_equal(&browseDescription->referenceTypeId, &relevantRefTypes[i]) == UA_EQUAL)
+			return UA_TRUE;
+	}
+	return UA_FALSE;
+}
+
+/* Return results to a single browsedescription. */
+static void Service_Browse_getBrowseResult(Namespace *ns, UA_BrowseDescription *browseDescription,
+										   UA_UInt32 maxReferences, UA_BrowseResult *browseResult) {
+	const UA_Node* node;
+	Namespace_Entry_Lock *lock;
+
+	if(Namespace_get(ns, &browseDescription->nodeId, &node, &lock) != UA_SUCCESS) {
+		browseResult->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
+		return;
+	}
+
+	// 0 => unlimited references
+	if(maxReferences == 0)
+		maxReferences = node->referencesSize;
+
+	// discover the relevant subtypes
+	UA_NodeId *relevantReferenceTypes;
+	UA_UInt32 relevantReferenceTypesCount=0;
+	if(!browseDescription->includeSubtypes ||
+	   findSubReferenceTypes(ns, &browseDescription->referenceTypeId, &relevantReferenceTypes, &relevantReferenceTypesCount) != UA_SUCCESS) {
+		UA_alloc((void**)&relevantReferenceTypes, sizeof(UA_NodeId));
+		UA_NodeId_copy(&browseDescription->referenceTypeId, relevantReferenceTypes);
+		relevantReferenceTypesCount = 1;
+	}
+
+	/* We do not use a linked list but traverse the nodes references list twice
+	 * (once for counting, once for generating the referencedescriptions). That
+	 * is much faster than using a linked list, since the references are
+	 * allocated in a continuous blob and RAM access is predictible/does not
+	 * miss cache lines so often. TODO: measure with some huge objects! */
+	UA_UInt32 refs = 0;
+	for(UA_Int32 i=0;i < node->referencesSize && refs <= maxReferences;i++) {
+		if(Service_Browse_returnReference(browseDescription, &node->references[i], relevantReferenceTypes, relevantReferenceTypesCount))
+			refs++;
+	}
+
+	// can we return all relevant references at once?
+	UA_Boolean finished = UA_TRUE;
+	if(refs > maxReferences) {
+		refs--;
+		finished = UA_FALSE;
+	}
+	
+	browseResult->referencesSize = refs;
+	UA_Array_new((void**) &browseResult->references, refs, &UA_.types[UA_REFERENCEDESCRIPTION]);
+	
+	for(UA_UInt32 i = 0, j=0; j < refs; i++) {
+		if(!Service_Browse_returnReference(browseDescription, &node->references[i], relevantReferenceTypes, relevantReferenceTypesCount))
+			continue;
+		
+		if(Service_Browse_getReferenceDescription(ns, &node->references[i], browseDescription->nodeClassMask,
+												  browseDescription->resultMask, &browseResult->references[j]) != UA_SUCCESS)
+			browseResult->statusCode = UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE;
+		j++;
+	}
+
+	if(!finished) {
+		// Todo. Set the Statuscode and the continuation point.
+	}
+	
+	Namespace_Entry_Lock_release(lock);
+	UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesCount, &UA_.types[UA_NODEID]);
+}
+
+UA_Int32 Service_Browse(UA_Session session, const UA_BrowseRequest *request, UA_BrowseResponse *response) {
 	UA_Int32 retval = UA_SUCCESS;
-	DBG_VERBOSE(UA_NodeId_printf("BrowseService - view=",&(request->view.viewId)));
-	UA_Int32 i = 0;
-	for (i=0;request->nodesToBrowseSize > 0 && i<request->nodesToBrowseSize;i++) {
-		UA_NodeId_printf("BrowseService - nodesToBrowse=", &(request->nodesToBrowse[i]->nodeId));
+	Application *application;
+	if(session == UA_NULL)
+	{
+		return UA_ERROR;
+	}
+	UA_Session_getApplicationPointer(session, &application);
+	if(application == UA_NULL)
+	{
+		return UA_ERROR;
+	}
+	DBG_VERBOSE(UA_NodeId_printf("BrowseService - view=", &request->view.viewId));
+
+	//TODO request->view not used atm
+	UA_Array_new((void**) &(response->results), request->nodesToBrowseSize, &UA_.types[UA_BROWSERESULT]);
+	response->resultsSize = request->nodesToBrowseSize;
+
+	for(UA_Int32 i=0; i < request->nodesToBrowseSize; i++) {
+		Namespace *ns = UA_indexedList_findValue(application->namespaces,
+												 request->nodesToBrowse[i].nodeId.namespace);
+		if(ns == UA_NULL) {
+			response->results[i].statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
+			continue;
+		}
+		
+		// Service_Browse_getBrowseResult has no return value. All errors are resolved internally.
+		Service_Browse_getBrowseResult(ns, &request->nodesToBrowse[i],
+									   request->requestedMaxReferencesPerNode, &response->results[i]);
 	}
+
+	//TODO fill Diagnostic info array
+	response->diagnosticInfosSize = 0;
+	response->diagnosticInfos = UA_NULL;
 	return retval;
 }
 
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session *session, const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response)
-{
-	UA_Int32 retval = UA_SUCCESS;
 
+UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session session, const UA_TranslateBrowsePathsToNodeIdsRequest *request,
+											   UA_TranslateBrowsePathsToNodeIdsResponse *response) {
+	UA_Int32 retval = UA_SUCCESS;
 	DBG_VERBOSE(printf("TranslateBrowsePathsToNodeIdsService - %i path(s)", request->browsePathsSize));
-	//Allocate space for a correct answer
-	UA_Array_new((void***)&(response->results),request->browsePathsSize,UA_BROWSEPATHRESULT);
 
+	// Allocate space for a correct answer
 	response->resultsSize = request->browsePathsSize;
+	// _init of the elements is done in Array_new
+	UA_Array_new((void**) &response->results, request->browsePathsSize, &UA_.types[UA_BROWSEPATHRESULT]);
 
-	UA_BrowsePathResult* path;
-	for(UA_Int32 i = 0;i<request->browsePathsSize;i++){
-		UA_BrowsePathResult_new(&path);
+	for (UA_Int32 i = 0; i < request->browsePathsSize; i++) {
 		//FIXME: implement
-		path->statusCode = UA_STATUSCODE_BADQUERYTOOCOMPLEX;
-		(response->results[i]) = path;
+		response->results[i].statusCode = UA_STATUSCODE_BADNOMATCH;
 	}
 
 	return retval;

+ 17 - 5
src/ua_stack_channel.c

@@ -45,8 +45,15 @@ UA_Int32 SL_Channel_getRemainingLifetime(SL_secureChannel channel, UA_Int32 *lif
 {
 	if(channel)
 	{
-		*lifetime = UA_DateTime_difference_ms(((SL_Channel1*)channel)->securityToken.createdAt,UA_DateTime_now());
-	return UA_SUCCESS;
+		UA_Int64 diffInMS = (((SL_Channel1*)channel)->securityToken.createdAt - UA_DateTime_now()) / 1e7;
+		if(diffInMS > UA_INT32_MAX)
+		{
+			*lifetime = UA_INT32_MAX;
+		}else
+		{
+			*lifetime = (UA_Int32)diffInMS;
+		}
+			return UA_SUCCESS;
 	}
 	else
 	{
@@ -79,7 +86,7 @@ UA_Int32 SL_Channel_getLocalAsymAlgSettings(SL_secureChannel channel, UA_Asymmet
 {
 	UA_Int32 retval = 0;
 
-	retval |= UA_alloc((void**)asymAlgSettings,UA_AsymmetricAlgorithmSecurityHeader_calcSize(UA_NULL));
+	retval |= UA_alloc((void**)asymAlgSettings,UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(UA_NULL));
 
 	retval |= UA_ByteString_copy(&(channel->localAsymAlgSettings.receiverCertificateThumbprint),
 			&(*asymAlgSettings)->receiverCertificateThumbprint);
@@ -175,7 +182,7 @@ UA_Int32 SL_Channel_init(SL_secureChannel channel,
 //TODO implement real nonce generator - DUMMY function
 UA_Int32 SL_Channel_generateNonce(UA_ByteString *nonce)
 {
-	UA_ByteString_new(&nonce);
+	//UA_ByteString_new(&nonce);
 	UA_alloc((void**)&(nonce->data),1);
 	nonce->length = 1;
 	nonce->data[0] = 'a';
@@ -225,7 +232,7 @@ UA_Int32 SL_Channel_new(SL_secureChannel **channel,
 UA_Int32 SL_Channel_initByRequest(SL_secureChannel channel,
 		UA_TL_Connection1 connection,
 		const UA_ByteString* msg,
-		UA_Int32* pos)
+		UA_UInt32* pos)
 {
 
 	UA_SequenceHeader *sequenceHeader;
@@ -293,6 +300,9 @@ UA_Int32 SL_Channel_renewToken(SL_secureChannel channel, UA_UInt32 tokenId,UA_Da
 
 UA_Int32 SL_Channel_checkSequenceNumber(SL_secureChannel channel, UA_UInt32 sequenceNumber)
 {
+	((SL_Channel1*)channel)->sequenceNumber = sequenceNumber; //TODO mock up, to be removed;
+	return UA_SUCCESS;
+
 	if(((SL_Channel1*)channel)->sequenceNumber+1 == sequenceNumber){
 		((SL_Channel1*)channel)->sequenceNumber++;
 
@@ -306,6 +316,8 @@ UA_Int32 SL_Channel_checkSequenceNumber(SL_secureChannel channel, UA_UInt32 sequ
 
 UA_Int32 SL_Channel_checkRequestId(SL_secureChannel channel, UA_UInt32 requestId)
 {
+	((SL_Channel1*)channel)->requestId = requestId; //TODO mock up, to be removed;
+	return UA_SUCCESS;
 	if(((SL_Channel1*)channel)->requestId+1 == requestId){
 		((SL_Channel1*)channel)->requestId++;
 

+ 2 - 2
src/ua_stack_channel.h

@@ -10,7 +10,7 @@
 
 #include <stdio.h>
 #include <memory.h> // memcpy
-#include "opcua.h"
+
 #include "ua_transport_connection.h"
 
 typedef enum ChannelState {
@@ -38,7 +38,7 @@ UA_Int32 SL_Channel_init(SL_secureChannel channel,
 		UA_ByteString *senderCertificate, UA_MessageSecurityMode securityMode);
 
 UA_Int32 SL_Channel_initByRequest(SL_secureChannel channel, UA_TL_Connection1 connection, const UA_ByteString* msg,
-		UA_Int32* pos);
+		UA_UInt32* pos);
 
 UA_Int32 SL_Channel_initMembers(SL_secureChannel channel,
 		UA_TL_Connection1 *connection,

+ 5 - 4
src/ua_stack_session.c

@@ -33,7 +33,7 @@ UA_Int32 UA_Session_generateAuthenticationToken(UA_NodeId *newToken)
 	//retval |= UA_NodeId_new(newToken);
 
 	newToken->encodingByte = 0x04; //GUID
-
+	newToken->namespace = 0; // where else?
 	newToken->identifier.guid.data1 = rand();
 	r = rand();
 	newToken->identifier.guid.data2 = (UA_UInt16)((r>>16) );
@@ -104,7 +104,8 @@ UA_Int32 UA_Session_init(UA_Session session, UA_String *sessionName, UA_Double r
 UA_Boolean UA_Session_compare(UA_Session session1, UA_Session session2)
 {
 	if(session1 && session2){
-		return UA_NodeId_compare(&((UA_SessionType*)session1)->sessionId,
+
+		return UA_NodeId_equal(&((UA_SessionType*)session1)->sessionId,
 				&((UA_SessionType*)session2)->sessionId);
 	}
 	return UA_NOT_EQUAL;
@@ -113,7 +114,7 @@ UA_Boolean UA_Session_compare(UA_Session session1, UA_Session session2)
 UA_Boolean UA_Session_compareByToken(UA_Session session, UA_NodeId *token)
 {
 	if(session && token){
-		return UA_NodeId_compare(&((UA_SessionType*)session)->authenticationToken, token);
+		return UA_NodeId_equal(&((UA_SessionType*)session)->authenticationToken, token);
 	}
 	return UA_NOT_EQUAL;
 }
@@ -121,7 +122,7 @@ UA_Boolean UA_Session_compareByToken(UA_Session session, UA_NodeId *token)
 UA_Boolean UA_Session_compareById(UA_Session session, UA_NodeId *sessionId)
 {
 	if(session && sessionId){
-		return UA_NodeId_compare(&((UA_SessionType*)session)->sessionId, sessionId);
+		return UA_NodeId_equal(&((UA_SessionType*)session)->sessionId, sessionId);
 	}
 	return UA_NOT_EQUAL;
 }

+ 1 - 1
src/ua_stack_session.h

@@ -8,7 +8,7 @@
 #ifndef UA_STACK_SESSION_H_
 #define UA_STACK_SESSION_H_
 
-#include "../include/opcua.h"
+
 #include "ua_stack_channel.h"
 
 

+ 2 - 2
src/ua_stack_session_manager.h

@@ -8,8 +8,8 @@
 #ifndef UA_STACK_SESSION_MANAGER_H_
 #define UA_STACK_SESSION_MANAGER_H_
 
-#include "../include/opcua.h"
-#include "../include/ua_list.h"
+
+
 #include "ua_stack_session.h"
 
 

+ 1 - 1
include/ua_statuscodes.h

@@ -1,7 +1,7 @@
 #ifndef OPCUA_STATUSCODES_H_
 #define OPCUA_STATUSCODES_H_
 
-#include "ua_basictypes.h"
+#include "ua_types.h"
 
 static const UA_StatusCode UA_STATUSCODE_GOOD = 0x00;
 static const UA_StatusCode UA_STATUSCODE_BADUNEXPECTEDERROR = 0x80010000; // An unexpected error occurred.

+ 312 - 237
src/ua_transport.c

@@ -1,148 +1,166 @@
 #include "ua_transport.h"
+#include "ua_types_encoding_binary.h"
 #include "stdio.h"
 
+UA_TYPE_DEFAULT(UA_MessageType)
 UA_Int32 UA_MessageType_calcSize(UA_MessageType const * ptr){
 	if(ptr==UA_NULL){return sizeof(UA_MessageType);}
 	return 0
 	 + 3 * sizeof(UA_Byte);
 }
 
-UA_Int32 UA_MessageType_encodeBinary(UA_MessageType const * src, UA_Int32* pos, UA_ByteString* dst){
+UA_Int32 UA_MessageType_encodeBinary(UA_MessageType const * src, UA_ByteString* dst, UA_UInt32 *offset){
 	UA_Int32 retval = UA_SUCCESS;
 	UA_Byte tmpBuf[3];
 	tmpBuf[0] = (UA_Byte)((((UA_Int32)*src) >> 16) );
 	tmpBuf[1] = (UA_Byte)((((UA_Int32)*src) >> 8));
 	tmpBuf[2] = (UA_Byte)(((UA_Int32)*src));
 
-	retval |= UA_Byte_encodeBinary(&(tmpBuf[0]),pos,dst);
-	retval |= UA_Byte_encodeBinary(&(tmpBuf[1]),pos,dst);
-	retval |= UA_Byte_encodeBinary(&(tmpBuf[2]),pos,dst);
+	retval |= UA_Byte_encodeBinary(&(tmpBuf[0]),dst,offset);
+	retval |= UA_Byte_encodeBinary(&(tmpBuf[1]),dst,offset);
+	retval |= UA_Byte_encodeBinary(&(tmpBuf[2]),dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_MessageType_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_MessageType* dst){
+UA_Int32 UA_MessageType_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_MessageType* dst){
 	UA_Int32 retval = UA_SUCCESS;
 	UA_Byte tmpBuf[3];
-	retval |= UA_Byte_decodeBinary(src,pos,&(tmpBuf[0])); //messageType to Byte representation
-	retval |= UA_Byte_decodeBinary(src,pos,&(tmpBuf[1]));
-	retval |= UA_Byte_decodeBinary(src,pos,&(tmpBuf[2]));
+	retval |= UA_Byte_decodeBinary(src,offset,&(tmpBuf[0])); //messageType to Byte representation
+	retval |= UA_Byte_decodeBinary(src,offset,&(tmpBuf[1]));
+	retval |= UA_Byte_decodeBinary(src,offset,&(tmpBuf[2]));
 	*dst = (UA_MessageType)((UA_Int32)(tmpBuf[0]<<16) + (UA_Int32)(tmpBuf[1]<<8) + (UA_Int32)(tmpBuf[2]));
 	return retval;
 }
-UA_TYPE_METHOD_DELETE_FREE(UA_MessageType)
-UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_MessageType)
+
 void UA_MessageType_printf(char *label, UA_MessageType* p) {
 	UA_Byte* b = (UA_Byte*) p;
 	printf("%s{%c%c%c}\n", label, b[2],b[1],b[0]);
 }
 
-UA_Int32 UA_OPCUATcpMessageHeader_calcSize(UA_OPCUATcpMessageHeader const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_OPCUATcpMessageHeader);}
-	return 0
-	 + UA_MessageType_calcSize(&(ptr->messageType)) // messageType
+UA_Int32 UA_OPCUATcpMessageHeader_calcSizeBinary(UA_OPCUATcpMessageHeader const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_OPCUATcpMessageHeader);
+    	return 0
+	 + 3 // messageType
 	 + sizeof(UA_Byte) // isFinal
 	 + sizeof(UA_UInt32) // messageSize
 	;
 }
 
-UA_Int32 UA_OPCUATcpMessageHeader_encodeBinary(UA_OPCUATcpMessageHeader const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_MessageType_encodeBinary(&(src->messageType),pos,dst);
-	retval |= UA_Byte_encodeBinary(&(src->isFinal),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->messageSize),pos,dst);
+UA_Int32 UA_OPCUATcpMessageHeader_encodeBinary(UA_OPCUATcpMessageHeader const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_MessageType_encodeBinary(&src->messageType,dst,offset);
+	retval |= UA_Byte_encodeBinary(&src->isFinal,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->messageSize,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpMessageHeader_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_OPCUATcpMessageHeader* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_OPCUATcpMessageHeader_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_OPCUATcpMessageHeader * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_OPCUATcpMessageHeader_init(dst);
-	CHECKED_DECODE(UA_MessageType_decodeBinary(src,pos,&(dst->messageType)), UA_OPCUATcpMessageHeader_deleteMembers(dst));
-	CHECKED_DECODE(UA_Byte_decodeBinary(src,pos,&(dst->isFinal)), UA_OPCUATcpMessageHeader_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->messageSize)), UA_OPCUATcpMessageHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_MessageType_decodeBinary(src,offset,&dst->messageType), UA_OPCUATcpMessageHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_Byte_decodeBinary(src,offset,&dst->isFinal), UA_OPCUATcpMessageHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->messageSize), UA_OPCUATcpMessageHeader_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpMessageHeader_delete(UA_OPCUATcpMessageHeader* p) {
+UA_Int32 UA_OPCUATcpMessageHeader_delete(UA_OPCUATcpMessageHeader *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_OPCUATcpMessageHeader_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_OPCUATcpMessageHeader_deleteMembers(UA_OPCUATcpMessageHeader* p) {
-	UA_Int32 retval = UA_SUCCESS;
+}
+
+UA_Int32 UA_OPCUATcpMessageHeader_deleteMembers(UA_OPCUATcpMessageHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpMessageHeader_init(UA_OPCUATcpMessageHeader * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_Byte_init(&(p->isFinal));
-	retval |= UA_UInt32_init(&(p->messageSize));
+UA_Int32 UA_OPCUATcpMessageHeader_init(UA_OPCUATcpMessageHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_Byte_init(&p->isFinal);
+	retval |= UA_UInt32_init(&p->messageSize);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_OPCUATcpMessageHeader)
-UA_Int32 UA_OPCUATcpHelloMessage_calcSize(UA_OPCUATcpHelloMessage const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_OPCUATcpHelloMessage);}
-	return 0
+UA_TYPE_NEW_DEFAULT(UA_OPCUATcpMessageHeader)
+UA_Int32 UA_OPCUATcpMessageHeader_copy(const UA_OPCUATcpMessageHeader *src,UA_OPCUATcpMessageHeader *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_OPCUATcpMessageHeader));
+	return retval;
+}
+
+UA_Int32 UA_OPCUATcpHelloMessage_calcSizeBinary(UA_OPCUATcpHelloMessage const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_OPCUATcpHelloMessage);
+    	return 0
 	 + sizeof(UA_UInt32) // protocolVersion
 	 + sizeof(UA_UInt32) // receiveBufferSize
 	 + sizeof(UA_UInt32) // sendBufferSize
 	 + sizeof(UA_UInt32) // maxMessageSize
 	 + sizeof(UA_UInt32) // maxChunkCount
-	 + UA_String_calcSize(&(ptr->endpointUrl))
+	 + UA_String_calcSizeBinary(&ptr->endpointUrl)
 	;
 }
 
-UA_Int32 UA_OPCUATcpHelloMessage_encodeBinary(UA_OPCUATcpHelloMessage const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_encodeBinary(&(src->protocolVersion),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->receiveBufferSize),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->sendBufferSize),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->maxMessageSize),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->maxChunkCount),pos,dst);
-	retval |= UA_String_encodeBinary(&(src->endpointUrl),pos,dst);
+UA_Int32 UA_OPCUATcpHelloMessage_encodeBinary(UA_OPCUATcpHelloMessage const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_encodeBinary(&src->protocolVersion,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->receiveBufferSize,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->sendBufferSize,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->maxMessageSize,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->maxChunkCount,dst,offset);
+	retval |= UA_String_encodeBinary(&src->endpointUrl,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpHelloMessage_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_OPCUATcpHelloMessage* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_OPCUATcpHelloMessage_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_OPCUATcpHelloMessage * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_OPCUATcpHelloMessage_init(dst);
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->protocolVersion)), UA_OPCUATcpHelloMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->receiveBufferSize)), UA_OPCUATcpHelloMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->sendBufferSize)), UA_OPCUATcpHelloMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->maxMessageSize)), UA_OPCUATcpHelloMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->maxChunkCount)), UA_OPCUATcpHelloMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_String_decodeBinary(src,pos,&(dst->endpointUrl)), UA_OPCUATcpHelloMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->protocolVersion), UA_OPCUATcpHelloMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->receiveBufferSize), UA_OPCUATcpHelloMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->sendBufferSize), UA_OPCUATcpHelloMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->maxMessageSize), UA_OPCUATcpHelloMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->maxChunkCount), UA_OPCUATcpHelloMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_String_decodeBinary(src,offset,&dst->endpointUrl), UA_OPCUATcpHelloMessage_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpHelloMessage_delete(UA_OPCUATcpHelloMessage* p) {
+UA_Int32 UA_OPCUATcpHelloMessage_delete(UA_OPCUATcpHelloMessage *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_OPCUATcpHelloMessage_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_OPCUATcpHelloMessage_deleteMembers(UA_OPCUATcpHelloMessage* p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_String_deleteMembers(&(p->endpointUrl));
+}
+
+UA_Int32 UA_OPCUATcpHelloMessage_deleteMembers(UA_OPCUATcpHelloMessage *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_String_deleteMembers(&p->endpointUrl);
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpHelloMessage_init(UA_OPCUATcpHelloMessage * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_init(&(p->protocolVersion));
-	retval |= UA_UInt32_init(&(p->receiveBufferSize));
-	retval |= UA_UInt32_init(&(p->sendBufferSize));
-	retval |= UA_UInt32_init(&(p->maxMessageSize));
-	retval |= UA_UInt32_init(&(p->maxChunkCount));
-	retval |= UA_String_init(&(p->endpointUrl));
+UA_Int32 UA_OPCUATcpHelloMessage_init(UA_OPCUATcpHelloMessage *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_init(&p->protocolVersion);
+	retval |= UA_UInt32_init(&p->receiveBufferSize);
+	retval |= UA_UInt32_init(&p->sendBufferSize);
+	retval |= UA_UInt32_init(&p->maxMessageSize);
+	retval |= UA_UInt32_init(&p->maxChunkCount);
+	retval |= UA_String_init(&p->endpointUrl);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_OPCUATcpHelloMessage)
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_calcSize(UA_OPCUATcpAcknowledgeMessage const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_OPCUATcpAcknowledgeMessage);}
-	return 0
+UA_TYPE_NEW_DEFAULT(UA_OPCUATcpHelloMessage)
+UA_Int32 UA_OPCUATcpHelloMessage_copy(const UA_OPCUATcpHelloMessage *src,UA_OPCUATcpHelloMessage *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_OPCUATcpHelloMessage));
+	retval |= UA_String_copy(&src->endpointUrl,&dst->endpointUrl);
+	return retval;
+}
+
+UA_Int32 UA_OPCUATcpAcknowledgeMessage_calcSizeBinary(UA_OPCUATcpAcknowledgeMessage const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_OPCUATcpAcknowledgeMessage);
+    	return 0
 	 + sizeof(UA_UInt32) // protocolVersion
 	 + sizeof(UA_UInt32) // receiveBufferSize
 	 + sizeof(UA_UInt32) // sendBufferSize
@@ -151,313 +169,370 @@ UA_Int32 UA_OPCUATcpAcknowledgeMessage_calcSize(UA_OPCUATcpAcknowledgeMessage co
 	;
 }
 
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_encodeBinary(UA_OPCUATcpAcknowledgeMessage const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_encodeBinary(&(src->protocolVersion),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->receiveBufferSize),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->sendBufferSize),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->maxMessageSize),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->maxChunkCount),pos,dst);
+UA_Int32 UA_OPCUATcpAcknowledgeMessage_encodeBinary(UA_OPCUATcpAcknowledgeMessage const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_encodeBinary(&src->protocolVersion,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->receiveBufferSize,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->sendBufferSize,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->maxMessageSize,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->maxChunkCount,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_OPCUATcpAcknowledgeMessage* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_OPCUATcpAcknowledgeMessage_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_OPCUATcpAcknowledgeMessage * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_OPCUATcpAcknowledgeMessage_init(dst);
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->protocolVersion)), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->receiveBufferSize)), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->sendBufferSize)), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->maxMessageSize)), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->maxChunkCount)), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->protocolVersion), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->receiveBufferSize), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->sendBufferSize), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->maxMessageSize), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->maxChunkCount), UA_OPCUATcpAcknowledgeMessage_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_delete(UA_OPCUATcpAcknowledgeMessage* p) {
+UA_Int32 UA_OPCUATcpAcknowledgeMessage_delete(UA_OPCUATcpAcknowledgeMessage *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_OPCUATcpAcknowledgeMessage_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_deleteMembers(UA_OPCUATcpAcknowledgeMessage* p) {
-	UA_Int32 retval = UA_SUCCESS;
+}
+
+UA_Int32 UA_OPCUATcpAcknowledgeMessage_deleteMembers(UA_OPCUATcpAcknowledgeMessage *p) {
+    	UA_Int32 retval = UA_SUCCESS;
 	return retval;
 }
 
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_init(UA_OPCUATcpAcknowledgeMessage * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_init(&(p->protocolVersion));
-	retval |= UA_UInt32_init(&(p->receiveBufferSize));
-	retval |= UA_UInt32_init(&(p->sendBufferSize));
-	retval |= UA_UInt32_init(&(p->maxMessageSize));
-	retval |= UA_UInt32_init(&(p->maxChunkCount));
+UA_Int32 UA_OPCUATcpAcknowledgeMessage_init(UA_OPCUATcpAcknowledgeMessage *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_init(&p->protocolVersion);
+	retval |= UA_UInt32_init(&p->receiveBufferSize);
+	retval |= UA_UInt32_init(&p->sendBufferSize);
+	retval |= UA_UInt32_init(&p->maxMessageSize);
+	retval |= UA_UInt32_init(&p->maxChunkCount);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_OPCUATcpAcknowledgeMessage)
-UA_Int32 UA_SecureConversationMessageHeader_calcSize(UA_SecureConversationMessageHeader const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_SecureConversationMessageHeader);}
-	return 0
-	 // + UA_OPCUATcpMessageHeader_calcSize(&(ptr->messageHeader))
+UA_TYPE_NEW_DEFAULT(UA_OPCUATcpAcknowledgeMessage)
+UA_Int32 UA_OPCUATcpAcknowledgeMessage_copy(const UA_OPCUATcpAcknowledgeMessage *src,UA_OPCUATcpAcknowledgeMessage *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_OPCUATcpAcknowledgeMessage));
+	return retval;
+}
+
+UA_Int32 UA_SecureConversationMessageHeader_calcSizeBinary(UA_SecureConversationMessageHeader const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_SecureConversationMessageHeader);
+    	return 0
+	 + sizeof(UA_OPCUATcpMessageHeader) // messageHeader CHECK: delete this or use in binary_secure.c
 	 + sizeof(UA_UInt32) // secureChannelId
 	;
 }
 
-UA_Int32 UA_SecureConversationMessageHeader_encodeBinary(UA_SecureConversationMessageHeader const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	// retval |= UA_OPCUATcpMessageHeader_encodeBinary(&(src->messageHeader),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->secureChannelId),pos,dst);
+UA_Int32 UA_SecureConversationMessageHeader_encodeBinary(UA_SecureConversationMessageHeader const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_OPCUATcpMessageHeader_encodeBinary(&src->messageHeader,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->secureChannelId,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageHeader_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_SecureConversationMessageHeader* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_SecureConversationMessageHeader_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_SecureConversationMessageHeader * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_SecureConversationMessageHeader_init(dst);
-	// CHECKED_DECODE(UA_OPCUATcpMessageHeader_decodeBinary(src,pos,&(dst->messageHeader)), UA_SecureConversationMessageHeader_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->secureChannelId)), UA_SecureConversationMessageHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_OPCUATcpMessageHeader_decodeBinary(src,offset,&dst->messageHeader), UA_SecureConversationMessageHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->secureChannelId), UA_SecureConversationMessageHeader_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageHeader_delete(UA_SecureConversationMessageHeader* p) {
+UA_Int32 UA_SecureConversationMessageHeader_delete(UA_SecureConversationMessageHeader *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_SecureConversationMessageHeader_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_SecureConversationMessageHeader_deleteMembers(UA_SecureConversationMessageHeader* p) {
-	UA_Int32 retval = UA_SUCCESS;
-	// retval |= UA_OPCUATcpMessageHeader_deleteMembers(&(p->messageHeader));
+}
+
+UA_Int32 UA_SecureConversationMessageHeader_deleteMembers(UA_SecureConversationMessageHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageHeader_init(UA_SecureConversationMessageHeader * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	// retval |= UA_OPCUATcpMessageHeader_init(&(p->messageHeader));
-	retval |= UA_UInt32_init(&(p->secureChannelId));
+UA_Int32 UA_SecureConversationMessageHeader_init(UA_SecureConversationMessageHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_OPCUATcpMessageHeader_init(&p->messageHeader);
+	retval |= UA_UInt32_init(&p->secureChannelId);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_SecureConversationMessageHeader)
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_calcSize(UA_AsymmetricAlgorithmSecurityHeader const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_AsymmetricAlgorithmSecurityHeader);}
-	return 0
-	 + UA_ByteString_calcSize(&(ptr->securityPolicyUri))
-	 + UA_ByteString_calcSize(&(ptr->senderCertificate))
-	 + UA_ByteString_calcSize(&(ptr->receiverCertificateThumbprint))
-	 // + sizeof(UA_UInt32) // requestId
+UA_TYPE_NEW_DEFAULT(UA_SecureConversationMessageHeader)
+UA_Int32 UA_SecureConversationMessageHeader_copy(const UA_SecureConversationMessageHeader *src,UA_SecureConversationMessageHeader *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_SecureConversationMessageHeader));
+	return retval;
+}
+
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(UA_AsymmetricAlgorithmSecurityHeader const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_AsymmetricAlgorithmSecurityHeader);
+    	return 0
+	 + UA_ByteString_calcSizeBinary(&ptr->securityPolicyUri)
+	 + UA_ByteString_calcSizeBinary(&ptr->senderCertificate)
+	 + UA_ByteString_calcSizeBinary(&ptr->receiverCertificateThumbprint)
+			//	 + sizeof(UA_UInt32) // requestId
 	;
 }
 
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(UA_AsymmetricAlgorithmSecurityHeader const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_ByteString_encodeBinary(&(src->securityPolicyUri),pos,dst);
-	retval |= UA_ByteString_encodeBinary(&(src->senderCertificate),pos,dst);
-	retval |= UA_ByteString_encodeBinary(&(src->receiverCertificateThumbprint),pos,dst);
-	// retval |= UA_UInt32_encodeBinary(&(src->requestId),pos,dst);
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(UA_AsymmetricAlgorithmSecurityHeader const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_ByteString_encodeBinary(&src->securityPolicyUri,dst,offset);
+	retval |= UA_ByteString_encodeBinary(&src->senderCertificate,dst,offset);
+	retval |= UA_ByteString_encodeBinary(&src->receiverCertificateThumbprint,dst,offset);
+	//	retval |= UA_UInt32_encodeBinary(&src->requestId,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_AsymmetricAlgorithmSecurityHeader* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_AsymmetricAlgorithmSecurityHeader * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_AsymmetricAlgorithmSecurityHeader_init(dst);
-	CHECKED_DECODE(UA_ByteString_decodeBinary(src,pos,&(dst->securityPolicyUri)), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
-	CHECKED_DECODE(UA_ByteString_decodeBinary(src,pos,&(dst->senderCertificate)), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
-	CHECKED_DECODE(UA_ByteString_decodeBinary(src,pos,&(dst->receiverCertificateThumbprint)), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
-	// CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->requestId)), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_ByteString_decodeBinary(src,offset,&dst->securityPolicyUri), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_ByteString_decodeBinary(src,offset,&dst->senderCertificate), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_ByteString_decodeBinary(src,offset,&dst->receiverCertificateThumbprint), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
+	//	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->requestId), UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_delete(UA_AsymmetricAlgorithmSecurityHeader* p) {
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_delete(UA_AsymmetricAlgorithmSecurityHeader *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader* p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_ByteString_deleteMembers(&(p->securityPolicyUri));
-	retval |= UA_ByteString_deleteMembers(&(p->senderCertificate));
-	retval |= UA_ByteString_deleteMembers(&(p->receiverCertificateThumbprint));
+}
+
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_ByteString_deleteMembers(&p->securityPolicyUri);
+	retval |= UA_ByteString_deleteMembers(&p->senderCertificate);
+	retval |= UA_ByteString_deleteMembers(&p->receiverCertificateThumbprint);
 	return retval;
 }
 
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_init(UA_AsymmetricAlgorithmSecurityHeader * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_ByteString_init(&(p->securityPolicyUri));
-	retval |= UA_ByteString_init(&(p->senderCertificate));
-	retval |= UA_ByteString_init(&(p->receiverCertificateThumbprint));
-	// retval |= UA_UInt32_init(&(p->requestId));
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_init(UA_AsymmetricAlgorithmSecurityHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_ByteString_init(&p->securityPolicyUri);
+	retval |= UA_ByteString_init(&p->senderCertificate);
+	retval |= UA_ByteString_init(&p->receiverCertificateThumbprint);
+	//retval |= UA_UInt32_init(&p->requestId);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_AsymmetricAlgorithmSecurityHeader)
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_calcSize(UA_SymmetricAlgorithmSecurityHeader const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_SymmetricAlgorithmSecurityHeader);}
-	return 0
+UA_TYPE_NEW_DEFAULT(UA_AsymmetricAlgorithmSecurityHeader)
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_copy(const UA_AsymmetricAlgorithmSecurityHeader *src,UA_AsymmetricAlgorithmSecurityHeader *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_AsymmetricAlgorithmSecurityHeader));
+	retval |= UA_ByteString_copy(&src->securityPolicyUri,&dst->securityPolicyUri);
+	retval |= UA_ByteString_copy(&src->senderCertificate,&dst->senderCertificate);
+	retval |= UA_ByteString_copy(&src->receiverCertificateThumbprint,&dst->receiverCertificateThumbprint);
+	return retval;
+}
+
+UA_Int32 UA_SymmetricAlgorithmSecurityHeader_calcSizeBinary(UA_SymmetricAlgorithmSecurityHeader const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_SymmetricAlgorithmSecurityHeader);
+    	return 0
 	 + sizeof(UA_UInt32) // tokenId
 	;
 }
 
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_encodeBinary(UA_SymmetricAlgorithmSecurityHeader const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_encodeBinary(&(src->tokenId),pos,dst);
+UA_Int32 UA_SymmetricAlgorithmSecurityHeader_encodeBinary(UA_SymmetricAlgorithmSecurityHeader const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_encodeBinary(&src->tokenId,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_SymmetricAlgorithmSecurityHeader* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_SymmetricAlgorithmSecurityHeader_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_SymmetricAlgorithmSecurityHeader * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_SymmetricAlgorithmSecurityHeader_init(dst);
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->tokenId)), UA_SymmetricAlgorithmSecurityHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->tokenId), UA_SymmetricAlgorithmSecurityHeader_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_delete(UA_SymmetricAlgorithmSecurityHeader* p) {
+UA_Int32 UA_SymmetricAlgorithmSecurityHeader_delete(UA_SymmetricAlgorithmSecurityHeader *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_SymmetricAlgorithmSecurityHeader_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_deleteMembers(UA_SymmetricAlgorithmSecurityHeader* p) {
-	UA_Int32 retval = UA_SUCCESS;
+}
+
+UA_Int32 UA_SymmetricAlgorithmSecurityHeader_deleteMembers(UA_SymmetricAlgorithmSecurityHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
 	return retval;
 }
 
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_init(UA_SymmetricAlgorithmSecurityHeader * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_init(&(p->tokenId));
+UA_Int32 UA_SymmetricAlgorithmSecurityHeader_init(UA_SymmetricAlgorithmSecurityHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_init(&p->tokenId);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_SymmetricAlgorithmSecurityHeader)
-UA_Int32 UA_SequenceHeader_calcSize(UA_SequenceHeader const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_SequenceHeader);}
-	return 0
+UA_TYPE_NEW_DEFAULT(UA_SymmetricAlgorithmSecurityHeader)
+UA_Int32 UA_SymmetricAlgorithmSecurityHeader_copy(const UA_SymmetricAlgorithmSecurityHeader *src,UA_SymmetricAlgorithmSecurityHeader *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_SymmetricAlgorithmSecurityHeader));
+	return retval;
+}
+
+UA_Int32 UA_SequenceHeader_calcSizeBinary(UA_SequenceHeader const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_SequenceHeader);
+    	return 0
 	 + sizeof(UA_UInt32) // sequenceNumber
 	 + sizeof(UA_UInt32) // requestId
 	;
 }
 
-UA_Int32 UA_SequenceHeader_encodeBinary(UA_SequenceHeader const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_encodeBinary(&(src->sequenceNumber),pos,dst);
-	retval |= UA_UInt32_encodeBinary(&(src->requestId),pos,dst);
+UA_Int32 UA_SequenceHeader_encodeBinary(UA_SequenceHeader const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_encodeBinary(&src->sequenceNumber,dst,offset);
+	retval |= UA_UInt32_encodeBinary(&src->requestId,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_SequenceHeader_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_SequenceHeader* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_SequenceHeader_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_SequenceHeader * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_SequenceHeader_init(dst);
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->sequenceNumber)), UA_SequenceHeader_deleteMembers(dst));
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->requestId)), UA_SequenceHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->sequenceNumber), UA_SequenceHeader_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->requestId), UA_SequenceHeader_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_SequenceHeader_delete(UA_SequenceHeader* p) {
+UA_Int32 UA_SequenceHeader_delete(UA_SequenceHeader *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_SequenceHeader_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_SequenceHeader_deleteMembers(UA_SequenceHeader* p) {
-	UA_Int32 retval = UA_SUCCESS;
+}
+
+UA_Int32 UA_SequenceHeader_deleteMembers(UA_SequenceHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
 	return retval;
 }
 
-UA_Int32 UA_SequenceHeader_init(UA_SequenceHeader * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_init(&(p->sequenceNumber));
-	retval |= UA_UInt32_init(&(p->requestId));
+UA_Int32 UA_SequenceHeader_init(UA_SequenceHeader *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_init(&p->sequenceNumber);
+	retval |= UA_UInt32_init(&p->requestId);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_SequenceHeader)
-UA_Int32 UA_SecureConversationMessageFooter_calcSize(UA_SecureConversationMessageFooter const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_SecureConversationMessageFooter);}
-	return 0
-	 + 0 //paddingSize is included in UA_Array_calcSize
-	 + UA_Array_calcSize(ptr->paddingSize, UA_BYTE, (void const**) ptr->padding)
+UA_TYPE_NEW_DEFAULT(UA_SequenceHeader)
+UA_Int32 UA_SequenceHeader_copy(const UA_SequenceHeader *src,UA_SequenceHeader *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_SequenceHeader));
+	return retval;
+}
+
+UA_Int32 UA_SecureConversationMessageFooter_calcSizeBinary(UA_SecureConversationMessageFooter const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_SecureConversationMessageFooter);
+    	return 0
+		+ UA_Array_calcSizeBinary(ptr->paddingSize,&UA_.types[UA_BYTE],ptr->padding)
 	 + sizeof(UA_Byte) // signature
 	;
 }
 
-UA_Int32 UA_SecureConversationMessageFooter_encodeBinary(UA_SecureConversationMessageFooter const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	//retval |= UA_Int32_encodeBinary(&(src->paddingSize),pos,dst); // encode size managed by UA_Array_encodeBinary
-	retval |= UA_Array_encodeBinary((void const**) (src->padding),src->paddingSize, UA_BYTE,pos,dst);
-	retval |= UA_Byte_encodeBinary(&(src->signature),pos,dst);
+UA_Int32 UA_SecureConversationMessageFooter_encodeBinary(UA_SecureConversationMessageFooter const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_Array_encodeBinary(&src->padding,src->paddingSize,&UA_.types[UA_BYTE],dst,offset);
+	retval |= UA_Byte_encodeBinary(&src->signature,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageFooter_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_SecureConversationMessageFooter* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_SecureConversationMessageFooter_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_SecureConversationMessageFooter * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_SecureConversationMessageFooter_init(dst);
-	CHECKED_DECODE(UA_Int32_decodeBinary(src,pos,&(dst->paddingSize)), UA_SecureConversationMessageFooter_deleteMembers(dst)); // decode size
-	CHECKED_DECODE(UA_Array_new((void***)&dst->padding, dst->paddingSize, UA_BYTE), dst->padding = UA_NULL; UA_SecureConversationMessageFooter_deleteMembers(dst));
-	CHECKED_DECODE(UA_Array_decodeBinary(src,dst->paddingSize, UA_BYTE,pos,(void *** const) (&dst->padding)), UA_SecureConversationMessageFooter_deleteMembers(dst));
-	CHECKED_DECODE(UA_Byte_decodeBinary(src,pos,&(dst->signature)), UA_SecureConversationMessageFooter_deleteMembers(dst));
+	CHECKED_DECODE(UA_Int32_decodeBinary(src,offset,&dst->paddingSize),UA_SecureConversationMessageFooter_deleteMembers(dst));
+	CHECKED_DECODE(UA_Array_decodeBinary(src,offset,dst->paddingSize,&UA_.types[UA_BYTE],(void**)&dst->padding), UA_SecureConversationMessageFooter_deleteMembers(dst));
+	CHECKED_DECODE(UA_Byte_decodeBinary(src,offset,&dst->signature), UA_SecureConversationMessageFooter_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageFooter_delete(UA_SecureConversationMessageFooter* p) {
+UA_Int32 UA_SecureConversationMessageFooter_delete(UA_SecureConversationMessageFooter *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_SecureConversationMessageFooter_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_SecureConversationMessageFooter_deleteMembers(UA_SecureConversationMessageFooter* p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_Array_delete((void***)&p->padding,p->paddingSize,UA_BYTE); p->padding = UA_NULL;
+}
+
+UA_Int32 UA_SecureConversationMessageFooter_deleteMembers(UA_SecureConversationMessageFooter *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_Array_delete((void*)p->padding,p->paddingSize,&UA_.types[UA_BYTE]);
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageFooter_init(UA_SecureConversationMessageFooter * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	p->paddingSize=0;
-	p->padding=UA_NULL;
-	retval |= UA_Byte_init(&(p->signature));
+UA_Int32 UA_SecureConversationMessageFooter_init(UA_SecureConversationMessageFooter *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	p->paddingSize = 0;
+	p->padding = UA_NULL;
+	retval |= UA_Byte_init(&p->signature);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_SecureConversationMessageFooter)
-UA_Int32 UA_SecureConversationMessageAbortBody_calcSize(UA_SecureConversationMessageAbortBody const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_SecureConversationMessageAbortBody);}
-	return 0
+UA_TYPE_NEW_DEFAULT(UA_SecureConversationMessageFooter)
+UA_Int32 UA_SecureConversationMessageFooter_copy(const UA_SecureConversationMessageFooter *src,UA_SecureConversationMessageFooter *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_SecureConversationMessageFooter));
+	dst->padding = src->padding;
+	retval |= UA_Array_copy(&src->padding, src->paddingSize,&UA_.types[UA_BYTE],(void**)&dst->padding);
+	return retval;
+}
+
+UA_Int32 UA_SecureConversationMessageAbortBody_calcSizeBinary(UA_SecureConversationMessageAbortBody const * ptr) {
+    	if(ptr==UA_NULL) return sizeof(UA_SecureConversationMessageAbortBody);
+    	return 0
 	 + sizeof(UA_UInt32) // error
-	 + UA_String_calcSize(&(ptr->reason))
+	 + UA_String_calcSizeBinary(&ptr->reason)
 	;
 }
 
-UA_Int32 UA_SecureConversationMessageAbortBody_encodeBinary(UA_SecureConversationMessageAbortBody const * src, UA_Int32* pos, UA_ByteString* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_encodeBinary(&(src->error),pos,dst);
-	retval |= UA_String_encodeBinary(&(src->reason),pos,dst);
+UA_Int32 UA_SecureConversationMessageAbortBody_encodeBinary(UA_SecureConversationMessageAbortBody const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_encodeBinary(&src->error,dst,offset);
+	retval |= UA_String_encodeBinary(&src->reason,dst,offset);
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageAbortBody_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_SecureConversationMessageAbortBody* dst) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 UA_SecureConversationMessageAbortBody_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, UA_SecureConversationMessageAbortBody * dst) {
+    	UA_Int32 retval = UA_SUCCESS;
 	UA_SecureConversationMessageAbortBody_init(dst);
-	CHECKED_DECODE(UA_UInt32_decodeBinary(src,pos,&(dst->error)), UA_SecureConversationMessageAbortBody_deleteMembers(dst));
-	CHECKED_DECODE(UA_String_decodeBinary(src,pos,&(dst->reason)), UA_SecureConversationMessageAbortBody_deleteMembers(dst));
+	CHECKED_DECODE(UA_UInt32_decodeBinary(src,offset,&dst->error), UA_SecureConversationMessageAbortBody_deleteMembers(dst));
+	CHECKED_DECODE(UA_String_decodeBinary(src,offset,&dst->reason), UA_SecureConversationMessageAbortBody_deleteMembers(dst));
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageAbortBody_delete(UA_SecureConversationMessageAbortBody* p) {
+UA_Int32 UA_SecureConversationMessageAbortBody_delete(UA_SecureConversationMessageAbortBody *p) {
 	UA_Int32 retval = UA_SUCCESS;
 	retval |= UA_SecureConversationMessageAbortBody_deleteMembers(p);
 	retval |= UA_free(p);
 	return retval;
-    }
-UA_Int32 UA_SecureConversationMessageAbortBody_deleteMembers(UA_SecureConversationMessageAbortBody* p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_String_deleteMembers(&(p->reason));
+}
+
+UA_Int32 UA_SecureConversationMessageAbortBody_deleteMembers(UA_SecureConversationMessageAbortBody *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_String_deleteMembers(&p->reason);
 	return retval;
 }
 
-UA_Int32 UA_SecureConversationMessageAbortBody_init(UA_SecureConversationMessageAbortBody * p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_init(&(p->error));
-	retval |= UA_String_init(&(p->reason));
+UA_Int32 UA_SecureConversationMessageAbortBody_init(UA_SecureConversationMessageAbortBody *p) {
+    	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_UInt32_init(&p->error);
+	retval |= UA_String_init(&p->reason);
 	return retval;
 }
 
-UA_TYPE_METHOD_NEW_DEFAULT(UA_SecureConversationMessageAbortBody)
+UA_TYPE_NEW_DEFAULT(UA_SecureConversationMessageAbortBody)
+UA_Int32 UA_SecureConversationMessageAbortBody_copy(const UA_SecureConversationMessageAbortBody *src,UA_SecureConversationMessageAbortBody *dst) {
+    	if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    	UA_Int32 retval = UA_SUCCESS;
+	memcpy(dst, src, sizeof(UA_SecureConversationMessageAbortBody));
+	retval |= UA_String_copy(&src->reason,&dst->reason);
+	return retval;
+}

+ 35 - 91
src/ua_transport.h

@@ -1,7 +1,8 @@
 #ifndef UA_TRANSPORT_H_
 #define UA_TRANSPORT_H_
 
-#include "opcua.h"
+#include "ua_types.h"
+#include "ua_types_encoding_binary.h"
 #include "ua_application.h"
 
 static const UA_Int32 SL_HEADER_LENGTH = 0;
@@ -39,31 +40,21 @@ enum UA_MessageType {
 	UA_MESSAGETYPE_MSG = 0x4D5347, // M S G
 	UA_MESSAGETYPE_CLO = 0x434C4F  // C L O
 };
-UA_Int32 UA_MessageType_calcSize(UA_MessageType const * ptr);
-UA_Int32 UA_MessageType_encodeBinary(UA_MessageType const * src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_MessageType_decodeBinary(UA_ByteString const * src, UA_Int32* pos, UA_MessageType* dst);
-UA_Int32 UA_MessageType_delete(UA_MessageType* p);
-UA_Int32 UA_MessageType_deleteMembers(UA_MessageType* p);
+UA_TYPE_PROTOTYPES(UA_MessageType)
+UA_TYPE_BINARY_ENCODING(UA_MessageType)
 void UA_MessageType_printf(char *label, UA_MessageType* p);
 
-/** @name UA_UA_OPCUATcpMessageHeader */
 /** @brief TCP Header */
 typedef struct UA_OPCUATcpMessageHeader {
-	UA_MessageType messageType; // MessageType instead of UInt32
+	UA_MessageType messageType;
 	UA_Byte isFinal;
 	UA_UInt32 messageSize;
 } UA_OPCUATcpMessageHeader;
-UA_Int32 UA_OPCUATcpMessageHeader_calcSize(UA_OPCUATcpMessageHeader const* ptr);
-UA_Int32 UA_OPCUATcpMessageHeader_encodeBinary(UA_OPCUATcpMessageHeader const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_OPCUATcpMessageHeader_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_OPCUATcpMessageHeader* dst);
-UA_Int32 UA_OPCUATcpMessageHeader_delete(UA_OPCUATcpMessageHeader* p);
-UA_Int32 UA_OPCUATcpMessageHeader_deleteMembers(UA_OPCUATcpMessageHeader* p);
-UA_Int32 UA_OPCUATcpMessageHeader_init(UA_OPCUATcpMessageHeader * p);
-UA_Int32 UA_OPCUATcpMessageHeader_new(UA_OPCUATcpMessageHeader ** p);
-
-/** @name UA_UA_OPCUATcpHelloMessage */
+UA_TYPE_PROTOTYPES(UA_OPCUATcpMessageHeader)
+UA_TYPE_BINARY_ENCODING(UA_OPCUATcpMessageHeader)
+
 /** @brief Hello Message */
-typedef struct UA_OPCUATcpHelloMessage {
+typedef struct UA_OPCUATcpHelloMesage {
 	UA_UInt32 protocolVersion;
 	UA_UInt32 receiveBufferSize;
 	UA_UInt32 sendBufferSize;
@@ -71,15 +62,9 @@ typedef struct UA_OPCUATcpHelloMessage {
 	UA_UInt32 maxChunkCount;
 	UA_String endpointUrl;
 } UA_OPCUATcpHelloMessage;
-UA_Int32 UA_OPCUATcpHelloMessage_calcSize(UA_OPCUATcpHelloMessage const* ptr);
-UA_Int32 UA_OPCUATcpHelloMessage_encodeBinary(UA_OPCUATcpHelloMessage const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_OPCUATcpHelloMessage_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_OPCUATcpHelloMessage* dst);
-UA_Int32 UA_OPCUATcpHelloMessage_delete(UA_OPCUATcpHelloMessage* p);
-UA_Int32 UA_OPCUATcpHelloMessage_deleteMembers(UA_OPCUATcpHelloMessage* p);
-UA_Int32 UA_OPCUATcpHelloMessage_init(UA_OPCUATcpHelloMessage * p);
-UA_Int32 UA_OPCUATcpHelloMessage_new(UA_OPCUATcpHelloMessage ** p);
-
-/** @name UA_UA_OPCUATcpAcknowledgeMessage */
+UA_TYPE_PROTOTYPES(UA_OPCUATcpHelloMessage)
+UA_TYPE_BINARY_ENCODING(UA_OPCUATcpHelloMessage)
+
 /** @brief Acknowledge Message */
 typedef struct UA_OPCUATcpAcknowledgeMessage {
 	UA_UInt32 protocolVersion;
@@ -88,98 +73,57 @@ typedef struct UA_OPCUATcpAcknowledgeMessage {
 	UA_UInt32 maxMessageSize;
 	UA_UInt32 maxChunkCount;
 } UA_OPCUATcpAcknowledgeMessage;
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_calcSize(UA_OPCUATcpAcknowledgeMessage const* ptr);
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_encodeBinary(UA_OPCUATcpAcknowledgeMessage const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_OPCUATcpAcknowledgeMessage* dst);
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_delete(UA_OPCUATcpAcknowledgeMessage* p);
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_deleteMembers(UA_OPCUATcpAcknowledgeMessage* p);
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_init(UA_OPCUATcpAcknowledgeMessage * p);
-UA_Int32 UA_OPCUATcpAcknowledgeMessage_new(UA_OPCUATcpAcknowledgeMessage ** p);
-
-/** @name UA_UA_SecureConversationMessageHeader */
+UA_TYPE_PROTOTYPES(UA_OPCUATcpAcknowledgeMessage)
+UA_TYPE_BINARY_ENCODING(UA_OPCUATcpAcknowledgeMessage)
+
 /** @brief Secure Layer Sequence Header */
 typedef struct UA_SecureConversationMessageHeader {
-	// UA_OPCUATcpMessageHeader messageHeader; // Treated with custom code
+	UA_OPCUATcpMessageHeader messageHeader;
 	UA_UInt32 secureChannelId;
 } UA_SecureConversationMessageHeader;
-UA_Int32 UA_SecureConversationMessageHeader_calcSize(UA_SecureConversationMessageHeader const* ptr);
-UA_Int32 UA_SecureConversationMessageHeader_encodeBinary(UA_SecureConversationMessageHeader const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_SecureConversationMessageHeader_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_SecureConversationMessageHeader* dst);
-UA_Int32 UA_SecureConversationMessageHeader_delete(UA_SecureConversationMessageHeader* p);
-UA_Int32 UA_SecureConversationMessageHeader_deleteMembers(UA_SecureConversationMessageHeader* p);
-UA_Int32 UA_SecureConversationMessageHeader_init(UA_SecureConversationMessageHeader * p);
-UA_Int32 UA_SecureConversationMessageHeader_new(UA_SecureConversationMessageHeader ** p);
-
-/** @name UA_UA_AsymmetricAlgorithmSecurityHeader */
+UA_TYPE_PROTOTYPES(UA_SecureConversationMessageHeader)
+UA_TYPE_BINARY_ENCODING(UA_SecureConversationMessageHeader)
+
 /** @brief Security Header> */
 typedef struct UA_AsymmetricAlgorithmSecurityHeader {
 	UA_ByteString securityPolicyUri;
 	UA_ByteString senderCertificate;
 	UA_ByteString receiverCertificateThumbprint;
-	// UA_UInt32 requestId; // Dealt with in the SequenceHeader
+	UA_UInt32 requestId;
 } UA_AsymmetricAlgorithmSecurityHeader;
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_calcSize(UA_AsymmetricAlgorithmSecurityHeader const* ptr);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(UA_AsymmetricAlgorithmSecurityHeader const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_AsymmetricAlgorithmSecurityHeader* dst);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_delete(UA_AsymmetricAlgorithmSecurityHeader* p);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader* p);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_init(UA_AsymmetricAlgorithmSecurityHeader * p);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_new(UA_AsymmetricAlgorithmSecurityHeader ** p);
-
-/** @name UA_UA_SymmetricAlgorithmSecurityHeader */
+UA_TYPE_PROTOTYPES(UA_AsymmetricAlgorithmSecurityHeader)
+UA_TYPE_BINARY_ENCODING(UA_AsymmetricAlgorithmSecurityHeader)
+
 /** @brief Secure Layer Symmetric Algorithm Header */
 typedef struct UA_SymmetricAlgorithmSecurityHeader {
 	UA_UInt32 tokenId;
 } UA_SymmetricAlgorithmSecurityHeader;
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_calcSize(UA_SymmetricAlgorithmSecurityHeader const* ptr);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_encodeBinary(UA_SymmetricAlgorithmSecurityHeader const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_SymmetricAlgorithmSecurityHeader* dst);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_delete(UA_SymmetricAlgorithmSecurityHeader* p);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_deleteMembers(UA_SymmetricAlgorithmSecurityHeader* p);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_init(UA_SymmetricAlgorithmSecurityHeader * p);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_new(UA_SymmetricAlgorithmSecurityHeader ** p);
-
-/** @name UA_UA_SequenceHeader */
+UA_TYPE_PROTOTYPES(UA_SymmetricAlgorithmSecurityHeader)
+UA_TYPE_BINARY_ENCODING(UA_SymmetricAlgorithmSecurityHeader)
+
 /** @brief Secure Layer Sequence Header */
 typedef struct UA_SequenceHeader {
 	UA_UInt32 sequenceNumber;
 	UA_UInt32 requestId;
 } UA_SequenceHeader;
-UA_Int32 UA_SequenceHeader_calcSize(UA_SequenceHeader const* ptr);
-UA_Int32 UA_SequenceHeader_encodeBinary(UA_SequenceHeader const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_SequenceHeader_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_SequenceHeader* dst);
-UA_Int32 UA_SequenceHeader_delete(UA_SequenceHeader* p);
-UA_Int32 UA_SequenceHeader_deleteMembers(UA_SequenceHeader* p);
-UA_Int32 UA_SequenceHeader_init(UA_SequenceHeader * p);
-UA_Int32 UA_SequenceHeader_new(UA_SequenceHeader ** p);
-
-/** @name UA_UA_SecureConversationMessageFooter */
+UA_TYPE_PROTOTYPES(UA_SequenceHeader)
+UA_TYPE_BINARY_ENCODING(UA_SequenceHeader)
+
 /** @brief Secure Conversation Message Footer */
 typedef struct UA_SecureConversationMessageFooter {
 	UA_Int32 paddingSize;
-	UA_Byte** padding;
+	UA_Byte* padding;
 	UA_Byte signature;
 } UA_SecureConversationMessageFooter;
-UA_Int32 UA_SecureConversationMessageFooter_calcSize(UA_SecureConversationMessageFooter const* ptr);
-UA_Int32 UA_SecureConversationMessageFooter_encodeBinary(UA_SecureConversationMessageFooter const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_SecureConversationMessageFooter_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_SecureConversationMessageFooter* dst);
-UA_Int32 UA_SecureConversationMessageFooter_delete(UA_SecureConversationMessageFooter* p);
-UA_Int32 UA_SecureConversationMessageFooter_deleteMembers(UA_SecureConversationMessageFooter* p);
-UA_Int32 UA_SecureConversationMessageFooter_init(UA_SecureConversationMessageFooter * p);
-UA_Int32 UA_SecureConversationMessageFooter_new(UA_SecureConversationMessageFooter ** p);
-
-/** @name UA_UA_SecureConversationMessageAbortBody */
+UA_TYPE_PROTOTYPES(UA_SecureConversationMessageFooter)
+UA_TYPE_BINARY_ENCODING(UA_SecureConversationMessageFooter)
+
 /** @brief Secure Conversation Message Abort Body */
 typedef struct UA_SecureConversationMessageAbortBody {
 	UA_UInt32 error;
 	UA_String reason;
 } UA_SecureConversationMessageAbortBody;
-UA_Int32 UA_SecureConversationMessageAbortBody_calcSize(UA_SecureConversationMessageAbortBody const* ptr);
-UA_Int32 UA_SecureConversationMessageAbortBody_encodeBinary(UA_SecureConversationMessageAbortBody const* src, UA_Int32* pos, UA_ByteString* dst);
-UA_Int32 UA_SecureConversationMessageAbortBody_decodeBinary(UA_ByteString const* src, UA_Int32* pos, UA_SecureConversationMessageAbortBody* dst);
-UA_Int32 UA_SecureConversationMessageAbortBody_delete(UA_SecureConversationMessageAbortBody* p);
-UA_Int32 UA_SecureConversationMessageAbortBody_deleteMembers(UA_SecureConversationMessageAbortBody* p);
-UA_Int32 UA_SecureConversationMessageAbortBody_init(UA_SecureConversationMessageAbortBody * p);
-UA_Int32 UA_SecureConversationMessageAbortBody_new(UA_SecureConversationMessageAbortBody ** p);
+UA_TYPE_PROTOTYPES(UA_SecureConversationMessageAbortBody)
+UA_TYPE_BINARY_ENCODING(UA_SecureConversationMessageAbortBody)
 
 #endif /* UA_TRANSPORT_H_ */

+ 11 - 10
src/ua_transport_binary.c

@@ -5,9 +5,9 @@
 #include "ua_transport_connection.h"
 
 
-static UA_Int32 TL_handleHello1(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos){
+static UA_Int32 TL_handleHello1(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos){
 	UA_Int32 retval = UA_SUCCESS;
-	UA_Int32 tmpPos = 0;
+	UA_UInt32 tmpPos = 0;
 	UA_Int32 connectionState;
 	UA_OPCUATcpHelloMessage helloMessage;
 	UA_TL_Connection_getState(connection, &connectionState);
@@ -38,12 +38,13 @@ static UA_Int32 TL_handleHello1(UA_TL_Connection1 connection, const UA_ByteStrin
 
 		// encode header and message to buffer
 		tmpPos = 0;
-		ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSize(&ackMessage) + UA_OPCUATcpMessageHeader_calcSize(&ackHeader);
+
+		ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSizeBinary(&ackMessage) + UA_OPCUATcpMessageHeader_calcSizeBinary(&ackHeader);
 		UA_ByteString *ack_msg;
 		UA_alloc((void **)&ack_msg, sizeof(UA_ByteString));
 		UA_ByteString_newMembers(ack_msg, ackHeader.messageSize);
-		UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader,&tmpPos,ack_msg);
-		UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage,&tmpPos,ack_msg);
+		UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader,ack_msg,&tmpPos);
+		UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage, ack_msg,&tmpPos);
 
 		DBG_VERBOSE(printf("TL_handleHello - Size messageToSend = %d, pos=%d\n",ackHeader.messageSize, tmpPos));
 		DBG_VERBOSE(UA_ByteString_printx("_handleHello - ack=", ack_msg));
@@ -129,7 +130,7 @@ static UA_Int32 TL_securitySettingsMockup_get(UA_ByteString *receiverCertificate
 
 	return UA_SUCCESS;
 }
-static UA_Int32 TL_handleOpen(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos) {
+static UA_Int32 TL_handleOpen(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos) {
 	UA_Int32 retval = UA_SUCCESS;
 	UA_Int32 state;
 	SL_secureChannel *channel;
@@ -166,16 +167,16 @@ static UA_Int32 TL_handleOpen(UA_TL_Connection1 connection, const UA_ByteString*
 	return UA_ERR_INVALID_VALUE;
 }
 
-static UA_Int32 TL_handleMsg(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos) {
+static UA_Int32 TL_handleMsg(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos) {
 	UA_Int32 state;
 	UA_TL_Connection_getState(connection,&state);
 	if (state == CONNECTIONSTATE_ESTABLISHED) {
-		return SL_Process(msg,pos);
+		return SL_Process(msg, pos);
 	}
 	return UA_ERR_INVALID_VALUE;
 }
 
-static UA_Int32 TL_handleClo(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos) {
+static UA_Int32 TL_handleClo(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos) {
 	UA_Int32 retval = UA_SUCCESS;
 	UA_SecureConversationMessageHeader *header;
 	retval |= UA_SecureConversationMessageHeader_new(&header);
@@ -193,7 +194,7 @@ static UA_Int32 TL_handleClo(UA_TL_Connection1 connection, const UA_ByteString*
 
 UA_Int32 TL_Process(UA_TL_Connection1 connection, const UA_ByteString* msg) {
 	UA_Int32 retval = UA_SUCCESS;
-	UA_Int32 pos = 0;
+	UA_UInt32 pos = 0;
 	UA_OPCUATcpMessageHeader tcpMessageHeader;
 
 	DBG_VERBOSE(printf("TL_Process - entered \n"));

+ 2 - 1
src/ua_transport_binary.h

@@ -2,7 +2,7 @@
 #define OPCUA_TRANSPORT_BINARY_H_
 #include <stdio.h>
 
-#include "opcua.h"
+
 #include "ua_transport_binary.h"
 #include "ua_transport_connection.h"
 
@@ -16,6 +16,7 @@
 #define TL_SERVER_MAX_MESSAGE_SIZE  8192
 
 
+
 /* Transport Layer Connection */
 //struct TL_Connection_T; // forward declaration
 

+ 132 - 34
src/ua_transport_binary_secure.c

@@ -1,6 +1,6 @@
 #include <stdio.h>
 #include <memory.h> // memcpy
-#include "opcua.h"
+
 #include "ua_transport_binary.h"
 #include "ua_transport_binary_secure.h"
 #include "ua_transport.h"
@@ -20,7 +20,7 @@ static UA_Int32 SL_Send(SL_secureChannel channel,
 	//SL_Channel_getId(secureChannel)
 	//SL_Channel_getSequenceNumber(secureChannel)
 
-	UA_Int32 pos = 0;
+	UA_UInt32 pos = 0;
 	UA_Int32 isAsym = (type == UA_OPENSECURECHANNELRESPONSE_NS0); // FIXME: this is a to dumb method to determine asymmetric algorithm setting
 	UA_UInt32 channelId;
 	UA_UInt32 sequenceNumber;
@@ -43,14 +43,14 @@ static UA_Int32 SL_Send(SL_secureChannel channel,
 		SL_Channel_getLocalAsymAlgSettings(channel, &asymAlgSettings);
 		UA_ByteString_newMembers((UA_ByteString *) response_gather[0],
 				SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER
-						+ UA_AsymmetricAlgorithmSecurityHeader_calcSize(
+						+ UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(
 								asymAlgSettings)
-						+ UA_NodeId_calcSize(&resp_nodeid));
+						+ UA_NodeId_calcSizeBinary(&resp_nodeid));
 	}
 	else
 	{
 		UA_ByteString_newMembers((UA_ByteString *) response_gather[0], 8 + 16 + // normal header + 4*32bit secure channel information
-				UA_NodeId_calcSize(&resp_nodeid));
+				UA_NodeId_calcSizeBinary(&resp_nodeid));
 	}
 
 	// sizePadding = 0;
@@ -75,20 +75,20 @@ static UA_Int32 SL_Send(SL_secureChannel channel,
 	pos += 1;
 
 	UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
-	UA_Int32_encodeBinary(&packetSize, &pos, header);
+	UA_Int32_encodeBinary(&packetSize, header,&pos);
 
 	//use get accessor to read the channel Id
 	SL_Channel_getChannelId(channel, &channelId);
 
-	UA_UInt32_encodeBinary(&channelId, &pos, header);
+	UA_UInt32_encodeBinary(&channelId, header,&pos);
 
 	/*---encode Algorithm Security Header ---*/
 	if (isAsym)
 	{
 
 
-		UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(asymAlgSettings, &pos,
-				header);
+		UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(asymAlgSettings,
+				header,&pos);
 		UA_free(asymAlgSettings);
 	}
 	else
@@ -97,17 +97,17 @@ static UA_Int32 SL_Send(SL_secureChannel channel,
 		UA_UInt32 tokenId = 0;
 		SL_Channel_getTokenId(channel, &tokenId);
 
-		UA_UInt32_encodeBinary(&tokenId, &pos, header);
+		UA_UInt32_encodeBinary(&tokenId, header,&pos);
 	}
 
 	/*---encode Sequence Header ---*/
 	SL_Channel_getSequenceNumber(channel, &sequenceNumber);
-	UA_UInt32_encodeBinary(&sequenceNumber, &pos, header);
+	UA_UInt32_encodeBinary(&sequenceNumber, header, &pos);
 	SL_Channel_getRequestId(channel, &requestId);
-	UA_UInt32_encodeBinary(&requestId, &pos, header);
+	UA_UInt32_encodeBinary(&requestId, header,&pos);
 
 	/*---add payload type---*/
-	UA_NodeId_encodeBinary(&resp_nodeid, &pos, header);
+	UA_NodeId_encodeBinary(&resp_nodeid, header,&pos);
 
 	/*---add encoded Message ---*/
 	response_gather[1] = responseMessage; // is deleted in the calling function
@@ -155,7 +155,7 @@ static void init_response_header(UA_RequestHeader const * p,
 	Service_##TYPE(session, &p, &r); \
 	DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
     *pos = 0; \
-	UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSize(&r)); \
+	UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSizeBinary(&r)); \
 	UA_##TYPE##Response_encodeBinary(&r, pos, &response_msg); \
 	UA_##TYPE##Request_deleteMembers(&p); \
 	UA_##TYPE##Response_deleteMembers(&r); \
@@ -168,28 +168,28 @@ static void init_response_header(UA_RequestHeader const * p,
 #define RESPONSE_CLEANUP(TYPE) \
 	DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
 	*pos = 0; \
-	UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSize(&r)); \
-	UA_##TYPE##Response_encodeBinary(&r, pos, &response_msg); \
+	UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSizeBinary(&r)); \
+	UA_##TYPE##Response_encodeBinary(&r, &response_msg,pos); \
 	UA_##TYPE##Request_deleteMembers(&p); \
 	UA_##TYPE##Response_deleteMembers(&r); \
-/** this function manages all the generic stuff for the request-response game */
-//UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString* msg,
-//		UA_Int32 *pos)
+
 
 UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
-		UA_Int32 *pos)
+		UA_UInt32 *pos)
 {
 	UA_Int32 retval = UA_SUCCESS;
 
 	// Every Message starts with a NodeID which names the serviceRequestType
 	UA_NodeId serviceRequestType;
-	UA_NodeId_decodeBinary(msg, pos, &serviceRequestType);
+	UA_NodeId_decodeBinary(msg, pos,&serviceRequestType);
+#ifdef DEBUG
 	UA_NodeId_printf("SL_processMessage - serviceRequestType=",
 			&serviceRequestType);
-
+#endif
 	UA_ByteString response_msg;
 	UA_Int32 serviceid = serviceRequestType.identifier.numeric - 2; // binary encoding has 2 added to the id
 	UA_Int32 responsetype;
+/* stack related services which only need information about the secure Channel */
 	//services which need a channel as parameter
 	if (serviceid == UA_GETENDPOINTSREQUEST_NS0)
 	{
@@ -209,21 +209,23 @@ UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
 	else if (serviceid == UA_CLOSESECURECHANNELREQUEST_NS0)
 	{
 		RESPONSE_PREPARE(CloseSecureChannel);
-		Service_CloseSecureChannel(&p,&r);
+		Service_CloseSecureChannel(channel,&p,&r);
 		RESPONSE_CLEANUP(CloseSecureChannel);
 		responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
 	}
+
 	else if (serviceid == UA_CREATESESSIONREQUEST_NS0)
 	{
 		RESPONSE_PREPARE(CreateSession);
-		Service_CreateSession(&session,&p, &r);
+		Service_CreateSession(channel,&p, &r);
 		RESPONSE_CLEANUP(CreateSession);
 		responsetype = UA_CREATESESSIONRESPONSE_NS0;
 	}
+/* services which need a session object */
 	else if (serviceid == UA_ACTIVATESESSIONREQUEST_NS0)
 	{
 		RESPONSE_PREPARE(ActivateSession);
-		Service_ActivateSession(channel,&session,&p, &r);
+		Service_ActivateSession(channel, session,&p, &r);
 		RESPONSE_CLEANUP(ActivateSession);
 
 		responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
@@ -231,7 +233,7 @@ UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
 	else if (serviceid == UA_CLOSESESSIONREQUEST_NS0)
 	{
 		RESPONSE_PREPARE(CloseSession);
-		Service_CloseSession(&session,&p, &r);
+		Service_CloseSession(session,&p, &r);
 		RESPONSE_CLEANUP(CloseSession);
 
 		responsetype = UA_CLOSESESSIONRESPONSE_NS0;
@@ -242,19 +244,107 @@ UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
 		RESPONSE_PREPARE(Read);
 		DBG_VERBOSE(printf("Finished Service: %s\n", Read));
 		if (UA_Session_verifyChannel(session,channel)){
-			Service_Read(&session,&p, &r);
+			Service_Read(session,&p, &r);
 		}
 		else
 		{
-			DBG_VERBOSE(printf("Finished Service: %s\n", Read));
-			//TODO return error, session does not belong to channel or vice versa
+			DBG_VERBOSE(printf("session does not match secure channel"));
 		}
 		DBG_VERBOSE(printf("Finished Service: %s\n", Read));
 		RESPONSE_CLEANUP(Read);
 		//TODO prepare userdefined implementation
-	//	INVOKE_SERVICE(Read);
+
 		responsetype = UA_READRESPONSE_NS0;
 	}
+	else if (serviceid == UA_BROWSEREQUEST_NS0)
+	{
+
+		RESPONSE_PREPARE(Browse);
+		DBG_VERBOSE(printf("Finished Service: %s\n", Browse));
+		if (UA_Session_verifyChannel(session,channel)){
+			Service_Browse(session,&p, &r);
+		}
+		else
+		{
+			DBG_VERBOSE(printf("session does not match secure channel"));
+		}
+		DBG_VERBOSE(printf("Finished Service: %s\n", Browse));
+		RESPONSE_CLEANUP(Browse);
+		//TODO prepare userdefined implementation
+
+		responsetype = UA_BROWSERESPONSE_NS0;
+	}
+	else if (serviceid == UA_CREATESUBSCRIPTIONREQUEST_NS0)
+	{
+
+		RESPONSE_PREPARE(CreateSubscription);
+		DBG_VERBOSE(printf("Finished Service: %s\n", CreateSubscription));
+		if (UA_Session_verifyChannel(session,channel)){
+			Service_CreateSubscription(session, &p, &r);
+		}
+		else
+		{
+			DBG_VERBOSE(printf("session does not match secure channel"));
+		}
+		DBG_VERBOSE(printf("Finished Service: %s\n", CreateSubscription));
+		RESPONSE_CLEANUP(CreateSubscription);
+		//TODO prepare userdefined implementation
+
+		responsetype = UA_CREATESUBSCRIPTIONRESPONSE_NS0;
+	}
+	else if (serviceid == UA_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_NS0)
+	{
+
+		RESPONSE_PREPARE(TranslateBrowsePathsToNodeIds);
+		DBG_VERBOSE(printf("Finished Service: %s\n", TranslateBrowsePathsToNodeIds));
+		if (UA_Session_verifyChannel(session,channel)){
+			Service_TranslateBrowsePathsToNodeIds(session, &p, &r);
+		}
+		else
+		{
+				DBG_VERBOSE(printf("session does not match secure channel"));
+		}
+		DBG_VERBOSE(printf("Finished Service: %s\n", TranslateBrowsePathsToNodeIds));
+		RESPONSE_CLEANUP(TranslateBrowsePathsToNodeIds);
+		//TODO prepare userdefined implementation
+
+		responsetype = UA_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE_NS0;
+	}
+	else if (serviceid == UA_PUBLISHREQUEST_NS0)
+	{
+
+		RESPONSE_PREPARE(Publish);
+		DBG_VERBOSE(printf("Finished Service: %s\n", Publish));
+		if (UA_Session_verifyChannel(session,channel)){
+			Service_Publish(session, &p, &r);
+		}
+		else
+		{
+			DBG_VERBOSE(printf("session does not match secure channel"));
+		}
+		DBG_VERBOSE(printf("Finished Service: %s\n", Publish));
+		RESPONSE_CLEANUP(Publish);
+		//TODO prepare userdefined implementation
+
+		responsetype = UA_PUBLISHRESPONSE_NS0;
+	}
+	else if (serviceid == UA_CREATEMONITOREDITEMSREQUEST_NS0)
+	{
+		RESPONSE_PREPARE(CreateMonitoredItems);
+		DBG_VERBOSE(printf("Finished Service: %s\n", CreateMonitoredItems));
+		if (UA_Session_verifyChannel(session,channel)){
+			Service_CreateMonitoredItems(session, &p, &r);
+		}
+		else
+		{
+			DBG_VERBOSE(printf("session does not match secure channel"));
+		}
+		DBG_VERBOSE(printf("Finished Service: %s\n", CreateMonitoredItems));
+		RESPONSE_CLEANUP(CreateMonitoredItems);
+		//TODO prepare userdefined implementation
+
+		responsetype = UA_CREATEMONITOREDITEMSRESPONSE_NS0;
+	}
 	else
 	{
 		printf(
@@ -264,13 +354,14 @@ UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
 		retval = UA_ERROR;
 		UA_RequestHeader p;
 		UA_ResponseHeader r;
+
 		UA_RequestHeader_decodeBinary(msg, pos, &p);
 		UA_ResponseHeader_init(&r);
 		r.requestHandle = p.requestHandle;
 		r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
 		*pos = 0;
-		UA_ByteString_newMembers(&response_msg, UA_ResponseHeader_calcSize(&r));
-		UA_ResponseHeader_encodeBinary(&r, pos, &response_msg);
+		UA_ByteString_newMembers(&response_msg, UA_ResponseHeader_calcSizeBinary(&r));
+		UA_ResponseHeader_encodeBinary(&r, &response_msg,pos);
 		responsetype = UA_RESPONSEHEADER_NS0;
 	}
 
@@ -279,15 +370,22 @@ UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
 
 	return retval;
 }
+/**
+ *
+ * @param connection
+ * @param msg
+ * @param pos
+ * @return
+ */
 
 UA_Int32 SL_ProcessOpenChannel(SL_secureChannel channel, const UA_ByteString* msg,
-		UA_Int32 *pos)
+		UA_UInt32 *pos)
 {
 	return SL_handleRequest(channel, msg, pos);
 }
 
 UA_Int32 SL_Process(const UA_ByteString* msg,
-		UA_Int32* pos)
+		UA_UInt32* pos)
 {
 
 	DBG_VERBOSE(printf("SL_process - entered \n"));

+ 3 - 3
src/ua_transport_binary_secure.h

@@ -1,6 +1,6 @@
 #ifndef OPCUA_TRANSPORT_BINARY_SECURE_H_
 #define OPCUA_TRANSPORT_BINARY_SECURE_H_
-#include "opcua.h"
+
 #include "ua_transport.h"
 #include "ua_transport_binary.h"
 #include "ua_stack_channel.h"
@@ -40,7 +40,7 @@ typedef struct SL_Channel_T {
 } SL_secureChannel;
 
 */
-UA_Int32 SL_Process(const UA_ByteString* msg, UA_Int32* pos);
+UA_Int32 SL_Process(const UA_ByteString* msg, UA_UInt32* pos);
 
 /**
  * @brief Wrapper function, to encapsulate handleRequest for openSecureChannel requests
@@ -51,5 +51,5 @@ UA_Int32 SL_Process(const UA_ByteString* msg, UA_Int32* pos);
 
  */
 UA_Int32 SL_ProcessOpenChannel(SL_secureChannel channel, const UA_ByteString* msg,
-		UA_Int32 *pos);
+		UA_UInt32 *pos);
 #endif /* OPCUA_TRANSPORT_BINARY_SECURE_H_ */

+ 15 - 1
src/ua_transport_connection.c

@@ -82,7 +82,21 @@ UA_Int32 UA_TL_Connection_setWriter(UA_TL_Connection1 connection, TL_Writer writ
 	((TL_Connection*)connection)->writer = writer;
 	return UA_SUCCESS;
 }
-
+UA_Int32 UA_TL_Connection_setConnectionHandle(UA_TL_Connection1 connection, UA_Int32 connectionHandle)
+{
+	((TL_Connection*)connection)->connectionHandle = connectionHandle;
+	return UA_SUCCESS;
+}
+UA_Int32 UA_TL_Connection_setState(UA_TL_Connection1 connection, UA_Int32 connectionState)
+{
+	if(connection)
+	{
+		((TL_Connection*)connection)->state = connectionState;
+		return UA_SUCCESS;
+	}else{
+		return UA_ERROR;
+	}
+}
 //getters
 UA_Int32 UA_TL_Connection_getState(UA_TL_Connection1 connection, UA_Int32 *connectionState)
 {

+ 9 - 5
src/ua_transport_connection.h

@@ -8,7 +8,7 @@
 #ifndef UA_TRANSPORT_CONNECTION_H_
 #define UA_TRANSPORT_CONNECTION_H_
 
-#include "opcua.h"
+
 #include "ua_transport.h"
 
 typedef struct TL_Buffer{
@@ -35,13 +35,17 @@ UA_Int32 UA_TL_Connection_new(UA_TL_Connection1 *connection,
 		TL_Buffer localBuffers,TL_Writer writer);
 UA_Int32 UA_TL_Connection_bind(UA_TL_Connection1 connection, UA_Int32 handle);
 UA_Boolean UA_TL_Connection_compare(UA_TL_Connection1 *connection1, UA_TL_Connection1 *connection2);
-//getter
+
+//setters
+UA_Int32 UA_TL_Connection_setState(UA_TL_Connection1 connection, UA_Int32 connectionState);
+UA_Int32 UA_TL_Connection_setWriter(UA_TL_Connection1 connection, TL_Writer writer);
+UA_Int32 UA_TL_Connection_setConnectionHandle(UA_TL_Connection1 connection, UA_Int32 connectionHandle);
+
+//getters
 UA_Int32 UA_TL_Connection_getHandle(UA_TL_Connection1 connection, UA_UInt32 *connectionId);
 UA_Int32 UA_TL_Connection_getProtocolVersion(UA_TL_Connection1 connection, UA_UInt32 *protocolVersion);
-
 UA_Int32 UA_TL_Connection_getState(UA_TL_Connection1 connection, UA_Int32 *connectionState);
 UA_Int32 UA_TL_Connection_getLocalConfiguration(UA_TL_Connection1 connection, TL_Buffer *localConfiguration);
 
-//setter
-UA_Int32 UA_TL_Connection_setWriter(UA_TL_Connection1 connection, TL_Writer writer);
+
 #endif /* UA_TRANSPORT_CONNECTION_H_ */

File diff suppressed because it is too large
+ 1175 - 0
src/ua_types.c


+ 516 - 0
src/ua_types.h

@@ -0,0 +1,516 @@
+#ifndef UA_TYPES_H_
+#define UA_TYPES_H_
+
+#include <stdio.h>
+#include <stdint.h>
+
+/**
+ * @defgroup types Datatypes
+ *
+ * @brief This module describes the datatypes used in OPC UA. There is a
+ * division into built-in datatypes (integers, strings, etc.) and more complex
+ * datatypes that are comprise of built-in datatypes (structs defined in the OPC
+ * UA standard).
+ *
+ * All datatypes follow the same schema in the naming of relevant functions.
+ *
+ * - <type>_init: Sets all values to a "safe" standard. For example, if the
+ *     datatype contains a string-element, its size will be set to zero.
+ *
+ * - <type>_new: Allocates the memory for the type and runs <type>_init on the
+ *     returned pointer.
+ *
+ * - <type>_copy: Copies a datatype. This performs a deep copy that iterates
+ *    over the members.
+ *
+ * - <type>_delete: Frees the memory where the datatype was stored.
+ *
+ * - <type>_deleteMembers: Frees the memory of dynamically sized members (e.g. a
+ *   string) of a datatype. This is useful when the datatype was allocated on
+ *   the stack, whereas the dynamically sized members is heap-allocated.
+ *
+ * @{
+ */
+
+/* Function return values */
+#define UA_SUCCESS 0
+#define UA_NO_ERROR UA_SUCCESS
+#define UA_ERROR (0x01 << 31)
+#define UA_ERR_INCONSISTENT (UA_ERROR | (0x01 << 1))
+#define UA_ERR_INVALID_VALUE (UA_ERROR | (0x01 << 2))
+#define UA_ERR_NO_MEMORY (UA_ERROR | (0x01 << 3))
+#define UA_ERR_NOT_IMPLEMENTED (UA_ERROR | (0x01 << 4))
+
+/* Boolean values and null */
+#define UA_TRUE (42 == 42)
+#define TRUE UA_TRUE
+#define UA_FALSE (!UA_TRUE)
+#define FALSE UA_FALSE
+
+/* Compare values */
+#define UA_EQUAL 0
+#define UA_NOT_EQUAL (!UA_EQUAL)
+
+/** @brief A two-state logical value (true or false). */
+typedef _Bool UA_Boolean;
+
+
+/** @brief An integer value between −128 and 127. */
+typedef int8_t UA_SByte;
+#define UA_SBYTE_MAX -128
+#define UA_SBYTE_MIN 127
+/** @brief An integer value between 0 and 256. */
+typedef uint8_t UA_Byte;
+#define UA_BYTE_MAX 256
+#define UA_BYTE_MIN 0
+/** @brief An integer value between −32 768 and 32 767. */
+typedef int16_t UA_Int16;
+#define UA_INT16_MAX 32767
+#define UA_INT16_MIN -32768
+/** @brief An integer value between 0 and 65 535. */
+typedef uint16_t UA_UInt16;
+#define UA_UINT16_MAX  65535
+#define UA_UINT16_MIN  0
+/** @brief An integer value between −2 147 483 648 and 2 147 483 647. */
+typedef int32_t UA_Int32;
+#define UA_INT32_MAX  2147483647
+#define UA_INT32_MIN  −2147483648
+/** @brief An integer value between 0 and 429 4967 295. */
+typedef uint32_t UA_UInt32;
+#define UA_UINT32_MAX  4294967295;
+#define UA_UINT32_MIN  0;
+/** @brief An integer value between −9 223 372 036 854 775 808 and 9 223 372 036 854 775 807 */
+typedef int64_t UA_Int64;
+#define UA_INT64_MAX  9223372036854775807
+#define UA_INT64_MIN  −9223372036854775808
+/** @brief An integer value between 0 and 18 446 744 073 709 551 615. */
+typedef uint64_t UA_UInt64;
+#define UA_UINT64_MAX = 18446744073709551615
+#define UA_UINT64_MIN = 0
+/** @brief An IEEE single precision (32 bit) floating point value. */
+typedef float UA_Float;
+
+/** @brief An IEEE double precision (64 bit) floating point value. */
+typedef double UA_Double;
+
+/** @brief A sequence of Unicode characters. */
+typedef struct UA_String {
+	UA_Int32 length;
+	UA_Byte *data;
+} UA_String;
+
+/** @brief An instance in time. */
+typedef UA_Int64 UA_DateTime; //100 nanosecond resolution
+
+/** @brief A 16 byte value that can be used as a globally unique identifier. */
+typedef struct UA_Guid {
+	UA_UInt32 data1;
+	UA_UInt16 data2;
+	UA_UInt16 data3;
+	UA_Byte   data4[8];
+} UA_Guid;
+
+/** @brief A sequence of octets. */
+typedef struct UA_String UA_ByteString;
+
+/** @brief An XML element. */
+typedef struct UA_String UA_XmlElement;
+
+/** @brief An identifier for a node in the address space of an OPC UA Server. */
+typedef struct UA_NodeId {
+	UA_Byte encodingByte;       //enum BID_NodeIdEncodingValuesType
+	UA_UInt16 namespace;
+	union {
+		UA_UInt32     numeric;
+		UA_String     string;
+		UA_Guid       guid;
+		UA_ByteString byteString;
+	} identifier;
+} UA_NodeId;
+
+#define NS0NODEID(NUMERIC_ID) \
+	(UA_NodeId){.encodingByte = 0 /*UA_NODEIDTYPE_TWOBYTE*/, .namespace = 0, .identifier.numeric = NUMERIC_ID}
+
+#define UA_NODEIDTYPE_NAMESPACE_URI_FLAG 0x80
+#define UA_NODEIDTYPE_SERVERINDEX_FLAG 0x40
+#define UA_NODEIDTYPE_MASK (~(UA_NODEIDTYPE_NAMESPACE_URI_FLAG | UA_NODEIDTYPE_SERVERINDEX_FLAG))
+
+/** @brief A NodeId that allows the namespace URI to be specified instead of an index. */
+typedef struct UA_ExpandedNodeId {
+	UA_NodeId nodeId;
+	UA_String namespaceUri;
+	UA_UInt32 serverIndex;
+} UA_ExpandedNodeId;
+
+#define NS0EXPANDEDNODEID(NUMERIC_ID) \
+	(UA_ExpandedNodeId){.nodeId = NS0NODEID(NUMERIC_ID), .namespaceUri = {-1, UA_NULL}, .serverIndex = 0}
+
+/** @brief A numeric identifier for a error or condition that is associated with a value or an operation. */
+typedef UA_UInt32 UA_StatusCode; // StatusCodes aren't an enum(=int) since 32 unsigned bits are needed. See also ua_statuscodes.h */
+
+/** @brief A name qualified by a namespace. */
+typedef struct UA_QualifiedName {
+	UA_UInt16 namespaceIndex;
+	UA_String name;
+} UA_QualifiedName;
+
+/** @brief Human readable text with an optional locale identifier. */
+typedef struct UA_LocalizedText {
+	UA_String locale;
+	UA_String text;
+} UA_LocalizedText;
+
+enum UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_enum {
+	UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE = 0x01,
+	UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT   = 0x02
+};
+
+/** @brief A structure that contains an application specific data type that may
+    not be recognized by the receiver. */
+typedef struct UA_ExtensionObject {
+	UA_NodeId     typeId;
+	UA_Byte       encoding;     // Type of the enum UA_ExtensionObjectEncodingMaskType
+	UA_ByteString body;         // contains either the bytestring or a pointer to the memory-object
+} UA_ExtensionObject;
+
+enum UA_ExtensionObject_EncodingMaskType_enum {
+	UA_EXTENSIONOBJECT_ENCODINGMASK_NOBODYISENCODED  = 0x00,
+	UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING = 0x01,
+	UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML        = 0x02
+};
+
+struct UA_VTable_Entry; // forwards declaration
+typedef struct UA_VTable_Entry UA_VTable_Entry;
+
+/** @brief A union of all of the types specified above.
+ *
+ * Variants store (arrays of) built-in types. If you want to store a more
+ * complex (or self-defined) type, you have to use an UA_ExtensionObject.*/
+typedef struct UA_Variant {
+	UA_VTable_Entry *vt;          // internal entry into vTable
+	UA_Int32  arrayLength;        // total number of elements
+	void     *data;
+	UA_Int32  arrayDimensionsLength;
+	UA_Int32 *arrayDimensions;
+} UA_Variant;
+
+/* VariantBinaryEncoding - Part: 6, Chapter: 5.2.2.16, Page: 22 */
+enum UA_VARIANT_ENCODINGMASKTYPE_enum {
+	UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK = 0x3F,            // bits 0:5
+	UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS  = (0x01 << 6),     // bit 6
+	UA_VARIANT_ENCODINGMASKTYPE_ARRAY       = (0x01 << 7)      // bit 7
+};
+
+/** @brief A data value with an associated status code and timestamps. */
+typedef struct UA_DataValue {
+	UA_Byte       encodingMask;
+	UA_Variant    value;
+	UA_StatusCode status;
+	UA_DateTime   sourceTimestamp;
+	UA_Int16      sourcePicoseconds;
+	UA_DateTime   serverTimestamp;
+	UA_Int16      serverPicoseconds;
+} UA_DataValue;
+
+enum UA_DATAVALUE_ENCODINGMASKTYPE_enum {
+	UA_DATAVALUE_ENCODINGMASK_VARIANT           = 0x01,
+	UA_DATAVALUE_ENCODINGMASK_STATUSCODE        = 0x02,
+	UA_DATAVALUE_ENCODINGMASK_SOURCETIMESTAMP   = 0x04,
+	UA_DATAVALUE_ENCODINGMASK_SERVERTIMESTAMP   = 0x08,
+	UA_DATAVALUE_ENCODINGMASK_SOURCEPICOSECONDS = 0x10,
+	UA_DATAVALUE_ENCODINGMASK_SERVERPICOSECONDS = 0x20
+};
+
+/** @brief A structure that contains detailed error and diagnostic information associated with a StatusCode. */
+typedef struct UA_DiagnosticInfo {
+	UA_Byte       encodingMask;     // Type of the Enum UA_DIAGNOSTICINFO_ENCODINGMASKTYPE
+	UA_Int32      symbolicId;
+	UA_Int32      namespaceUri;
+	UA_Int32      localizedText;
+	UA_Int32      locale;
+	UA_String     additionalInfo;
+	UA_StatusCode innerStatusCode;
+	struct UA_DiagnosticInfo *innerDiagnosticInfo;
+} UA_DiagnosticInfo;
+
+enum UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_enum {
+	UA_DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID          = 0x01,
+	UA_DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE           = 0x02,
+	UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT       = 0x04,
+	UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALE              = 0x08,
+	UA_DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO      = 0x10,
+	UA_DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE     = 0x20,
+	UA_DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO = 0x40
+};
+
+/** @brief Type use internally to denote an invalid datatype. */
+typedef void UA_InvalidType;
+
+/*************/
+/* Functions */
+/*************/
+
+#ifdef DEBUG
+#define UA_TYPE_PROTOTYPES(TYPE)             \
+    UA_Int32 TYPE##_new(TYPE **p);           \
+    UA_Int32 TYPE##_init(TYPE * p);          \
+    UA_Int32 TYPE##_delete(TYPE * p);        \
+    UA_Int32 TYPE##_deleteMembers(TYPE * p); \
+    UA_Int32 TYPE##_copy(const TYPE *src, TYPE *dst); \
+	void TYPE##_print(const TYPE *p, FILE *stream);
+#else
+#define UA_TYPE_PROTOTYPES(TYPE)             \
+    UA_Int32 TYPE##_new(TYPE **p);           \
+    UA_Int32 TYPE##_init(TYPE * p);          \
+    UA_Int32 TYPE##_delete(TYPE * p);        \
+    UA_Int32 TYPE##_deleteMembers(TYPE * p); \
+    UA_Int32 TYPE##_copy(const TYPE *src, TYPE *dst);
+#endif
+
+/* Functions for all types */
+UA_TYPE_PROTOTYPES(UA_Boolean)
+UA_TYPE_PROTOTYPES(UA_SByte)
+UA_TYPE_PROTOTYPES(UA_Byte)
+UA_TYPE_PROTOTYPES(UA_Int16)
+UA_TYPE_PROTOTYPES(UA_UInt16)
+UA_TYPE_PROTOTYPES(UA_Int32)
+UA_TYPE_PROTOTYPES(UA_UInt32)
+UA_TYPE_PROTOTYPES(UA_Int64)
+UA_TYPE_PROTOTYPES(UA_UInt64)
+UA_TYPE_PROTOTYPES(UA_Float)
+UA_TYPE_PROTOTYPES(UA_Double)
+UA_TYPE_PROTOTYPES(UA_String)
+UA_TYPE_PROTOTYPES(UA_DateTime)
+UA_TYPE_PROTOTYPES(UA_Guid)
+UA_TYPE_PROTOTYPES(UA_ByteString)
+UA_TYPE_PROTOTYPES(UA_XmlElement)
+UA_TYPE_PROTOTYPES(UA_NodeId)
+UA_TYPE_PROTOTYPES(UA_ExpandedNodeId)
+UA_TYPE_PROTOTYPES(UA_StatusCode)
+UA_TYPE_PROTOTYPES(UA_QualifiedName)
+UA_TYPE_PROTOTYPES(UA_LocalizedText)
+UA_TYPE_PROTOTYPES(UA_ExtensionObject)
+UA_TYPE_PROTOTYPES(UA_DataValue)
+UA_TYPE_PROTOTYPES(UA_Variant)
+UA_TYPE_PROTOTYPES(UA_DiagnosticInfo)
+UA_TYPE_PROTOTYPES(UA_InvalidType)
+
+/* String */
+#define UA_STRING_NULL (UA_String){-1, UA_NULL}
+#define UA_STRING_STATIC(STRING) (UA_String){sizeof(STRING)-1, (UA_Byte*)STRING}
+
+UA_Int32 UA_String_copycstring(char const *src, UA_String *dst);
+UA_Int32 UA_String_copyprintf(char const *fmt, UA_String *dst, ...);
+UA_Int32 UA_String_equal(const UA_String *string1, const UA_String *string2);
+#ifdef DEBUG
+void UA_String_printf(char const *label, const UA_String *string);
+void UA_String_printx(char const *label, const UA_String *string);
+void UA_String_printx_hex(char const *label, const UA_String *string);
+#endif
+
+/* DateTime */
+UA_DateTime UA_DateTime_now();
+typedef struct UA_DateTimeStruct {
+	UA_Int16 nanoSec;
+	UA_Int16 microSec;
+	UA_Int16 milliSec;
+	UA_Int16 sec;
+	UA_Int16 min;
+	UA_Int16 hour;
+	UA_Int16 day;
+	UA_Int16 mounth;
+	UA_Int16 year;
+} UA_DateTimeStruct;
+UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time);
+UA_Int32 UA_DateTime_toString(UA_DateTime time, UA_String *timeString);
+
+/* Guid */
+UA_Int32 UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
+
+/* ByteString */
+UA_Int32 UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2);
+UA_Int32 UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length);
+#ifdef DEBUG
+void UA_ByteString_printf(char *label, const UA_ByteString *string);
+void UA_ByteString_printx(char *label, const UA_ByteString *string);
+void UA_ByteString_printx_hex(char *label, const UA_ByteString *string);
+#endif
+
+/* NodeId */
+UA_Int32 UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2);
+#ifdef DEBUG
+void UA_NodeId_printf(char *label, const UA_NodeId *node);
+#endif
+UA_Boolean UA_NodeId_isNull(const UA_NodeId *p);
+UA_Boolean UA_NodeId_isBasicType(UA_NodeId const *id);
+
+/* ExpandedNodeId */
+UA_Boolean UA_ExpandedNodeId_isNull(const UA_ExpandedNodeId *p);
+
+/* QualifiedName */
+#define UA_QUALIFIEDNAME_STATIC(STRING) \
+	(UA_QualifiedName){0, {sizeof(STRING)-1, (UA_Byte*)STRING}}
+#ifdef DEBUG
+void UA_QualifiedName_printf(char const *label, const UA_QualifiedName *qn);
+#endif
+
+/* LocalizedText */
+#define UA_LOCALIZEDTEXT_STATIC(STRING) (UA_LocalizedText){{2, (UA_Byte*)"en"}, UA_STRING_STATIC(STRING)}
+UA_Int32 UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst);
+
+/* Variant */
+UA_Int32 UA_Variant_copySetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value);
+UA_Int32 UA_Variant_copySetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array);
+
+/** @brief Functions UA_Variant_borrowSetValue and ..Array allow to define
+   variants whose payload will not be deleted. This is achieved by a second
+   vtable. The functionality can be used e.g. when UA_VariableNodes point into a
+   "father" structured object that is stored in an UA_VariableNode itself. */
+UA_Int32 UA_Variant_borrowSetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value);
+UA_Int32 UA_Variant_borrowSetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength,
+                                   const void *array);
+
+/* Array operations */
+UA_Int32 UA_Array_new(void **p, UA_Int32 noElements, UA_VTable_Entry *vt);
+UA_Int32 UA_Array_init(void *p, UA_Int32 noElements, UA_VTable_Entry *vt);
+UA_Int32 UA_Array_delete(void *p, UA_Int32 noElements, UA_VTable_Entry *vt);
+
+/* @brief The destination array is allocated according to noElements. */
+UA_Int32 UA_Array_copy(const void *src, UA_Int32 noElements, UA_VTable_Entry *vt, void **dst);
+#ifdef DEBUG
+void UA_Array_print(const void *p, UA_Int32 noElements, UA_VTable_Entry *vt, FILE *stream);
+#endif
+
+/**********/
+/* VTable */
+/**********/
+
+/* @brief Returns the size of the encoded element.*/
+typedef UA_Int32 (*UA_calcSize)(const void *p);
+
+/* @brief The encoding function allocates the target bytestring. */
+typedef UA_Int32 (*UA_encode)(const void *src, UA_ByteString *dst, UA_UInt32 *offset);
+
+/* @brief The decoding function decodes a ByteString into an UA datatype. */
+typedef UA_Int32 (*UA_decode)(const UA_ByteString *src, UA_UInt32 *offset, void *dst);
+
+typedef struct UA_Encoding {
+	UA_calcSize calcSize;
+	UA_encode   encode;
+	UA_decode   decode;
+} UA_Encoding;
+
+#define UA_ENCODING_BINARY 0
+#define UA_ENCODING_XML 1
+
+struct UA_VTable_Entry {
+	UA_NodeId  typeId;
+	UA_Byte   *name;
+	UA_Int32   (*new)(void **p);
+	UA_Int32   (*init)(void *p);
+	UA_Int32   (*copy)(void const *src, void *dst);
+	UA_Int32   (*delete)(void *p);
+	UA_Int32   (*deleteMembers)(void *p);
+#ifdef DEBUG
+	void       (*print)(const void *p, FILE *stream);
+#endif
+	UA_UInt32  memSize;       // size of the struct only in memory (no dynamic components)
+	UA_Boolean dynMembers;    // does the type contain members that are dynamically
+	                          // allocated (strings, ..)? Otherwise, the size on
+	                          // the wire == size in memory.
+	UA_Encoding encodings[2]; // binary, xml, ...
+};
+
+typedef UA_Int32 (*UA_nodeIdToVTableIndex)(const UA_NodeId *id);
+typedef struct UA_VTable {
+	UA_nodeIdToVTableIndex getTypeIndex;
+	UA_VTable_Entry       *types;
+} UA_VTable;
+
+/***********************************/
+/* Macros for type implementations */
+/***********************************/
+
+#define UA_TYPE_DEFAULT(TYPE)            \
+    UA_TYPE_DELETE_DEFAULT(TYPE)         \
+    UA_TYPE_DELETEMEMBERS_NOACTION(TYPE) \
+    UA_TYPE_INIT_DEFAULT(TYPE)           \
+    UA_TYPE_NEW_DEFAULT(TYPE)            \
+    UA_TYPE_COPY_DEFAULT(TYPE)           \
+
+#define UA_TYPE_NEW_DEFAULT(TYPE)                     \
+    UA_Int32 TYPE##_new(TYPE **p) {                   \
+		UA_Int32 retval = UA_SUCCESS;                 \
+		retval |= UA_alloc((void **)p, sizeof(TYPE)); \
+		retval |= TYPE##_init(*p);                    \
+		return retval;                                \
+	}
+
+#define UA_TYPE_INIT_DEFAULT(TYPE)         \
+    UA_Int32 TYPE##_init(TYPE * p) {       \
+		if(p == UA_NULL) return UA_ERROR;  \
+		*p = (TYPE)0;                      \
+		return UA_SUCCESS;                 \
+	}
+
+#define UA_TYPE_INIT_AS(TYPE, TYPE_AS)       \
+    UA_Int32 TYPE##_init(TYPE * p) {         \
+		return TYPE_AS##_init((TYPE_AS *)p); \
+	}
+
+#define UA_TYPE_DELETE_DEFAULT(TYPE)       \
+    UA_Int32 TYPE##_delete(TYPE *p) {      \
+		UA_Int32 retval = UA_SUCCESS;      \
+		retval |= TYPE##_deleteMembers(p); \
+		retval |= UA_free(p);              \
+		return retval;                     \
+	}
+
+#define UA_TYPE_DELETE_AS(TYPE, TYPE_AS) \
+    UA_Int32 TYPE##_delete(TYPE * p) { return TYPE_AS##_delete((TYPE_AS *)p); }
+
+#define UA_TYPE_DELETEMEMBERS_NOACTION(TYPE) \
+    UA_Int32 TYPE##_deleteMembers(TYPE * p) { return UA_SUCCESS; }
+
+#define UA_TYPE_DELETEMEMBERS_AS(TYPE, TYPE_AS) \
+    UA_Int32 TYPE##_deleteMembers(TYPE * p) { return TYPE_AS##_deleteMembers((TYPE_AS *)p); }
+
+/* Use only when the type has no arrays. Otherwise, implement deep copy */
+#define UA_TYPE_COPY_DEFAULT(TYPE)                             \
+    UA_Int32 TYPE##_copy(TYPE const *src, TYPE *dst) {         \
+		if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;  \
+		UA_Int32 retval = UA_SUCCESS;                          \
+		retval |= UA_memcpy(dst, src, sizeof(TYPE));           \
+		return retval;                                         \
+	}
+
+#define UA_TYPE_COPY_AS(TYPE, TYPE_AS)                         \
+    UA_Int32 TYPE##_copy(TYPE const *src, TYPE *dst) {         \
+		return TYPE_AS##_copy((TYPE_AS *)src, (TYPE_AS *)dst); \
+	}
+
+#define UA_TYPE_PRINT_AS(TYPE, TYPE_AS)                        \
+    void TYPE##_print(TYPE const *p, FILE *stream) {		   \
+		TYPE_AS##_print((TYPE_AS *)p, stream);				   \
+	}														   \
+
+#ifdef DEBUG //print functions only in debug mode
+#define UA_TYPE_AS(TYPE, TYPE_AS)           \
+    UA_TYPE_NEW_DEFAULT(TYPE)               \
+    UA_TYPE_INIT_AS(TYPE, TYPE_AS)          \
+    UA_TYPE_DELETE_AS(TYPE, TYPE_AS)        \
+    UA_TYPE_DELETEMEMBERS_AS(TYPE, TYPE_AS) \
+    UA_TYPE_COPY_AS(TYPE, TYPE_AS)			\
+	UA_TYPE_PRINT_AS(TYPE, TYPE_AS)
+#else
+#define UA_TYPE_AS(TYPE, TYPE_AS)           \
+    UA_TYPE_NEW_DEFAULT(TYPE)               \
+    UA_TYPE_INIT_AS(TYPE, TYPE_AS)          \
+    UA_TYPE_DELETE_AS(TYPE, TYPE_AS)        \
+    UA_TYPE_DELETEMEMBERS_AS(TYPE, TYPE_AS) \
+    UA_TYPE_COPY_AS(TYPE, TYPE_AS)
+#endif
+
+/// @} /* end of group */
+
+#endif /* UA_TYPES_H_ */

+ 987 - 0
src/ua_types_encoding_binary.c

@@ -0,0 +1,987 @@
+#include "ua_types_encoding_binary.h"
+#include "ua_namespace_0.h"
+
+static inline UA_Boolean is_builtin(UA_NodeId *typeid) {
+	return (typeid->namespace == 0 && 1 <= typeid->identifier.numeric && typeid->identifier.numeric <= 25);
+}
+
+/*********/
+/* Array */
+/*********/
+
+UA_Int32 UA_Array_calcSizeBinary(UA_Int32 nElements, UA_VTable_Entry *vt, const void *data) {
+	if(vt == UA_NULL){
+		return 0; // do not return error as the result will be used to allocate memory
+	}
+	if(data == UA_NULL){ //NULL Arrays are encoded as length = -1
+		return sizeof(UA_Int32);
+	}
+	UA_Int32  length     = sizeof(UA_Int32);
+	UA_UInt32 memSize    = vt->memSize;
+	const UA_Byte *cdata = (const UA_Byte *)data;
+	for(UA_Int32 i = 0;i < nElements;i++) {
+		length += vt->encodings[UA_ENCODING_BINARY].calcSize(cdata);
+		cdata  += memSize;
+	}
+	return length;
+}
+
+static UA_Int32 UA_Array_calcSizeBinary_asExtensionObject(UA_Int32 nElements, UA_VTable_Entry *vt,
+														   const void *data) {
+	if(vt == UA_NULL){
+		return 0; // do not return error as the result will be used to allocate memory
+	}
+	if(data == UA_NULL){ //NULL Arrays are encoded as length = -1
+		return sizeof(UA_Int32);
+	}
+	UA_Int32  length     = sizeof(UA_Int32);
+	UA_UInt32 memSize    = vt->memSize;
+	UA_Boolean isBuiltin = is_builtin(&vt->typeId);
+	const UA_Byte *cdata = (const UA_Byte *)data;
+	for(UA_Int32 i = 0;i < nElements;i++) {
+		length += vt->encodings[UA_ENCODING_BINARY].calcSize(cdata);
+		cdata  += memSize;
+	}
+	if(isBuiltin)
+		length += 9*nElements; // extensionobject header for each element
+	return length;
+}
+
+UA_Int32 UA_Array_encodeBinary(const void *src, UA_Int32 noElements, UA_VTable_Entry *vt, UA_ByteString *dst,
+                               UA_UInt32 *offset) {
+	if(vt == UA_NULL || dst == UA_NULL || offset == UA_NULL || ((src == UA_NULL) && (noElements > 0)))
+		return UA_ERROR;
+
+	//Null Arrays are encoded with length = -1 // part 6 - §5.24
+	if(noElements < -1) noElements = -1;
+
+	UA_Int32 retval     = UA_SUCCESS;
+	retval = UA_Int32_encodeBinary(&noElements, dst, offset);
+	const UA_Byte *csrc = (const UA_Byte *)src;
+	UA_UInt32 memSize   = vt->memSize;
+	for(UA_Int32 i = 0;i < noElements && retval == UA_SUCCESS;i++) {
+		retval |= vt->encodings[UA_ENCODING_BINARY].encode(csrc, dst, offset);
+		csrc   += memSize;
+	}
+	return retval;
+}
+
+static UA_Int32 UA_Array_encodeBinary_asExtensionObject(const void *src, UA_Int32 noElements, UA_VTable_Entry *vt,
+														UA_ByteString *dst, UA_UInt32 *offset) {
+	if(vt == UA_NULL || dst == UA_NULL || offset == UA_NULL || (src == UA_NULL && noElements > 0))
+		return UA_ERROR;
+
+	//Null Arrays are encoded with length = -1 // part 6 - §5.24
+	if(noElements < -1) noElements = -1;
+
+	UA_Int32 retval     = UA_SUCCESS;
+	retval = UA_Int32_encodeBinary(&noElements, dst, offset);
+	const UA_Byte *csrc = (const UA_Byte *)src;
+	UA_UInt32 memSize   = vt->memSize;
+	UA_Boolean isBuiltin = is_builtin(&vt->typeId);
+	for(UA_Int32 i = 0;i < noElements && retval == UA_SUCCESS;i++) {
+		if(!isBuiltin) {
+			// print the extensionobject header
+			UA_NodeId_encodeBinary(&vt->typeId, dst, offset);
+			UA_Byte eoEncoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
+			UA_Byte_encodeBinary(&eoEncoding, dst, offset);
+			UA_Int32 eoEncodingLength = vt->encodings[UA_ENCODING_BINARY].calcSize(csrc);
+			UA_Int32_encodeBinary(&eoEncodingLength, dst, offset);
+		}
+		retval |= vt->encodings[UA_ENCODING_BINARY].encode(csrc, dst, offset);
+		csrc   += memSize;
+	}
+	return retval;
+}
+
+UA_Int32 UA_Array_decodeBinary(const UA_ByteString *src, UA_UInt32 *offset, UA_Int32 noElements, UA_VTable_Entry *vt,
+                               void **dst) {
+	if(vt == UA_NULL || src == UA_NULL || dst == UA_NULL || offset == UA_NULL)
+		return UA_ERROR;
+
+	UA_Int32 retval = UA_SUCCESS;
+	if(noElements <= 0) {
+		*dst = UA_NULL;
+		return retval;
+	}
+	retval |= UA_Array_new(dst, noElements, vt);
+
+	UA_Byte  *arr     = (UA_Byte *)*dst;
+	UA_Int32  i       = 0;
+	UA_UInt32 memSize = vt->memSize;
+	for(;i < noElements && retval == UA_SUCCESS;i++) {
+		retval |= vt->encodings[UA_ENCODING_BINARY].decode(src, offset, arr);
+		arr    += memSize;
+	}
+
+	/* If dynamically sized elements have already been decoded into the array. */
+	if(retval != UA_SUCCESS) {
+		i--; // undo last increase
+		UA_Array_delete(*dst, i, vt);
+		*dst = UA_NULL;
+	}
+
+	return retval;
+}
+
+/************/
+/* Built-In */
+/************/
+
+#define UA_TYPE_CALCSIZEBINARY_SIZEOF(TYPE) \
+    UA_Int32 TYPE##_calcSizeBinary(TYPE const *p) { return sizeof(TYPE); }
+
+#define UA_TYPE_ENCODEBINARY(TYPE, CODE)                                                    \
+    UA_Int32 TYPE##_encodeBinary(TYPE const *src, UA_ByteString * dst, UA_UInt32 *offset) { \
+		UA_Int32 retval = UA_SUCCESS;                                                       \
+		if((UA_Int32)(*offset + TYPE##_calcSizeBinary(src)) > dst->length ) {               \
+			return UA_ERR_INVALID_VALUE;                                                    \
+		} else {                                                                            \
+			CODE                                                                            \
+		}                                                                                   \
+		return retval;                                                                      \
+	}
+
+// Attention! this macro works only for TYPEs with memSize = encodingSize
+#define UA_TYPE_DECODEBINARY(TYPE, CODE)                                                    \
+    UA_Int32 TYPE##_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, TYPE * dst) { \
+		UA_Int32 retval = UA_SUCCESS;                                                       \
+		if((UA_Int32)(*offset + TYPE##_calcSizeBinary(UA_NULL)) > src->length ) {           \
+			return UA_ERR_INVALID_VALUE;                                                    \
+		} else {                                                                            \
+			CODE                                                                            \
+		}                                                                                   \
+		return retval;                                                                      \
+	}
+
+/* Boolean */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Boolean)
+UA_TYPE_ENCODEBINARY(UA_Boolean,
+                     UA_Boolean tmpBool = ((*src > 0) ? UA_TRUE : UA_FALSE);
+                     memcpy(&dst->data[(*offset)++], &tmpBool, sizeof(UA_Boolean)); )
+UA_TYPE_DECODEBINARY(UA_Boolean, *dst = ((UA_Boolean)(src->data[(*offset)++]) > (UA_Byte)0) ? UA_TRUE : UA_FALSE; )
+
+/* SByte */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_SByte)
+UA_TYPE_ENCODEBINARY(UA_SByte, dst->data[(*offset)++] = *src; )
+UA_TYPE_DECODEBINARY(UA_SByte, *dst = src->data[(*offset)++]; )
+
+/* Byte */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Byte)
+UA_TYPE_ENCODEBINARY(UA_Byte, dst->data[(*offset)++] = *src; )
+UA_TYPE_DECODEBINARY(UA_Byte, *dst = src->data[(*offset)++]; )
+
+/* Int16 */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Int16)
+UA_TYPE_ENCODEBINARY(UA_Int16, retval = UA_UInt16_encodeBinary((UA_UInt16 const *)src, dst, offset); )
+UA_TYPE_DECODEBINARY(UA_Int16,
+                     *dst  = (UA_Int16)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 0);
+                     *dst |= (UA_Int16)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 8); )
+
+/* UInt16 */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_UInt16)
+UA_TYPE_ENCODEBINARY(UA_UInt16,
+                     dst->data[(*offset)++] = (*src & 0x00FF) >> 0;
+                     dst->data[(*offset)++] = (*src & 0xFF00) >> 8; )
+UA_TYPE_DECODEBINARY(UA_UInt16,
+                     *dst =  (UA_UInt16)src->data[(*offset)++] << 0;
+                     *dst |= (UA_UInt16)src->data[(*offset)++] << 8; )
+
+/* Int32 */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Int32)
+UA_TYPE_ENCODEBINARY(UA_Int32,
+                     dst->data[(*offset)++] = (*src & 0x000000FF) >> 0;
+                     dst->data[(*offset)++] = (*src & 0x0000FF00) >> 8;
+                     dst->data[(*offset)++] = (*src & 0x00FF0000) >> 16;
+                     dst->data[(*offset)++] = (*src & 0xFF000000) >> 24; )
+UA_TYPE_DECODEBINARY(UA_Int32,
+                     *dst  = (UA_Int32)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 0);
+                     *dst |= (UA_Int32)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 8);
+                     *dst |= (UA_Int32)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 16);
+                     *dst |= (UA_Int32)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 24); )
+
+/* UInt32 */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_UInt32)
+UA_TYPE_ENCODEBINARY(UA_UInt32, retval = UA_Int32_encodeBinary((UA_Int32 const *)src, dst, offset); )
+UA_TYPE_DECODEBINARY(UA_UInt32,
+                     UA_UInt32 t1 = (UA_UInt32)((UA_Byte)(src->data[(*offset)++] & 0xFF));
+                     UA_UInt32 t2 = (UA_UInt32)((UA_Byte)(src->data[(*offset)++]& 0xFF) << 8);
+                     UA_UInt32 t3 = (UA_UInt32)((UA_Byte)(src->data[(*offset)++]& 0xFF) << 16);
+                     UA_UInt32 t4 = (UA_UInt32)((UA_Byte)(src->data[(*offset)++]& 0xFF) << 24);
+                     *dst = t1 + t2 + t3 + t4; )
+
+/* Int64 */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Int64)
+UA_TYPE_ENCODEBINARY(UA_Int64,
+                     dst->data[(*offset)++] = (*src & 0x00000000000000FF) >> 0;
+                     dst->data[(*offset)++] = (*src & 0x000000000000FF00) >> 8;
+                     dst->data[(*offset)++] = (*src & 0x0000000000FF0000) >> 16;
+                     dst->data[(*offset)++] = (*src & 0x00000000FF000000) >> 24;
+                     dst->data[(*offset)++] = (*src & 0x000000FF00000000) >> 32;
+                     dst->data[(*offset)++] = (*src & 0x0000FF0000000000) >> 40;
+                     dst->data[(*offset)++] = (*src & 0x00FF000000000000) >> 48;
+                     dst->data[(*offset)++] = (*src & 0xFF00000000000000) >> 56; )
+UA_TYPE_DECODEBINARY(UA_Int64,
+                     *dst  = (UA_Int64)src->data[(*offset)++] << 0;
+                     *dst |= (UA_Int64)src->data[(*offset)++] << 8;
+                     *dst |= (UA_Int64)src->data[(*offset)++] << 16;
+                     *dst |= (UA_Int64)src->data[(*offset)++] << 24;
+                     *dst |= (UA_Int64)src->data[(*offset)++] << 32;
+                     *dst |= (UA_Int64)src->data[(*offset)++] << 40;
+                     *dst |= (UA_Int64)src->data[(*offset)++] << 48;
+                     *dst |= (UA_Int64)src->data[(*offset)++] << 56; )
+
+/* UInt64 */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_UInt64)
+UA_TYPE_ENCODEBINARY(UA_UInt64, return UA_Int64_encodeBinary((UA_Int64 const *)src, dst, offset); )
+UA_TYPE_DECODEBINARY(UA_UInt64,
+                     UA_UInt64 t1 = (UA_UInt64)src->data[(*offset)++];
+                     UA_UInt64 t2 = (UA_UInt64)src->data[(*offset)++] << 8;
+                     UA_UInt64 t3 = (UA_UInt64)src->data[(*offset)++] << 16;
+                     UA_UInt64 t4 = (UA_UInt64)src->data[(*offset)++] << 24;
+                     UA_UInt64 t5 = (UA_UInt64)src->data[(*offset)++] << 32;
+                     UA_UInt64 t6 = (UA_UInt64)src->data[(*offset)++] << 40;
+                     UA_UInt64 t7 = (UA_UInt64)src->data[(*offset)++] << 48;
+                     UA_UInt64 t8 = (UA_UInt64)src->data[(*offset)++] << 56;
+                     *dst = t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8; )
+
+/* Float */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Float)
+// FIXME: Implement NaN, Inf and Zero(s)
+UA_Byte UA_FLOAT_ZERO[] = { 0x00, 0x00, 0x00, 0x00 };
+UA_TYPE_DECODEBINARY(UA_Float,
+                     if(memcmp(&src->data[*offset], UA_FLOAT_ZERO,
+                               4) == 0) return UA_Int32_decodeBinary(src, offset, (UA_Int32 *)dst); UA_Float mantissa;
+                     mantissa = (UA_Float)(src->data[*offset] & 0xFF);                         // bits 0-7
+                     mantissa = (mantissa / 256.0 ) + (UA_Float)(src->data[*offset+1] & 0xFF); // bits 8-15
+                     mantissa = (mantissa / 256.0 ) + (UA_Float)(src->data[*offset+2] & 0x7F); // bits 16-22
+                     UA_UInt32 biasedExponent;
+                     biasedExponent  = (src->data[*offset+2] & 0x80) >>  7;                   // bits 23
+                     biasedExponent |= (src->data[*offset+3] & 0x7F) <<  1;                   // bits 24-30
+                     UA_Float sign = ( src->data[*offset+ 3] & 0x80 ) ? -1.0 : 1.0;           // bit 31
+                     if(biasedExponent >= 127)
+						 *dst = (UA_Float)sign * (1 << (biasedExponent-127)) * (1.0 + mantissa / 128.0 );
+                     else
+						 *dst = (UA_Float)sign * 2.0 * (1.0 + mantissa / 128.0 ) / ((UA_Float)(biasedExponent-127));
+                     *offset += 4; )
+UA_TYPE_ENCODEBINARY(UA_Float, return UA_UInt32_encodeBinary((UA_UInt32 *)src, dst, offset); )
+
+/* Double */
+UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Double)
+// FIXME: Implement NaN, Inf and Zero(s)
+UA_Byte UA_DOUBLE_ZERO[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+UA_TYPE_DECODEBINARY(UA_Double,
+                     if(memcmp(&src->data[*offset], UA_DOUBLE_ZERO,
+                               8) == 0) return UA_Int64_decodeBinary(src, offset, (UA_Int64 *)dst); UA_Double mantissa;
+                     mantissa = (UA_Double)(src->data[*offset] & 0xFF);                         // bits 0-7
+                     mantissa = (mantissa / 256.0 ) + (UA_Double)(src->data[*offset+1] & 0xFF); // bits 8-15
+                     mantissa = (mantissa / 256.0 ) + (UA_Double)(src->data[*offset+2] & 0xFF); // bits 16-23
+                     mantissa = (mantissa / 256.0 ) + (UA_Double)(src->data[*offset+3] & 0xFF); // bits 24-31
+                     mantissa = (mantissa / 256.0 ) + (UA_Double)(src->data[*offset+4] & 0xFF); // bits 32-39
+                     mantissa = (mantissa / 256.0 ) + (UA_Double)(src->data[*offset+5] & 0xFF); // bits 40-47
+                     mantissa = (mantissa / 256.0 ) + (UA_Double)(src->data[*offset+6] & 0x0F); // bits 48-51
+                     DBG_VERBOSE(printf("UA_Double_decodeBinary - mantissa=%f\n", mantissa));
+                     UA_UInt32 biasedExponent;
+                     biasedExponent  = (src->data[*offset+6] & 0xF0) >>  4; // bits 52-55
+                     DBG_VERBOSE(printf("UA_Double_decodeBinary - biasedExponent52-55=%d, src=%d\n", biasedExponent,
+                                        src->data[*offset+6]));
+                     biasedExponent |= ((UA_UInt32)(src->data[*offset+7] & 0x7F)) <<  4; // bits 56-62
+                     DBG_VERBOSE(printf("UA_Double_decodeBinary - biasedExponent56-62=%d, src=%d\n", biasedExponent,
+                                        src->data[*offset+7]));
+                     UA_Double sign = ( src->data[*offset+7] & 0x80 ) ? -1.0 : 1.0; // bit 63
+                     if(biasedExponent >= 1023)
+						 *dst = (UA_Double)sign * (1 << (biasedExponent-1023)) * (1.0 + mantissa / 8.0 );
+                     else
+						 *dst = (UA_Double)sign * 2.0 * (1.0 + mantissa / 8.0 ) / ((UA_Double)(biasedExponent-1023));
+                     *offset += 8; )
+UA_TYPE_ENCODEBINARY(UA_Double, return UA_UInt64_encodeBinary((UA_UInt64 *)src, dst, offset); )
+
+/* String */
+UA_Int32 UA_String_calcSizeBinary(UA_String const *string) {
+	if(string == UA_NULL) // internal size for UA_memalloc
+		return sizeof(UA_String);
+	else {                // binary encoding size
+		if(string->length > 0)
+			return sizeof(UA_Int32) + string->length * sizeof(UA_Byte);
+		else
+			return sizeof(UA_Int32);
+	}
+}
+UA_Int32 UA_String_encodeBinary(UA_String const *src, UA_ByteString *dst, UA_UInt32 *offset) {
+	UA_Int32 retval = UA_SUCCESS;
+	if(src == UA_NULL) return UA_ERR_INVALID_VALUE;
+	if((UA_Int32)(*offset+ UA_String_calcSizeBinary(src)) > dst->length) return UA_ERR_INVALID_VALUE;
+	retval |= UA_Int32_encodeBinary(&src->length, dst, offset);
+	if(src->length > 0) {
+		retval  |= UA_memcpy(&dst->data[*offset], src->data, src->length);
+		*offset += src->length;
+	}
+	return retval;
+}
+UA_Int32 UA_String_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_String *dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_String_init(dst);
+	retval |= UA_Int32_decodeBinary(src, offset, &dst->length);
+	if(dst->length > (UA_Int32)(src->length - *offset))
+		retval = UA_ERR_INVALID_VALUE;
+	if(retval != UA_SUCCESS || dst->length <= 0) {
+		dst->length = -1;
+		dst->data   = UA_NULL;
+	} else {
+		CHECKED_DECODE(UA_alloc((void **)&dst->data, dst->length), dst->length = -1);
+		CHECKED_DECODE(UA_memcpy(dst->data, &src->data[*offset], dst->length), UA_free(
+		                   dst->data); dst->data = UA_NULL; dst->length = -1);
+		*offset += dst->length;
+	}
+	return retval;
+}
+
+/* DateTime */
+UA_TYPE_BINARY_ENCODING_AS(UA_DateTime, UA_Int64)
+
+/* Guid */
+UA_Int32 UA_Guid_calcSizeBinary(UA_Guid const *p) {
+	if(p == UA_NULL)
+		return sizeof(UA_Guid);
+	else
+		return 16;
+}
+
+UA_TYPE_ENCODEBINARY(UA_Guid,
+                     CHECKED_DECODE(UA_UInt32_encodeBinary(&src->data1, dst, offset),; );
+                     CHECKED_DECODE(UA_UInt16_encodeBinary(&src->data2, dst, offset),; );
+                     CHECKED_DECODE(UA_UInt16_encodeBinary(&src->data3, dst, offset),; );
+                     for(UA_Int32 i = 0;i < 8;i++)
+						 CHECKED_DECODE(UA_Byte_encodeBinary(&src->data4[i], dst, offset),; ); )
+
+UA_TYPE_DECODEBINARY(UA_Guid,
+                     // TODO: This could be done with a single memcpy (if the compiler does no fancy realigning of structs)
+                     CHECKED_DECODE(UA_UInt32_decodeBinary(src, offset, &dst->data1),; );
+                     CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dst->data2),; );
+                     CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dst->data3),; );
+                     for(UA_Int32 i = 0;i < 8;i++)
+						 CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &dst->data4[i]),; ); )
+
+/* ByteString */
+UA_TYPE_BINARY_ENCODING_AS(UA_ByteString, UA_String)
+
+/* XmlElement */
+UA_TYPE_BINARY_ENCODING_AS(UA_XmlElement, UA_String)
+
+/* NodeId */
+UA_Int32 UA_NodeId_calcSizeBinary(UA_NodeId const *p) {
+	UA_Int32 length = 0;
+	if(p == UA_NULL)
+		length = sizeof(UA_NodeId);
+	else {
+		switch(p->encodingByte & UA_NODEIDTYPE_MASK) {
+		case UA_NODEIDTYPE_TWOBYTE:
+			length = 2;
+			break;
+
+		case UA_NODEIDTYPE_FOURBYTE:
+			length = 4;
+			break;
+
+		case UA_NODEIDTYPE_NUMERIC:
+			length += sizeof(UA_Byte) + sizeof(UA_UInt16) + sizeof(UA_UInt32);
+			break;
+
+		case UA_NODEIDTYPE_STRING:
+			length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_String_calcSizeBinary(&p->identifier.string);
+			break;
+
+		case UA_NODEIDTYPE_GUID:
+			length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_Guid_calcSizeBinary(&p->identifier.guid);
+			break;
+
+		case UA_NODEIDTYPE_BYTESTRING:
+			length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_ByteString_calcSizeBinary(&p->identifier.byteString);
+			break;
+
+		default:
+			break;
+		}
+	}
+	return length;
+}
+
+UA_TYPE_ENCODEBINARY(UA_NodeId,
+                     // temporary variables for endian-save code
+                     UA_Byte srcByte;
+                     UA_UInt16 srcUInt16;
+
+                     UA_Int32 retval = UA_SUCCESS;
+                     retval |= UA_Byte_encodeBinary(&src->encodingByte, dst, offset);
+                     switch(src->encodingByte & UA_NODEIDTYPE_MASK) {
+					 case UA_NODEIDTYPE_TWOBYTE:
+						 srcByte = src->identifier.numeric;
+						 retval |= UA_Byte_encodeBinary(&srcByte, dst, offset);
+						 break;
+
+					 case UA_NODEIDTYPE_FOURBYTE:
+						 srcByte = src->namespace;
+						 srcUInt16 = src->identifier.numeric;
+						 retval |= UA_Byte_encodeBinary(&srcByte, dst, offset);
+						 retval |= UA_UInt16_encodeBinary(&srcUInt16, dst, offset);
+						 break;
+
+					 case UA_NODEIDTYPE_NUMERIC:
+						 retval |= UA_UInt16_encodeBinary(&src->namespace, dst, offset);
+						 retval |= UA_UInt32_encodeBinary(&src->identifier.numeric, dst, offset);
+						 break;
+
+					 case UA_NODEIDTYPE_STRING:
+						 retval |= UA_UInt16_encodeBinary(&src->namespace, dst, offset);
+						 retval |= UA_String_encodeBinary(&src->identifier.string, dst, offset);
+						 break;
+
+					 case UA_NODEIDTYPE_GUID:
+						 retval |= UA_UInt16_encodeBinary(&src->namespace, dst, offset);
+						 retval |= UA_Guid_encodeBinary(&src->identifier.guid, dst, offset);
+						 break;
+
+					 case UA_NODEIDTYPE_BYTESTRING:
+						 retval |= UA_UInt16_encodeBinary(&src->namespace, dst, offset);
+						 retval |= UA_ByteString_encodeBinary(&src->identifier.byteString, dst, offset);
+						 break;
+					 }
+                     )
+
+UA_Int32 UA_NodeId_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_NodeId *dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_NodeId_init(dst);
+	// temporary variables to overcome decoder's non-endian-saveness for datatypes with different length
+	UA_Byte   dstByte   = 0;
+	UA_UInt16 dstUInt16 = 0;
+
+	CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &dst->encodingByte),; );
+	switch(dst->encodingByte & UA_NODEIDTYPE_MASK) {
+	case UA_NODEIDTYPE_TWOBYTE: // Table 7
+		CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &dstByte),; );
+		dst->identifier.numeric = dstByte;
+		dst->namespace = 0; // default namespace
+		break;
+
+	case UA_NODEIDTYPE_FOURBYTE: // Table 8
+		CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &dstByte),; );
+		dst->namespace = dstByte;
+		CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dstUInt16),; );
+		dst->identifier.numeric = dstUInt16;
+		break;
+
+	case UA_NODEIDTYPE_NUMERIC: // Table 6, first entry
+		CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dst->namespace),; );
+		CHECKED_DECODE(UA_UInt32_decodeBinary(src, offset, &dst->identifier.numeric),; );
+		break;
+
+	case UA_NODEIDTYPE_STRING: // Table 6, second entry
+		CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dst->namespace),; );
+		CHECKED_DECODE(UA_String_decodeBinary(src, offset, &dst->identifier.string),; );
+		break;
+
+	case UA_NODEIDTYPE_GUID: // Table 6, third entry
+		CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dst->namespace),; );
+		CHECKED_DECODE(UA_Guid_decodeBinary(src, offset, &dst->identifier.guid),; );
+		break;
+
+	case UA_NODEIDTYPE_BYTESTRING: // Table 6, "OPAQUE"
+		CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dst->namespace),; );
+		CHECKED_DECODE(UA_ByteString_decodeBinary(src, offset, &dst->identifier.byteString),; );
+		break;
+	}
+	return retval;
+}
+
+/* ExpandedNodeId */
+UA_Int32 UA_ExpandedNodeId_calcSizeBinary(UA_ExpandedNodeId const *p) {
+	UA_Int32 length = 0;
+	if(p == UA_NULL)
+		length = sizeof(UA_ExpandedNodeId);
+	else {
+		length = UA_NodeId_calcSizeBinary(&p->nodeId);
+		if(p->nodeId.encodingByte & UA_NODEIDTYPE_NAMESPACE_URI_FLAG)
+			length += UA_String_calcSizeBinary(&p->namespaceUri);  //p->namespaceUri
+		if(p->nodeId.encodingByte & UA_NODEIDTYPE_SERVERINDEX_FLAG)
+			length += sizeof(UA_UInt32);                    //p->serverIndex
+	}
+	return length;
+}
+
+UA_String UA_String_null = { -1, UA_NULL };
+UA_TYPE_ENCODEBINARY(UA_ExpandedNodeId,
+                     retval |= UA_NodeId_encodeBinary(&src->nodeId, dst, offset);
+                     if(src->nodeId.encodingByte & UA_NODEIDTYPE_NAMESPACE_URI_FLAG)
+						 retval |= UA_String_encodeBinary(&src->namespaceUri, dst, offset);
+                     if(src->nodeId.encodingByte & UA_NODEIDTYPE_SERVERINDEX_FLAG)
+						 retval |= UA_UInt32_encodeBinary(&src->serverIndex, dst, offset);
+                     )
+UA_Int32 UA_ExpandedNodeId_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_ExpandedNodeId *dst) {
+	UA_UInt32 retval = UA_SUCCESS;
+	UA_ExpandedNodeId_init(dst);
+	CHECKED_DECODE(UA_NodeId_decodeBinary(src, offset, &dst->nodeId), UA_ExpandedNodeId_deleteMembers(dst));
+	if(dst->nodeId.encodingByte & UA_NODEIDTYPE_NAMESPACE_URI_FLAG) {
+		dst->nodeId.namespace = 0;
+		CHECKED_DECODE(UA_String_decodeBinary(src, offset, &dst->namespaceUri), UA_ExpandedNodeId_deleteMembers(dst));
+	} else {
+	CHECKED_DECODE(UA_String_copy(&UA_String_null, &dst->namespaceUri), UA_ExpandedNodeId_deleteMembers(dst));
+	}
+
+	if(dst->nodeId.encodingByte & UA_NODEIDTYPE_SERVERINDEX_FLAG)
+		CHECKED_DECODE(UA_UInt32_decodeBinary(src, offset, &dst->serverIndex), UA_ExpandedNodeId_deleteMembers(dst));
+	return retval;
+}
+
+/* StatusCode */
+UA_TYPE_BINARY_ENCODING_AS(UA_StatusCode, UA_UInt32)
+
+/* QualifiedName */
+UA_Int32 UA_QualifiedName_calcSizeBinary(UA_QualifiedName const *p) {
+	UA_Int32 length = 0;
+	if(p == UA_NULL) return sizeof(UA_QualifiedName);
+	length += sizeof(UA_UInt16);              //qualifiedName->namespaceIndex
+	// length += sizeof(UA_UInt16); //qualifiedName->reserved
+	length += UA_String_calcSizeBinary(&p->name); //qualifiedName->name
+	return length;
+}
+UA_Int32 UA_QualifiedName_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_QualifiedName *dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_QualifiedName_init(dst);
+	CHECKED_DECODE(UA_UInt16_decodeBinary(src, offset, &dst->namespaceIndex),; );
+	CHECKED_DECODE(UA_String_decodeBinary(src, offset, &dst->name),; );
+	return retval;
+}
+UA_TYPE_ENCODEBINARY(UA_QualifiedName,
+                     retval |= UA_UInt16_encodeBinary(&src->namespaceIndex, dst, offset);
+                     retval |= UA_String_encodeBinary(&src->name, dst, offset); )
+
+/* LocalizedText */
+UA_Int32 UA_LocalizedText_calcSizeBinary(UA_LocalizedText const *p) {
+	UA_Int32 length = 1; // for encodingMask
+	if(p == UA_NULL)
+		return sizeof(UA_LocalizedText);
+	if(p->locale.data != UA_NULL)
+		length += UA_String_calcSizeBinary(&p->locale);
+	if(p->text.data != UA_NULL)
+		length += UA_String_calcSizeBinary(&p->text);
+	return length;
+}
+
+UA_TYPE_ENCODEBINARY(UA_LocalizedText,
+					 UA_Byte encodingMask = 0;
+					 if(src->locale.data != UA_NULL)
+						 encodingMask |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE;
+					 if(src->text.data != UA_NULL)
+						 encodingMask |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
+                     retval |= UA_Byte_encodeBinary(&encodingMask, dst, offset);
+                     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
+						 retval |= UA_String_encodeBinary(&src->locale, dst, offset);
+                     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
+						 retval |= UA_String_encodeBinary(&src->text, dst, offset); )
+
+UA_Int32 UA_LocalizedText_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_LocalizedText *dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_LocalizedText_init(dst);
+	UA_Byte encodingMask = 0;
+	CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &encodingMask),; );
+	if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
+		CHECKED_DECODE(UA_String_decodeBinary(src, offset, &dst->locale),
+					   UA_LocalizedText_deleteMembers(dst));
+	if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
+		CHECKED_DECODE(UA_String_decodeBinary(src, offset, &dst->text),
+					   UA_LocalizedText_deleteMembers(dst));
+	return retval;
+}
+
+/* ExtensionObject */
+UA_Int32 UA_ExtensionObject_calcSizeBinary(UA_ExtensionObject const *p) {
+	UA_Int32 length = 0;
+	if(p == UA_NULL)
+		length = sizeof(UA_ExtensionObject);
+	else {
+		length += UA_NodeId_calcSizeBinary(&p->typeId);
+		length += 1; //p->encoding
+		switch(p->encoding) {
+		case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING:
+			length += UA_ByteString_calcSizeBinary(&p->body);
+			break;
+
+		case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML:
+			length += UA_XmlElement_calcSizeBinary((UA_XmlElement *)&p->body);
+			break;
+		}
+	}
+	return length;
+}
+
+UA_TYPE_ENCODEBINARY(UA_ExtensionObject,
+                     retval |= UA_NodeId_encodeBinary(&src->typeId, dst, offset);
+                     retval |= UA_Byte_encodeBinary(&src->encoding, dst, offset);
+                     switch(src->encoding) {
+					 case UA_EXTENSIONOBJECT_ENCODINGMASK_NOBODYISENCODED:
+						 break;
+
+					 case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING:
+						 // FIXME: This code is valid for numeric nodeIds in ns0 only!
+						 retval |=
+						     UA_.types[UA_ns0ToVTableIndex(&src->typeId)].encodings[0].encode(src->body.data, dst,
+						                                                                      offset);
+						 break;
+
+					 case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML:
+						 retval |= UA_ByteString_encodeBinary(&src->body, dst, offset);
+						 break;
+					 }
+                     )
+
+UA_Int32 UA_ExtensionObject_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_ExtensionObject *dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_ExtensionObject_init(dst);
+	CHECKED_DECODE(UA_NodeId_decodeBinary(src, offset, &dst->typeId), UA_ExtensionObject_deleteMembers(dst));
+	CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &dst->encoding), UA_ExtensionObject_deleteMembers(dst));
+	CHECKED_DECODE(UA_String_copy(&UA_String_null, (UA_String *)&dst->body), UA_ExtensionObject_deleteMembers(dst));
+	switch(dst->encoding) {
+	case UA_EXTENSIONOBJECT_ENCODINGMASK_NOBODYISENCODED:
+		break;
+
+	case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING:
+	case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML:
+		CHECKED_DECODE(UA_ByteString_decodeBinary(src, offset, &dst->body), UA_ExtensionObject_deleteMembers(dst));
+		break;
+	}
+	return retval;
+}
+
+/* DataValue */
+//TODO: place this define at the server configuration
+#define MAX_PICO_SECONDS 1000
+UA_Int32 UA_DataValue_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_DataValue *dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_DataValue_init(dst);
+	retval |= UA_Byte_decodeBinary(src, offset, &dst->encodingMask);
+	if(dst->encodingMask & UA_DATAVALUE_ENCODINGMASK_VARIANT)
+		CHECKED_DECODE(UA_Variant_decodeBinary(src, offset, &dst->value), UA_DataValue_deleteMembers(dst));
+	if(dst->encodingMask & UA_DATAVALUE_ENCODINGMASK_STATUSCODE)
+		CHECKED_DECODE(UA_StatusCode_decodeBinary(src, offset, &dst->status), UA_DataValue_deleteMembers(dst));
+	if(dst->encodingMask & UA_DATAVALUE_ENCODINGMASK_SOURCETIMESTAMP)
+		CHECKED_DECODE(UA_DateTime_decodeBinary(src, offset, &dst->sourceTimestamp), UA_DataValue_deleteMembers(dst));
+	if(dst->encodingMask & UA_DATAVALUE_ENCODINGMASK_SOURCEPICOSECONDS) {
+		CHECKED_DECODE(UA_Int16_decodeBinary(src, offset, &dst->sourcePicoseconds), UA_DataValue_deleteMembers(dst));
+		if(dst->sourcePicoseconds > MAX_PICO_SECONDS)
+			dst->sourcePicoseconds = MAX_PICO_SECONDS;
+	}
+	if(dst->encodingMask & UA_DATAVALUE_ENCODINGMASK_SERVERTIMESTAMP)
+		CHECKED_DECODE(UA_DateTime_decodeBinary(src, offset, &dst->serverTimestamp), UA_DataValue_deleteMembers(dst));
+	if(dst->encodingMask & UA_DATAVALUE_ENCODINGMASK_SERVERPICOSECONDS) {
+		CHECKED_DECODE(UA_Int16_decodeBinary(src, offset, &dst->serverPicoseconds), UA_DataValue_deleteMembers(dst));
+		if(dst->serverPicoseconds > MAX_PICO_SECONDS)
+			dst->serverPicoseconds = MAX_PICO_SECONDS;
+	}
+	return retval;
+}
+
+UA_TYPE_ENCODEBINARY(UA_DataValue,
+                     retval |= UA_Byte_encodeBinary(&src->encodingMask, dst, offset);
+                     if(src->encodingMask & UA_DATAVALUE_ENCODINGMASK_VARIANT)
+						 retval |= UA_Variant_encodeBinary(&src->value, dst, offset);
+                     if(src->encodingMask & UA_DATAVALUE_ENCODINGMASK_STATUSCODE)
+						 retval |= UA_StatusCode_encodeBinary(&src->status, dst, offset);
+                     if(src->encodingMask & UA_DATAVALUE_ENCODINGMASK_SOURCETIMESTAMP)
+						 retval |= UA_DateTime_encodeBinary(&src->sourceTimestamp, dst, offset);
+                     if(src->encodingMask & UA_DATAVALUE_ENCODINGMASK_SOURCEPICOSECONDS)
+						 retval |= UA_Int16_encodeBinary(&src->sourcePicoseconds, dst, offset);
+                     if(src->encodingMask & UA_DATAVALUE_ENCODINGMASK_SERVERTIMESTAMP)
+						 retval |= UA_DateTime_encodeBinary(&src->serverTimestamp, dst, offset);
+                     if(src->encodingMask & UA_DATAVALUE_ENCODINGMASK_SERVERPICOSECONDS)
+						 retval |= UA_Int16_encodeBinary(&src->serverPicoseconds, dst, offset);
+                     )
+
+UA_Int32 UA_DataValue_calcSizeBinary(UA_DataValue const *p) {
+	UA_Int32 length = 0;
+
+	if(p == UA_NULL) // get static storage size
+		length = sizeof(UA_DataValue);
+	else {           // get decoding size
+		length = sizeof(UA_Byte);
+		if(p->encodingMask & UA_DATAVALUE_ENCODINGMASK_VARIANT) {
+			// FIXME: this one can return with an error value instead of a size
+			length += UA_Variant_calcSizeBinary(&p->value);
+		}
+		if(p->encodingMask & UA_DATAVALUE_ENCODINGMASK_STATUSCODE)
+			length += sizeof(UA_UInt32);   //dataValue->status
+		if(p->encodingMask & UA_DATAVALUE_ENCODINGMASK_SOURCETIMESTAMP)
+			length += sizeof(UA_DateTime);  //dataValue->sourceTimestamp
+		if(p->encodingMask & UA_DATAVALUE_ENCODINGMASK_SOURCEPICOSECONDS)
+			length += sizeof(UA_Int64);    //dataValue->sourcePicoseconds
+		if(p->encodingMask & UA_DATAVALUE_ENCODINGMASK_SERVERTIMESTAMP)
+			length += sizeof(UA_DateTime);  //dataValue->serverTimestamp
+		if(p->encodingMask & UA_DATAVALUE_ENCODINGMASK_SERVERPICOSECONDS)
+			length += sizeof(UA_Int64);    //dataValue->serverPicoseconds
+	}
+	return length;
+}
+
+/* Variant */
+/* We can store all data types in a variant internally. But for communication we
+ * encode them in an ExtensionObject if they are not one of the built in types.
+ * Officially, only builtin types are contained in a variant.
+ *
+ * Every ExtensionObject incurrs an overhead of 4 byte (nodeid) + 1 byte (encoding) */
+UA_Int32 UA_Variant_calcSizeBinary(UA_Variant const *p) { if(p == UA_NULL)
+   return sizeof(UA_Variant);
+
+	if(p->vt == UA_NULL)
+		return UA_ERR_INCONSISTENT;
+	UA_Int32 arrayLength = p->arrayLength;
+	if(p->data == UA_NULL)
+		arrayLength = -1;
+
+	UA_Boolean isArray = arrayLength != 1;       // a single element is not an array
+	UA_Boolean hasDimensions = isArray && p->arrayDimensions != UA_NULL;
+	UA_Boolean isBuiltin = is_builtin(&p->vt->typeId);
+
+	UA_Int32   length        = sizeof(UA_Byte); //p->encodingMask
+	if(isArray) {
+		// array length + the array itself
+		length += UA_Array_calcSizeBinary(arrayLength, p->vt, p->data);
+	} else {
+		length += p->vt->encodings[UA_ENCODING_BINARY].calcSize(p->data);
+		if(!isBuiltin)
+			length += 9; // 4 byte nodeid + 1 byte encoding + 4 byte bytestring length
+	}
+
+	if(hasDimensions) {
+		if(isBuiltin)
+			length += UA_Array_calcSizeBinary(p->arrayDimensionsLength, &UA_.types[UA_INT32], p->arrayDimensions);
+		else
+			length += UA_Array_calcSizeBinary_asExtensionObject(p->arrayDimensionsLength, &UA_.types[UA_INT32],
+																p->arrayDimensions);
+	}
+			
+
+	return length;
+}
+
+UA_TYPE_ENCODEBINARY(UA_Variant,
+                     if(src == UA_NULL || src->vt == UA_NULL || src->vt->typeId.namespace != 0)
+						 return UA_ERROR;
+
+                     UA_Boolean isArray       = src->arrayLength != 1;  // a single element is not an array
+                     UA_Boolean hasDimensions = isArray && src->arrayDimensions != UA_NULL;
+					 UA_Boolean isBuiltin = is_builtin(&src->vt->typeId);
+
+                     UA_Byte encodingByte = 0;
+                     if(isArray) {
+                         encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_ARRAY;
+                         if(hasDimensions)
+							 encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS;
+					 }
+
+					 if(isBuiltin) {
+						 encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)src->vt->typeId.identifier.numeric;
+					 } else
+						 encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)22; // ExtensionObject
+					 
+                     retval |= UA_Byte_encodeBinary(&encodingByte, dst, offset);
+
+                     if(isArray)
+						 retval |= UA_Array_encodeBinary(src->data, src->arrayLength, src->vt, dst, offset);
+                     else if(src->data == UA_NULL)
+							 retval = UA_ERROR;       // an array can be empty. a single element must be present.
+					 else {
+						 if(!isBuiltin) {
+							 // print the extensionobject header
+							 UA_NodeId_encodeBinary(&src->vt->typeId, dst, offset);
+							 UA_Byte eoEncoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
+							 UA_Byte_encodeBinary(&eoEncoding, dst, offset);
+							 UA_Int32 eoEncodingLength = src->vt->encodings[UA_ENCODING_BINARY].calcSize(src->data);
+							 UA_Int32_encodeBinary(&eoEncodingLength, dst, offset);
+						 }
+						 retval |= src->vt->encodings[UA_ENCODING_BINARY].encode(src->data, dst, offset);
+					 }
+
+                     if(hasDimensions) {
+						 if(isBuiltin)
+							 retval |= UA_Array_encodeBinary(src->arrayDimensions, src->arrayDimensionsLength,
+															 &UA_.types[UA_INT32], dst, offset);
+						 else
+							 retval |= UA_Array_encodeBinary_asExtensionObject(src->arrayDimensions,
+																			   src->arrayDimensionsLength,
+																			   &UA_.types[UA_INT32], dst, offset);
+					 })
+
+/* For decoding, we read extensionobects as is. */
+UA_Int32 UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_Variant * dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_Variant_init(dst);
+	
+	UA_Byte encodingByte;
+	CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &encodingByte),; );
+
+	UA_Boolean isArray = encodingByte & (0x01 << 7);                             // Bit 7
+	UA_Boolean hasDimensions = isArray && (encodingByte & (0x01 << 6));            // Bit 6
+
+	UA_NodeId typeid = { .encodingByte = (UA_Byte)UA_NODEIDTYPE_FOURBYTE, .namespace= 0,
+						 .identifier.numeric = encodingByte & 0x3F };
+	UA_Int32 typeNs0Id = UA_ns0ToVTableIndex(&typeid );
+	dst->vt = &UA_.types[typeNs0Id];
+
+	if(isArray) {
+	CHECKED_DECODE(UA_Int32_decodeBinary(src, offset, &dst->arrayLength),; );
+	CHECKED_DECODE(UA_Array_decodeBinary(src, offset, dst->arrayLength, dst->vt,
+	                                     &dst->data), UA_Variant_deleteMembers(dst));
+	}else {
+		dst->arrayLength = 1;
+		UA_alloc(&dst->data, dst->vt->memSize);
+		dst->vt->encodings[UA_ENCODING_BINARY].decode(src, offset, dst->data);
+	}
+
+	//decode the dimension field array if present
+	if(hasDimensions) {
+		UA_Int32_decodeBinary(src, offset, &dst->arrayDimensionsLength);
+		CHECKED_DECODE(UA_Array_decodeBinary(src, offset, dst->arrayDimensionsLength,
+		                                     &UA_.types[UA_INT32],
+		                                     &dst->data), UA_Variant_deleteMembers(dst));
+	}
+	return retval;
+}
+
+/* DiagnosticInfo */
+UA_Int32 UA_DiagnosticInfo_calcSizeBinary(UA_DiagnosticInfo const *ptr) {
+	UA_Int32 length = 0;
+	if(ptr == UA_NULL)
+		length = sizeof(UA_DiagnosticInfo);
+	else {
+		UA_Byte mask;
+		length += sizeof(UA_Byte);                           // EncodingMask
+
+		for(mask = 0x01;mask <= 0x40;mask *= 2) {
+			switch(mask & (ptr->encodingMask)) {
+
+			case UA_DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID:
+				//	puts("diagnosticInfo symbolic id");
+				length += sizeof(UA_Int32);
+				break;
+
+			case UA_DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE:
+				length += sizeof(UA_Int32);
+				break;
+
+			case UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT:
+				length += sizeof(UA_Int32);
+				break;
+
+			case UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALE:
+				length += sizeof(UA_Int32);
+				break;
+
+			case UA_DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO:
+				length += UA_String_calcSizeBinary(&ptr->additionalInfo);
+				break;
+
+			case UA_DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE:
+				length += sizeof(UA_StatusCode);
+				break;
+
+			case UA_DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO:
+				length += UA_DiagnosticInfo_calcSizeBinary(ptr->innerDiagnosticInfo);
+				break;
+			}
+		}
+	}
+	return length;
+}
+
+UA_Int32 UA_DiagnosticInfo_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset,
+                                        UA_DiagnosticInfo *dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_DiagnosticInfo_init(dst);
+	CHECKED_DECODE(UA_Byte_decodeBinary(src, offset, &dst->encodingMask),; );
+
+	for(UA_Int32 i = 0;i < 7;i++) {
+		switch( (0x01 << i) & dst->encodingMask) {
+
+		case UA_DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID:
+			CHECKED_DECODE(UA_Int32_decodeBinary(src, offset, &dst->symbolicId),; );
+			break;
+
+		case UA_DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE:
+			CHECKED_DECODE(UA_Int32_decodeBinary(src, offset, &dst->namespaceUri),; );
+			break;
+
+		case UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT:
+			CHECKED_DECODE(UA_Int32_decodeBinary(src, offset, &dst->localizedText),; );
+			break;
+
+		case UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALE:
+			CHECKED_DECODE(UA_Int32_decodeBinary(src, offset, &dst->locale),; );
+			break;
+
+		case UA_DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO:
+			CHECKED_DECODE(UA_String_decodeBinary(src, offset, &dst->additionalInfo),; );
+			break;
+
+		case UA_DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE:
+			CHECKED_DECODE(UA_StatusCode_decodeBinary(src, offset, &dst->innerStatusCode),; );
+			break;
+
+		case UA_DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO:
+			// innerDiagnosticInfo is a pointer to struct, therefore allocate
+			CHECKED_DECODE(UA_alloc((void **)&dst->innerDiagnosticInfo,
+			                        UA_DiagnosticInfo_calcSizeBinary(UA_NULL)),; );
+			CHECKED_DECODE(UA_DiagnosticInfo_decodeBinary(src, offset,
+			                                              dst->innerDiagnosticInfo),
+			               UA_DiagnosticInfo_deleteMembers(dst));
+			break;
+		}
+	}
+	return retval;
+}
+
+UA_TYPE_ENCODEBINARY(UA_DiagnosticInfo,
+                     retval |= UA_Byte_encodeBinary(&src->encodingMask, dst, offset);
+                     for(UA_Int32 i = 0;i < 7;i++) {
+                         switch( (0x01 << i) & src->encodingMask) {
+						 case UA_DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID:
+							 retval |= UA_Int32_encodeBinary(&src->symbolicId, dst, offset);
+							 break;
+
+						 case UA_DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE:
+							 retval |=
+							     UA_Int32_encodeBinary( &src->namespaceUri, dst, offset);
+							 break;
+
+						 case UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT:
+							 retval |= UA_Int32_encodeBinary(&src->localizedText, dst, offset);
+							 break;
+
+						 case UA_DIAGNOSTICINFO_ENCODINGMASK_LOCALE:
+							 retval |= UA_Int32_encodeBinary(&src->locale, dst, offset);
+							 break;
+
+						 case UA_DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO:
+							 retval |=
+							     UA_String_encodeBinary(&src->additionalInfo, dst, offset);
+							 break;
+
+						 case UA_DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE:
+							 retval |=
+							     UA_StatusCode_encodeBinary(&src->innerStatusCode, dst,
+							                                offset);
+							 break;
+
+						 case UA_DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO:
+							 retval |=
+							     UA_DiagnosticInfo_encodeBinary(src->innerDiagnosticInfo, dst,
+							                                    offset);
+							 break;
+						 }
+					 }
+                     )
+
+/* InvalidType */
+UA_Int32 UA_InvalidType_calcSizeBinary(UA_InvalidType const *p) {
+	return 0;
+}
+UA_TYPE_ENCODEBINARY(UA_InvalidType, retval = UA_ERR_INVALID_VALUE; )
+UA_TYPE_DECODEBINARY(UA_InvalidType, retval = UA_ERR_INVALID_VALUE; )

+ 112 - 0
src/ua_types_encoding_binary.h

@@ -0,0 +1,112 @@
+#ifndef UA_TYPES_ENCODING_BINARY_H_
+#define UA_TYPES_ENCODING_BINARY_H_
+
+#include "util/ua_util.h"
+#include "ua_types.h"
+
+/**
+ * @ingroup types
+ * @defgroup encoding Datatype Encoding
+ *
+ * @brief Datatypes can have several encodings. The methods defined for
+ * encodings and their signature are fixed.
+ *
+ * - CalcSize: Returns the size of the (encoded) variable in bytes. This
+ *    function is mainly used to allocate the bytestring into which the encoding
+ *    is done.
+ *
+ * - Encode: Encodes a variable into a bytestring.
+ *
+ * - Decode: Decodes a variable stored in a bytestring. It is assumed that the
+ *   input variable (dst) is allocated in memory, but not its dynamically sized
+ *   members.
+ */
+
+/**
+ * @ingroup encoding
+ * @defgroup encoding_binary Binary Encoding
+ *
+ * @brief Functions for binary en- and decoding of built-in datatypes as defined
+ * in the standard.
+ *
+ * @{
+ */
+
+/* Stop decoding at the first failure. Free members that were already allocated.
+   It is assumed that retval is already defined. */
+#define CHECKED_DECODE(DECODE, CLEAN_UP) do { \
+		retval |= DECODE;                     \
+		if(retval != UA_SUCCESS) {            \
+			CLEAN_UP;                         \
+			return retval;                    \
+		} } while(0)
+
+#define UA_TYPE_CALCSIZEBINARY_AS(TYPE, TYPE_AS)       \
+    UA_Int32 TYPE##_calcSizeBinary(TYPE const *p) {    \
+		return TYPE_AS##_calcSizeBinary((TYPE_AS *)p); \
+	}
+
+#define UA_TYPE_ENCODEBINARY_AS(TYPE, TYPE_AS)                                             \
+    UA_Int32 TYPE##_encodeBinary(TYPE const *src, UA_ByteString *dst, UA_UInt32 *offset) { \
+		return TYPE_AS##_encodeBinary((TYPE_AS *)src, dst, offset);                        \
+	}
+
+#define UA_TYPE_DECODEBINARY_AS(TYPE, TYPE_AS)                                             \
+    UA_Int32 TYPE##_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, TYPE *dst) { \
+		return TYPE_AS##_decodeBinary(src, offset, (TYPE_AS *)dst);                        \
+	}
+#define UA_TYPE_BINARY_ENCODING_AS(TYPE, TYPE_AS) \
+    UA_TYPE_CALCSIZEBINARY_AS(TYPE, TYPE_AS)      \
+    UA_TYPE_ENCODEBINARY_AS(TYPE, TYPE_AS)        \
+    UA_TYPE_DECODEBINARY_AS(TYPE, TYPE_AS)
+
+#define UA_TYPE_BINARY_ENCODING(TYPE)                                                     \
+    UA_Int32 TYPE##_calcSizeBinary(TYPE const *p);                                        \
+    UA_Int32 TYPE##_encodeBinary(TYPE const *src, UA_ByteString *dst, UA_UInt32 *offset); \
+    UA_Int32 TYPE##_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, TYPE *dst);
+
+UA_TYPE_BINARY_ENCODING(UA_Boolean)
+UA_TYPE_BINARY_ENCODING(UA_SByte)
+UA_TYPE_BINARY_ENCODING(UA_Byte)
+UA_TYPE_BINARY_ENCODING(UA_Int16)
+UA_TYPE_BINARY_ENCODING(UA_UInt16)
+UA_TYPE_BINARY_ENCODING(UA_Int32)
+UA_TYPE_BINARY_ENCODING(UA_UInt32)
+UA_TYPE_BINARY_ENCODING(UA_Int64)
+UA_TYPE_BINARY_ENCODING(UA_UInt64)
+UA_TYPE_BINARY_ENCODING(UA_Float)
+UA_TYPE_BINARY_ENCODING(UA_Double)
+UA_TYPE_BINARY_ENCODING(UA_String)
+UA_TYPE_BINARY_ENCODING(UA_DateTime)
+UA_TYPE_BINARY_ENCODING(UA_Guid)
+UA_TYPE_BINARY_ENCODING(UA_ByteString)
+UA_TYPE_BINARY_ENCODING(UA_XmlElement)
+UA_TYPE_BINARY_ENCODING(UA_NodeId)
+UA_TYPE_BINARY_ENCODING(UA_ExpandedNodeId)
+UA_TYPE_BINARY_ENCODING(UA_StatusCode)
+UA_TYPE_BINARY_ENCODING(UA_QualifiedName)
+UA_TYPE_BINARY_ENCODING(UA_LocalizedText)
+UA_TYPE_BINARY_ENCODING(UA_ExtensionObject)
+UA_TYPE_BINARY_ENCODING(UA_DataValue)
+UA_TYPE_BINARY_ENCODING(UA_Variant)
+UA_TYPE_BINARY_ENCODING(UA_DiagnosticInfo)
+
+/* Not built-in types */
+UA_TYPE_BINARY_ENCODING(UA_InvalidType)
+
+/*********/
+/* Array */
+/*********/
+
+/* Computes the size of an array (incl. length field) in a binary blob. */
+UA_Int32 UA_Array_calcSizeBinary(UA_Int32 nElements, UA_VTable_Entry *vt, const void *data);
+
+/* @brief Encodes an array into a binary blob. The array size is printed as well. */
+UA_Int32 UA_Array_encodeBinary(const void *src, UA_Int32 noElements, UA_VTable_Entry *vt, UA_ByteString *dst, UA_UInt32 *offset);
+
+/* @brief Decodes an array from a binary blob. The array is allocated automatically before decoding. */
+UA_Int32 UA_Array_decodeBinary(const UA_ByteString *src, UA_UInt32 * offset, UA_Int32 noElements, UA_VTable_Entry *vt, void **dst);
+
+/// @} /* end of group */
+
+#endif /* UA_TYPES_ENCODING_BINARY_H_ */

+ 447 - 0
src/ua_types_encoding_xml.c

@@ -0,0 +1,447 @@
+#include "ua_types_encoding_xml.h"
+#include "ua_util.h"
+#include "ua_namespace_0.h"
+#include "ua_xml.h"
+
+/* Boolean */
+
+UA_Int32 UA_Boolean_copycstring(cstring src, UA_Boolean *dst) {
+	*dst = UA_FALSE;
+	if(0 == strncmp(src, "true", 4) || 0 == strncmp(src, "TRUE", 4))
+		*dst = UA_TRUE;
+	return UA_SUCCESS;
+}
+
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Boolean)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Boolean)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_Boolean)
+/* UA_Int32 UA_Boolean_decodeXML(XML_Stack *s, XML_Attr *attr, UA_Boolean *dst, _Bool isStart) { */
+/* 	DBG_VERBOSE(printf("UA_Boolean entered with dst=%p,isStart=%d\n", (void * )dst, isStart)); */
+/* 	if(isStart) { */
+/* 		if(dst == UA_NULL) { */
+/* 			UA_Boolean_new(&dst); */
+/* 			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst; */
+/* 		} */
+/* 		UA_Boolean_copycstring((cstring)attr[1], dst); */
+/* 	} */
+/* 	return UA_SUCCESS; */
+/* } */
+
+/* SByte */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_SByte)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_SByte)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_SByte)
+
+/* Byte */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Byte)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Byte)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_Byte)
+
+/* Int16 */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Int16)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Int16)
+
+UA_Int32 UA_Int16_copycstring(cstring src, UA_Int16 *dst) {
+	*dst = atoi(src);
+	return UA_SUCCESS;
+}
+
+UA_Int32 UA_UInt16_copycstring(cstring src, UA_UInt16 *dst) {
+	*dst = atoi(src);
+	return UA_SUCCESS;
+}
+
+UA_Int32 UA_Int16_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_Int16 *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_Int32 entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	if(isStart) {
+		if(dst == UA_NULL) {
+			UA_Int16_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+		UA_Int16_copycstring((cstring)attr[1], dst);
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_Int16)
+
+/* UInt16 */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_UInt16)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_UInt16)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_UInt16)
+
+/* Int32 */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Int32)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Int32)
+
+UA_Int32 UA_Int32_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_Int32 *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_Int32 entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	if(isStart) {
+		if(dst == UA_NULL) {
+			UA_Int32_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+		*dst = atoi(attr[1]);
+	}
+	return UA_SUCCESS;
+}
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_Int32)
+
+/* UInt32 */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_UInt32)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_UInt32)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_UInt32)
+
+/* Int64 */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Int64)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Int64)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_Int64)
+
+/* UInt64 */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_UInt64)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_UInt64)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_UInt64)
+
+/* Float */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Float)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Float)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_Float)
+
+/* Double */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Double)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Double)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_Double)
+
+/* String */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_String)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_String)
+
+UA_Int32 UA_String_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_String *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_String entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	UA_UInt32 i;
+	if(isStart) {
+		if(dst == UA_NULL) {
+			UA_String_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+		s->parent[s->depth].len = 0;
+		XML_Stack_addChildHandler(s, "Data", strlen("Data"), (XML_decoder)UA_Text_decodeXmlFromStack, UA_BYTE,
+		                          &(dst->data));
+		XML_Stack_addChildHandler(s, "Length", strlen("Length"), (XML_decoder)UA_Int32_decodeXmlFromStack, UA_INT32,
+		                          &(dst->length));
+		XML_Stack_handleTextAsElementOf(s, "Data", 0);
+
+		// set attributes
+		for(i = 0;attr[i];i += 2) {
+			if(0 == strncmp("Data", attr[i], strlen("Data")))
+				UA_String_copycstring(attr[i + 1], dst);
+			else
+				printf("UA_String_decodeXml - Unknown attribute - name=%s, value=%s\n", attr[i], attr[i+1]);
+		}
+	} else {
+		switch(s->parent[s->depth - 1].activeChild) {
+		case 0:
+			if(dst != UA_NULL && dst->data != UA_NULL && dst->length == -1)
+				dst->length = strlen((char const *)dst->data);
+			break;
+		}
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_String)
+
+/* DateTime */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_DateTime)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_DateTime)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_DateTime)
+
+/* Guid */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Guid)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Guid)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_Guid)
+
+/* ByteString */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_ByteString)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_ByteString)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_ByteString)
+
+/* XmlElement */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_XmlElement)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_XmlElement)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_XmlElement)
+
+/* NodeId */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_NodeId)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_NodeId)
+
+UA_Int32 UA_NodeId_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_NodeId *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_NodeId entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	UA_UInt32 i;
+	if(isStart) {
+		if(dst == UA_NULL) {
+			UA_NodeId_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+		s->parent[s->depth].len = 0;
+		XML_Stack_addChildHandler(s, "Namespace", strlen(
+		                              "Namespace"), (XML_decoder)UA_Int16_decodeXmlFromStack, UA_INT16,
+		                          &(dst->namespace));
+		XML_Stack_addChildHandler(s, "Numeric", strlen(
+		                              "Numeric"), (XML_decoder)UA_Int32_decodeXmlFromStack, UA_INT32,
+		                          &(dst->identifier.numeric));
+		XML_Stack_addChildHandler(s, "Identifier", strlen(
+		                              "Identifier"), (XML_decoder)UA_String_decodeXmlFromStack, UA_STRING, UA_NULL);
+		XML_Stack_handleTextAsElementOf(s, "Data", 2);
+
+		// set attributes
+		for(i = 0; attr[i]; i += 2) {
+		if(0 == strncmp("Namespace", attr[i], strlen("Namespace")))
+			dst->namespace = atoi(attr[i + 1]);
+		else if(0 == strncmp("Numeric", attr[i], strlen("Numeric"))) {
+		dst->identifier.numeric = atoi(attr[i + 1]);
+		dst->encodingByte       = UA_NODEIDTYPE_FOURBYTE;
+		} else
+			printf("UA_NodeId_decodeXml - Unknown attribute name=%s, value=%s\n", attr[i], attr[i+1]);
+		}
+	} else {
+		if(s->parent[s->depth - 1].activeChild == 2)
+			UA_NodeId_copycstring((cstring)((UA_String *)attr)->data, dst, s->aliases);
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_NodeId)
+
+/* ExpandedNodeId */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_ExpandedNodeId)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_ExpandedNodeId)
+
+UA_Int32 UA_ExpandedNodeId_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_ExpandedNodeId *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_ExpandedNodeId entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	UA_UInt32 i;
+	if(isStart) {
+		if(dst == UA_NULL) {
+			UA_ExpandedNodeId_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+		s->parent[s->depth].len = 0;
+		XML_Stack_addChildHandler(s, "NodeId", strlen(
+		                              "NodeId"), (XML_decoder)UA_NodeId_decodeXmlFromStack, UA_NODEID, &(dst->nodeId));
+		XML_Stack_addChildHandler(s, "Namespace", strlen(
+		                              "Namespace"), (XML_decoder)UA_Int16_decodeXmlFromStack, UA_INT16,
+		                          &(dst->nodeId.namespace));
+		XML_Stack_addChildHandler(s, "Numeric", strlen("Numeric"), (XML_decoder)UA_Int32_decodeXmlFromStack, UA_INT32,
+		                          &(dst->nodeId.identifier.numeric));
+		XML_Stack_addChildHandler(s, "Id", strlen("Id"), (XML_decoder)UA_String_decodeXmlFromStack, UA_STRING, UA_NULL);
+		XML_Stack_handleTextAsElementOf(s, "Data", 3);
+
+		// set attributes
+		for(i = 0; attr[i]; i += 2) {
+		if(0 == strncmp("Namespace", attr[i], strlen("Namespace")))
+			UA_UInt16_copycstring((cstring)attr[i + 1], &(dst->nodeId.namespace));
+		else if(0 == strncmp("Numeric", attr[i], strlen("Numeric"))) {
+		UA_NodeId_copycstring((cstring)attr[i + 1], &(dst->nodeId), s->aliases);
+		} else if(0 == strncmp("NodeId", attr[i], strlen("NodeId")))
+			UA_NodeId_copycstring((cstring)attr[i + 1], &(dst->nodeId), s->aliases);
+		else
+			printf("UA_ExpandedNodeId_decodeXml - unknown attribute name=%s, value=%s\n", attr[i], attr[i+1]);
+		}
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_ExpandedNodeId)
+
+/* StatusCode */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_StatusCode)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_StatusCode)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_StatusCode)
+/* UA_Int32 UA_StatusCode_decodeXML(XML_Stack *s, XML_Attr *attr, UA_StatusCode *dst, _Bool isStart) { */
+/* 	DBG_VERBOSE(printf("UA_StatusCode_decodeXML entered with dst=%p,isStart=%d\n", (void * )dst, isStart)); */
+/* 	return UA_ERR_NOT_IMPLEMENTED; */
+/* } */
+
+/* QualifiedName */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_QualifiedName)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_QualifiedName)
+
+UA_Int32 UA_QualifiedName_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_QualifiedName *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_QualifiedName entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	UA_UInt32 i;
+	if(isStart) {
+		if(dst == UA_NULL) {
+			UA_QualifiedName_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+		s->parent[s->depth].len = 0;
+		XML_Stack_addChildHandler(s, "Name", strlen("Name"), (XML_decoder)UA_String_decodeXmlFromStack, UA_STRING,
+		                          &(dst->name));
+		XML_Stack_addChildHandler(s, "NamespaceIndex", strlen(
+		                              "NamespaceIndex"), (XML_decoder)UA_Int16_decodeXmlFromStack, UA_STRING,
+		                          &(dst->namespaceIndex));
+		XML_Stack_handleTextAsElementOf(s, "Data", 0);
+
+		// set attributes
+		for(i = 0;attr[i];i += 2) {
+			if(0 == strncmp("NamespaceIndex", attr[i], strlen("NamespaceIndex")))
+				dst->namespaceIndex = atoi(attr[i + 1]);
+			else if(0 == strncmp("Name", attr[i], strlen("Name")))
+				UA_String_copycstring(attr[i + 1], &(dst->name));
+			else
+				perror("Unknown attribute");
+		}
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_QualifiedName)
+
+/* LocalizedText */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_LocalizedText)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_LocalizedText)
+
+UA_Int32 UA_LocalizedText_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_LocalizedText *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_LocalizedText entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	UA_UInt32 i;
+	if(isStart) {
+		if(dst == UA_NULL) {
+			UA_LocalizedText_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+		// s->parent[s->depth].len = 0;
+		XML_Stack_addChildHandler(s, "Text", strlen("Text"), (XML_decoder)UA_String_decodeXmlFromStack, UA_STRING,
+		                          &(dst->text));
+		XML_Stack_addChildHandler(s, "Locale", strlen(
+		                              "Locale"), (XML_decoder)UA_String_decodeXmlFromStack, UA_STRING, &(dst->locale));
+		XML_Stack_handleTextAsElementOf(s, "Data", 0);
+
+		// set attributes
+		for(i = 0;attr[i];i += 2) {
+			if(0 == strncmp("Text", attr[i], strlen("Text"))) {
+				UA_String_copycstring(attr[i + 1], &dst->text);
+			} else if(0 == strncmp("Locale", attr[i], strlen("Locale"))) {
+				UA_String_copycstring(attr[i + 1], &dst->locale);
+			} else
+				perror("Unknown attribute");
+		}
+	} else {
+		switch(s->parent[s->depth - 1].activeChild) {
+		case 0:
+			//dst->encodingMask |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
+			break;
+
+		case 1:
+			//dst->encodingMask |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE;
+			break;
+
+		default:
+			break;
+		}
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_LocalizedText)
+
+/* ExtensionObject */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_ExtensionObject)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_ExtensionObject)
+
+UA_Int32 UA_ExtensionObject_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_ExtensionObject *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_ExtensionObject entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	UA_UInt32 i;
+
+	if(isStart) {
+		// create a new object if called with UA_NULL
+		if(dst == UA_NULL) {
+			UA_ExtensionObject_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+
+		s->parent[s->depth].len = 0;
+		XML_Stack_addChildHandler(s, "TypeId", strlen(
+		                              "TypeId"), (XML_decoder)UA_NodeId_decodeXmlFromStack, UA_NODEID, &(dst->typeId));
+		// XML_Stack_addChildHandler(s, "Body", strlen("Body"), (XML_decoder) UA_Body_decodeXml, UA_LOCALIZEDTEXT, UA_NULL);
+
+		// set attributes
+		for(i = 0;attr[i];i += 2) {
+			{
+				DBG_ERR(XML_Stack_print(s));
+				DBG_ERR(printf("%s - unknown attribute\n", attr[i]));
+			}
+		}
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_ExtensionObject)
+
+/* DataValue */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_DataValue)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_DataValue)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_DataValue)
+
+/* Variant */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_Variant)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_Variant)
+
+UA_Int32 UA_Variant_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_Variant *dst, _Bool isStart) {
+	DBG_VERBOSE(printf("UA_Variant entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
+	UA_UInt32 i;
+
+	if(isStart) {
+		// create a new object if called with UA_NULL
+		if(dst == UA_NULL) {
+			UA_Variant_new(&dst);
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
+		}
+
+		s->parent[s->depth].len = 0;
+		XML_Stack_addChildHandler(s, "ListOfExtensionObject", strlen(
+		                              "ListOfExtensionObject"), (XML_decoder)UA_TypedArray_decodeXmlFromStack,
+		                          UA_EXTENSIONOBJECT, UA_NULL);
+		XML_Stack_addChildHandler(s, "ListOfLocalizedText", strlen(
+		                              "ListOfLocalizedText"), (XML_decoder)UA_TypedArray_decodeXmlFromStack,
+		                          UA_LOCALIZEDTEXT, UA_NULL);
+
+		// set attributes
+		for(i = 0;attr[i];i += 2) {
+			{
+				DBG_ERR(XML_Stack_print(s));
+				DBG_ERR(printf("%s - unknown attribute\n", attr[i]));
+			}
+		}
+	} else {
+		if(s->parent[s->depth - 1].activeChild == 0 && attr != UA_NULL ) {  // ExtensionObject
+			UA_TypedArray *array = (UA_TypedArray *)attr;
+			DBG_VERBOSE(printf("UA_Variant_decodeXml - finished array: references=%p, size=%d\n", (void *)array,
+			                   (array == UA_NULL) ? -1 : array->size));
+			dst->arrayLength  = array->size;
+			dst->data         = array->elements;
+			dst->vt = &UA_.types[UA_EXTENSIONOBJECT];
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL;
+		} else if(s->parent[s->depth - 1].activeChild == 1 && attr != UA_NULL ) {  // LocalizedText
+			UA_TypedArray *array = (UA_TypedArray *)attr;
+			DBG_VERBOSE(printf("UA_Variant_decodeXml - finished array: references=%p, size=%d\n", (void *)array,
+			                   (array == UA_NULL) ? -1 : array->size));
+			dst->arrayLength  = array->size;
+			dst->data         = array->elements;
+			dst->vt = &UA_.types[UA_LOCALIZEDTEXT];
+			s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL;
+		}
+	}
+	return UA_SUCCESS;
+}
+
+UA_TYPE_DECODEXML_FROM_BYTESTRING(UA_Variant)
+
+/* DiagnosticInfo */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_DiagnosticInfo)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_DiagnosticInfo)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_DiagnosticInfo)
+
+/* InvalidType */
+UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(UA_InvalidType)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(UA_InvalidType)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(UA_InvalidType)

+ 77 - 0
src/ua_types_encoding_xml.h

@@ -0,0 +1,77 @@
+#ifndef UA_TYPES_ENCODING_XML_H_
+#define UA_TYPES_ENCODING_XML_H_
+
+#include "ua_xml.h"
+#include "ua_types.h"
+
+#define UA_TYPE_XML_ENCODING(TYPE)							\
+	UA_Int32 TYPE##_calcSizeXml(const void * p); \
+    UA_Int32 TYPE##_encodeXml(const TYPE *src, UA_ByteString *dst, UA_UInt32 *offset); \
+	UA_Int32 TYPE##_decodeXml(UA_ByteString *src, UA_UInt32 *offset, TYPE *dst); \
+	UA_Int32 TYPE##_encodeXmlToStack(const TYPE *src, XML_Stack *s, XML_Attr *attr); \
+	UA_Int32 TYPE##_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, TYPE* dst, UA_Boolean isStart);
+
+#define UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(TYPE) \
+	UA_Int32 TYPE##_calcSizeXml(const void * p) { \
+	return -1; \
+ }
+
+#define UA_TYPE_METHOD_ENCODEXML_NOTIMPL(TYPE) \
+    UA_Int32 TYPE##_encodeXml(const TYPE *src, UA_ByteString *dst, UA_UInt32 *offset) { \
+        return UA_ERR_NOT_IMPLEMENTED; \
+	}																	\
+	UA_Int32 TYPE##_encodeXmlToStack(const TYPE *src, XML_Stack *s, XML_Attr *attr) { \
+																					 DBG_VERBOSE(printf(#TYPE "_encodeXML entered with src=%p\n", (void* ) src)); \
+     return UA_ERR_NOT_IMPLEMENTED;\
+ }
+
+#define UA_TYPE_METHOD_DECODEXML_NOTIMPL(TYPE) \
+	UA_Int32 TYPE##_decodeXml(UA_ByteString *src, UA_UInt32 *offset, TYPE *dst) { \
+        return UA_ERR_NOT_IMPLEMENTED;									\
+	}																	\
+																		\
+ UA_Int32 TYPE##_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, TYPE* dst, UA_Boolean isStart) { \
+																								  DBG_VERBOSE(printf(#TYPE "_decodeXML entered with dst=%p,isStart=%d\n", (void* ) dst, (_Bool) isStart)); \
+     return UA_ERR_NOT_IMPLEMENTED; \
+ }
+
+#define UA_TYPE_DECODEXML_FROM_BYTESTRING(TYPE) \
+	UA_Int32 TYPE##_decodeXml(UA_ByteString *src, UA_UInt32 *offset, TYPE *dst) { \
+	/* // Init Stack here \
+	UA_Stack *stack; \
+	UA_Attr *attr; \
+	TYPE##decodeXmlFromStack(stack, attr, dst, UA_TRUE); \
+	*/ \
+	return UA_ERR_NOT_IMPLEMENTED; \
+} 
+
+UA_TYPE_XML_ENCODING(UA_Boolean)
+UA_TYPE_XML_ENCODING(UA_SByte)
+UA_TYPE_XML_ENCODING(UA_Byte)
+UA_TYPE_XML_ENCODING(UA_Int16)
+UA_TYPE_XML_ENCODING(UA_UInt16)
+UA_TYPE_XML_ENCODING(UA_Int32)
+UA_TYPE_XML_ENCODING(UA_UInt32)
+UA_TYPE_XML_ENCODING(UA_Int64)
+UA_TYPE_XML_ENCODING(UA_UInt64)
+UA_TYPE_XML_ENCODING(UA_Float)
+UA_TYPE_XML_ENCODING(UA_Double)
+UA_TYPE_XML_ENCODING(UA_String)
+UA_TYPE_XML_ENCODING(UA_DateTime)
+UA_TYPE_XML_ENCODING(UA_Guid)
+UA_TYPE_XML_ENCODING(UA_ByteString)
+UA_TYPE_XML_ENCODING(UA_XmlElement)
+UA_TYPE_XML_ENCODING(UA_NodeId)
+UA_TYPE_XML_ENCODING(UA_ExpandedNodeId)
+UA_TYPE_XML_ENCODING(UA_StatusCode)
+UA_TYPE_XML_ENCODING(UA_QualifiedName)
+UA_TYPE_XML_ENCODING(UA_LocalizedText)
+UA_TYPE_XML_ENCODING(UA_ExtensionObject)
+UA_TYPE_XML_ENCODING(UA_DataValue)
+UA_TYPE_XML_ENCODING(UA_Variant)
+UA_TYPE_XML_ENCODING(UA_DiagnosticInfo)
+
+/* Not built-in types */
+UA_TYPE_XML_ENCODING(UA_InvalidType)
+
+#endif /* UA_TYPES_ENCODING_XML_H_ */

File diff suppressed because it is too large
+ 657 - 887
src/ua_xml.c


+ 68 - 59
src/ua_xml.h

@@ -1,63 +1,85 @@
-/*
- * ua_xml.h
- *
- *  Created on: 03.05.2014
- *      Author: mrt
- */
-
-#ifndef __UA_XML_H__
-#define __UA_XML_H__
+#ifndef __UA_XML_H
+#define __UA_XML_H
 
 #include <expat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h> // strlen
-#include <ctype.h> // isspace
+#include <ctype.h>  // isspace
 #include <unistd.h> // read
 
-#include "opcua.h"
-#include "ua_namespace.h"
+#include "ua_types.h"
+
+struct XML_Stack;
+typedef char const *const XML_Attr;
+typedef char const *cstring;
+#define XML_STACK_MAX_DEPTH 10
+#define XML_STACK_MAX_CHILDREN 40
+typedef UA_Int32 (*XML_decoder)(struct XML_Stack *s, XML_Attr *attr, void *dst, UA_Boolean isStart);
 
-UA_Int32 UA_Boolean_copycstring(cstring src, UA_Boolean* dst);
-UA_Int32 UA_Int16_copycstring(cstring src, UA_Int16* dst);
-UA_Int32 UA_UInt16_copycstring(cstring src, UA_UInt16* dst) ;
-UA_Boolean UA_NodeId_isBuiltinType(UA_NodeId* nodeid);
-void print_node(UA_Node const * node);
+/** @brief A readable shortcut for NodeIds. A list of aliases is intensively used in the namespace0-xml-files */
+typedef struct UA_NodeSetAlias {
+	UA_String alias;
+	UA_String value;
+} UA_NodeSetAlias;
+//UA_TYPE_PROTOTYPES(UA_NodeSetAlias)
+
+/** @brief UA_NodeSetAliases - a list of aliases */
+typedef struct UA_NodeSetAliases {
+	UA_Int32 size;
+	UA_NodeSetAlias **aliases;
+} UA_NodeSetAliases;
+//UA_TYPE_PROTOTYPES(UA_NodeSetAliases)
+
+typedef struct XML_child {
+	cstring     name;
+	UA_Int32    length;
+	UA_Int32    type;
+	XML_decoder elementHandler;
+	void       *obj;
+} XML_child;
+
+typedef struct XML_Parent {
+	cstring   name;
+	int       textAttribIdx;  // -1 - not set
+	cstring   textAttrib;
+	int       activeChild;    // -1 - no active child
+	int       len;            // -1 - empty set
+	XML_child children[XML_STACK_MAX_CHILDREN];
+} XML_Parent;
+
+typedef struct XML_Stack {
+	int depth;
+	XML_Parent parent[XML_STACK_MAX_DEPTH];
+	UA_NodeSetAliases *aliases;  // shall point to the aliases of the NodeSet after reading
+} XML_Stack;
+
+UA_Int32 UA_Boolean_copycstring(cstring src, UA_Boolean *dst);
+UA_Int32 UA_Int16_copycstring(cstring src, UA_Int16 *dst);
+UA_Int32 UA_UInt16_copycstring(cstring src, UA_UInt16 *dst);
+UA_Boolean UA_NodeId_isBuiltinType(UA_NodeId *nodeid);
 
 /** @brief an object to hold a typed array */
 typedef struct UA_TypedArray {
-	UA_Int32 size;
-	UA_VTable* vt;
-	void** elements;
+	UA_Int32         size;
+	UA_VTable_Entry *vt;
+	void *elements;
 } UA_TypedArray;
 
 /** @brief init typed array with size=-1 and an UA_INVALIDTYPE */
-UA_Int32 UA_TypedArray_init(UA_TypedArray* p);
+UA_Int32 UA_TypedArray_init(UA_TypedArray *p);
 
 /** @brief allocate memory for the array header only */
-UA_Int32 UA_TypedArray_new(UA_TypedArray** p);
-UA_Int32 UA_TypedArray_setType(UA_TypedArray* p, UA_Int32 type);
-UA_Int32 UA_TypedArray_decodeXML(XML_Stack* s, XML_Attr* attr, UA_TypedArray* dst, _Bool isStart);
+UA_Int32 UA_TypedArray_new(UA_TypedArray **p);
+UA_Int32 UA_TypedArray_setType(UA_TypedArray *p, UA_Int32 type);
+//UA_Int32 UA_TypedArray_decodeXML(XML_Stack *s, XML_Attr *attr, UA_TypedArray *dst, UA_Boolean isStart);
 
 UA_Int32 UA_NodeSetAlias_init(UA_NodeSetAlias* p);
 UA_Int32 UA_NodeSetAlias_new(UA_NodeSetAlias** p);
-UA_Int32 UA_NodeSetAlias_decodeXML(XML_Stack* s, XML_Attr* attr, UA_NodeSetAlias* dst, _Bool isStart);
 
 UA_Int32 UA_NodeSetAliases_init(UA_NodeSetAliases* p);
 UA_Int32 UA_NodeSetAliases_new(UA_NodeSetAliases** p);
 UA_Int32 UA_NodeSetAliases_println(cstring label, UA_NodeSetAliases *p);
-UA_Int32 UA_NodeSetAliases_decodeXML(XML_Stack* s, XML_Attr* attr, UA_NodeSetAliases* dst, _Bool isStart);
-
-typedef struct UA_NodeSet {
-	Namespace* ns;
-	UA_NodeSetAliases aliases;
-} UA_NodeSet;
-
-/** @brief init typed array with size=-1 and an UA_INVALIDTYPE */
-UA_Int32 UA_NodeSet_init(UA_NodeSet* p, UA_UInt32 nsid);
-UA_Int32 UA_NodeSet_new(UA_NodeSet** p, UA_UInt32 nsid);
-UA_Int32 UA_NodeId_copycstring(cstring src, UA_NodeId* dst, UA_NodeSetAliases* aliases);
-UA_Int32 UA_NodeSet_decodeXML(XML_Stack* s, XML_Attr* attr, UA_NodeSet* dst, _Bool isStart);
 
 UA_Int32 UA_ExpandedNodeId_copycstring(cstring src, UA_ExpandedNodeId* dst, UA_NodeSetAliases* aliases);
 
@@ -77,13 +99,13 @@ void XML_Stack_print(XML_Stack* s);
  * We would add two (@ref XML_Stack_addChildHandler), one for Locale (index 0) and one for Text (index 1),
  * both to be handled by (@ref UA_String_decodeXML) with elements "Data" and "Length". To handle the
  * abbreviation we add
- *   	XML_Stack_handleTextAsElementOf(s,"Data",1)
+ *      XML_Stack_handleTextAsElementOf(s,"Data",1)
  *
  * @param[in] s the stack
  * @param[in] textAttrib the name of the element of the handler at position textAttribIdx
  * @param[in] textAttribIdx the index of the handler
  */
-void XML_Stack_handleTextAsElementOf(XML_Stack* p, cstring textAttrib, unsigned int textAttribIdx);
+void XML_Stack_handleTextAsElementOf(XML_Stack *p, cstring textAttrib, unsigned int textAttribIdx);
 
 /** @brief make a handler known to the XML-stack on the current level
  *
@@ -97,29 +119,16 @@ void XML_Stack_handleTextAsElementOf(XML_Stack* p, cstring textAttrib, unsigned
  * @param[in] type the open62541-type of the element, UA_INVALIDTYPE if not in the VTable
  * @param[out] dst the address of the object for the data, handlers will allocate object if UA_NULL
  */
-void XML_Stack_addChildHandler(XML_Stack* p, cstring name, UA_Int32 nameLength, XML_decoder handler, UA_Int32 type, void* dst);
+void XML_Stack_addChildHandler(XML_Stack *p, cstring name, UA_Int32 nameLength, XML_decoder handler, UA_Int32 type,
+                               void *dst);
 
-void XML_Stack_startElement(void * data, const char *el, const char **attr);
+void XML_Stack_startElement(void *data, const char *el, const char **attr);
 UA_Int32 XML_isSpace(cstring s, int len);
-void XML_Stack_handleText(void * data, const char *txt, int len);
+void XML_Stack_handleText(void *data, const char *txt, int len);
 void XML_Stack_endElement(void *data, const char *el);
 
-/** @brief load a namespace from an XML-File
- *
- * @param[in/out] ns the address of the namespace ptr
- * @param[in] namespaceId the numeric id of the namespace
- * @param[in] rootName the name of the root element of the hierarchy (not used?)
- * @param[in] fileName the name of an existing file, e.g. Opc.Ua.NodeSet2.xml
- */
-UA_Int32 Namespace_loadFromFile(Namespace **ns,UA_UInt32 namespaceId,const char* rootName,const char* fileName);
-
-/** @brief load a namespace from a string
- *
- * @param[in/out] ns the address of the namespace ptr
- * @param[in] namespaceId the numeric id of the namespace
- * @param[in] rootName the name of the root element of the hierarchy (not used?)
- * @param[in] buffer the xml string
- */
-UA_Int32 Namespace_loadFromString(Namespace **ns,UA_UInt32 nsid,const char* rootName,const char* buffer);
+UA_Int32 UA_Text_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_Byte **dst, _Bool isStart);
+UA_Int32 UA_NodeId_copycstring(cstring src, UA_NodeId *dst, UA_NodeSetAliases *aliases);
+UA_Int32 UA_TypedArray_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_TypedArray *dst, _Bool isStart);
 
 #endif // __UA_XML_H__

+ 153 - 0
src/util/ua_base64.c

@@ -0,0 +1,153 @@
+/*
+begin library headers
+*/
+
+/*
+cdecode.h - c header for a base64 decoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+#ifndef BASE64_CDECODE_H
+#define BASE64_CDECODE_H
+
+typedef enum
+{
+	step_a, step_b, step_c, step_d
+} base64_decodestep;
+
+typedef struct
+{
+	base64_decodestep step;
+	char plainchar;
+} base64_decodestate;
+
+void base64_init_decodestate(base64_decodestate* state_in);
+
+int base64_decode_value(char value_in);
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in);
+
+#endif /* BASE64_CDECODE_H */
+
+/*
+end library headers
+*/
+
+#include "ua_base64.h"
+
+UA_Int32 UA_base64_getDecodedSize(UA_String* const base64EncodedData){
+	//note that base64-encoded data length is always divisible by 4
+	UA_Int32 temp = base64EncodedData->length * 3 / 4;
+
+	//subtract padding
+	if(base64EncodedData->data[base64EncodedData->length-1] == '=') {
+		temp--;
+		if(base64EncodedData->data[base64EncodedData->length-2] == '=') {
+			temp--;
+		}
+	}
+
+	return temp;
+}
+
+UA_Int32 UA_base64_decode(UA_String* const base64EncodedData, UA_Byte* target){
+	if(target == UA_NULL){
+		return UA_ERROR;
+	}
+	base64_decodestate state;
+	base64_init_decodestate(&state);
+	base64_decode_block((char*)(base64EncodedData->data), base64EncodedData->length, (char*)target, &state);
+	return UA_NO_ERROR;
+}
+
+/*
+begin library code
+*/
+
+/*
+cdecoder.c - c source to a base64 decoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+int base64_decode_value(char value_in)
+{
+	static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
+	static const char decoding_size = sizeof(decoding);
+	value_in -= 43;
+	if (value_in > decoding_size) return -1;
+	return decoding[(int)value_in];
+}
+
+void base64_init_decodestate(base64_decodestate* state_in)
+{
+	state_in->step = step_a;
+	state_in->plainchar = 0;
+}
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in)
+{
+	const char* codechar = code_in;
+	char* plainchar = plaintext_out;
+	signed char fragment;
+	
+	*plainchar = state_in->plainchar;
+	
+	switch (state_in->step)
+	{
+		while (1)
+		{
+	case step_a:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_a;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar    = (fragment & 0x03f) << 2;
+	case step_b:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_b;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar++ |= (fragment & 0x030) >> 4;
+			*plainchar    = (fragment & 0x00f) << 4;
+	case step_c:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_c;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar++ |= (fragment & 0x03c) >> 2;
+			*plainchar    = (fragment & 0x003) << 6;
+	case step_d:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_d;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar++   |= (fragment & 0x03f);
+		}
+	}
+	/* control should not reach here */
+	return plainchar - plaintext_out;
+}
+

+ 20 - 0
src/util/ua_base64.h

@@ -0,0 +1,20 @@
+/*
+ * ua_base64.h
+ *
+ *  Created on: Jun 10, 2014
+ *      Author: sten
+ */
+
+#ifndef UA_BASE64_H_
+#define UA_BASE64_H_
+
+#include "ua_types.h"
+#include "ua_util.h"
+
+/** @brief calculates the exact size for the binary data that is encoded in base64 encoded string */
+UA_Int32 UA_base64_getDecodedSize(UA_String* const base64EncodedData);
+
+/** @brief decodes base64 encoded string into target, target should be at least of the size returned by UA_base64_getDecodedSizeUB */
+UA_Int32 UA_base64_decode(UA_String* const base64EncodedData, UA_Byte* target);
+
+#endif /* UA_BASE64_H_ */

+ 1 - 0
src/util/ua_indexedList.c

@@ -1,4 +1,5 @@
 #include "ua_indexedList.h"
+#include "ua_util.h"
 
 void UA_indexedList_defaultFreer(void* payload){
 	UA_list_defaultFreer(payload);

+ 1 - 1
include/ua_indexedList.h

@@ -1,7 +1,7 @@
 #ifndef UA_INDEXEDLIST_H_
 #define UA_INDEXEDLIST_H_
 
-#include "opcua.h"
+#include "ua_types.h"
 /* UA_indexedList reuses many types of UA_list */
 #include "ua_list.h"
 

+ 2 - 0
src/util/ua_list.c

@@ -1,4 +1,5 @@
 #include "ua_list.h"
+#include "ua_util.h"
 
 void UA_list_defaultFreer(void* payload){
 	if(payload){
@@ -108,6 +109,7 @@ UA_Int32 UA_list_removeLast(UA_list_List* list, UA_list_PayloadVisitor visitor){
 			(*visitor)(list->last->payload);
 		}
 		UA_free(list->last);
+		temp->next = UA_NULL;
 		list->last = temp;
 		list->size--;
 		if(list->size == 1){

+ 0 - 1
include/ua_list.h

@@ -5,7 +5,6 @@
 #include <stddef.h> /* Needed for sys/queue.h */
 #include <sys/queue.h>
 
-
 /**********************/
 /* Singly Linked List */
 /**********************/

+ 29 - 0
src/util/ua_util.c

@@ -0,0 +1,29 @@
+#include "ua_util.h"
+
+
+UA_Int32 _UA_free(void *ptr, char *pname, char *f, UA_Int32 l) {
+	DBG_VERBOSE(printf("UA_free;%p;;%s;;%s;%d\n", ptr, pname, f, l); fflush(stdout));
+	free(ptr); // checks if ptr != NULL in the background
+	return UA_SUCCESS;
+}
+
+UA_Int32 _UA_alloc(void **ptr, UA_Int32 size, char *pname, char *sname, char *f, UA_Int32 l) {
+	if(ptr == UA_NULL) return UA_ERR_INVALID_VALUE;
+	UA_alloc_lastptr = *ptr = malloc(size);
+	DBG_VERBOSE(printf("UA_alloc - %p;%d;%s;%s;%s;%d\n", *ptr, size, pname, sname, f, l); fflush(stdout));
+	if(*ptr == UA_NULL) return UA_ERR_NO_MEMORY;
+	return UA_SUCCESS;
+}
+
+UA_Int32 UA_memcpy(void *dst, void const *src, UA_Int32 size) {
+	if(dst == UA_NULL) return UA_ERR_INVALID_VALUE;
+	DBG_VERBOSE(printf("UA_memcpy - %p;%p;%d\n", dst, src, size));
+	memcpy(dst, src, size);
+	return UA_SUCCESS;
+}
+
+UA_Int32 UA_VTable_isValidType(UA_Int32 type) {
+	if(type < 0 /* UA_BOOLEAN */ || type > 271 /* UA_INVALID */)
+		return UA_ERR_INVALID_VALUE;
+	return UA_SUCCESS;
+}

+ 38 - 0
src/util/ua_util.h

@@ -0,0 +1,38 @@
+#ifndef UA_UTILITY_H_
+#define UA_UTILITY_H_
+
+#include <stdio.h>  // printf
+#include <stdlib.h> // malloc, free
+#include <string.h> // memcpy
+#include "ua_types.h"
+
+/* Debug macros */
+#define DBG_VERBOSE(expression) // omit debug code
+#define DBG_ERR(expression)     // omit debug code
+#define DBG(expression)         // omit debug code
+#if defined(DEBUG)              // --enable-debug=(yes|verbose)
+# undef DBG
+# define DBG(expression) expression
+# undef DBG_ERR
+# define DBG_ERR(expression) expression
+# if defined(VERBOSE)   // --enable-debug=verbose
+#  undef DBG_VERBOSE
+#  define DBG_VERBOSE(expression) expression
+# endif
+#endif
+
+/* Global Variables */
+extern UA_ByteString UA_ByteString_securityPoliceNone;
+void const *UA_alloc_lastptr;
+
+/* Heap memory functions */
+#define UA_NULL ((void *)0)
+UA_Int32 _UA_free(void *ptr, char *pname, char *f, UA_Int32 l);
+UA_Int32 _UA_alloc(void **ptr, UA_Int32 size, char *pname, char *sname, char *f, UA_Int32 l);
+UA_Int32 UA_memcpy(void *dst, void const *src, UA_Int32 size);
+UA_Int32 UA_VTable_isValidType(UA_Int32 type);
+
+#define UA_free(ptr) _UA_free(ptr, # ptr, __FILE__, __LINE__)
+#define UA_alloc(ptr, size) _UA_alloc(ptr, size, # ptr, # size, __FILE__, __LINE__)
+
+#endif /* UA_UTILITY_H_ */

+ 4 - 0
tests/.gitignore

@@ -2,3 +2,7 @@
 /check_list
 /check_stack
 /check_indexedList
+/check_base64
+/check_services_view
+/check_xml
+			

+ 3 - 3
tests/Makefile.am

@@ -3,7 +3,7 @@ TESTS=
 UNIT_TESTS=
 check_PROGRAMS=
 
-UNIT_TESTS += check_stack check_list check_indexedList check_builtin check_namespace check_memory check_services_view check_xml
+UNIT_TESTS += check_stack check_list check_indexedList check_builtin check_namespace check_memory check_services_view check_base64
 TESTS += $(UNIT_TESTS)
 check_PROGRAMS += $(UNIT_TESTS)
 
@@ -26,8 +26,8 @@ check_memory-mem: check_memory
 	
 clean-local:
 	rm -rf coverage || true;
-	rm -rf *.gcda *.gcdo *.gcno 
-	lcov --directory . --zerocounters
+	rm -rf *.gcda *.gcdo *.gcno *.o *.gcov *.log *.trs
+	lcov --directory . --zerocounters || true;
 	
 # --- no changes beyond this line needed ---
 INCLUDE = @CHECK_CFLAGS@ -I$(top_builddir)/src -I$(top_builddir)/include

+ 115 - 0
tests/check_base64.c

@@ -0,0 +1,115 @@
+#include <stdlib.h> // EXIT_SUCCESS
+#include "util/ua_base64.h"
+#include "check.h"
+
+START_TEST(base64_test_2padding)
+{
+	//this is base64'd ASCII string "open62541!"
+	UA_String encodedString = UA_STRING_STATIC("b3BlbjYyNTQxIQ==");
+
+	//assure that we allocate exactly 10 bytes
+	ck_assert_int_eq(UA_base64_getDecodedSize(&encodedString), 10);
+
+	UA_Byte* decodedData = (UA_Byte*)malloc(UA_base64_getDecodedSize(&encodedString));
+
+	UA_base64_decode(&encodedString, decodedData);
+
+	//check the string
+	ck_assert_int_eq(decodedData[0], 'o');
+	ck_assert_int_eq(decodedData[1], 'p');
+	ck_assert_int_eq(decodedData[2], 'e');
+	ck_assert_int_eq(decodedData[3], 'n');
+	ck_assert_int_eq(decodedData[4], '6');
+	ck_assert_int_eq(decodedData[5], '2');
+	ck_assert_int_eq(decodedData[6], '5');
+	ck_assert_int_eq(decodedData[7], '4');
+	ck_assert_int_eq(decodedData[8], '1');
+	ck_assert_int_eq(decodedData[9], '!');
+
+	free(decodedData);
+}
+END_TEST
+
+START_TEST(base64_test_1padding)
+{
+
+	//this is base64'd ASCII string "open62541!!"
+	UA_String encodedString = UA_STRING_STATIC("b3BlbjYyNTQxISE=");
+
+	//assure that we allocate exactly 11 bytes
+	ck_assert_int_eq(UA_base64_getDecodedSize(&encodedString), 11);
+
+	UA_Byte* decodedData = (UA_Byte*)malloc(UA_base64_getDecodedSize(&encodedString));
+
+	UA_base64_decode(&encodedString, decodedData);
+
+	//check the string
+	ck_assert_int_eq(decodedData[0], 'o');
+	ck_assert_int_eq(decodedData[1], 'p');
+	ck_assert_int_eq(decodedData[2], 'e');
+	ck_assert_int_eq(decodedData[3], 'n');
+	ck_assert_int_eq(decodedData[4], '6');
+	ck_assert_int_eq(decodedData[5], '2');
+	ck_assert_int_eq(decodedData[6], '5');
+	ck_assert_int_eq(decodedData[7], '4');
+	ck_assert_int_eq(decodedData[8], '1');
+	ck_assert_int_eq(decodedData[9], '!');
+	ck_assert_int_eq(decodedData[10], '!');
+
+	free(decodedData);
+}
+END_TEST
+
+START_TEST(base64_test_0padding)
+{
+
+	//this is base64'd ASCII string "open62541"
+	UA_String encodedString = UA_STRING_STATIC("b3BlbjYyNTQx");
+
+	//assure that we allocate exactly 9 bytes
+	ck_assert_int_eq(UA_base64_getDecodedSize(&encodedString), 9);
+
+	UA_Byte* decodedData = (UA_Byte*)malloc(UA_base64_getDecodedSize(&encodedString));
+
+	UA_base64_decode(&encodedString, decodedData);
+
+	//check the string
+	ck_assert_int_eq(decodedData[0], 'o');
+	ck_assert_int_eq(decodedData[1], 'p');
+	ck_assert_int_eq(decodedData[2], 'e');
+	ck_assert_int_eq(decodedData[3], 'n');
+	ck_assert_int_eq(decodedData[4], '6');
+	ck_assert_int_eq(decodedData[5], '2');
+	ck_assert_int_eq(decodedData[6], '5');
+	ck_assert_int_eq(decodedData[7], '4');
+	ck_assert_int_eq(decodedData[8], '1');
+
+	free(decodedData);
+}
+END_TEST
+
+Suite*base64_testSuite(void)
+{
+	Suite *s = suite_create("base64_test");
+	TCase *tc_core = tcase_create("Core");
+	tcase_add_test(tc_core, base64_test_2padding);
+	tcase_add_test(tc_core, base64_test_1padding);
+	tcase_add_test(tc_core, base64_test_0padding);
+	suite_add_tcase(s,tc_core);
+	return s;
+}
+
+int main (void)
+{
+	int number_failed = 0;
+
+	Suite* s = base64_testSuite();
+	SRunner* sr = srunner_create(s);
+	srunner_run_all(sr,CK_NORMAL);
+	number_failed += srunner_ntests_failed(sr);
+	srunner_free(sr);
+
+	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+
+}
+

File diff suppressed because it is too large
+ 822 - 995
tests/check_builtin.c


+ 28 - 2
tests/check_indexedList.c

@@ -1,6 +1,6 @@
 #include <stdlib.h> // EXIT_SUCCESS
-#include "ua_indexedList.h"
-
+#include "util/ua_indexedList.h"
+#include "util/ua_util.h"
 #include "check.h"
 
 /* global test counters */
@@ -28,6 +28,29 @@ _Bool matcher(void* payload){
 	return FALSE;
 }
 
+START_TEST(linkedList_test_destroyemptylist)
+{
+	UA_indexedList_List list;
+	UA_indexedList_init(&list);
+	ck_assert_int_eq(list.size, 0);
+	UA_indexedList_destroy(&list, UA_indexedList_defaultFreer);
+	ck_assert_int_eq(list.size, 0);
+}
+END_TEST
+
+START_TEST(linkedList_test_destroysingle)
+{
+	UA_indexedList_List list;
+	UA_indexedList_init(&list);
+	ck_assert_int_eq(list.size, 0);
+	UA_Int32* payload = (UA_Int32*)malloc(sizeof(*payload));
+	*payload = 10;
+	UA_indexedList_addValue(&list, 1, payload);
+	UA_indexedList_destroy(&list, UA_indexedList_defaultFreer);
+	ck_assert_int_eq(list.size, 0);
+}
+END_TEST
+	
 START_TEST(linkedList_test_basic)
 {
 
@@ -76,6 +99,7 @@ START_TEST(linkedList_test_basic)
 
 	ck_assert_int_eq(free_count, 2);
 	ck_assert_int_eq(list.size, 0);
+	
 }
 END_TEST
 
@@ -84,6 +108,8 @@ Suite*linkedList_testSuite(void)
 	Suite *s = suite_create("linkedList_test");
 	TCase *tc_core = tcase_create("Core");
 	tcase_add_test(tc_core, linkedList_test_basic);
+	tcase_add_test(tc_core, linkedList_test_destroyemptylist);
+	tcase_add_test(tc_core, linkedList_test_destroysingle);
 	suite_add_tcase(s,tc_core);
 	return s;
 }

+ 2 - 1
tests/check_list.c

@@ -1,5 +1,6 @@
 #include <stdlib.h> // EXIT_SUCCESS
-#include "ua_list.h"
+#include "util/ua_util.h"
+#include "util/ua_list.h"
 #include "check.h"
 
 /* global test counters */

+ 109 - 105
tests/check_memory.c

@@ -1,155 +1,158 @@
-/*
- * check_memory.c
- *
- *  Created on: 10.04.2014
- *      Author: mrt
- */
-
 #define _XOPEN_SOURCE 500
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "opcua.h"
+#include "ua_types.h"
+#include "util/ua_util.h"
+#include "ua_namespace_0.h"
 #include "check.h"
 
-START_TEST (newAndEmptyObjectShallBeDeleted)
-{
+START_TEST(newAndEmptyObjectShallBeDeleted) {
 	// given
 	UA_Int32 retval;
-	void* obj;
+	void    *obj;
 	// when
-	retval = UA_[_i].new(&obj);
-	retval |= UA_[_i].delete(obj);
+	retval  = UA_.types[_i].new(&obj);
+#ifdef DEBUG //no print functions if not in debug mode
+	UA_.types[_i].print(obj, stdout);
+#endif
+	retval |= UA_.types[_i].delete(obj);
 	// then
-	ck_assert_int_eq(retval,UA_SUCCESS);
+	ck_assert_int_eq(retval, UA_SUCCESS);
 }
 END_TEST
 
-START_TEST (arrayCopyShallMakeADeepCopy)
-{
+START_TEST(arrayCopyShallMakeADeepCopy) {
 	// given
-	UA_String **a1; UA_Array_new((void***)&a1,3,UA_STRING);
-	UA_String_copycstring("a",a1[0]);
-	UA_String_copycstring("bb",a1[1]);
-	UA_String_copycstring("ccc",a1[2]);
+	UA_String a1[3];
+	a1[0] = (UA_String){1, (UA_Byte*)"a"};
+	a1[1] = (UA_String){2, (UA_Byte*)"bb"};
+	a1[2] = (UA_String){3, (UA_Byte*)"ccc"};
 	// when
-	UA_String **a2;
-	UA_Int32 retval = UA_Array_copy((void const*const*)a1,3,UA_STRING,(void ***)&a2);
+	UA_String *a2;
+	UA_Int32   retval = UA_Array_copy((const void *)a1, 3, &UA_.types[UA_STRING], (void **)&a2);
 	// then
-	ck_assert_int_eq(retval,UA_SUCCESS);
-	ck_assert_int_eq(((UA_String **)a1)[0]->length,1);
-	ck_assert_int_eq(((UA_String **)a1)[1]->length,2);
-	ck_assert_int_eq(((UA_String **)a1)[2]->length,3);
-	ck_assert_int_eq(((UA_String **)a1)[0]->length,((UA_String **)a2)[0]->length);
-	ck_assert_int_eq(((UA_String **)a1)[1]->length,((UA_String **)a2)[1]->length);
-	ck_assert_int_eq(((UA_String **)a1)[2]->length,((UA_String **)a2)[2]->length);
-	ck_assert_ptr_ne(((UA_String **)a1)[0]->data,((UA_String **)a2)[0]->data);
-	ck_assert_ptr_ne(((UA_String **)a1)[1]->data,((UA_String **)a2)[1]->data);
-	ck_assert_ptr_ne(((UA_String **)a1)[2]->data,((UA_String **)a2)[2]->data);
-	ck_assert_int_eq(((UA_String **)a1)[0]->data[0],((UA_String **)a2)[0]->data[0]);
-	ck_assert_int_eq(((UA_String **)a1)[1]->data[0],((UA_String **)a2)[1]->data[0]);
-	ck_assert_int_eq(((UA_String **)a1)[2]->data[0],((UA_String **)a2)[2]->data[0]);
+	ck_assert_int_eq(retval, UA_SUCCESS);
+	ck_assert_int_eq(a1[0].length, 1);
+	ck_assert_int_eq(a1[1].length, 2);
+	ck_assert_int_eq(a1[2].length, 3);
+	ck_assert_int_eq(a1[0].length, a2[0].length);
+	ck_assert_int_eq(a1[1].length, a2[1].length);
+	ck_assert_int_eq(a1[2].length, a2[2].length);
+	ck_assert_ptr_ne(a1[0].data, a2[0].data);
+	ck_assert_ptr_ne(a1[1].data, a2[1].data);
+	ck_assert_ptr_ne(a1[2].data, a2[2].data);
+	ck_assert_int_eq(a1[0].data[0], a2[0].data[0]);
+	ck_assert_int_eq(a1[1].data[0], a2[1].data[0]);
+	ck_assert_int_eq(a1[2].data[0], a2[2].data[0]);
 	// finally
-	UA_Array_delete((void***)&a1,3,UA_STRING);
-	UA_Array_delete((void***)&a2,3,UA_STRING);
+	UA_Array_delete((void *)a2, 3, &UA_.types[UA_STRING]);
 }
 END_TEST
 
-START_TEST (encodeShallYieldDecode)
-{
+START_TEST(encodeShallYieldDecode) {
 	// given
-	void *obj1 = UA_NULL, *obj2 = UA_NULL;
+	void         *obj1 = UA_NULL, *obj2 = UA_NULL;
 	UA_ByteString msg1, msg2;
-	UA_Int32 retval, pos = 0;
-	retval = UA_[_i].new(&obj1);
-	UA_ByteString_newMembers(&msg1,UA_[_i].calcSize(obj1));
-	retval = UA_[_i].encodeBinary(obj1, &pos, &msg1);
+	UA_Int32      retval;
+	UA_UInt32     pos = 0;
+	retval = UA_.types[_i].new(&obj1);
+	UA_ByteString_newMembers(&msg1, UA_.types[_i].encodings[UA_ENCODING_BINARY].calcSize(obj1));
+	retval |= UA_.types[_i].encodings[UA_ENCODING_BINARY].encode(obj1, &msg1, &pos);
+	if(retval != UA_SUCCESS) {
+		// this happens, e.g. when we encode a variant (with UA_.types[UA_INVALIDTYPE] in the vtable)
+		UA_.types[_i].delete(obj1);
+		UA_ByteString_deleteMembers(&msg1);
+		return;	
+	}
+
 	// when
-	UA_[_i].new(&obj2);
-	pos = 0; retval = UA_[_i].decodeBinary(&msg1, &pos, obj2);
-	UA_ByteString_newMembers(&msg2,UA_[_i].calcSize(obj2));
-	pos = 0; retval = UA_[_i].encodeBinary(obj2, &pos, &msg2);
+	UA_.types[_i].new(&obj2);
+	pos = 0; retval = UA_.types[_i].encodings[UA_ENCODING_BINARY].decode(&msg1, &pos, obj2);
+	ck_assert_msg(retval == UA_SUCCESS, "messages differ idx=%d,name=%s", _i, UA_.types[_i].name);
+	retval = UA_ByteString_newMembers(&msg2, UA_.types[_i].encodings[UA_ENCODING_BINARY].calcSize(obj2));
+	ck_assert_int_eq(retval, UA_SUCCESS);
+	pos = 0; retval = UA_.types[_i].encodings[UA_ENCODING_BINARY].encode(obj2, &msg2, &pos);
+	ck_assert_int_eq(retval, UA_SUCCESS);
+
 	// then
-	ck_assert_msg(UA_ByteString_compare(&msg1,&msg2)==0,"messages differ idx=%d,name=%s",_i,UA_[_i].name);
-	ck_assert_int_eq(retval,UA_SUCCESS);
+	ck_assert_msg(UA_ByteString_equal(&msg1, &msg2) == 0, "messages differ idx=%d,name=%s", _i, UA_.types[_i].name);
+
 	// finally
-	UA_[_i].delete(obj1);
-	UA_[_i].delete(obj2);
+	UA_.types[_i].delete(obj1);
+	UA_.types[_i].delete(obj2);
 	UA_ByteString_deleteMembers(&msg1);
 	UA_ByteString_deleteMembers(&msg2);
 }
 END_TEST
 
-START_TEST (decodeShallFailWithTruncatedBufferButSurvive)
-{
+START_TEST(decodeShallFailWithTruncatedBufferButSurvive) {
 	// given
 	void *obj1 = UA_NULL, *obj2 = UA_NULL;
 	UA_ByteString msg1;
-	UA_Int32 pos;
-	UA_[_i].new(&obj1);
-	UA_ByteString_newMembers(&msg1,UA_[_i].calcSize(obj1));
-	pos = 0; UA_[_i].encodeBinary(obj1, &pos, &msg1);
-	UA_[_i].delete(obj1);
+	UA_UInt32 pos;
+	UA_.types[_i].new(&obj1);
+	UA_ByteString_newMembers(&msg1, UA_.types[_i].encodings[0].calcSize(obj1));
+	pos = 0; UA_.types[_i].encodings[0].encode(obj1, &msg1, &pos);
+	UA_.types[_i].delete(obj1);
 	// when
-	UA_[_i].new(&obj2);
+	UA_.types[_i].new(&obj2);
 	pos = 0;
 	msg1.length = msg1.length / 2;
 	//fprintf(stderr,"testing %s with half buffer\n",UA_[_i].name);
-	UA_[_i].decodeBinary(&msg1, &pos, obj2);
+	UA_.types[_i].encodings[0].decode(&msg1, &pos, obj2);
 	//then
 	// finally
 	//fprintf(stderr,"delete %s with half buffer\n",UA_[_i].name);
-	UA_[_i].delete(obj2);
+	UA_.types[_i].delete(obj2);
 	UA_ByteString_deleteMembers(&msg1);
 }
 END_TEST
 
-START_TEST (decodeScalarBasicTypeFromRandomBufferShallSucceed)
-{
+START_TEST(decodeScalarBasicTypeFromRandomBufferShallSucceed) {
 	// given
 	void *obj1 = UA_NULL;
 	UA_ByteString msg1;
-	UA_Int32 retval, buflen;
-	buflen = 256;
-	UA_ByteString_newMembers(&msg1,buflen); // fixed size
+	UA_Int32 retval = UA_SUCCESS;
+	UA_Int32 buflen = 256;
+	UA_ByteString_newMembers(&msg1, buflen); // fixed size
 	srandom(42);
-	retval = UA_SUCCESS;
-	for(int n=0;n<100;n++) {
-		retval |= UA_[_i].new(&obj1);
-		UA_Int32 i; for(i=0;i<buflen;i++) { msg1.data[i] = (UA_Byte) random(); }
-		// when
-		UA_Int32 pos = 0;
-		retval |= UA_[_i].decodeBinary(&msg1, &pos, obj1);
+	for(int n = 0;n < 100;n++) {
+		for(UA_Int32 i = 0;i < buflen;i++) msg1.data[i] = (UA_Byte)random();  // when
+		UA_UInt32 pos = 0;
+		retval |= UA_.types[_i].new(&obj1);
+		retval |= UA_.types[_i].encodings[0].decode(&msg1, &pos, obj1);
 		//then
-		ck_assert_msg(retval==UA_SUCCESS,"Decoding %s from random buffer",UA_[_i].name);
+		ck_assert_msg(retval == UA_SUCCESS, "Decoding %s from random buffer", UA_.types[_i].name);
 		// finally
-		UA_[_i].delete(obj1);
+		UA_.types[_i].delete(obj1);
 	}
 	UA_ByteString_deleteMembers(&msg1);
 }
 END_TEST
 
-START_TEST (decodeComplexTypeFromRandomBufferShallSurvive)
-{
+START_TEST(decodeComplexTypeFromRandomBufferShallSurvive) {
 	// given
-	void *obj1 = UA_NULL;
+	void    *obj1 = UA_NULL;
 	UA_ByteString msg1;
-	UA_Int32 retval, buflen;
-	buflen = 256;
-	UA_ByteString_newMembers(&msg1,buflen); // fixed size
+	UA_Int32 retval = UA_SUCCESS;
+	UA_Int32 buflen = 256;
+	UA_ByteString_newMembers(&msg1, buflen); // fixed size
 	srandom(42);
-	retval = UA_SUCCESS;
-	for(int n=0;n<100;n++) {
-		retval |= UA_[_i].new(&obj1);
-		UA_Int32 i; for(i=0;i<buflen;i++) { msg1.data[i] = (UA_Byte) random(); }
-		// when
-		UA_Int32 pos = 0;
-		retval |= UA_[_i].decodeBinary(&msg1, &pos, obj1);
-		//then
-		ck_assert_msg(retval==UA_SUCCESS||retval==UA_ERROR,"Decoding %s from random buffer",UA_[_i].name);
-		// finally
-		UA_[_i].delete(obj1);
+	// when
+	for(int n = 0;n < 100;n++) {
+		for(UA_Int32 i = 0;i < buflen;i++) msg1.data[i] = (UA_Byte)random();
+		UA_UInt32 pos = 0;
+		retval |= UA_.types[_i].new(&obj1);
+		retval |= UA_.types[_i].encodings[0].decode(&msg1, &pos, obj1);
+
+		//this is allowed to fail and return UA_ERROR
+		//ck_assert_msg(retval == UA_SUCCESS, "Decoding %s from random buffer", UA_.types[_i].name);
+		
+		UA_.types[_i].delete(obj1);
 	}
+
+	// finally
 	UA_ByteString_deleteMembers(&msg1);
 }
 END_TEST
@@ -158,25 +161,26 @@ int main() {
 	int number_failed = 0;
 	SRunner *sr;
 
-	Suite *s = suite_create("testMemoryHandling");
-	TCase *tc = tcase_create("Empty Objects");
-	tcase_add_loop_test(tc, newAndEmptyObjectShallBeDeleted,UA_BOOLEAN,UA_INVALIDTYPE-1);
+	Suite   *s  = suite_create("testMemoryHandling");
+	TCase   *tc = tcase_create("Empty Objects");
+	tcase_add_loop_test(tc, newAndEmptyObjectShallBeDeleted, UA_BOOLEAN, UA_INVALIDTYPE-1);
 	tcase_add_test(tc, arrayCopyShallMakeADeepCopy);
-	tcase_add_loop_test(tc, encodeShallYieldDecode,UA_BOOLEAN,UA_INVALIDTYPE-1);
-	suite_add_tcase(s,tc);
+	tcase_add_loop_test(tc, encodeShallYieldDecode, UA_BOOLEAN, UA_INVALIDTYPE-1);
+	suite_add_tcase(s, tc);
 	tc = tcase_create("Truncated Buffers");
-	tcase_add_loop_test(tc, decodeShallFailWithTruncatedBufferButSurvive,UA_BOOLEAN,UA_INVALIDTYPE-1);
-	suite_add_tcase(s,tc);
+	tcase_add_loop_test(tc, decodeShallFailWithTruncatedBufferButSurvive, UA_BOOLEAN, UA_INVALIDTYPE-1);
+	suite_add_tcase(s, tc);
 
 	tc = tcase_create("Fuzzing with Random Buffers");
-	tcase_add_loop_test(tc, decodeScalarBasicTypeFromRandomBufferShallSucceed,UA_BOOLEAN,UA_DOUBLE);
-	tcase_add_loop_test(tc, decodeComplexTypeFromRandomBufferShallSurvive,UA_STRING,UA_DIAGNOSTICINFO);
-	tcase_add_loop_test(tc, decodeComplexTypeFromRandomBufferShallSurvive,UA_IDTYPE,UA_INVALIDTYPE);
+	tcase_add_loop_test(tc, decodeScalarBasicTypeFromRandomBufferShallSucceed, UA_BOOLEAN, UA_DOUBLE);
+	tcase_add_loop_test(tc, decodeComplexTypeFromRandomBufferShallSurvive, UA_STRING, UA_DIAGNOSTICINFO);
+	tcase_add_loop_test(tc, decodeComplexTypeFromRandomBufferShallSurvive, UA_IDTYPE, UA_INVALIDTYPE);
+	suite_add_tcase(s, tc);
 
 	sr = srunner_create(s);
 	//for debugging puposes only, will break make check
-	//srunner_set_fork_status(sr,CK_NOFORK);
-	srunner_run_all(sr,CK_NORMAL);
+	//srunner_set_fork_status(sr, CK_NOFORK);
+	srunner_run_all (sr, CK_NORMAL);
 	number_failed += srunner_ntests_failed(sr);
 	srunner_free(sr);
 

+ 1 - 1
tests/check_namespace.c

@@ -1,7 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "opcua.h"
+#include "ua_types.h"
 #include "ua_namespace.h"
 #include "check.h"
 

+ 14 - 12
tests/check_services_view.c

@@ -11,28 +11,30 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "opcua.h"
+#include "ua_types.h"
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 #include "check.h"
 
-
-
 START_TEST(Service_TranslateBrowsePathsToNodeIds_SmokeTest)
 {
-	UA_TranslateBrowsePathsToNodeIdsRequest* request;
-	UA_TranslateBrowsePathsToNodeIdsRequest_new(&request);
+	UA_TranslateBrowsePathsToNodeIdsRequest request;
+	UA_TranslateBrowsePathsToNodeIdsRequest_init(&request);
+
+	UA_TranslateBrowsePathsToNodeIdsResponse response;
+	UA_TranslateBrowsePathsToNodeIdsResponse_init(&response);
 
-	UA_TranslateBrowsePathsToNodeIdsResponse* response;
-	UA_TranslateBrowsePathsToNodeIdsResponse_new(&response);
+	request.browsePathsSize = 1;
+	UA_Array_new((void**)&request.browsePaths,request.browsePathsSize, &UA_.types[UA_BROWSEPATH]);
 
-	request->browsePathsSize = 1;
-	UA_Array_new((void***)&(request->browsePaths),request->browsePathsSize,UA_BROWSEPATH);
+	Service_TranslateBrowsePathsToNodeIds(UA_NULL,&request,&response);
 
-	Service_TranslateBrowsePathsToNodeIds(UA_NULL,request,response);
+	ck_assert_int_eq(response.resultsSize,request.browsePathsSize);
+	ck_assert_int_eq(response.results[0].statusCode,UA_STATUSCODE_BADNOMATCH);
 
-	ck_assert_int_eq(response->resultsSize,request->browsePathsSize);
-	ck_assert_int_eq(response->results[0]->statusCode,UA_STATUSCODE_BADQUERYTOOCOMPLEX);
+	//finally
+	UA_TranslateBrowsePathsToNodeIdsRequest_deleteMembers(&request);
+	UA_TranslateBrowsePathsToNodeIdsResponse_deleteMembers(&response);
 }
 END_TEST
 

+ 294 - 290
tests/check_stack.c

@@ -1,27 +1,7 @@
-/****************************************************************************
- Name        : check_stack.c
- Author      : uleon @ open62541
- Version     : 0.1
- Copyright   : Your copyright notice
- Description : test cases to check different aspects of the
- stack indication-response behavior w/o any network aspects
-
-
-```
- Client            Server
-
-request  o--__
-              --> indication        +
-                                    | <---
-            __--o response          +
-confirm. <--
-```
-*****************************************************************************/
-
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "opcua.h"
+#include "ua_types.h"
 #include "ua_transport.h"
 #include "ua_transport_binary.h"
 #include "ua_transport_binary_secure.h"
@@ -47,24 +27,25 @@ typedef struct stackTestFixture {
 /** @brief this map marks the slots in fixtures as free (bit=0) or in use (bit=1) */
 UA_Int32 fixturesMap = 0;
 /** @brief the array of pointers to the fixtures */
-stackTestFixture* fixtures[MAX_FIXTURES];
+stackTestFixture *fixtures[MAX_FIXTURES];
 
 /** @brief search first free handle, set and return */
 UA_Int32 stackTestFixture_getAndMarkFreeHandle() {
 	UA_Int32 freeFixtureHandle = 0;
 
-	for (freeFixtureHandle=0;freeFixtureHandle < MAX_FIXTURES;++freeFixtureHandle) {
-		if (!(fixturesMap & (1 << freeFixtureHandle))) { // when free
-			fixturesMap |= (1 << freeFixtureHandle); // then set
+	for(freeFixtureHandle = 0;freeFixtureHandle < MAX_FIXTURES;++freeFixtureHandle) {
+		if(!(fixturesMap & (1 << freeFixtureHandle))) { // when free
+			fixturesMap |= (1 << freeFixtureHandle);    // then set
 			return freeFixtureHandle;
 		}
 	}
 	return UA_ERR_NO_MEMORY;
 }
+
 /** @brief clear bit in fixture map */
 UA_Int32 stackTestFixture_markHandleAsFree(UA_Int32 fixtureHandle) {
-	if (fixtureHandle >= 0 && fixtureHandle < MAX_FIXTURES) {
-		fixturesMap &= ~ (1 << fixtureHandle); // clear bit
+	if(fixtureHandle >= 0 && fixtureHandle < MAX_FIXTURES) {
+		fixturesMap &= ~(1 << fixtureHandle);  // clear bit
 		return UA_SUCCESS;
 	}
 	return UA_ERR_INVALID_VALUE;
@@ -73,25 +54,25 @@ UA_Int32 stackTestFixture_markHandleAsFree(UA_Int32 fixtureHandle) {
 /** @brief get a handle to a free slot and create a new stackTestFixture */
 UA_Int32 stackTestFixture_create(TL_Writer writerCallback) {
 	UA_UInt32 fixtureHandle = stackTestFixture_getAndMarkFreeHandle();
-	if (fixtureHandle < MAX_FIXTURES) {
-		UA_alloc((void**)&fixtures[fixtureHandle], sizeof(stackTestFixture));
-		stackTestFixture* fixture = fixtures[fixtureHandle];
-		fixture->respMsg.data = fixture->respMsgBuffer;
+	if(fixtureHandle < MAX_FIXTURES) {
+		UA_alloc((void **)&fixtures[fixtureHandle], sizeof(stackTestFixture));
+		stackTestFixture *fixture = fixtures[fixtureHandle];
+		fixture->respMsg.data   = fixture->respMsgBuffer;
 		fixture->respMsg.length = 0;
 		fixture->connection.connectionState = CONNECTIONSTATE_CLOSED;
-		fixture->connection.writerCallback = writerCallback;
-		fixture->connection.localConf.maxChunkCount = 1;
-		fixture->connection.localConf.maxMessageSize = BUFFER_SIZE;
+		fixture->connection.writerCallback  = writerCallback;
+		fixture->connection.localConf.maxChunkCount   = 1;
+		fixture->connection.localConf.maxMessageSize  = BUFFER_SIZE;
 		fixture->connection.localConf.protocolVersion = 0;
-		fixture->connection.localConf.recvBufferSize = BUFFER_SIZE;
-		fixture->connection.localConf.recvBufferSize = BUFFER_SIZE;
+		fixture->connection.localConf.recvBufferSize  = BUFFER_SIZE;
+		fixture->connection.localConf.recvBufferSize  = BUFFER_SIZE;
 		fixture->connection.connectionHandle = fixtureHandle;
 	}
 	return fixtureHandle;
 }
 /** @brief free the allocated memory of the stackTestFixture associated with the handle */
 UA_Int32 stackTestFixture_delete(UA_UInt32 fixtureHandle) {
-	if (fixtureHandle < MAX_FIXTURES) {
+	if(fixtureHandle < MAX_FIXTURES) {
 		UA_free(fixtures[fixtureHandle]);
 		stackTestFixture_markHandleAsFree(fixtureHandle);
 		return UA_SUCCESS;
@@ -100,262 +81,266 @@ UA_Int32 stackTestFixture_delete(UA_UInt32 fixtureHandle) {
 }
 
 /** @brief return the fixture associated with the handle */
-stackTestFixture* stackTestFixture_getFixture(UA_UInt32 fixtureHandle) {
-	if (fixtureHandle < MAX_FIXTURES && ( fixturesMap & (1 << fixtureHandle)))
-			return fixtures[fixtureHandle];
+stackTestFixture *stackTestFixture_getFixture(UA_UInt32 fixtureHandle) {
+	if(fixtureHandle < MAX_FIXTURES && ( fixturesMap & (1 << fixtureHandle)))
+		return fixtures[fixtureHandle];
 	return UA_NULL;
 }
 
 /** @brief write message provided in the gather buffers to the buffer of the fixture */
-UA_Int32 responseMsg(struct TL_Connection * c, UA_ByteString const ** gather_buf, UA_Int32 gather_len) {
-	UA_Int32 retval = UA_SUCCESS;
+UA_Int32 responseMsg(struct TL_Connection *c, UA_ByteString const **gather_buf, UA_Int32 gather_len) {
+	stackTestFixture *fixture = stackTestFixture_getFixture(c->connectionHandle);
+	UA_Int32  retval    = UA_SUCCESS;
 	UA_UInt32 total_len = 0;
 
-	stackTestFixture* fixture = stackTestFixture_getFixture(c->connectionHandle);
-
-	for (UA_Int32 i=0; i<gather_len && retval == UA_SUCCESS; ++i) {
-		if (total_len + gather_buf[i]->length < BUFFER_SIZE) {
-			memcpy(&(fixture->respMsg.data[total_len]),gather_buf[i]->data,gather_buf[i]->length);
+	for(UA_Int32 i = 0;i < gather_len && retval == UA_SUCCESS;++i) {
+		if(total_len + gather_buf[i]->length < BUFFER_SIZE) {
+			memcpy(&(fixture->respMsg.data[total_len]), gather_buf[i]->data, gather_buf[i]->length);
 			total_len += gather_buf[i]->length;
-		} else {
+		} else
 			retval = UA_ERR_NO_MEMORY;
-		}
 	}
 	fixture->respMsg.length = total_len;
 	return UA_SUCCESS;
 }
 
 void indicateMsg(UA_Int32 handle, UA_ByteString *slMessage) {
-	TL_Process(&(stackTestFixture_getFixture(handle)->connection), slMessage);
+	printf("indicate: %d", TL_Process(&(stackTestFixture_getFixture(handle)->connection), slMessage));
 }
 
 UA_Byte pkt_HEL[] = {
-            0x48, 0x45, 0x4c, 0x46, 0x39, 0x00, /*   HELF9. */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
-0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */
-0x00, 0x01, 0x88, 0x13, 0x00, 0x00, 0x19, 0x00, /* ........ */
-0x00, 0x00, 0x6f, 0x70, 0x63, 0x2e, 0x74, 0x63, /* ..opc.tc */
-0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x30, 0x2e, 0x30, /* p://10.0 */
-0x2e, 0x35, 0x34, 0x2e, 0x37, 0x37, 0x3a, 0x34, /* .54.77:4 */
-0x38, 0x34, 0x32                                /* 842 */
+	0x48, 0x45, 0x4c, 0x46, 0x39, 0x00,             /*   HELF9. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+	0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */
+	0x00, 0x01, 0x88, 0x13, 0x00, 0x00, 0x19, 0x00, /* ........ */
+	0x00, 0x00, 0x6f, 0x70, 0x63, 0x2e, 0x74, 0x63, /* ..opc.tc */
+	0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x30, 0x2e, 0x30, /* p://10.0 */
+	0x2e, 0x35, 0x34, 0x2e, 0x37, 0x37, 0x3a, 0x34, /* .54.77:4 */
+	0x38, 0x34, 0x32                                /* 842 */
 };
 UA_Byte pkt_OPN[] = {
-            0x4f, 0x50, 0x4e, 0x46, 0x85, 0x00, /*   OPNF.. */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, /* ....../. */
-0x00, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, /* ..http:/ */
-0x2f, 0x6f, 0x70, 0x63, 0x66, 0x6f, 0x75, 0x6e, /* /opcfoun */
-0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6f, /* dation.o */
-0x72, 0x67, 0x2f, 0x55, 0x41, 0x2f, 0x53, 0x65, /* rg/UA/Se */
-0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x6f, /* curityPo */
-0x6c, 0x69, 0x63, 0x79, 0x23, 0x4e, 0x6f, 0x6e, /* licy#Non */
-0x65, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* e....... */
-0xff, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* .3...... */
-0x00, 0x01, 0x00, 0xbe, 0x01, 0x00, 0x00, 0x40, /* .......@ */
-0xaf, 0xfc, 0xe8, 0xa1, 0x76, 0xcf, 0x01, 0x00, /* ....v... */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* ........ */
-0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
-0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* ........ */
-0x00, 0x00, 0x00, 0x80, 0xee, 0x36, 0x00        /* .....6. */
+	0x4f, 0x50, 0x4e, 0x46, 0x85, 0x00,             /*   OPNF.. */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, /* ....../. */
+	0x00, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, /* ..http:/ */
+	0x2f, 0x6f, 0x70, 0x63, 0x66, 0x6f, 0x75, 0x6e, /* /opcfoun */
+	0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6f, /* dation.o */
+	0x72, 0x67, 0x2f, 0x55, 0x41, 0x2f, 0x53, 0x65, /* rg/UA/Se */
+	0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x6f, /* curityPo */
+	0x6c, 0x69, 0x63, 0x79, 0x23, 0x4e, 0x6f, 0x6e, /* licy#Non */
+	0x65, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* e....... */
+	0xff, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* .3...... */
+	0x00, 0x01, 0x00, 0xbe, 0x01, 0x00, 0x00, 0x40, /* .......@ */
+	0xaf, 0xfc, 0xe8, 0xa1, 0x76, 0xcf, 0x01, 0x00, /* ....v... */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* ........ */
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* ........ */
+	0x00, 0x00, 0x00, 0x80, 0xee, 0x36, 0x00        /* .....6. */
+};
+
+UA_Byte pkt_CLO[] = {
+	0x43, 0x4c, 0x4f, 0x46, 0x39, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,  /* CLOF9........... */ /*19 here assusmes channelid=25 ! */
+	0xea, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc4, 0x01, 0x00, 0x00, 0x4d, 0x65,  /* ..............Me */
+	0x16, 0x3b, 0x47, 0x99, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,  /* .;G............. */
+	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00                                             /* ......... */
 };
 
 UA_Byte pkt_MSG_CreateSession[] = {
-0x4d, 0x53, 0x47, 0x46, 0xb4, 0x05, 0x00, 0x00, /* MSGF.... */
-0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* QQ...... */  // assumes fixed secureChannelID=25 !
-0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, /* 4....... */
-0x01, 0x00, 0xcd, 0x01, 0x00, 0x00, 0x50, 0xd6, /* ......P. */
-0xfc, 0xe8, 0xa1, 0x76, 0xcf, 0x01, 0x01, 0x00, /* ...v.... */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */
-0xff, 0xff, 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, /* ...'.... */
-0x00, 0x2d, 0x00, 0x00, 0x00, 0x75, 0x72, 0x6e, /* .-...urn */
-0x3a, 0x6d, 0x72, 0x74, 0x2d, 0x56, 0x69, 0x72, /* :mrt-Vir */
-0x74, 0x75, 0x61, 0x6c, 0x42, 0x6f, 0x78, 0x3a, /* tualBox: */
-0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41, /* UnifiedA */
-0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x6f, /* utomatio */
-0x6e, 0x3a, 0x55, 0x61, 0x45, 0x78, 0x70, 0x65, /* n:UaExpe */
-0x72, 0x74, 0x1e, 0x00, 0x00, 0x00, 0x75, 0x72, /* rt....ur */
-0x6e, 0x3a, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, /* n:Unifie */
-0x64, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, /* dAutomat */
-0x69, 0x6f, 0x6e, 0x3a, 0x55, 0x61, 0x45, 0x78, /* ion:UaEx */
-0x70, 0x65, 0x72, 0x74, 0x02, 0x1b, 0x00, 0x00, /* pert.... */
-0x00, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, /* .Unified */
-0x20, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, /*  Automat */
-0x69, 0x6f, 0x6e, 0x20, 0x55, 0x61, 0x45, 0x78, /* ion UaEx */
-0x70, 0x65, 0x72, 0x74, 0x01, 0x00, 0x00, 0x00, /* pert.... */
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* ........ */
-0x19, 0x00, 0x00, 0x00, 0x6f, 0x70, 0x63, 0x2e, /* ....opc. */
-0x74, 0x63, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x30, /* tcp://10 */
-0x2e, 0x30, 0x2e, 0x35, 0x34, 0x2e, 0x37, 0x37, /* .0.54.77 */
-0x3a, 0x34, 0x38, 0x34, 0x32, 0x2d, 0x00, 0x00, /* :4842-.. */
-0x00, 0x75, 0x72, 0x6e, 0x3a, 0x6d, 0x72, 0x74, /* .urn:mrt */
-0x2d, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, /* -Virtual */
-0x42, 0x6f, 0x78, 0x3a, 0x55, 0x6e, 0x69, 0x66, /* Box:Unif */
-0x69, 0x65, 0x64, 0x41, 0x75, 0x74, 0x6f, 0x6d, /* iedAutom */
-0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x55, 0x61, /* ation:Ua */
-0x45, 0x78, 0x70, 0x65, 0x72, 0x74, 0x20, 0x00, /* Expert . */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
-0x00, 0x00, 0x72, 0x04, 0x00, 0x00, 0x30, 0x82, /* ..r...0. */
-0x04, 0x6e, 0x30, 0x82, 0x03, 0xd7, 0xa0, 0x03, /* .n0..... */
-0x02, 0x01, 0x02, 0x02, 0x04, 0x53, 0x1b, 0x10, /* .....S.. */
-0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, /* .0...*.H */
-0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, /* ........ */
-0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, /* 0..1.0.. */
-0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, /* .U....DE */
-0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, /* 1.0...U. */
-0x08, 0x13, 0x08, 0x41, 0x6e, 0x79, 0x77, 0x68, /* ...Anywh */
-0x65, 0x72, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, /* ere1.0.. */
-0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x41, 0x6e, /* .U....An */
-0x79, 0x77, 0x68, 0x65, 0x72, 0x65, 0x31, 0x13, /* ywhere1. */
-0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, /* 0...U... */
-0x0a, 0x54, 0x55, 0x20, 0x44, 0x72, 0x65, 0x73, /* .TU Dres */
-0x64, 0x65, 0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, /* den1604. */
-0x03, 0x55, 0x04, 0x0b, 0x13, 0x2d, 0x43, 0x68, /* .U...-Ch */
-0x61, 0x69, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, /* air for  */
-0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, /* Process  */
-0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, /* Control  */
-0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, /* Systems  */
-0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, /* Engineer */
-0x69, 0x6e, 0x67, 0x31, 0x11, 0x30, 0x0f, 0x06, /* ing1.0.. */
-0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x55, 0x61, /* .U....Ua */
-0x45, 0x78, 0x70, 0x65, 0x72, 0x74, 0x30, 0x1e, /* Expert0. */
-0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x30, 0x38, /* ..140308 */
-0x31, 0x32, 0x34, 0x34, 0x31, 0x35, 0x5a, 0x17, /* 124415Z. */
-0x0d, 0x31, 0x34, 0x30, 0x33, 0x30, 0x38, 0x31, /* .1403081 */
-0x33, 0x34, 0x34, 0x31, 0x35, 0x5a, 0x30, 0x81, /* 34415Z0. */
-0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, /* .1.0...U */
-0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x11, /* ....DE1. */
-0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, /* 0...U... */
-0x08, 0x41, 0x6e, 0x79, 0x77, 0x68, 0x65, 0x72, /* .Anywher */
-0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, /* e1.0...U */
-0x04, 0x07, 0x13, 0x08, 0x41, 0x6e, 0x79, 0x77, /* ....Anyw */
-0x68, 0x65, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, /* here1.0. */
-0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x54, /* ..U....T */
-0x55, 0x20, 0x44, 0x72, 0x65, 0x73, 0x64, 0x65, /* U Dresde */
-0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, /* n1604..U */
-0x04, 0x0b, 0x13, 0x2d, 0x43, 0x68, 0x61, 0x69, /* ...-Chai */
-0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x50, 0x72, /* r for Pr */
-0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x43, 0x6f, /* ocess Co */
-0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x53, 0x79, /* ntrol Sy */
-0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x45, 0x6e, /* stems En */
-0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, /* gineerin */
-0x67, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, /* g1.0...U */
-0x04, 0x03, 0x13, 0x08, 0x55, 0x61, 0x45, 0x78, /* ....UaEx */
-0x70, 0x65, 0x72, 0x74, 0x30, 0x81, 0x9f, 0x30, /* pert0..0 */
-0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, /* ...*.H.. */
-0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, /* ........ */
-0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, /* ..0..... */
-0x00, 0xb3, 0xb3, 0xc9, 0x97, 0xb7, 0x4f, 0x6d, /* ......Om */
-0x6f, 0x72, 0x48, 0xe2, 0x5f, 0x8c, 0x89, 0x0f, /* orH._... */
-0xc3, 0x47, 0x17, 0x4c, 0xd2, 0x8c, 0x2a, 0x85, /* .G.L..*. */
-0xf6, 0x80, 0xb1, 0x9e, 0xf4, 0x90, 0xff, 0x0f, /* ........ */
-0xff, 0x42, 0x74, 0x75, 0xcd, 0xd5, 0xe0, 0x8f, /* .Btu.... */
-0x7f, 0xa1, 0x41, 0x86, 0x83, 0xcf, 0x2c, 0xef, /* ..A...,. */
-0xbd, 0xb7, 0xbf, 0x50, 0xa9, 0x5c, 0xfa, 0x39, /* ...P.\.9 */
-0x84, 0xbb, 0x7e, 0xc9, 0x7e, 0x5b, 0xc8, 0x1b, /* ..~.~[.. */
-0x19, 0xfc, 0x31, 0x05, 0xa9, 0x0c, 0x31, 0x3c, /* ..1...1< */
-0x1a, 0x86, 0x50, 0x17, 0x45, 0x0a, 0xfd, 0xfe, /* ..P.E... */
-0xa0, 0xc4, 0x88, 0x93, 0xff, 0x1c, 0xf3, 0x60, /* .......` */
-0x06, 0xc6, 0xdf, 0x7c, 0xc6, 0xcd, 0x95, 0x7d, /* ...|...} */
-0xf8, 0x3b, 0x7a, 0x53, 0x15, 0xbb, 0x2e, 0xcf, /* .;zS.... */
-0xd1, 0x63, 0xae, 0x5a, 0x30, 0x48, 0x67, 0x5f, /* .c.Z0Hg_ */
-0xa8, 0x30, 0x7f, 0x35, 0xe4, 0x43, 0x94, 0xa3, /* .0.5.C.. */
-0xc1, 0xfe, 0x69, 0xcd, 0x5c, 0xd7, 0x88, 0xc0, /* ..i.\... */
-0xa5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, /* ........ */
-0x01, 0xcb, 0x30, 0x82, 0x01, 0xc7, 0x30, 0x0c, /* ..0...0. */
-0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, /* ..U..... */
-0x04, 0x02, 0x30, 0x00, 0x30, 0x50, 0x06, 0x09, /* ..0.0P.. */
-0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, /* `.H...B. */
-0x0d, 0x04, 0x43, 0x16, 0x41, 0x22, 0x47, 0x65, /* ..C.A"Ge */
-0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, /* nerated  */
-0x77, 0x69, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x69, /* with Uni */
-0x66, 0x69, 0x65, 0x64, 0x20, 0x41, 0x75, 0x74, /* fied Aut */
-0x6f, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, /* omation  */
-0x55, 0x41, 0x20, 0x42, 0x61, 0x73, 0x65, 0x20, /* UA Base  */
-0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, /* Library  */
-0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x4f, 0x70, /* using Op */
-0x65, 0x6e, 0x53, 0x53, 0x4c, 0x22, 0x30, 0x1d, /* enSSL"0. */
-0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, /* ..U..... */
-0x14, 0x37, 0x39, 0x34, 0x93, 0xa2, 0x65, 0xef, /* .794..e. */
-0xb9, 0xd4, 0x71, 0x21, 0x4b, 0x77, 0xdb, 0x28, /* ..q!Kw.( */
-0xc8, 0xfa, 0x03, 0xfe, 0x05, 0x30, 0x81, 0xc3, /* .....0.. */
-0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xbb, /* ..U.#... */
-0x30, 0x81, 0xb8, 0x80, 0x14, 0x37, 0x39, 0x34, /* 0....794 */
-0x93, 0xa2, 0x65, 0xef, 0xb9, 0xd4, 0x71, 0x21, /* ..e...q! */
-0x4b, 0x77, 0xdb, 0x28, 0xc8, 0xfa, 0x03, 0xfe, /* Kw.(.... */
-0x05, 0xa1, 0x81, 0x99, 0xa4, 0x81, 0x96, 0x30, /* .......0 */
-0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, /* ..1.0... */
-0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, /* U....DE1 */
-0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x08, /* .0...U.. */
-0x13, 0x08, 0x41, 0x6e, 0x79, 0x77, 0x68, 0x65, /* ..Anywhe */
-0x72, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, /* re1.0... */
-0x55, 0x04, 0x07, 0x13, 0x08, 0x41, 0x6e, 0x79, /* U....Any */
-0x77, 0x68, 0x65, 0x72, 0x65, 0x31, 0x13, 0x30, /* where1.0 */
-0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, /* ...U.... */
-0x54, 0x55, 0x20, 0x44, 0x72, 0x65, 0x73, 0x64, /* TU Dresd */
-0x65, 0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, /* en1604.. */
-0x55, 0x04, 0x0b, 0x13, 0x2d, 0x43, 0x68, 0x61, /* U...-Cha */
-0x69, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x50, /* ir for P */
-0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x43, /* rocess C */
-0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x53, /* ontrol S */
-0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x45, /* ystems E */
-0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, /* ngineeri */
-0x6e, 0x67, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, /* ng1.0... */
-0x55, 0x04, 0x03, 0x13, 0x08, 0x55, 0x61, 0x45, /* U....UaE */
-0x78, 0x70, 0x65, 0x72, 0x74, 0x82, 0x04, 0x53, /* xpert..S */
-0x1b, 0x10, 0x9f, 0x30, 0x0e, 0x06, 0x03, 0x55, /* ...0...U */
-0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, /* ........ */
-0x02, 0x02, 0xf4, 0x30, 0x20, 0x06, 0x03, 0x55, /* ...0 ..U */
-0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x16, 0x30, /* .%.....0 */
-0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, /* ...+.... */
-0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, /* .....+.. */
-0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x4e, 0x06, /* .....0N. */
-0x03, 0x55, 0x1d, 0x11, 0x04, 0x47, 0x30, 0x45, /* .U...G0E */
-0x86, 0x2d, 0x75, 0x72, 0x6e, 0x3a, 0x6d, 0x72, /* .-urn:mr */
-0x74, 0x2d, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, /* t-Virtua */
-0x6c, 0x42, 0x6f, 0x78, 0x3a, 0x55, 0x6e, 0x69, /* lBox:Uni */
-0x66, 0x69, 0x65, 0x64, 0x41, 0x75, 0x74, 0x6f, /* fiedAuto */
-0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x55, /* mation:U */
-0x61, 0x45, 0x78, 0x70, 0x65, 0x72, 0x74, 0x82, /* aExpert. */
-0x0e, 0x6d, 0x72, 0x74, 0x2d, 0x56, 0x69, 0x72, /* .mrt-Vir */
-0x74, 0x75, 0x61, 0x6c, 0x42, 0x6f, 0x78, 0x87, /* tualBox. */
-0x04, 0xc0, 0xa8, 0x02, 0x73, 0x30, 0x0d, 0x06, /* ....s0.. */
-0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, /* .*.H.... */
-0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, /* ........ */
-0x77, 0x2c, 0x9c, 0x23, 0x60, 0x13, 0x3f, 0xa5, /* w,.#`.?. */
-0xc8, 0xb3, 0x20, 0x27, 0x64, 0xda, 0x7f, 0xaa, /* .. 'd... */
-0xc5, 0x86, 0xfa, 0xd7, 0x24, 0x2e, 0xbe, 0xa0, /* ....$... */
-0xfc, 0x49, 0x8f, 0xc0, 0xef, 0xfb, 0x9a, 0xe6, /* .I...... */
-0x50, 0xe6, 0xb3, 0x53, 0x91, 0x91, 0x89, 0xd3, /* P..S.... */
-0x5a, 0xa5, 0xc9, 0x9c, 0xf6, 0x7b, 0x8f, 0x93, /* Z....{.. */
-0xb4, 0x98, 0xc3, 0x92, 0x26, 0x49, 0x8a, 0x96, /* ....&I.. */
-0x6e, 0x8f, 0xf5, 0x93, 0x48, 0x90, 0x9e, 0x7e, /* n...H..~ */
-0x1d, 0xad, 0x63, 0xbb, 0x5e, 0x1c, 0x0c, 0x86, /* ..c.^... */
-0x2d, 0xce, 0xe2, 0xe1, 0x87, 0x8d, 0x4c, 0x4b, /* -.....LK */
-0x89, 0x24, 0x77, 0xff, 0x62, 0x95, 0xf7, 0xec, /* .$w.b... */
-0x16, 0x7c, 0x8a, 0x1e, 0x4d, 0x89, 0xcb, 0x3d, /* .|..M..= */
-0xc8, 0xc0, 0x7c, 0x12, 0x5a, 0x29, 0xf2, 0xe7, /* ..|.Z).. */
-0x68, 0xf9, 0xb9, 0x85, 0xe5, 0xc0, 0x46, 0xac, /* h.....F. */
-0x89, 0xdb, 0xd0, 0x87, 0xaa, 0xa1, 0x7a, 0x73, /* ......zs */
-0x71, 0xcc, 0x8e, 0x01, 0x80, 0xf3, 0x07, 0x70, /* q......p */
-0x00, 0x00, 0x00, 0x00, 0x80, 0x4f, 0x32, 0x41, /* .....O2A */
-0xff, 0xff, 0xff, 0xff                          /* .... */
+	0x4d, 0x53, 0x47, 0x46, 0xb4, 0x05, 0x00, 0x00, /* MSGF.... */
+	0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* QQ...... // assumes fixed secureChannelID=25 ! */
+	0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, /* 4....... */
+	0x01, 0x00, 0xcd, 0x01, 0x00, 0x00, 0x50, 0xd6, /* ......P. */
+	0xfc, 0xe8, 0xa1, 0x76, 0xcf, 0x01, 0x01, 0x00, /* ...v.... */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */
+	0xff, 0xff, 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, /* ...'.... */
+	0x00, 0x2d, 0x00, 0x00, 0x00, 0x75, 0x72, 0x6e, /* .-...urn */
+	0x3a, 0x6d, 0x72, 0x74, 0x2d, 0x56, 0x69, 0x72, /* :mrt-Vir */
+	0x74, 0x75, 0x61, 0x6c, 0x42, 0x6f, 0x78, 0x3a, /* tualBox: */
+	0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41, /* UnifiedA */
+	0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x6f, /* utomatio */
+	0x6e, 0x3a, 0x55, 0x61, 0x45, 0x78, 0x70, 0x65, /* n:UaExpe */
+	0x72, 0x74, 0x1e, 0x00, 0x00, 0x00, 0x75, 0x72, /* rt....ur */
+	0x6e, 0x3a, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, /* n:Unifie */
+	0x64, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, /* dAutomat */
+	0x69, 0x6f, 0x6e, 0x3a, 0x55, 0x61, 0x45, 0x78, /* ion:UaEx */
+	0x70, 0x65, 0x72, 0x74, 0x02, 0x1b, 0x00, 0x00, /* pert.... */
+	0x00, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, /* .Unified */
+	0x20, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, /*  Automat */
+	0x69, 0x6f, 0x6e, 0x20, 0x55, 0x61, 0x45, 0x78, /* ion UaEx */
+	0x70, 0x65, 0x72, 0x74, 0x01, 0x00, 0x00, 0x00, /* pert.... */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */
+	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* ........ */
+	0x19, 0x00, 0x00, 0x00, 0x6f, 0x70, 0x63, 0x2e, /* ....opc. */
+	0x74, 0x63, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x30, /* tcp://10 */
+	0x2e, 0x30, 0x2e, 0x35, 0x34, 0x2e, 0x37, 0x37, /* .0.54.77 */
+	0x3a, 0x34, 0x38, 0x34, 0x32, 0x2d, 0x00, 0x00, /* :4842-.. */
+	0x00, 0x75, 0x72, 0x6e, 0x3a, 0x6d, 0x72, 0x74, /* .urn:mrt */
+	0x2d, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, /* -Virtual */
+	0x42, 0x6f, 0x78, 0x3a, 0x55, 0x6e, 0x69, 0x66, /* Box:Unif */
+	0x69, 0x65, 0x64, 0x41, 0x75, 0x74, 0x6f, 0x6d, /* iedAutom */
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x55, 0x61, /* ation:Ua */
+	0x45, 0x78, 0x70, 0x65, 0x72, 0x74, 0x20, 0x00, /* Expert . */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+	0x00, 0x00, 0x72, 0x04, 0x00, 0x00, 0x30, 0x82, /* ..r...0. */
+	0x04, 0x6e, 0x30, 0x82, 0x03, 0xd7, 0xa0, 0x03, /* .n0..... */
+	0x02, 0x01, 0x02, 0x02, 0x04, 0x53, 0x1b, 0x10, /* .....S.. */
+	0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, /* .0...*.H */
+	0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, /* ........ */
+	0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, /* 0..1.0.. */
+	0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, /* .U....DE */
+	0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, /* 1.0...U. */
+	0x08, 0x13, 0x08, 0x41, 0x6e, 0x79, 0x77, 0x68, /* ...Anywh */
+	0x65, 0x72, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, /* ere1.0.. */
+	0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x41, 0x6e, /* .U....An */
+	0x79, 0x77, 0x68, 0x65, 0x72, 0x65, 0x31, 0x13, /* ywhere1. */
+	0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, /* 0...U... */
+	0x0a, 0x54, 0x55, 0x20, 0x44, 0x72, 0x65, 0x73, /* .TU Dres */
+	0x64, 0x65, 0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, /* den1604. */
+	0x03, 0x55, 0x04, 0x0b, 0x13, 0x2d, 0x43, 0x68, /* .U...-Ch */
+	0x61, 0x69, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, /* air for  */
+	0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, /* Process  */
+	0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, /* Control  */
+	0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, /* Systems  */
+	0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, /* Engineer */
+	0x69, 0x6e, 0x67, 0x31, 0x11, 0x30, 0x0f, 0x06, /* ing1.0.. */
+	0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x55, 0x61, /* .U....Ua */
+	0x45, 0x78, 0x70, 0x65, 0x72, 0x74, 0x30, 0x1e, /* Expert0. */
+	0x17, 0x0d, 0x31, 0x34, 0x30, 0x33, 0x30, 0x38, /* ..140308 */
+	0x31, 0x32, 0x34, 0x34, 0x31, 0x35, 0x5a, 0x17, /* 124415Z. */
+	0x0d, 0x31, 0x34, 0x30, 0x33, 0x30, 0x38, 0x31, /* .1403081 */
+	0x33, 0x34, 0x34, 0x31, 0x35, 0x5a, 0x30, 0x81, /* 34415Z0. */
+	0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, /* .1.0...U */
+	0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x11, /* ....DE1. */
+	0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, /* 0...U... */
+	0x08, 0x41, 0x6e, 0x79, 0x77, 0x68, 0x65, 0x72, /* .Anywher */
+	0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, /* e1.0...U */
+	0x04, 0x07, 0x13, 0x08, 0x41, 0x6e, 0x79, 0x77, /* ....Anyw */
+	0x68, 0x65, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, /* here1.0. */
+	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x54, /* ..U....T */
+	0x55, 0x20, 0x44, 0x72, 0x65, 0x73, 0x64, 0x65, /* U Dresde */
+	0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, /* n1604..U */
+	0x04, 0x0b, 0x13, 0x2d, 0x43, 0x68, 0x61, 0x69, /* ...-Chai */
+	0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x50, 0x72, /* r for Pr */
+	0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x43, 0x6f, /* ocess Co */
+	0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x53, 0x79, /* ntrol Sy */
+	0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x45, 0x6e, /* stems En */
+	0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, /* gineerin */
+	0x67, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, /* g1.0...U */
+	0x04, 0x03, 0x13, 0x08, 0x55, 0x61, 0x45, 0x78, /* ....UaEx */
+	0x70, 0x65, 0x72, 0x74, 0x30, 0x81, 0x9f, 0x30, /* pert0..0 */
+	0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, /* ...*.H.. */
+	0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, /* ........ */
+	0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, /* ..0..... */
+	0x00, 0xb3, 0xb3, 0xc9, 0x97, 0xb7, 0x4f, 0x6d, /* ......Om */
+	0x6f, 0x72, 0x48, 0xe2, 0x5f, 0x8c, 0x89, 0x0f, /* orH._... */
+	0xc3, 0x47, 0x17, 0x4c, 0xd2, 0x8c, 0x2a, 0x85, /* .G.L..*. */
+	0xf6, 0x80, 0xb1, 0x9e, 0xf4, 0x90, 0xff, 0x0f, /* ........ */
+	0xff, 0x42, 0x74, 0x75, 0xcd, 0xd5, 0xe0, 0x8f, /* .Btu.... */
+	0x7f, 0xa1, 0x41, 0x86, 0x83, 0xcf, 0x2c, 0xef, /* ..A...,. */
+	0xbd, 0xb7, 0xbf, 0x50, 0xa9, 0x5c, 0xfa, 0x39, /* ...P.\.9 */
+	0x84, 0xbb, 0x7e, 0xc9, 0x7e, 0x5b, 0xc8, 0x1b, /* ..~.~[.. */
+	0x19, 0xfc, 0x31, 0x05, 0xa9, 0x0c, 0x31, 0x3c, /* ..1...1< */
+	0x1a, 0x86, 0x50, 0x17, 0x45, 0x0a, 0xfd, 0xfe, /* ..P.E... */
+	0xa0, 0xc4, 0x88, 0x93, 0xff, 0x1c, 0xf3, 0x60, /* .......` */
+	0x06, 0xc6, 0xdf, 0x7c, 0xc6, 0xcd, 0x95, 0x7d, /* ...|...} */
+	0xf8, 0x3b, 0x7a, 0x53, 0x15, 0xbb, 0x2e, 0xcf, /* .;zS.... */
+	0xd1, 0x63, 0xae, 0x5a, 0x30, 0x48, 0x67, 0x5f, /* .c.Z0Hg_ */
+	0xa8, 0x30, 0x7f, 0x35, 0xe4, 0x43, 0x94, 0xa3, /* .0.5.C.. */
+	0xc1, 0xfe, 0x69, 0xcd, 0x5c, 0xd7, 0x88, 0xc0, /* ..i.\... */
+	0xa5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, /* ........ */
+	0x01, 0xcb, 0x30, 0x82, 0x01, 0xc7, 0x30, 0x0c, /* ..0...0. */
+	0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, /* ..U..... */
+	0x04, 0x02, 0x30, 0x00, 0x30, 0x50, 0x06, 0x09, /* ..0.0P.. */
+	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, /* `.H...B. */
+	0x0d, 0x04, 0x43, 0x16, 0x41, 0x22, 0x47, 0x65, /* ..C.A"Ge */
+	0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, /* nerated  */
+	0x77, 0x69, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x69, /* with Uni */
+	0x66, 0x69, 0x65, 0x64, 0x20, 0x41, 0x75, 0x74, /* fied Aut */
+	0x6f, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, /* omation  */
+	0x55, 0x41, 0x20, 0x42, 0x61, 0x73, 0x65, 0x20, /* UA Base  */
+	0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, /* Library  */
+	0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x4f, 0x70, /* using Op */
+	0x65, 0x6e, 0x53, 0x53, 0x4c, 0x22, 0x30, 0x1d, /* enSSL"0. */
+	0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, /* ..U..... */
+	0x14, 0x37, 0x39, 0x34, 0x93, 0xa2, 0x65, 0xef, /* .794..e. */
+	0xb9, 0xd4, 0x71, 0x21, 0x4b, 0x77, 0xdb, 0x28, /* ..q!Kw.( */
+	0xc8, 0xfa, 0x03, 0xfe, 0x05, 0x30, 0x81, 0xc3, /* .....0.. */
+	0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xbb, /* ..U.#... */
+	0x30, 0x81, 0xb8, 0x80, 0x14, 0x37, 0x39, 0x34, /* 0....794 */
+	0x93, 0xa2, 0x65, 0xef, 0xb9, 0xd4, 0x71, 0x21, /* ..e...q! */
+	0x4b, 0x77, 0xdb, 0x28, 0xc8, 0xfa, 0x03, 0xfe, /* Kw.(.... */
+	0x05, 0xa1, 0x81, 0x99, 0xa4, 0x81, 0x96, 0x30, /* .......0 */
+	0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, /* ..1.0... */
+	0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, /* U....DE1 */
+	0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x08, /* .0...U.. */
+	0x13, 0x08, 0x41, 0x6e, 0x79, 0x77, 0x68, 0x65, /* ..Anywhe */
+	0x72, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, /* re1.0... */
+	0x55, 0x04, 0x07, 0x13, 0x08, 0x41, 0x6e, 0x79, /* U....Any */
+	0x77, 0x68, 0x65, 0x72, 0x65, 0x31, 0x13, 0x30, /* where1.0 */
+	0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, /* ...U.... */
+	0x54, 0x55, 0x20, 0x44, 0x72, 0x65, 0x73, 0x64, /* TU Dresd */
+	0x65, 0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, /* en1604.. */
+	0x55, 0x04, 0x0b, 0x13, 0x2d, 0x43, 0x68, 0x61, /* U...-Cha */
+	0x69, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x50, /* ir for P */
+	0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x43, /* rocess C */
+	0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x53, /* ontrol S */
+	0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x45, /* ystems E */
+	0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, /* ngineeri */
+	0x6e, 0x67, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, /* ng1.0... */
+	0x55, 0x04, 0x03, 0x13, 0x08, 0x55, 0x61, 0x45, /* U....UaE */
+	0x78, 0x70, 0x65, 0x72, 0x74, 0x82, 0x04, 0x53, /* xpert..S */
+	0x1b, 0x10, 0x9f, 0x30, 0x0e, 0x06, 0x03, 0x55, /* ...0...U */
+	0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, /* ........ */
+	0x02, 0x02, 0xf4, 0x30, 0x20, 0x06, 0x03, 0x55, /* ...0 ..U */
+	0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x16, 0x30, /* .%.....0 */
+	0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, /* ...+.... */
+	0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, /* .....+.. */
+	0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x4e, 0x06, /* .....0N. */
+	0x03, 0x55, 0x1d, 0x11, 0x04, 0x47, 0x30, 0x45, /* .U...G0E */
+	0x86, 0x2d, 0x75, 0x72, 0x6e, 0x3a, 0x6d, 0x72, /* .-urn:mr */
+	0x74, 0x2d, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, /* t-Virtua */
+	0x6c, 0x42, 0x6f, 0x78, 0x3a, 0x55, 0x6e, 0x69, /* lBox:Uni */
+	0x66, 0x69, 0x65, 0x64, 0x41, 0x75, 0x74, 0x6f, /* fiedAuto */
+	0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x55, /* mation:U */
+	0x61, 0x45, 0x78, 0x70, 0x65, 0x72, 0x74, 0x82, /* aExpert. */
+	0x0e, 0x6d, 0x72, 0x74, 0x2d, 0x56, 0x69, 0x72, /* .mrt-Vir */
+	0x74, 0x75, 0x61, 0x6c, 0x42, 0x6f, 0x78, 0x87, /* tualBox. */
+	0x04, 0xc0, 0xa8, 0x02, 0x73, 0x30, 0x0d, 0x06, /* ....s0.. */
+	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, /* .*.H.... */
+	0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, /* ........ */
+	0x77, 0x2c, 0x9c, 0x23, 0x60, 0x13, 0x3f, 0xa5, /* w,.#`.?. */
+	0xc8, 0xb3, 0x20, 0x27, 0x64, 0xda, 0x7f, 0xaa, /* .. 'd... */
+	0xc5, 0x86, 0xfa, 0xd7, 0x24, 0x2e, 0xbe, 0xa0, /* ....$... */
+	0xfc, 0x49, 0x8f, 0xc0, 0xef, 0xfb, 0x9a, 0xe6, /* .I...... */
+	0x50, 0xe6, 0xb3, 0x53, 0x91, 0x91, 0x89, 0xd3, /* P..S.... */
+	0x5a, 0xa5, 0xc9, 0x9c, 0xf6, 0x7b, 0x8f, 0x93, /* Z....{.. */
+	0xb4, 0x98, 0xc3, 0x92, 0x26, 0x49, 0x8a, 0x96, /* ....&I.. */
+	0x6e, 0x8f, 0xf5, 0x93, 0x48, 0x90, 0x9e, 0x7e, /* n...H..~ */
+	0x1d, 0xad, 0x63, 0xbb, 0x5e, 0x1c, 0x0c, 0x86, /* ..c.^... */
+	0x2d, 0xce, 0xe2, 0xe1, 0x87, 0x8d, 0x4c, 0x4b, /* -.....LK */
+	0x89, 0x24, 0x77, 0xff, 0x62, 0x95, 0xf7, 0xec, /* .$w.b... */
+	0x16, 0x7c, 0x8a, 0x1e, 0x4d, 0x89, 0xcb, 0x3d, /* .|..M..= */
+	0xc8, 0xc0, 0x7c, 0x12, 0x5a, 0x29, 0xf2, 0xe7, /* ..|.Z).. */
+	0x68, 0xf9, 0xb9, 0x85, 0xe5, 0xc0, 0x46, 0xac, /* h.....F. */
+	0x89, 0xdb, 0xd0, 0x87, 0xaa, 0xa1, 0x7a, 0x73, /* ......zs */
+	0x71, 0xcc, 0x8e, 0x01, 0x80, 0xf3, 0x07, 0x70, /* q......p */
+	0x00, 0x00, 0x00, 0x00, 0x80, 0x4f, 0x32, 0x41, /* .....O2A */
+	0xff, 0xff, 0xff, 0xff                          /* .... */
 };
 
-START_TEST(emptyIndicationShallYieldNoResponse)
-{
+START_TEST(emptyIndicationShallYieldNoResponse) {
 	// given
 	UA_Int32 handle = stackTestFixture_create(responseMsg);
-	UA_ByteString message = { -1, (UA_Byte*) UA_NULL };
+	UA_ByteString message = { -1, (UA_Byte *)UA_NULL };
 
 	// when
 	indicateMsg(handle, &message);
 
 	// then
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.length,0);
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.length, 0);
 
 	// finally
 	stackTestFixture_delete(handle);
@@ -363,8 +348,7 @@ START_TEST(emptyIndicationShallYieldNoResponse)
 END_TEST
 
 
-START_TEST(validHELIndicationShallYieldACKResponse)
-{
+START_TEST(validHELIndicationShallYieldACKResponse) {
 	// given
 	UA_Int32 handle = stackTestFixture_create(responseMsg);
 	UA_ByteString message_001 = { sizeof(pkt_HEL), pkt_HEL };
@@ -373,18 +357,17 @@ START_TEST(validHELIndicationShallYieldACKResponse)
 	indicateMsg(handle, &message_001);
 
 	// then
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.length,28);
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[0],'A');
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[1],'C');
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[2],'K');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.length, 28);
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[0], 'A');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[1], 'C');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[2], 'K');
 
 	// finally
 	stackTestFixture_delete(handle);
 }
 END_TEST
 
-START_TEST(validOpeningSequenceShallCreateChannel)
-{
+START_TEST(validOpeningSequenceShallCreateChannel) {
 	// given
 	UA_Int32 handle = stackTestFixture_create(responseMsg);
 
@@ -396,9 +379,9 @@ START_TEST(validOpeningSequenceShallCreateChannel)
 	indicateMsg(handle, &message_002);
 
 	// then
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[0],'O');
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[1],'P');
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[2],'N');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[0], 'O');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[1], 'P');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[2], 'N');
 	ck_assert_int_eq(stackTestFixture_getFixture(handle)->connection.connectionState, CONNECTIONSTATE_ESTABLISHED);
 
 	// finally
@@ -406,8 +389,28 @@ START_TEST(validOpeningSequenceShallCreateChannel)
 }
 END_TEST
 
-START_TEST(validCreateSessionShallCreateSession)
-{
+START_TEST(validOpeningCloseSequence) {
+	// given
+	UA_Int32 handle = stackTestFixture_create(responseMsg);
+
+	UA_ByteString message_001 = { sizeof(pkt_HEL), pkt_HEL };
+	UA_ByteString message_002 = { sizeof(pkt_OPN), pkt_OPN };
+	UA_ByteString message_003 = { sizeof(pkt_CLO), pkt_CLO };
+
+	// when
+	indicateMsg(handle, &message_001);
+	indicateMsg(handle, &message_002);
+	indicateMsg(handle, &message_003);
+
+	// then
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->connection.connectionState, CONNECTIONSTATE_CLOSE);
+
+	// finally
+	stackTestFixture_delete(handle);
+}
+END_TEST
+
+START_TEST(validCreateSessionShallCreateSession) {
 	// given
 	UA_Int32 handle = stackTestFixture_create(responseMsg);
 
@@ -418,15 +421,16 @@ START_TEST(validCreateSessionShallCreateSession)
 	// when
 	indicateMsg(handle, &message_001);
 	indicateMsg(handle, &message_002);
-	UA_Int32 pos = 8;
-	UA_UInt32 secureChannelId = stackTestFixture_getFixture(handle)->connection.secureChannel->securityToken.secureChannelId;
-	UA_UInt32_encodeBinary(&secureChannelId,&pos,&message_003);
+	UA_UInt32 pos = 8;
+	UA_UInt32 secureChannelId =
+	    stackTestFixture_getFixture(handle)->connection.secureChannel->securityToken.secureChannelId;
+	UA_UInt32_encodeBinary(&secureChannelId, &message_003, &pos);
 	indicateMsg(handle, &message_003);
 
 	// then
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[0],'M');
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[1],'S');
-	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[2],'G');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[0], 'M');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[1], 'S');
+	ck_assert_int_eq(stackTestFixture_getFixture(handle)->respMsg.data[2], 'G');
 	ck_assert_ptr_ne(stackTestFixture_getFixture(handle)->connection.secureChannel, UA_NULL);
 
 	// finally
@@ -434,28 +438,28 @@ START_TEST(validCreateSessionShallCreateSession)
 }
 END_TEST
 
-Suite* testSuite()
-{
+Suite *testSuite() {
 	Suite *s = suite_create("Stack Test");
 	TCase *tc_core = tcase_create("Core");
 	tcase_add_test(tc_core, emptyIndicationShallYieldNoResponse);
 	tcase_add_test(tc_core, validHELIndicationShallYieldACKResponse);
 	tcase_add_test(tc_core, validOpeningSequenceShallCreateChannel);
+	tcase_add_test(tc_core, validOpeningCloseSequence);
 	tcase_add_test(tc_core, validCreateSessionShallCreateSession);
-	suite_add_tcase(s,tc_core);
+	suite_add_tcase(s, tc_core);
 	return s;
 }
 
-int main (void)
-{
-	int number_failed = 0;
+int main(void) {
+	int      number_failed = 0;
 
-	Suite *s;
+	Suite   *s;
 	SRunner *sr;
 
-	s = testSuite();
+	s  = testSuite();
 	sr = srunner_create(s);
-	srunner_run_all(sr,CK_NORMAL);
+	//srunner_set_fork_status (sr, CK_NOFORK);
+	srunner_run_all(sr, CK_NORMAL);
 	number_failed += srunner_ntests_failed(sr);
 	srunner_free(sr);
 

+ 8 - 17
tests/check_xml.c

@@ -1,19 +1,10 @@
-/****************************************************************************
- Name        : check_xml.c
- Author      : uleon @ open62541
- Version     : 0.1
- Copyright   : Your copyright notice
- Description : test cases to check different aspects of the
- xml-processing
-
-
-*****************************************************************************/
-
 #include <stdio.h>
 #include <stdlib.h>
-
 #include "ua_xml.h"
-
+#include "util/ua_util.h"
+#include "ua_types_generated.h"
+#include "ua_namespace.h"
+#include "ua_namespace_xml.h"
 #include "check.h"
 
 START_TEST(parseNumericNodeIdWithoutNsIdShallYieldNs0NodeId)
@@ -86,8 +77,8 @@ START_TEST(loadUserNamespaceWithSingleProcessVariableShallSucceed)
 	retval = Namespace_get(ns,&nodeId,&nr,&nl);
 	ck_assert_int_eq(retval,UA_SUCCESS);
 	ck_assert_ptr_ne(nr,UA_NULL);
-	ck_assert_int_eq(nr->references[0]->referenceTypeId.identifier.numeric,40);
-	ck_assert_int_eq(nr->references[0]->targetId.nodeId.identifier.numeric,63);
+	ck_assert_int_eq(nr->references[0].referenceTypeId.identifier.numeric,40);
+	ck_assert_int_eq(nr->references[0].targetId.nodeId.identifier.numeric,63);
 
 
 	UA_NodeId_copycstring("i=2",&nodeId,UA_NULL);
@@ -134,8 +125,8 @@ START_TEST(loadUserNamespaceWithSingleProcessVariableAndAliasesShallSucceed)
 	retval = Namespace_get(ns,&nodeId,&nr,&nl);
 	ck_assert_int_eq(retval,UA_SUCCESS);
 	ck_assert_ptr_ne(nr,UA_NULL);
-	ck_assert_int_eq(nr->references[0]->referenceTypeId.identifier.numeric,40);
-	ck_assert_int_eq(nr->references[0]->targetId.nodeId.identifier.numeric,63);
+	ck_assert_int_eq(nr->references[0].referenceTypeId.identifier.numeric,40);
+	ck_assert_int_eq(nr->references[0].targetId.nodeId.identifier.numeric,63);
 
 	UA_NodeId_copycstring("ns=1;i=2",&nodeId,UA_NULL);
 	ck_assert_int_eq(Namespace_contains(ns,&nodeId),UA_FALSE);

+ 2 - 2
tools/.coverity.sh

@@ -5,9 +5,9 @@
 # of the day to the coverity scan service
 #
 
-COMMITS=`git log --since=today.midnight | grep commit | wc -l`
+COMMITS=`git log --since=today.midnight --oneline | wc -l`
 
-if [[ "$COMMITS" == "1" ]]; then
+if [[ "$COMMITS" -le "1" ]]; then
     #first commit a day - push changes to branch coverity_scan
     git clone -b coverity_scan https://$GITAUTH@github.com/acplt/open62541
     cd open62541

+ 0 - 25
tools/Makefile.am

@@ -1,25 +0,0 @@
-SRC_DIR = $(top_builddir)/src
-INCLUDE_DIR = $(top_builddir)/include
-AUTO_NAME = opcua
-NS0_NAME = ua_namespace_0
-
-all-local: $(AUTO_NAME).cgen $(AUTO_NAME).hgen $(NS0_NAME).cgen $(NS0_NAME).hgen $(bin_PROGRAMS)
-
-$(AUTO_NAME).cgen $(AUTO_NAME).hgen: Opc.Ua.Types.bsd generate_builtin.py
-	python generate_builtin.py Opc.Ua.Types.bsd $(AUTO_NAME)
-	cp $(AUTO_NAME).cgen $(SRC_DIR)/$(AUTO_NAME).c
-	cp $(AUTO_NAME).hgen $(INCLUDE_DIR)/$(AUTO_NAME).h
-	
-$(NS0_NAME).cgen $(NS0_NAME).hgen: NodeIds.csv generate_namespace.py 
-	python generate_namespace.py NodeIds.csv $(NS0_NAME)
-	cp $(NS0_NAME).cgen $(SRC_DIR)/$(NS0_NAME).c
-	cp $(NS0_NAME).hgen $(INCLUDE_DIR)/$(NS0_NAME).h
-
-PHONY: clean-autogenerated
-clean-autogenerated:
-	rm -rf $(AUTO_NAME).cgen $(AUTO_NAME).hgen
-	rm -rf $(SRC_DIR)/$(AUTO_NAME).c $(INCLUDE_DIR)/$(AUTO_NAME).h
-	rm -rf $(NS0_NAME).cgen $(NS0_NAME).hgen
-	rm -rf $(SRC_DIR)/$(NS0_NAME).c $(INCLUDE_DIR)/$(NS0_NAME).h
-
-clean-local: clean-autogenerated

+ 215 - 228
tools/generate_builtin.py

@@ -6,31 +6,41 @@ import getpass
 from collections import OrderedDict
 import re
 from lxml import etree
+import inspect
 
 if len(sys.argv) != 3:
 	print("Usage: python generate_builtin.py <path/to/Opc.Ua.Types.bsd> <outfile w/o extension>", file=sys.stdout)
 	exit(0)
 
-# types that are coded manually 
-exclude_types = set(["Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32",
-					"Int64", "UInt64", "Float", "Double", "String", "DateTime", "Guid",
-					"ByteString", "XmlElement", "NodeId", "ExpandedNodeId", "StatusCode", 
-					"QualifiedName", "LocalizedText", "ExtensionObject", "DataValue",
-					 "Variant", "DiagnosticInfo", "IntegerId"])
+ns = {"opc": "http://opcfoundation.org/BinarySchema/"}
+tree = etree.parse(sys.argv[1])
+types = tree.xpath("/opc:TypeDictionary/*[not(self::opc:Import)]", namespaces=ns)
+
+fh = open(sys.argv[2] + ".h",'w')
+fc = open(sys.argv[2] + ".c",'w')
 
-# do not forget to get rid of these excludes once it works
-exclude_xml_decode = set(["UA_ReferenceNode", "UA_ObjectNode", "UA_ObjectTypeNode", "UA_VariableNode", "UA_VariableTypeNode", "UA_DataTypeNode"])
+# dirty hack. we go up the call frames to access local variables of the calling
+# function. this allows to shorten code and get %()s replaces with less clutter.
+def printh(string):
+    print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fh)
 
-elementary_size = {"Boolean":1, "SByte":1, "Byte":1, "Int16":2, "UInt16":2, "Int32":4, "UInt32":4,
-                   "Int64":8, "UInt64":8, "Float":4, "Double":8, "DateTime":8, "StatusCode":4}
+def printc(string):
+    print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fc)
 
-enum_types = []
-structured_types = []
-printed_types = exclude_types # types that were already printed and which we can use in the structures to come
+# types that are coded manually 
+existing_types = set(["Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32",
+                      "Int64", "UInt64", "Float", "Double", "String", "DateTime", "Guid",
+                      "ByteString", "XmlElement", "NodeId", "ExpandedNodeId", "StatusCode", 
+                      "QualifiedName", "LocalizedText", "ExtensionObject", "DataValue",
+                      "Variant", "DiagnosticInfo"])
+
+fixed_size = set(["UA_Boolean", "UA_SByte", "UA_Byte", "UA_Int16", "UA_UInt16",
+                  "UA_Int32", "UA_UInt32", "UA_Int64", "UA_UInt64", "UA_Float",
+                  "UA_Double", "UA_DateTime", "UA_Guid", "UA_StatusCode"])
 
 # types we do not want to autogenerate
 def skipType(name):
-    if name in exclude_types:
+    if name in existing_types:
         return True
     if re.search("NodeId$", name) != None:
         return True
@@ -49,235 +59,206 @@ def printableStructuredType(element):
     for child in element:
         if child.tag == "{http://opcfoundation.org/BinarySchema/}Field":
             typename = stripTypename(child.get("TypeName"))
-            if typename not in printed_types:
+            if typename not in existing_types:
                 return False
     return True
 
-# There are three types of types in the bsd file:
-# StructuredType, EnumeratedType OpaqueType
-
 def createEnumerated(element):	
     valuemap = OrderedDict()
     name = "UA_" + element.get("Name")
-    enum_types.append(name)
+    fixed_size.add(name)
     for child in element:
         if child.tag == "{http://opcfoundation.org/BinarySchema/}Documentation":
-            print("/** @brief " + child.text + " */", end='\n', file=fh)
+            printh("/** @brief " + child.text + " */")
         if child.tag == "{http://opcfoundation.org/BinarySchema/}EnumeratedValue":
             valuemap[name + "_" + child.get("Name")] = child.get("Value")
     valuemap = OrderedDict(sorted(valuemap.iteritems(), key=lambda (k,v): int(v)))
-    print("typedef UA_UInt32 " + name + ";", end='\n', file=fh);
-    print("enum " + name + "_enum { \n\t" + ",\n\t".join(map(lambda (key, value) : key.upper() + " = " + value, valuemap.iteritems())) + "\n};", end='\n', file=fh)
-    print("UA_TYPE_METHOD_PROTOTYPES (" + name + ")", end='\n', file=fh)
-    print("UA_TYPE_METHOD_CALCSIZE_AS("+name+", UA_UInt32)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_ENCODEBINARY_AS("+name+", UA_UInt32)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DECODEBINARY_AS("+name+", UA_UInt32)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DELETE_AS("+name+", UA_UInt32)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DELETEMEMBERS_AS("+name+", UA_UInt32)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_INIT_AS("+name+", UA_UInt32)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_COPY_AS("+name+", UA_UInt32)",'\n', file=fc)  
-    print("UA_TYPE_METHOD_NEW_DEFAULT("+name+")\n", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DECODEXML_NOTIMPL("+name+")", end='\n', file=fc)
-    return
-    
+    printh("typedef UA_Int32 " + name + ";")
+    printh("enum " + name + "_enum { \n\t" +
+           ",\n\t".join(map(lambda (key, value) : key.upper() + " = " + value, valuemap.iteritems())) +
+           "\n};")
+    printh("UA_TYPE_PROTOTYPES (" + name + ")")
+    printh("UA_TYPE_BINARY_ENCODING(" + name + ")")
+    printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
+    printc("UA_TYPE_AS(" + name + ", UA_Int32)")
+    printc("UA_TYPE_BINARY_ENCODING_AS(" + name + ", UA_Int32)")
+    printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(%(name)s)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s\n)''')
+
+def createOpaque(element):
+    name = "UA_" + element.get("Name")
+    for child in element:
+        if child.tag == "{http://opcfoundation.org/BinarySchema/}Documentation":
+            printh("/** @brief " + child.text + " */")
+    printh("typedef UA_ByteString %(name)s;")
+    printh("UA_TYPE_PROTOTYPES(%(name)s)")
+    printh("UA_TYPE_BINARY_ENCODING(%(name)s)")
+    printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
+    printc("UA_TYPE_AS(%(name)s, UA_ByteString)")
+    printc("UA_TYPE_BINARY_ENCODING_AS(%(name)s, UA_ByteString)")
+    printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(%(name)s)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)\n''')
+
 def createStructured(element):
-    valuemap = OrderedDict()
     name = "UA_" + element.get("Name")
-    print("\n/** @name " + name + " */\n", file=fh)
 
+    # 1) Are there arrays in the type?
     lengthfields = set()
     for child in element:
-		if child.get("LengthField"):
-			lengthfields.add(child.get("LengthField"))
-	
+        if child.get("LengthField"):
+            lengthfields.add(child.get("LengthField"))
+
+    # 2) Store members in membermap (name->type).
+    membermap = OrderedDict()
     for child in element:
         if child.tag == "{http://opcfoundation.org/BinarySchema/}Documentation":
-            print("/** @brief " + child.text + " */", end='\n', file=fh)
+            printh("/** @brief " + child.text + " */")
         elif child.tag == "{http://opcfoundation.org/BinarySchema/}Field":
             if child.get("Name") in lengthfields:
                 continue
             childname = camlCase2CCase(child.get("Name"))
             typename = stripTypename(child.get("TypeName"))
             if child.get("LengthField"):
-                valuemap[childname] = typename + "**"
+                membermap[childname] = "UA_" + typename + "*"
             else:
-                valuemap[childname] = typename
-
-    print("typedef struct " + name + " {", end='\n', file=fh)
-    if len(valuemap) == 0:
-		typename = stripTypename(element.get("BaseType"))
-		childname = camlCase2CCase(typename)
-		valuemap[childname] = typename 
-    for n,t in valuemap.iteritems():
-		if t.find("**") != -1:
-			print("\t" + "UA_Int32 " + n + "Size;", end='\n', file=fh)
-		print("\t" + "UA_" + t + " " + n + ";", end='\n', file=fh)
-    print("} " + name + ";", end='\n', file=fh)
-
-    print("UA_Int32 " + name + "_calcSize(" + name + " const* ptr);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_encodeBinary(" + name + " const* src, UA_Int32* pos, UA_ByteString* dst);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_decodeBinary(UA_ByteString const* src, UA_Int32* pos, " + name + "* dst);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_decodeXML(XML_Stack* s, XML_Attr* attr, " + name + "* dst, _Bool isStart);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_delete("+ name + "* p);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_deleteMembers(" + name + "* p);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_init("+ name + " * p);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_new(" + name + " ** p);", end='\n', file=fh)
-    print("UA_Int32 " + name + "_copy(" + name + "* src, " + name + "* dst);", end='\n', file=fh)
-
-    print("UA_Int32 "  + name + "_calcSize(" + name + " const * ptr) {", end='', file=fc)
-    print("\n\tif(ptr==UA_NULL){return sizeof("+ name +");}", end='', file=fc)
-    print("\n\treturn 0", end='', file=fc)
-
-	# code _calcSize
-    for n,t in valuemap.iteritems():
-		if t in elementary_size:
-			print('\n\t + sizeof(UA_' + t + ") // " + n, end='', file=fc)
-		else:
-			if t in enum_types:
-				print('\n\t + 4 //' + n, end='', file=fc) # enums are all 32 bit
-			elif t.find("**") != -1:
-				print("\n\t + 0 //" + n + "Size is included in UA_Array_calcSize", end='', file=fc),
-				print("\n\t + UA_Array_calcSize(ptr->" + n + "Size, UA_" + t[0:t.find("*")].upper() + ", (void const**) ptr->" + n +")", end='', file=fc)
-			elif t.find("*") != -1:
-				print('\n\t + ' + "UA_" + t[0:t.find("*")] + "_calcSize(ptr->" + n + ')', end='', file=fc)
-			else:
-				print('\n\t + ' + "UA_" + t + "_calcSize(&(ptr->" + n + '))', end='', file=fc)
-
-    print("\n\t;\n}\n", end='\n', file=fc)
-
-    print("UA_Int32 "+name+"_encodeBinary("+name+" const * src, UA_Int32* pos, UA_ByteString* dst) {\n\tUA_Int32 retval = UA_SUCCESS;", end='\n', file=fc)
-	# code _encode
-    for n,t in valuemap.iteritems():
-		if t in elementary_size:
-			print('\tretval |= UA_'+t+'_encodeBinary(&(src->'+n+'),pos,dst);', end='\n', file=fc)
-		else:
-			if t in enum_types:
-				print('\tretval |= UA_'+t+'_encodeBinary(&(src->'+n+'),pos,dst);', end='\n', file=fc)
-			elif t.find("**") != -1:
-				print('\t//retval |= UA_Int32_encodeBinary(&(src->'+n+'Size),pos,dst); // encode size managed by UA_Array_encodeBinary', end='\n', file=fc)
-				print("\tretval |= UA_Array_encodeBinary((void const**) (src->"+n+"),src->"+n+"Size, UA_" + t[0:t.find("*")].upper()+",pos,dst);", end='\n', file=fc)
-			elif t.find("*") != -1:
-				print('\tretval |= UA_' + t[0:t.find("*")] + "_encodeBinary(src->" + n + ',pos,dst);', end='\n', file=fc)
-			else:
-				print('\tretval |= UA_'+t+"_encodeBinary(&(src->"+n+"),pos,dst);", end='\n', file=fc)
-    print("\treturn retval;\n}\n", end='\n', file=fc)
-
-	# code _decodeBinary
-    print("UA_Int32 "+name+"_decodeBinary(UA_ByteString const * src, UA_Int32* pos, " + name + "* dst) {\n\tUA_Int32 retval = UA_SUCCESS;", end='\n', file=fc)
-    print('\t'+name+'_init(dst);', end='\n', file=fc)
-    for n,t in valuemap.iteritems():
-        if t in elementary_size:
-            print('\tCHECKED_DECODE(UA_'+t+'_decodeBinary(src,pos,&(dst->'+n+')), '+name+'_deleteMembers(dst));', end='\n', file=fc)
+                membermap[childname] = "UA_" + typename
+
+    # 3) Print structure
+    if len(membermap) > 0:
+        printh("typedef struct %(name)s {")
+        for n,t in membermap.iteritems():
+	    if t.find("*") != -1:
+	        printh("\t" + "UA_Int32 " + n + "Size;")
+            printh("\t%(t)s %(n)s;")
+        printh("} %(name)s;")
+    else:
+        printh("typedef void* %(name)s;")
+        
+
+    # 3) function prototypes
+    printh("UA_TYPE_PROTOTYPES(" + name + ")")
+    printh("UA_TYPE_BINARY_ENCODING(" + name + ")")
+    printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
+
+    # 4) CalcSizeBinary
+    printc('''UA_Int32 %(name)s_calcSizeBinary(%(name)s const * ptr) {
+    if(ptr==UA_NULL) return sizeof(%(name)s);
+    return 0''')
+    has_fixed_size = True
+    for n,t in membermap.iteritems():
+        if t in fixed_size:
+            printc('\t + sizeof(%(t)s) // %(n)s')
+        elif t.find("*") != -1:
+            printc('\t + UA_Array_calcSizeBinary(ptr->%(n)sSize,&UA_.types['+ t[0:t.find("*")].upper() +
+                   "],ptr->%(n)s)")
+            has_fixed_size = False
         else:
-            if t in enum_types:
-                print('\tCHECKED_DECODE(UA_'+t+'_decodeBinary(src,pos,&(dst->'+n+')), '+name+'_deleteMembers(dst));', end='\n', file=fc)
-            elif t.find("**") != -1:
-            	# decode size
-		print('\tCHECKED_DECODE(UA_Int32_decodeBinary(src,pos,&(dst->'+n+'Size)), ' +
-                      name + '_deleteMembers(dst)); // decode size', end='\n', file=fc)
-		# allocate memory for array
-		print("\tCHECKED_DECODE(UA_Array_new((void***)&dst->"+n+", dst->"+n+"Size, UA_"+t[0:t.find("*")].upper()+"), dst->" +
-                      n + " = UA_NULL; "+name+'_deleteMembers(dst));', end='\n', file=fc)
-		print("\tCHECKED_DECODE(UA_Array_decodeBinary(src,dst->"+n+"Size, UA_" + t[0:t.find("*")].upper() +
-                      ",pos,(void *** const) (&dst->"+n+")), "+name+'_deleteMembers(dst));', end='\n', file=fc)
-            elif t.find("*") != -1:
-		#allocate memory using new
-		print('\tCHECKED_DECODE(UA_'+ t[0:t.find("*")] +"_new(&(dst->" + n + ")), "+name+'_deleteMembers(dst));', end='\n', file=fc)
-		print('\tCHECKED_DECODE(UA_' + t[0:t.find("*")] + "_decodeBinary(src,pos,dst->"+ n +"), "+name+'_deleteMembers(dst));', end='\n', file=fc)
-            else:
-                print('\tCHECKED_DECODE(UA_'+t+"_decodeBinary(src,pos,&(dst->"+n+")), "+name+'_deleteMembers(dst));', end='\n', file=fc)
-    print("\treturn retval;\n}\n", end='\n', file=fc)
- 
-    if not name in exclude_xml_decode:
-        print("UA_Int32 "+name+"_decodeXML(XML_Stack* s, XML_Attr* attr, " + name + "* dst, _Bool isStart)", end='\n', file=fc)
-        print('''{
-        DBG_VERBOSE(printf("'''+name+'''_decodeXML entered with dst=%p,isStart=%d\\n", (void* ) dst, isStart));
-        return UA_ERR_NOT_IMPLEMENTED;}''', end='\n', file=fc)
+            printc('\t + %(t)s_calcSizeBinary(&ptr->%(n)s)')
+            has_fixed_size = False
+    printc("\t;\n}\n")
+    if has_fixed_size:
+        fixed_size.add(name)
+
+    # 5) EncodeBinary
+    printc('''UA_Int32 %(name)s_encodeBinary(%(name)s const * src, UA_ByteString* dst, UA_UInt32 *offset) {
+    UA_Int32 retval = UA_SUCCESS;''')
+    for n,t in membermap.iteritems():
+        if t.find("*") != -1:
+            printc("\tretval |= UA_Array_encodeBinary(src->%(n)s,src->%(n)sSize,&UA_.types[" +
+                   t[0:t.find("*")].upper() + "],dst,offset);")
+        else:
+            printc('\tretval |= %(t)s_encodeBinary(&src->%(n)s,dst,offset);')
+    printc("\treturn retval;\n}\n")
+
+    # 6) DecodeBinary
+    printc('''UA_Int32 %(name)s_decodeBinary(UA_ByteString const * src, UA_UInt32 *offset, %(name)s * dst) {
+    UA_Int32 retval = UA_SUCCESS;''')
+    printc('\t'+name+'_init(dst);')
+    for n,t in membermap.iteritems():
+        if t.find("*") != -1:
+            printc('\tretval |= UA_Int32_decodeBinary(src,offset,&dst->%(n)sSize);')
+            printc('\tretval |= UA_Array_decodeBinary(src,offset,dst->%(n)sSize,&UA_.types[' +
+                   t[0:t.find("*")].upper() + '],(void**)&dst->%(n)s);')
+            printc('\tif(retval != UA_SUCCESS) { dst->%(n)sSize = -1; }') # arrays clean up internally. But the size needs to be set here for the eventual deleteMembers.
+        else:
+            printc('\tretval |= %(t)s_decodeBinary(src,offset,&dst->%(n)s);')
+    printc("\tif(retval != UA_SUCCESS) %(name)s_deleteMembers(dst);")
+    printc("\treturn retval;\n}\n")
+
+    # 7) Xml
+    printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
+    UA_TYPE_METHOD_ENCODEXML_NOTIMPL(%(name)s)
+    UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     
-    # code _delete and _deleteMembers
-    print('UA_Int32 '+name+'_delete('+name+'''* p) {
+    # 8) Delete
+    printc('''UA_Int32 %(name)s_delete(%(name)s *p) {
 	UA_Int32 retval = UA_SUCCESS;
-	retval |= '''+name+'''_deleteMembers(p);
+	retval |= %(name)s_deleteMembers(p);
 	retval |= UA_free(p);
-	return retval;
-}''', end='\n', file=fc)
+	return retval;\n}\n''')
 	
-    print("UA_Int32 "+name+"_deleteMembers(" + name + "* p) {\n\tUA_Int32 retval = UA_SUCCESS;", end='\n', file=fc)
-    for n,t in valuemap.iteritems():
-        if t not in elementary_size:
-            if t.find("**") != -1:
-		print("\tretval |= UA_Array_delete((void***)&p->"+n+",p->"+n+"Size,UA_"+t[0:t.find("*")].upper()+"); p->"+n+" = UA_NULL;", end='\n', file=fc)
-            elif t.find("*") != -1:
-		print('\tretval |= UA_' + t[0:t.find("*")] + "_delete(p->"+n+");", end='\n', file=fc)
+    # 9) DeleteMembers
+    printc('''UA_Int32 %(name)s_deleteMembers(%(name)s *p) {
+    UA_Int32 retval = UA_SUCCESS;''')
+    for n,t in membermap.iteritems():
+        if not t in fixed_size: # dynamic size on the wire
+            if t.find("*") != -1:
+		printc("\tretval |= UA_Array_delete((void*)p->%(n)s,p->%(n)sSize,&UA_.types[" +
+                       t[0:t.find("*")].upper()+"]);")
             else:
-		print('\tretval |= UA_' + t + "_deleteMembers(&(p->"+n+"));", end='\n', file=fc)
-		
-    print("\treturn retval;\n}\n", end='\n', file=fc)
-
-	# code _init
-    print("UA_Int32 "+name+"_init(" + name + " * p) {\n\tUA_Int32 retval = UA_SUCCESS;", end='\n', file=fc)
-    for n,t in valuemap.iteritems():
-		if t in elementary_size:
-			print('\tretval |= UA_'+t+'_init(&(p->'+n+'));', end='\n', file=fc)
-		else:
-			if t in enum_types:
-				print('\tretval |= UA_'+t+'_init(&(p->'+n+'));', end='\n', file=fc)
-			elif t.find("**") != -1:
-				print('\tp->'+n+'Size=0;', end='\n', file=fc)
-				print("\tp->"+n+"=UA_NULL;", end='\n', file=fc)
-			elif t.find("*") != -1:
-				print("\tp->"+n+"=UA_NULL;", end='\n', file=fc)
-			else:
-				print('\tretval |= UA_'+t+"_init(&(p->"+n+"));", end='\n', file=fc)
-    print("\treturn retval;\n}\n", end='\n', file=fc)
-
-	# code _new
-    print("UA_TYPE_METHOD_NEW_DEFAULT(" + name + ")", end='\n', file=fc)
-	# code _copy
-    print("UA_Int32 "+name+"_copy(" + name + " * src," + name + " * dst) {\n\tUA_Int32 retval = UA_SUCCESS;", end='\n', file=fc)
-    for n,t in valuemap.iteritems():
-        if t in elementary_size:
-            print('\tretval |= UA_'+t+'_copy(&(src->'+n+'),&(dst->'+n+'));', end='\n', file=fc)
+		printc('\tretval |= %(t)s_deleteMembers(&p->%(n)s);')
+    printc("\treturn retval;\n}\n")
+
+    # 10) Init
+    printc('''UA_Int32 %(name)s_init(%(name)s *p) {
+    UA_Int32 retval = UA_SUCCESS;''')
+    for n,t in membermap.iteritems():
+        if t.find("*") != -1:
+            printc('\tp->%(n)sSize = 0;')
+            printc('\tp->%(n)s = UA_NULL;')
         else:
-            if t in enum_types:
-                print('\tretval |= UA_'+t+'_copy(&(src->'+n+'),&(dst->'+n+'));', end='\n', file=fc)
-            elif t.find("**") != -1:
-                print('\tretval |= UA_Int32_copy(&(src->'+n+'Size),&(dst->'+n+'Size)); // size of following array', end='\n', file=fc)
-		print("\tretval |= UA_Array_copy((void const* const*) (src->"+n+"), src->"+n+"Size," + "UA_" +
-                      t[0:t.find("*")].upper()+",(void***)&(dst->"+n+"));", end='\n', file=fc)
-            elif t.find("*") != -1:
-                print('\tretval |= UA_' + t[0:t.find("*")] + '_copy(src->' + n + ',dst->' + n + ');', end='\n', file=fc)
-            else:
-                print('\tretval |= UA_'+t+"_copy(&(src->"+n+"),&(dst->" + n + '));', end='\n', file=fc)
-    print("\treturn retval;\n}\n", end='\n', file=fc)
+            printc('\tretval |= %(t)s_init(&p->%(n)s);')
+    printc("\treturn retval;\n}\n")
+
+    # 11) New
+    printc("UA_TYPE_NEW_DEFAULT(%(name)s)")
+
+    # 12) Copy
+    printc('''UA_Int32 %(name)s_copy(const %(name)s *src,%(name)s *dst) {
+    if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
+    UA_Int32 retval = UA_SUCCESS;''')
+    printc("\tmemcpy(dst, src, sizeof(%(name)s));")
+    for n,t in membermap.iteritems():
+        if t.find("*") != -1:
+            printc('\tdst->%(n)s = src->%(n)s;')
+            printc("\tretval |= UA_Array_copy(src->%(n)s, src->%(n)sSize,&UA_.types[" +
+                      t[0:t.find("*")].upper()+"],(void**)&dst->%(n)s);")
+            continue
+        if not t in fixed_size: # there are members of variable size    
+            printc('\tretval |= %(t)s_copy(&src->%(n)s,&dst->%(n)s);')
+    printc("\treturn retval;\n}\n")
+
+    # 13) Print
+    printc('''#ifdef DEBUG''') 
+    printc('''void %(name)s_print(const %(name)s *p, FILE *stream) {
+    fprintf(stream, "(%(name)s){");''')
+    for i,(n,t) in enumerate(membermap.iteritems()):
+        if t.find("*") != -1:
+            printc('\tUA_Int32_print(&p->%(n)sSize, stream);')
+            printc("\tUA_Array_print(p->%(n)s, p->%(n)sSize, &UA_.types[" + t[0:t.find("*")].upper()+"], stream);")
+        else:
+            printc('\t%(t)s_print(&p->%(n)s,stream);')
+        if i == len(membermap)-1:
+            continue
+	printc('\tfprintf(stream, ",");')
+    printc('''\tfprintf(stream, "}");\n}''')
+    printc('#endif');
+    printc('''\n''')
+    
 	
-def createOpaque(element):
-    name = "UA_" + element.get("Name")
-    print("\n/** @name " + name + " */\n", file=fh)
-    for child in element:
-        if child.tag == "{http://opcfoundation.org/BinarySchema/}Documentation":
-            print("/** @brief " + child.text + " */", end='\n', file=fh)
-
-    print("typedef UA_ByteString " + name + ";", end='\n', file=fh)
-    print("UA_TYPE_METHOD_PROTOTYPES (" + name + ")", end='\n', file=fh)
-    print("UA_TYPE_METHOD_CALCSIZE_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_ENCODEBINARY_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DECODEBINARY_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DECODEXML_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DELETE_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_DELETEMEMBERS_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_INIT_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_COPY_AS("+name+", UA_ByteString)", end='\n', file=fc)
-    print("UA_TYPE_METHOD_NEW_DEFAULT("+name+")\n", end='\n', file=fc)
-
-ns = {"opc": "http://opcfoundation.org/BinarySchema/"}
-tree = etree.parse(sys.argv[1])
-types = tree.xpath("/opc:TypeDictionary/*[not(self::opc:Import)]", namespaces=ns)
-
-fh = open(sys.argv[2] + ".hgen",'w');
-fc = open(sys.argv[2] + ".cgen",'w');
-
-print('''/**
+printh('''/**
  * @file '''+sys.argv[2]+'''.h
  *
  * @brief Autogenerated data types defined in the UA standard
@@ -286,13 +267,15 @@ print('''/**
  * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
  */
 
-#ifndef OPCUA_H_
-#define OPCUA_H_
+#ifndef ''' + sys.argv[2].upper() + '''_H_
+#define ''' + sys.argv[2].upper() + '''_H_
 
-#include "ua_basictypes.h"
-#include "ua_namespace_0.h"''', end='\n', file=fh);
+#include "ua_types.h"
+#include "ua_types_encoding_binary.h"
+#include "ua_types_encoding_xml.h"
+#include "ua_namespace_0.h"\n''')
 
-print('''/**
+printc('''/**
  * @file '''+sys.argv[2]+'''.c
  *
  * @brief Autogenerated function implementations to manage the data types defined in the UA standard
@@ -301,7 +284,9 @@ print('''/**
  * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
  */
  
-#include "''' + sys.argv[2] + '.h"', end='\n', file=fc);
+#include "''' + sys.argv[2] + '.h"\n')
+#include "ua_types_encoding_binary.h"
+#include "util/ua_util.h"
 
 # types for which we create a vector type
 arraytypes = set()
@@ -335,28 +320,30 @@ for element in types:
 		
 	if element.tag == "{http://opcfoundation.org/BinarySchema/}EnumeratedType":
 		createEnumerated(element)
-		printed_types.add(name)
+		existing_types.add(name)
 	elif element.tag == "{http://opcfoundation.org/BinarySchema/}StructuredType":
 		if printableStructuredType(element):
 			createStructured(element)
-			structured_types.append(name)
-			printed_types.add(name)
+			existing_types.add(name)
 		else: # the record contains types that were not yet detailed
 			deferred_types[name] = element
 			continue
 	elif element.tag == "{http://opcfoundation.org/BinarySchema/}OpaqueType":
 		createOpaque(element)
-		printed_types.add(name)
+		existing_types.add(name)
 
 for name, element in deferred_types.iteritems():
-	if name in plugin_types:
-		#execute plugin if registered
-		exec "ret = " + packageForType[name][0]+"."+packageForType[name][1]["functionCall"]
-		if ret == "default":
-			createStructured(element)
-	else:
-		createStructured(element)
+    if name in plugin_types:
+        #execute plugin if registered
+	exec "ret = " + packageForType[name][0]+"."+packageForType[name][1]["functionCall"]
+	if ret == "default":
+            createStructured(element)
+            existing_types.add(name)
+    else:
+	createStructured(element)
+        existing_types.add(name)
+
+printh('#endif')
 
-print('#endif /* OPCUA_H_ */', end='\n', file=fh)
 fh.close()
 fc.close()

+ 115 - 95
tools/generate_namespace.py

@@ -1,32 +1,56 @@
 from __future__ import print_function
+import inspect
 import sys
 import platform
 import getpass
 import time
 
 if len(sys.argv) != 3:
-	print("Usage: python generate_namespace.py <path/to/NodeIds.csv> <outfile w/o extension>", file=sys.stdout)
-	exit(0)
+    print("Usage: python generate_namespace.py <path/to/NodeIds.csv> <outfile w/o extension>",
+          file=sys.stdout)
+    exit(0)
 
 # types that are to be excluded
 exclude_kinds = set(["Object","ObjectType","Variable","Method","ReferenceType"])
-exclude_types = set(["Number", "Integer", "UInteger", "Enumeration",
-	"Image", "ImageBMP", "ImageGIF", "ImageJPG", "ImagePNG",
-	"References", "BaseVariableType", "BaseDataVariableType", 
-	"PropertyType", "DataTypeDescriptionType", "DataTypeDictionaryType", "NamingRuleType",
-	"IntegerId","Counter","Duration","NumericRange","Time","Date",
-	"UtcTime", "LocaleId","UserTokenType",
-	"ApplicationType","ApplicationInstanceCertificate",
-	"ServerVendorCapabilityType","ServerStatusType","ServerDiagnosticsSummaryType",
-	"SamplingIntervalDiagnosticsArrayType", "SamplingIntervalDiagnosticsType", 
-	"SubscriptionDiagnosticsArrayType", "SubscriptionDiagnosticsType",
-	"SessionDiagnosticsArrayType", "SessionDiagnosticsVariableType", 
-	"SessionSecurityDiagnosticsArrayType", "SessionSecurityDiagnosticsType", 
-	"DataItemType", "AnalogItemType", "DiscreteItemType", "TwoStateDiscreteType",
-	"MultiStateDiscreteType", "ProgramDiagnosticType", "StateVariableType", "FiniteStateVariableType",
-	"TransitionVariableType", "FiniteTransitionVariableType", "BuildInfoType", "TwoStateVariableType",
-	"ConditionVariableType", "MultiStateValueDiscreteType", "OptionSetType", "ArrayItemType",
-	"YArrayItemType", "XYArrayItemType", "ImageItemType", "CubeItemType", "NDimensionArrayItemType"])
+exclude_types = set(["Number", "Integer", "UInteger", "Enumeration", "Image", "ImageBMP",
+                     "ImageGIF", "ImageJPG", "ImagePNG", "References", "BaseVariableType",
+                     "BaseDataVariableType", "PropertyType", "DataTypeDescriptionType",
+                     "DataTypeDictionaryType", "NamingRuleType", "IntegerId", "Counter",
+                     "Duration", "NumericRange", "Time", "Date", "UtcTime", "LocaleId",
+                     "UserTokenType", "ApplicationType", "ApplicationInstanceCertificate",
+                     "ServerVendorCapabilityType", "ServerStatusType",
+                     "ServerDiagnosticsSummaryType", "SamplingIntervalDiagnosticsArrayType",
+                     "SamplingIntervalDiagnosticsType", "SubscriptionDiagnosticsArrayType",
+                     "SubscriptionDiagnosticsType", "SessionDiagnosticsArrayType",
+                     "SessionDiagnosticsVariableType", "SessionSecurityDiagnosticsArrayType",
+                     "SessionSecurityDiagnosticsType", "DataItemType", "AnalogItemType",
+                     "DiscreteItemType", "TwoStateDiscreteType", "MultiStateDiscreteType",
+                     "ProgramDiagnosticType", "StateVariableType", "FiniteStateVariableType",
+                     "TransitionVariableType", "FiniteTransitionVariableType", "BuildInfoType",
+                     "TwoStateVariableType", "ConditionVariableType",
+                     "MultiStateValueDiscreteType", "OptionSetType", "ArrayItemType",
+                     "YArrayItemType", "XYArrayItemType", "ImageItemType", "CubeItemType",
+                     "NDimensionArrayItemType"])
+
+fixed_size = ['UA_DeadbandType', 'UA_DataChangeTrigger', 'UA_Guid', 'UA_ApplicationType',
+              'UA_ComplexNumberType', 'UA_EnumeratedTestType', 'UA_BrowseResultMask',
+              'UA_TimeZoneDataType', 'UA_NodeClass', 'UA_IdType', 'UA_ServiceCounterDataType',
+              'UA_Float', 'UA_ModelChangeStructureVerbMask', 'UA_EndpointConfiguration',
+              'UA_NodeAttributesMask', 'UA_DataChangeFilter', 'UA_StatusCode',
+              'UA_MonitoringFilterResult', 'UA_OpenFileMode', 'UA_SecurityTokenRequestType',
+              'UA_ServerDiagnosticsSummaryDataType', 'UA_ElementOperand',
+              'UA_AggregateConfiguration', 'UA_UInt64', 'UA_FilterOperator',
+              'UA_ReadRawModifiedDetails', 'UA_ServerState', 'UA_FilterOperand',
+              'UA_SubscriptionAcknowledgement', 'UA_AttributeWriteMask', 'UA_SByte', 'UA_Int32',
+              'UA_Range', 'UA_Byte', 'UA_TimestampsToReturn', 'UA_UserTokenType', 'UA_Int16',
+              'UA_XVType', 'UA_AggregateFilterResult', 'UA_Boolean', 'UA_MessageSecurityMode',
+              'UA_AxisScaleEnumeration', 'UA_PerformUpdateType', 'UA_UInt16',
+              'UA_NotificationData', 'UA_DoubleComplexNumberType', 'UA_HistoryUpdateType',
+              'UA_MonitoringFilter', 'UA_NodeIdType', 'UA_BrowseDirection',
+              'UA_SamplingIntervalDiagnosticsDataType', 'UA_UInt32', 'UA_ChannelSecurityToken',
+              'UA_RedundancySupport', 'UA_MonitoringMode', 'UA_HistoryReadDetails',
+              'UA_ExceptionDeviationFormat', 'UA_ComplianceLevel', 'UA_DateTime', 'UA_Int64',
+              'UA_Double']
 
 f = open(sys.argv[1])
 input_str = f.read() + "\nInvalidType,0,DataType"
@@ -34,21 +58,26 @@ input_str = input_str.replace('\r','')
 rows = map(lambda x:tuple(x.split(',')), input_str.split('\n'))
 f.close()
 
-fh = open(sys.argv[2] + ".hgen",'w')
-fc = open(sys.argv[2] + ".cgen",'w')
+fh = open(sys.argv[2] + ".h",'w')
+fc = open(sys.argv[2] + ".c",'w')
+def printh(string):
+    print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fh)
 
-print('''/**********************************************************
+def printc(string):
+    print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fc)
+
+printh('''/**********************************************************
  * '''+sys.argv[2]+'''.hgen -- do not modify
  **********************************************************
  * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
- * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
- **********************************************************/
- 
-#ifndef OPCUA_NAMESPACE_0_H_
-#define OPCUA_NAMESPACE_0_H_
-
-#include "ua_basictypes.h"  // definition of UA_VTable and basic UA_Types
-
+ * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+
+       time.strftime("%Y-%m-%d %I:%M:%S")+'''
+ **********************************************************/\n 
+#ifndef ''' + sys.argv[2].upper() + '''_H_
+#define ''' + sys.argv[2].upper() + '''_H_\n
+#include "util/ua_util.h"
+#include "ua_types.h"  // definition of UA_VTable and basic UA_Types
+#include "ua_types_generated.h"\n
 /**
  * @brief maps namespace zero nodeId to index into UA_VTable
  *
@@ -56,32 +85,30 @@ print('''/**********************************************************
  *
  * @retval UA_ERR_INVALID_VALUE whenever ns0Id could not be mapped
  * @retval the corresponding index into UA_VTable
- */
-UA_Int32 UA_ns0ToVTableIndex(UA_Int32 id);
-extern UA_VTable UA_[]; 
-
+ */\n
+UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id);\n
+extern const UA_VTable UA_;\n
 static UA_Int32 phantom_delete(void * p) { return UA_SUCCESS; }
-extern UA_VTable UA_noDelete_[];
-
+extern const UA_VTable UA_borrowed_;\n
 /**
  * @brief the set of possible indices into UA_VTable
  *
  * Enumerated type to define the types that the open62541 stack can handle
  */
-enum UA_VTableIndex_enum {''', end='\n', file=fh)
+enum UA_VTableIndex_enum {''')
 
-print('''/**********************************************************
+printc('''/**********************************************************
  * '''+sys.argv[2]+'''.cgen -- do not modify
  **********************************************************
  * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
- * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
- **********************************************************/
- 
-#include "opcua.h"
-
-UA_Int32 UA_ns0ToVTableIndex(UA_Int32 ns0Id) {
-	UA_Int32 retval = UA_ERR_INVALID_VALUE;
-	switch (ns0Id) { ''', end='\n',file=fc)
+ * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser() +
+       ''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
+ **********************************************************/\n
+#include "''' + sys.argv[2] + '''.h"\n
+UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
+	UA_Int32 retval = 0; // InvalidType
+        if(id->namespace != 0) return retval;
+	switch (id->identifier.numeric) {''')
 
 i = 0
 for row in rows:
@@ -94,18 +121,18 @@ for row in rows:
     else:
         name = "UA_" + row[0]
 	
-    print("\t"+name.upper()+" = "+str(i)+",", file=fh)
-    print('\tcase '+row[1]+': retval='+name.upper()+'; break; //'+row[2], file=fc)
+    printh("\t"+name.upper()+" = "+str(i)+",")
+    printc('\tcase '+row[1]+': retval='+name.upper()+'; break; //'+row[2])
     i = i+1
 
-print("};\n", file=fh)
-print('''
-    }
-    return retval;
-}
+printh("};\n")
+printc('''\n}\nreturn retval;\n}\n''');
 
-UA_VTable UA_[] = {''', file=fc)
+printc('''const UA_VTable UA_ = {
+\t.getTypeIndex = UA_ns0ToVTableIndex,
+\t.types = (UA_VTable_Entry[]){''')
 
+i = 0
 for row in rows:
     if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
         continue
@@ -115,47 +142,40 @@ for row in rows:
         name = "UA_ExtensionObject"
     else:
 	name = "UA_" + row[0]
-
-    print('#define '+name.upper()+'_NS0 '+row[1], file=fh)
-
-    print("\t{" + row[1] + 
-          ",(UA_Int32(*)(void const*))"+name+"_calcSize" + 
-          ",(UA_Int32(*)(UA_ByteString const*,UA_Int32*,void*))"+name+ "_decodeBinary" +
-          ",(UA_Int32(*)(void const*,UA_Int32*,UA_ByteString*))"+name+"_encodeBinary"+
-          ",(UA_Int32(*)(XML_Stack*,XML_Attr*,void*,_Bool))"+ name + "_decodeXML" +
-          ",(UA_Int32(*)(void *))"+name+"_init"+
-          ",(UA_Int32(*)(void **))"+name+"_new"+
-          ",(UA_Int32(*)(void const * ,void*))"+name+"_copy"+
-          ",(UA_Int32(*)(void *))"+name+"_delete"+
-          (",sizeof("+name+")" if (name != "UA_InvalidType") else ",0") +
-          ',(UA_Byte*)"'+name+'"},',end='\n',file=fc) 
-
-print("};\n\nUA_VTable UA_noDelete_[] = {", end='\n', file=fc)
-
-for row in rows:
-    if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
-        continue
-    if row[0] == "BaseDataType":
-        name = "UA_Variant"
-    elif row[0] == "Structure":
-        name = "UA_ExtensionObject"
-    else:	
-	name = "UA_" + row[0]
-
-    print("\t{" + row[1] +
-          ",(UA_Int32(*)(void const*))"+name+"_calcSize" + 
-          ",(UA_Int32(*)(UA_ByteString const*,UA_Int32*,void*))"+name+ "_decodeBinary" +
-          ",(UA_Int32(*)(void const*,UA_Int32*,UA_ByteString*))"+name+"_encodeBinary"+
-          ",(UA_Int32(*)(XML_Stack*,XML_Attr*,void*,_Bool))" + name + "_decodeXML" +          
-          ",(UA_Int32(*)(void *))"+name+"_init"+
-          ",(UA_Int32(*)(void **))"+name+"_new"+
-          ",(UA_Int32(*)(void const * ,void*))"+name+"_copy"+
-          ",(UA_Int32(*)(void *))phantom_delete"+
-          (",sizeof("+name+")" if (name != "UA_InvalidType") else ",0") +
-          ',(UA_Byte*)"'+name+'"},',end='\n',file=fc)
-print("};", end='\n', file=fc) 
-
-print('\n#endif /* OPCUA_NAMESPACE_0_H_ */', end='\n', file=fh)
+	i=i+1
+    printh('#define '+name.upper()+'_NS0 '+row[1])
+
+    printc("\t{.typeId={UA_NODEIDTYPE_FOURBYTE,0,.identifier.numeric=" + row[1] + "}" + 
+          ",\n.name=(UA_Byte*)&\"%(name)s\"" +
+          ",\n.new=(UA_Int32(*)(void **))%(name)s_new" +
+          ",\n.init=(UA_Int32(*)(void *))%(name)s_init"+
+          ",\n.copy=(UA_Int32(*)(void const * ,void*))%(name)s_copy" +
+          ",\n.delete=(UA_Int32(*)(void *))%(name)s_delete" +
+          ",\n.deleteMembers=(UA_Int32(*)(void *))%(name)s_deleteMembers" +
+          ",\n#ifdef DEBUG //FIXME: seems to be okay atm, however a pointer to a noop function would be more safe" + 
+          "\n.print=(void(*)(const void *, FILE *))%(name)s_print," +
+          "\n#endif" + 
+          "\n.memSize=" + ("sizeof(%(name)s)" if (name != "UA_InvalidType") else "0") +
+          ",\n.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
+          ",\n.encodings={{.calcSize=(UA_calcSize)%(name)s_calcSizeBinary" +
+          ",\n.encode=(UA_encode)%(name)s_encodeBinary" +
+          ",\n.decode=(UA_decode)%(name)s_decodeBinary}" +
+          ",\n{.calcSize=(UA_calcSize)%(name)s_calcSizeXml" +
+          ",\n.encode=(UA_encode)%(name)s_encodeXml" +
+          ",\n.decode=(UA_decode)%(name)s_decodeXml}" +
+          "}},")
+
+printc('''}};''')
+
+printc("UA_VTable_Entry borrowed_types[" + str(i) + "];");
+printc("const UA_VTable UA_borrowed_ = {\n"+
+"\t.getTypeIndex=UA_ns0ToVTableIndex,\n"+
+"\t.types = borrowed_types\n"+
+"};")
+
+printh('\n#define SIZE_UA_VTABLE '+str(i));
+
+printh('\n#endif /* OPCUA_NAMESPACE_0_H_ */')
 
 fh.close()
 fc.close()

+ 4 - 40
tools/indent.sh

@@ -3,49 +3,13 @@ if [ $# -eq 0 ]; then
 echo "usage: $0 <file1 file2 ...>"
    exit 1
 fi
-if [ "$(type -t indent)" = "" ]; then
-echo "Please install GNU indent first."
+if [ "$(type -t uncrustify)" = "" ]; then
+echo "Please install uncrustify first."
    exit 1
 fi
 
-# Assume a width of 4 spaces per tab.
-# E.g. when indenting to the opening braces of an argument list.
-
-indent \
---line-length120 \
---comment-line-length100 \
---indent-level4 \
---use-tabs \
---tab-size4 \
---case-indentation0 \
---declaration-indentation1 \
---ignore-newlines \
---swallow-optional-blank-lines \
---blank-lines-after-procedures \
---no-blank-lines-after-commas \
---break-after-boolean-operator \
---no-space-after-for \
---no-space-after-if \
---no-space-after-while \
---no-space-after-casts \
---braces-on-if-line \
---braces-on-func-def-line \
---braces-on-struct-decl-line \
---cuddle-do-while \
---cuddle-else \
---dont-break-procedure-type \
---continue-at-parentheses \
---no-space-after-function-call-names \
---no-space-after-parentheses \
---no-comment-delimiters-on-blank-lines \
---comment-indentation0 \
---format-first-column-comments \
---declaration-comment-column0 \
---format-all-comments \
---line-comments-indentation0 \
---space-special-semicolon \
-$@
-
+TOOL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+uncrustify -c $TOOL_DIR/uncrustify.cfg -l C --replace $@
 
 # Remove trailing whitespace
 for file in $@; do

+ 95 - 0
tools/uncrustify.cfg

@@ -0,0 +1,95 @@
+# Basics
+code_width		= 110
+indent_with_tabs	= 1		# 1=indent to level only, 2=indent with tabs
+input_tab_size		= 4		# original tab size
+output_tab_size		= 4		# new tab size
+indent_columns		= output_tab_size
+indent_label		= 1		# pos: absolute col, neg: relative column
+
+# Newlines
+nl_enum_brace		= remove	# "enum {" vs "enum \n {"
+nl_union_brace		= remove	# "union {" vs "union \n {"
+nl_struct_brace		= remove	# "struct {" vs "struct \n {"
+nl_assign_brace		= remove
+nl_do_brace 		= remove	# "do {" vs "do \n {"
+nl_if_brace 		= remove	# "if () {" vs "if () \n {"
+nl_else_if		= remove
+nl_for_brace 		= remove	# "for () {" vs "for () \n {"
+nl_else_brace 		= remove	# "else {" vs "else \n {"
+nl_while_brace 		= remove	# "while () {" vs "while () \n {"
+nl_switch_brace 	= remove	# "switch () {" vs "switch () \n {"
+nl_brace_while		= remove	# "} while" vs "} \n while" - cuddle while
+nl_brace_else		= remove	# "} else" vs "} \n else" - cuddle else
+nl_func_var_def_blk	= 0		# number of blank lines after variable definitions
+
+# Source code modifications
+mod_paren_on_return	= remove	# "return 1;" vs "return (1);"
+mod_full_brace_if	= remove	# "if (a) a--;" vs "if (a) { a--; }"
+mod_full_brace_for	= remove	# "for () a--;" vs "for () { a--; }"
+mod_full_brace_do	= add		# "do a--; while ();" vs "do { a--; } while ();"
+mod_full_brace_while	= add		# "while (a) a--;" vs "while (a) { a--; }"
+mod_full_brace_nl	= 2		# don't remove if more than 3 newlines
+
+# inter-character spacing options
+sp_return_paren		= force		# "return (1);" vs "return(1);"
+sp_sizeof_paren		= remove	# "sizeof (int)" vs "sizeof(int)"
+sp_before_sparen	= remove	# "if (" vs "if("
+sp_after_sparen		= add		# "if () {" vs "if (){"
+sp_after_cast		= remove	# "(int) a" vs "(int)a"
+sp_inside_braces	= add		# "{ 1 }" vs "{1}"
+sp_inside_braces_struct	= add		# "{ 1 }" vs "{1}"
+sp_inside_braces_enum	= add		# "{ 1 }" vs "{1}"
+sp_assign		= add
+sp_arith		= ignore
+sp_bool			= add
+sp_compare		= add
+sp_after_comma		= add
+sp_fparen_brace		= add
+sp_pp_concat		= remove
+sp_after_semi_for_empty	= remove
+sp_after_semi_for	= remove
+
+# Functions
+sp_paren_brace		= add		# "int foo(){ vs. int foo() {"
+sp_func_def_paren	= remove	# "int foo\n(){" vs "int foo(){"
+sp_func_call_paren	= remove	# "foo (" vs "foo("
+sp_func_proto_paren	= remove	# "int foo ();" vs "int foo();"
+nl_fcall_brace		= remove	# "list_for_each() {" vs "list_for_each()\n{"
+nl_fdef_brace		= remove	# "int foo() {" vs "int foo()\n{"
+
+# Macros
+sp_macro		= remove
+sp_macro_func		= remove 
+align_nl_cont		= true
+
+# Switch
+nl_before_case		= true
+nl_after_case		= true
+
+# Pointers
+sp_between_ptr_star	= remove
+sp_before_ptr_star	= force
+sp_after_ptr_star	= remove
+
+# Aligning
+align_with_tabs		= false		# use tabs to align
+align_on_tabstop	= false		# align on tabstops
+align_var_def_thresh	= 6
+align_func_params	= true		# align variable definitions
+align_assign_span	= 2
+align_assign_thresh	= 6
+align_nl_cont		= true		# align macros with backlash+newline
+## Algin Variable Assignment
+align_var_def_span	= 2		# max distance of lines considered together
+align_var_def_thresh	= 6		# max horizontal distance for grouping
+align_var_def_star_style = 2
+align_var_def_amp_style = 2
+align_var_def_inline	= true
+## Enum Assignment
+align_enum_equ_thresh	= 12
+align_enum_equ_span	= 2
+sp_enum_assign		= force
+align_struct_init_span	= 2		# align stuff in a structure init '= { }'
+align_var_struct_span	= 2
+align_var_struct_thresh = 6
+align_right_cmt_span	= 2

+ 11 - 0
wrappers/Makefile.am

@@ -0,0 +1,11 @@
+# We expand open62541.h with the preprocessor. SWIG can't handle all our macros.
+# The standard libs are not included into the expanded header file.
+
+# the lib is stated as a dependency to refresh if a header changes in ../src
+open62541_expanded.h: open62541.h open62541.i $(top_builddir)/lib/libopen62541.a
+	gcc -E open62541.h > open62541_expanded.h -I../src -D_STDIO_H=1 -D_STDDEF_H=1 -D_STDLIB_H=1 -D_STRING_H=1 -D_CTYPE_H=1 -D_UNISTD_H=1 -D_STDINT_H=1
+
+all: open62541_expanded.h
+
+clean-local:
+	rm -rf open62541_expanded.h

+ 20 - 0
wrappers/lua/Makefile.am

@@ -0,0 +1,20 @@
+INCLUDEDIRS = -I$(top_builddir)/src -I$(top_builddir)/src/util -I$(top_builddir)/examples/src
+AM_CFLAGS = $(GLOBAL_AM_CFLAGS) $(INCLUDEDIRS)
+WRAPPER_DIR = $(top_builddir)/wrappers
+
+open62541.lua open62541_wrap_lua.c:
+	swig -lua $(INCLUDEDIRS) -o ./open62541_wrap_lua.c $(WRAPPER_DIR)/open62541.i
+
+networklayer.so:
+	gcc -c $(AM_CFLAGS) $(top_builddir)/examples/src/networklayer.c -o networklayer.so
+
+open62541_wrap_lua.o: open62541_wrap_lua.c
+	gcc -c $(subst -Wall, ,$(subst -Wreturn-type, ,$(subst -pedantic, , $(AM_CFLAGS)))) -I/usr/include/lua5.2 open62541_wrap_lua.c
+
+open62541.so: networklayer.so open62541_wrap_lua.o
+	ld -shared open62541_wrap_lua.o networklayer.so $(top_builddir)/lib/libopen62541.so -o open62541.so
+
+all: open62541.lua open62541.so
+
+clean-local:
+	rm -rf networklayer.so open62541.lua open62541.so open62541_wrap_lua.c open62541_wrap_lua.o || true;

+ 2 - 0
wrappers/open62541.h

@@ -0,0 +1,2 @@
+#include "ua_types.h"
+#include "ua_application.h"

+ 9 - 0
wrappers/open62541.i

@@ -0,0 +1,9 @@
+%module open62541
+%{
+/* Includes the header in the wrapper code */
+#include "open62541_expanded.h"
+%}
+
+/* Parse the header file to generate wrappers */
+%include "stdint.i"
+%include "open62541_expanded.h"

+ 18 - 0
wrappers/python/Makefile.am

@@ -0,0 +1,18 @@
+WRAPPER_DIR = $(top_builddir)/wrappers
+#AM_CFLAGS = $(GLOBAL_AM_CFLAGS) -I$(WRAPPER_DIR)
+AM_CFLAGS = -fPIC -I$(WRAPPER_DIR)
+
+open62541.py open62541_wrap_python.c: $(WRAPPER_DIR)/open62541.i \
+									  $(WRAPPER_DIR)/open62541_expanded.h
+	swig -python -o ./open62541_wrap_python.c $(WRAPPER_DIR)/open62541.i
+
+open62541_wrap_python.o: open62541_wrap_python.c
+	gcc -c $(subst -pedantic, , $(AM_CFLAGS)) -I/usr/include/python2.7 open62541_wrap_python.c
+
+_open62541.so: open62541_wrap_python.o
+	ld -shared open62541_wrap_python.o $(top_builddir)/lib/libopen62541.a -lexpat -o _open62541.so
+
+all: open62541.py _open62541.so
+
+clean-local:
+	rm -rf open62541.py open62541.pyc _open62541.so open62541_wrap_python.c open62541_wrap_python.o || true;