Browse Source

Merge pull request #1595 from cabralfortiss/feature/architectures

architectures folder for easier porting to embedded devices
Stefan Profanter 6 years ago
parent
commit
c0360c3215
75 changed files with 2015 additions and 1104 deletions
  1. 110 69
      CMakeLists.txt
  2. 2 1
      README.md
  3. 3 2
      appveyor.yml
  4. 21 0
      arch/CMakeLists.txt
  5. 106 0
      arch/Readme.md
  6. 46 0
      arch/common/freeRTOS62541.h
  7. 79 0
      arch/common/lwip62541.h
  8. 29 0
      arch/eCos/CMakeLists.txt
  9. 88 0
      arch/eCos/ua_architecture.h
  10. 37 0
      arch/eCos/ua_architecture_functions.c
  11. 35 0
      arch/eCos/ua_clock.c
  12. 21 0
      arch/freertosLWIP/CMakeLists.txt
  13. 21 0
      arch/freertosLWIP/ua_architecture.h
  14. 47 0
      arch/freertosLWIP/ua_architecture_functions.c
  15. 45 0
      arch/freertosLWIP/ua_clock.c
  16. 35 0
      arch/posix/CMakeLists.txt
  17. 137 0
      arch/posix/ua_architecture.h
  18. 33 0
      arch/posix/ua_architecture_functions.c
  19. 58 0
      arch/posix/ua_clock.c
  20. 208 0
      arch/ua_architecture_functions.h
  21. 103 357
      plugins/ua_network_tcp.c
  22. 0 0
      arch/ua_network_tcp.h
  23. 1 8
      plugins/ua_network_udp.c
  24. 0 0
      arch/ua_network_udp.h
  25. 20 0
      arch/vxworks/CMakeLists.txt
  26. 114 0
      arch/vxworks/ua_architecture.h
  27. 33 0
      arch/vxworks/ua_architecture_functions.c
  28. 56 0
      arch/vxworks/ua_clock.c
  29. 21 0
      arch/win32/CMakeLists.txt
  30. 147 0
      arch/win32/ua_architecture.h
  31. 34 0
      arch/win32/ua_architecture_functions.c
  32. 64 0
      arch/win32/ua_clock.c
  33. 0 5
      deps/queue.h
  34. 1 1
      doc/building.rst
  35. 0 8
      examples/client_async.c
  36. 0 21
      examples/client_connect_loop.c
  37. 0 21
      examples/client_connectivitycheck_loop.c
  38. 0 21
      examples/client_subscription_loop.c
  39. 2 10
      examples/server_ctt.c
  40. 1 6
      examples/server_mainloop.c
  41. 2 46
      include/ua_config.h.in
  42. 1 1
      include/ua_plugin_network.h
  43. 1 1
      include/ua_plugin_pubsub.h
  44. 0 10
      include/ua_util.h
  45. 0 126
      plugins/ua_clock.c
  46. 16 8
      plugins/ua_config_default.c
  47. 23 2
      plugins/ua_config_default.h
  48. 0 37
      plugins/ua_log_socket_error.h
  49. 9 9
      plugins/ua_log_stdout.c
  50. 76 95
      plugins/ua_network_pubsub_udp.c
  51. 1 1
      src/client/ua_client_internal.h
  52. 1 1
      src/pubsub/ua_pubsub.h
  53. 1 1
      src/pubsub/ua_pubsub_manager.c
  54. 1 20
      src/server/ua_mdns.c
  55. 1 5
      src/server/ua_server.c
  56. 1 5
      src/server/ua_server_internal.h
  57. 2 11
      src/server/ua_services_discovery.c
  58. 21 101
      src/server/ua_services_discovery_multicast.c
  59. 0 1
      src/server/ua_session.h
  60. 1 1
      src/server/ua_session_manager.h
  61. 1 1
      src/ua_securechannel.h
  62. 6 2
      src/ua_util_internal.h
  63. 2 2
      tests/CMakeLists.txt
  64. 0 4
      tests/client/check_client_async.c
  65. 0 4
      tests/client/check_client_async_connect.c
  66. 2 2
      tests/fuzz/CMakeLists.txt
  67. 3 20
      tests/server/check_discovery.c
  68. 4 21
      tests/testing-plugins/testing_clock.c
  69. 0 5
      tests/testing-plugins/testing_clock.h
  70. 0 13
      tools/amalgamate.py
  71. 55 0
      tools/cmake/macros.cmake
  72. 2 2
      tools/nodeset_compiler/backend_open62541.py
  73. 15 13
      tools/nodeset_compiler/backend_open62541_nodes.py
  74. 7 1
      tools/nodeset_compiler/nodeset_compiler.py
  75. 2 2
      tools/travis/travis_linux_script.sh

+ 110 - 69
CMakeLists.txt

@@ -6,6 +6,7 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake")
 find_package(PythonInterp REQUIRED)
 find_package(Git)
 include(AssignSourceGroup)
+include(macros)
 
 #############################
 # Compiled binaries folders #
@@ -49,6 +50,68 @@ if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build" FORCE)
 endif()
 
+
+option(UA_ENABLE_AMALGAMATION "Concatenate the library to a single file open62541.h/.c" OFF)
+set(UA_AMALGAMATION_ARCHITECUTRES "" CACHE STRING "List of architectures to include in amalgamation")
+mark_as_advanced(UA_AMALGAMATION_ARCHITECUTRES)
+
+# Platform. This is at the beginning in case the architecture changes some UA options
+set(UA_ARCHITECTURE "None" CACHE STRING "Architecture to build open62541 on")
+
+if(UA_ENABLE_AMALGAMATION)
+    if(NOT "${UA_ARCHITECTURE}" STREQUAL "None")
+        set(UA_AMALGAMATION_ARCHITECUTRES "${UA_ARCHITECTURE}")
+    else()
+        if("${UA_AMALGAMATION_ARCHITECUTRES}" STREQUAL "")
+            # select some default architectures which should be included
+            set(UA_AMALGAMATION_ARCHITECUTRES "win32;posix")
+        endif()
+    endif()
+    message(STATUS "Architectures included in amalgamation: ${UA_AMALGAMATION_ARCHITECUTRES}")
+endif()
+
+if("${UA_ARCHITECTURE}" STREQUAL "None")
+    if(UNIX)
+        set(UA_ARCHITECTURE "posix" CACHE STRING "" FORCE)
+    elseif(WIN32)
+        set(UA_ARCHITECTURE "win32" CACHE STRING ""  FORCE)
+    endif(UNIX)
+endif()
+
+message(STATUS "The selected architecture is: ${UA_ARCHITECTURE}")
+string(TOUPPER ${UA_ARCHITECTURE} UA_ARCHITECTURE_UPPER)
+add_definitions(-DUA_ARCHITECTURE_${UA_ARCHITECTURE_UPPER})
+
+add_subdirectory(arch)
+
+GET_PROPERTY(architectures GLOBAL PROPERTY UA_ARCHITECTURES)
+list(SORT architectures)
+set_property(CACHE UA_ARCHITECTURE PROPERTY STRINGS None ${architectures})
+
+GET_PROPERTY(ua_directories_to_include GLOBAL PROPERTY UA_INCLUDE_DIRECTORIES)
+include_directories(${ua_directories_to_include})
+
+GET_PROPERTY(ua_architecture_headers GLOBAL PROPERTY UA_ARCHITECTURE_HEADERS)
+
+GET_PROPERTY(ua_architecture_headers_beginning GLOBAL PROPERTY UA_ARCHITECTURE_HEADERS_BEGINNING)
+
+GET_PROPERTY(ua_architecture_sources GLOBAL PROPERTY UA_ARCHITECTURE_SOURCES)
+
+set(ua_architecture_sources ${ua_architecture_sources}
+            ${PROJECT_SOURCE_DIR}/arch/ua_network_tcp.c
+)
+
+set(ua_architecture_headers ${ua_architecture_headers}
+            ${PROJECT_SOURCE_DIR}/arch/ua_network_tcp.h
+            ${PROJECT_SOURCE_DIR}/arch/ua_architecture_functions.h
+)
+
+
+
+if(${UA_ARCHITECTURE} STREQUAL "None")
+  message(FATAL_ERROR "No architecture was selected. Please select the architecture of your target platform")
+endif(${UA_ARCHITECTURE} STREQUAL "None")
+
 # Options
 set(UA_LOGLEVEL 300 CACHE STRING "Level at which logs shall be reported")
 option(UA_ENABLE_HISTORIZING "Enable server to provide historical access." ON)
@@ -59,7 +122,6 @@ option(UA_ENABLE_SUBSCRIPTIONS_EVENTS "Enable the use of events. (EXPERIMENTAL)"
 option(UA_ENABLE_DISCOVERY "Enable Discovery Service (LDS)" ON)
 option(UA_ENABLE_DISCOVERY_MULTICAST "Enable Discovery Service with multicast support (LDS-ME)" OFF)
 option(UA_ENABLE_QUERY "Enable query support." OFF)
-option(UA_ENABLE_AMALGAMATION "Concatenate the library to a single file open62541.h/.c" OFF)
 option(UA_ENABLE_COVERAGE "Enable gcov coverage" OFF)
 option(UA_ENABLE_ENCRYPTION "Enable encryption support (uses mbedTLS)" OFF)
 option(BUILD_SHARED_LIBS "Enable building of shared libraries (dll/so)" OFF)
@@ -158,12 +220,6 @@ option(UA_ENABLE_UNIT_TEST_FAILURE_HOOKS
        "Add hooks to force failure modes for additional unit tests. Not for production use!" OFF)
 mark_as_advanced(UA_ENABLE_UNIT_TEST_FAILURE_HOOKS)
 
-set(UA_VXWORKS_WRS_KERNEL OFF CACHE BOOL "Enable if you want to compile for VxWorks as kernel Module")
-mark_as_advanced(UA_VXWORKS_WRS_KERNEL)
-
-set(UA_FREERTOS OFF CACHE BOOL "Enable if you want to compile for freeRTOS")
-mark_as_advanced(UA_FREERTOS)
-
 set(UA_VALGRIND_INTERACTIVE_INTERVAL 1000 CACHE STRING "The number of iterations to wait before creating the next dump")
 mark_as_advanced(UA_VALGRIND_INTERACTIVE_INTERVAL)
 
@@ -233,31 +289,6 @@ if(UA_ENABLE_ENCRYPTION)
     list(APPEND open62541_LIBRARIES ${MBEDTLS_LIBRARIES})
 endif()
 
-if(NOT WIN32)
-  if(QNXNTO)
-    list(APPEND open62541_LIBRARIES socket)
-    list(APPEND open62541_LIBRARIES c)
-    list(APPEND open62541_LIBRARIES stdc++)
-  elseif(OS9)
-    list(APPEND open62541_LIBRARIES netdb)
-    list(APPEND open62541_LIBRARIES ndblib)
-    list(APPEND open62541_LIBRARIES socket)
-  else()
-    list(APPEND open62541_LIBRARIES m)
-    if(UA_ENABLE_MULTITHREADING OR UA_BUILD_UNIT_TESTS)
-      list(APPEND open62541_LIBRARIES pthread)
-    endif()
-    if(NOT APPLE AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD"))
-      list(APPEND open62541_LIBRARIES rt)
-    endif()
-  endif()
-else()
-  list(APPEND open62541_LIBRARIES ws2_32)
-    if(UA_ENABLE_DISCOVERY_MULTICAST OR UA_ENABLE_PUBSUB)
-        list(APPEND open62541_LIBRARIES iphlpapi)
-    endif()
-endif()
-
 #####################
 # Compiler Settings #
 #####################
@@ -279,30 +310,10 @@ if(NOT UA_COMPILE_AS_CXX AND (CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID
                     -Wundef
                     -Wc++-compat)
 
-    if(NOT WIN32 AND NOT CYGWIN AND NOT QNXNTO AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD"))
-        add_definitions(-Wshadow -Wconversion -fvisibility=hidden -fPIC)
-    endif()
-
     if(UA_ENABLE_AMALGAMATION)
         add_definitions(-Wno-unused-function)
     endif()
 
-    if(UA_VXWORKS_WRS_KERNEL)
-        # Disable flags for VXWORKS
-        remove_definitions(-Werror -Wpedantic -Wno-static-in-inline -fPIC)
-        add_definitions(-D_WRS_KERNEL)
-    endif()
-
-    if(UA_FREERTOS)
-       SET(UA_FREERTOS_INCLUDES "" CACHE STRING "Folders to include from the freeRTOS OS")
-       include_directories(${UA_FREERTOS_INCLUDES})
-        # Disable flags for freeRTOS
-        remove_definitions(-fPIC -Wconversion )
-        add_definitions(-DUA_FREERTOS -DLWIP_TIMEVAL_PRIVATE=0 -DLWIP_COMPAT_MUTEX=0 -DLWIP_POSIX_SOCKETS_IO_NAMES=0 -mcpu=cortex-m3 -mthumb -g -Wall -O0 -specs=nano.specs
-                        -ffunction-sections -fdata-sections  -fno-exceptions -fstack-usage -Wno-unused-variable -Wno-format -Wno-format-security -Wno-format-nonliteral)
-        list(APPEND open62541_LIBRARIES c m stdc++ supc++)
-    endif(UA_FREERTOS)
-
     # Linker
     set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # cmake sets -rdynamic by default
 
@@ -378,11 +389,22 @@ include_directories(${PROJECT_SOURCE_DIR}/include
                     ${PROJECT_BINARY_DIR}/src_generated
                     ${MBEDTLS_INCLUDE_DIRS})
 
-set(exported_headers ${PROJECT_BINARY_DIR}/src_generated/ua_config.h
+if(NOT "${UA_AMALGAMATION_ARCHITECUTRES}" STREQUAL "")
+    set(exported_headers)
+    foreach(arch ${UA_AMALGAMATION_ARCHITECUTRES})
+        list(APPEND exported_headers ${PROJECT_SOURCE_DIR}/arch/${arch}/ua_architecture.h)
+    endforeach()
+else()
+    set(exported_headers ${PROJECT_SOURCE_DIR}/arch/${UA_ARCHITECTURE}/ua_architecture.h)
+endif()
+
+set(exported_headers ${exported_headers}
+                     ${ua_architecture_headers_beginning}
+                     ${PROJECT_BINARY_DIR}/src_generated/ua_config.h
                      ${PROJECT_SOURCE_DIR}/deps/ms_stdint.h
-                     ${PROJECT_SOURCE_DIR}/include/ua_constants.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids.h
+                     ${PROJECT_SOURCE_DIR}/include/ua_constants.h
                      ${PROJECT_SOURCE_DIR}/include/ua_types.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated_handling.h
@@ -481,19 +503,15 @@ set(lib_sources ${PROJECT_SOURCE_DIR}/src/ua_types.c
                 ${PROJECT_SOURCE_DIR}/deps/pcg_basic.c
                 ${PROJECT_SOURCE_DIR}/deps/base64.c)
 
-set(default_plugin_headers ${PROJECT_SOURCE_DIR}/plugins/ua_network_tcp.h
-                           ${PROJECT_SOURCE_DIR}/plugins/ua_accesscontrol_default.h
+set(default_plugin_headers ${PROJECT_SOURCE_DIR}/plugins/ua_accesscontrol_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/ua_pki_certificate.h
                            ${PROJECT_SOURCE_DIR}/plugins/ua_log_stdout.h
                            ${PROJECT_SOURCE_DIR}/plugins/ua_nodestore_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/ua_config_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/ua_securitypolicy_none.h
-                           ${PROJECT_SOURCE_DIR}/plugins/ua_log_socket_error.h
 )
 
-set(default_plugin_sources ${PROJECT_SOURCE_DIR}/plugins/ua_network_tcp.c
-                           ${PROJECT_SOURCE_DIR}/plugins/ua_clock.c
-                           ${PROJECT_SOURCE_DIR}/plugins/ua_log_stdout.c
+set(default_plugin_sources ${PROJECT_SOURCE_DIR}/plugins/ua_log_stdout.c
                            ${PROJECT_SOURCE_DIR}/plugins/ua_accesscontrol_default.c
                            ${PROJECT_SOURCE_DIR}/plugins/ua_pki_certificate.c
                            ${PROJECT_SOURCE_DIR}/plugins/ua_nodestore_default.c
@@ -519,7 +537,7 @@ if(UA_DEBUG_DUMP_PKGS)
 endif()
 
 if(UA_ENABLE_NONSTANDARD_UDP)
-    list(APPEND exported_headers ${PROJECT_SOURCE_DIR}/plugins/ua_network_udp.h)
+    list(APPEND exported_headers ${PROJECT_SOURCE_DIR}/arch/ua_network_udp.h)
 endif()
 
 if(UA_ENABLE_DISCOVERY_MULTICAST)
@@ -669,17 +687,17 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/open62541.h
                    PRE_BUILD
                    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tools/amalgamate.py
                            ${OPEN62541_VER_COMMIT} ${CMAKE_CURRENT_BINARY_DIR}/open62541.h
-                           ${exported_headers} ${default_plugin_headers}
+                           ${exported_headers} ${default_plugin_headers} ${ua_architecture_headers}
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/amalgamate.py
-                           ${exported_headers} ${default_plugin_headers})
+                           ${exported_headers} ${default_plugin_headers} ${ua_architecture_headers})
 
 add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/open62541.c
                    PRE_BUILD
                    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tools/amalgamate.py
                            ${OPEN62541_VER_COMMIT} ${CMAKE_CURRENT_BINARY_DIR}/open62541.c
-                           ${internal_headers} ${lib_sources} ${default_plugin_sources}
+                           ${internal_headers} ${lib_sources} ${default_plugin_sources} ${ua_architecture_sources}
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/amalgamate.py ${internal_headers}
-                           ${lib_sources} ${default_plugin_sources})
+                           ${lib_sources} ${default_plugin_sources} ${ua_architecture_sources} )
 
 add_custom_target(open62541-amalgamation-source DEPENDS ${PROJECT_BINARY_DIR}/open62541.c)
 add_custom_target(open62541-amalgamation-header DEPENDS ${PROJECT_BINARY_DIR}/open62541.h)
@@ -695,6 +713,10 @@ if(MSVC)
     set(NODESET_MAX_STR_LEN 65535)
 endif()
 
+if(NOT UA_NODESET_ENCODE_BINARY_SIZE)
+    set(UA_NODESET_ENCODE_BINARY_SIZE 32000)
+endif()
+
 # generated namespace 0
 add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.c
                           ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.h
@@ -703,6 +725,7 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.c
                            --generate-ns0
                            --internal-headers
                            --max-string-length=${NODESET_MAX_STR_LEN}
+                           --encode-binary-size=${UA_NODESET_ENCODE_BINARY_SIZE}
                            --ignore ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/NodeID_NS0_Base.txt
                            --xml ${UA_FILE_NS0}
                            ${UA_FILE_NSPUBSUB}
@@ -734,6 +757,7 @@ assign_source_group(${lib_sources})
 assign_source_group(${internal_headers})
 assign_source_group(${exported_headers})
 assign_source_group(${default_plugin_sources})
+assign_source_group(${ua_architecture_sources})
 
 if(UA_ENABLE_AMALGAMATION)
     add_library(open62541-object OBJECT ${PROJECT_BINARY_DIR}/open62541.c ${PROJECT_BINARY_DIR}/open62541.h)
@@ -764,7 +788,7 @@ else()
                      open62541-generator-statuscode)
     target_include_directories(open62541-object PRIVATE ${PROJECT_SOURCE_DIR}/src)
 
-    add_library(open62541-plugins OBJECT ${default_plugin_sources} ${exported_headers})
+    add_library(open62541-plugins OBJECT ${default_plugin_sources} ${ua_architecture_sources} ${exported_headers})
     add_dependencies(open62541-plugins open62541-generator-types open62541-generator-transport)
     target_include_directories(open62541-plugins PRIVATE ${PROJECT_SOURCE_DIR}/plugins)
     target_include_directories(open62541-plugins PRIVATE ${PROJECT_BINARY_DIR}/src_generated)
@@ -775,7 +799,7 @@ else()
 
     if(UA_COMPILE_AS_CXX)
         set_source_files_properties(${lib_sources} PROPERTIES LANGUAGE CXX)
-        set_source_files_properties(${default_plugin_sources} PROPERTIES LANGUAGE CXX)
+        set_source_files_properties(${default_plugin_sources} ${ua_architecture_sources} PROPERTIES LANGUAGE CXX)
     endif()
 endif()
 
@@ -792,12 +816,25 @@ if (UA_ENABLE_DISCOVERY_MULTICAST)
     target_compile_definitions(open62541-object PRIVATE -DMDNSD_DYNAMIC_LINKING_EXPORT)
     target_compile_definitions(open62541 PRIVATE -DMDNSD_DYNAMIC_LINKING_EXPORT)
 endif()
+# Generate properly versioned shared library links on Linux
+SET_TARGET_PROPERTIES(open62541 PROPERTIES SOVERSION 0 VERSION "${OPEN62541_VER_MAJOR}.${OPEN62541_VER_MINOR}.${OPEN62541_VER_PATCH}")
+
+##################################
+#     Architectures changes      #
+##################################
+
+GET_PROPERTY(ua_architecture_add_definitions GLOBAL PROPERTY UA_ARCHITECTURE_ADD_DEFINITIONS)
+add_definitions(${ua_architecture_add_definitions})
+
+GET_PROPERTY(ua_architecture_remove_definitions GLOBAL PROPERTY UA_ARCHITECTURE_REMOVE_DEFINITIONS)
+remove_definitions(${ua_architecture_remove_definitions})
+
+GET_PROPERTY(ua_architecture_append_to_library GLOBAL PROPERTY UA_ARCHITECTURE_APPEND_TO_LIBRARY)
+list(APPEND open62541_LIBRARIES ${ua_architecture_append_to_library})
 
 # DLL requires linking to dependencies
 target_link_libraries(open62541 ${open62541_LIBRARIES})
 
-# Generate properly versioned shared library links on Linux
-SET_TARGET_PROPERTIES(open62541 PROPERTIES SOVERSION 0 VERSION "${OPEN62541_VER_MAJOR}.${OPEN62541_VER_MINOR}.${OPEN62541_VER_PATCH}")
 
 ##########################
 # Build Selected Targets #
@@ -851,10 +888,14 @@ add_custom_target(cpplint cpplint
                   ${internal_headers}
                   ${default_plugin_headers}
                   ${default_plugin_sources}
+                  ${ua_architecture_headers}
+                  ${ua_architecture_sources}
                   DEPENDS ${lib_sources}
                           ${internal_headers}
                           ${default_plugin_headers}
                           ${default_plugin_sources}
+                          ${ua_architecture_headers}
+                          ${ua_architecture_sources}
 
                   COMMENT "Run cpplint code style checker on the library")
 

+ 2 - 1
README.md

@@ -106,7 +106,8 @@ As an open source project, new contributors are encouraged to help improve open6
 
 ### Example Server Implementation
 Compile the examples with the single-file distribution `open62541.h/.c` header and source file.
-Using the GCC compiler, just run ```gcc -std=c99 <server.c> open62541.c -o server``` (under Windows you may need to add ``` -lws2_32```).
+Using the GCC compiler, just run ```gcc -std=c99 -DUA_ARCHITECTURE_POSIX <server.c> open62541.c -o server``` (under Windows you may need to add ``` -lws2_32``` 
+and change `-DUA_ARCHITECTURE_POSIX` to `-DUA_ARCHITECTURE_WIN32`).
 ```c
 #include <signal.h>
 #include "open62541.h"

+ 3 - 2
appveyor.yml

@@ -13,8 +13,9 @@ environment:
     matrix:
         - CC_NAME: MinGW Makefiles
           CC_SHORTNAME: mingw
-          # We need to redirect stderr to stdout otherwise powershell will fail if there is an output during amalgamation
-          MAKE: mingw32-make -j 2>&1
+          # We need to redirect stderr to stdout otherwise powershell will fail if there is an output during amalgamation.
+          # Only use one thread, otherwise appveyor runs out of memory
+          MAKE: mingw32-make -j1 2>&1
           FORCE_CXX: OFF
           OUT_DIR_LIB: bin
           OUT_DIR_EXAMPLES: bin\examples

+ 21 - 0
arch/CMakeLists.txt

@@ -0,0 +1,21 @@
+SET(SOURCE_GROUP ${SOURCE_GROUP}\\arch)
+
+ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) #to have access to ua_network_tcp.h and udp.h
+
+add_subdirectory(posix)
+add_subdirectory(win32)
+add_subdirectory(freertosLWIP)
+add_subdirectory(vxworks)
+add_subdirectory(eCos)
+
+SET(UA_ARCH_EXTRA_INCLUDES "" CACHE STRING "Folders to include from the architecture")
+ua_include_directories(${UA_ARCH_EXTRA_INCLUDES})
+
+SET(UA_ARCH_REMOVE_FLAGS "" CACHE STRING "Flags to be removed from compilation that depends on the architecure")
+ua_architecture_remove_definitions(${UA_ARCH_REMOVE_FLAGS})
+
+SET(UA_ARCH_ADD_FLAGS "" CACHE STRING "Flags to be added to compilation that depends on the architecure")
+ua_architecture_add_definitions(${UA_ARCH_ADD_FLAGS})
+
+SET(UA_ARCH_LINKER_FLAGS "" CACHE STRING "Linker Flags to be added to compilation that depends on the architecure")
+ua_architecture_append_to_library(${UA_ARCH_LINKER_FLAGS})

+ 106 - 0
arch/Readme.md

@@ -0,0 +1,106 @@
+# To port to a new architecture you should follow this file:
+
+1. Create a folder with your architecture, let's call it new_arch
+2. In the CMakeLists.txt file located next to this file, add `add_subdirectory(new_arch)` at the end of it
+3. Create a CMakeLists.txt file in the new_arch folder
+4. Use the following template for it (remember that when you see new_arch you should replace with the name of your architecture)
+    ```C
+    # ---------------------------------------------------
+    # ---- Beginning of the CMakeLists.txt template -----
+    # ---------------------------------------------------
+    
+    SET(SOURCE_GROUP ${SOURCE_GROUP}\\new_arch)
+    
+    ua_add_architecture("new_arch")
+    
+    if("${UA_ARCHITECTURE}" STREQUAL "new_arch")
+    
+        ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+        ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
+        
+        #
+        # Add here below all the things that are specific for your architecture
+        #
+        
+        #You can use the following available CMake functions:
+         
+        #ua_include_directories() include some directories specific to your architecture when compiling the open62541 stack
+        #ua_architecture_remove_definitions() remove compiler flags from the general ../../CMakeLists.txt file that won't work with your architecture
+        #ua_architecture_add_definitions() add compiler flags that your architecture needs
+        #ua_architecture_append_to_library() add libraries to be linked to the open62541 that are needed by your architecture
+        #ua_add_architecture_header() add header files to compilation (Don't add the file ua_architecture.h)
+        #ua_add_architecture_file() add .c files to compilation    
+        
+    endif()
+    
+    # ---------------------------------------------------
+    # ---- End of the CMakeLists.txt template -----
+    # ---------------------------------------------------
+    ```
+5. Create a ua_clock.c file that implements the following functions defined in ua_types.h:
+
+    UA_DateTime UA_DateTime_now(void);
+    UA_Int64 UA_DateTime_localTimeUtcOffset(void);
+    UA_DateTime UA_DateTime_nowMonotonic(void);
+
+6. Create a file in the folder new_arch called ua_architecture.h
+
+7. Use the following template for it:
+  a: Change YEAR, YOUR_NAME and YOUR_COMPANY in the header
+  b: Change NEW_ARCH at the beginning in PLUGINS_ARCH_NEW_ARCH_UA_ARCHITECTURE_H_ for your own name in uppercase
+   
+    ```C
+    /* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+     * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+     *
+     *    Copyright YEAR (c) YOUR_NAME, YOUR_COMPANY
+     */
+    
+    #ifndef PLUGINS_ARCH_NEW_ARCH_UA_ARCHITECTURE_H_
+    #define PLUGINS_ARCH_NEW_ARCH_UA_ARCHITECTURE_H_
+    
+    /*
+    * Define and include all that's needed for your architecture
+    */
+    
+    /*
+    * Define OPTVAL_TYPE for non windows systems. In doubt, use int //TODO: Is this really necessary
+    */
+    
+    /*
+    * Define the following network options
+    */
+    
+    
+    //#define UA_IPV6 1 //or 0
+    //#define UA_SOCKET
+    //#define UA_INVALID_SOCKET
+    //#define UA_ERRNO  
+    //#define UA_INTERRUPTED
+    //#define UA_AGAIN
+    //#define UA_EAGAIN
+    //#define UA_WOULDBLOCK
+    //#define UA_ERR_CONNECTION_PROGRESS
+    //#define UA_INTERRUPTED
+    
+    /*
+    * Define the ua_getnameinfo if your architecture supports it
+    */
+    
+    /*
+    * Use #define for the functions defined in ua_architecture_functions.h
+    * or implement them in a ua_architecture_functions.c file and 
+    * put it in your new_arch folder and add it in the CMakeLists.txt file 
+    * using ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture_functions.c)
+    */ 
+    
+    /*
+    * Define UA_LOG_SOCKET_ERRNO_WRAP(LOG) which prints the string error given a char* errno_str variable
+    * Do the same for UA_LOG_SOCKET_ERRNO_GAI_WRAP(LOG) for errors related to getaddrinfo
+    */
+    
+    #include "../ua_architecture_functions.h"
+    
+    #endif /* PLUGINS_ARCH_NEW_ARCH_UA_ARCHITECTURE_H_ */
+    
+    ```

+ 46 - 0
arch/common/freeRTOS62541.h

@@ -0,0 +1,46 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#ifndef ARCH_COMMON_FREERTOS62541_H_
+#define ARCH_COMMON_FREERTOS62541_H_
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef BYTE_ORDER
+# undef BYTE_ORDER
+#endif
+
+#include <unistd.h> // read, write, close
+
+#define UA_sleep_ms(X) vTaskDelay(pdMS_TO_TICKS(X))
+
+#ifdef OPEN62541_FEERTOS_USE_OWN_MEM
+# define UA_free vPortFree
+# define UA_malloc pvPortMalloc
+# define UA_calloc pvPortCalloc
+# define UA_realloc pvPortRealloc
+#else
+# define UA_free free
+# define UA_malloc malloc
+# define UA_calloc calloc
+# define UA_realloc realloc
+#endif
+
+#define UA_access access
+
+// No log colors on freeRTOS
+// #define UA_ENABLE_LOG_COLORS
+
+#include <stdio.h>
+#define UA_snprintf snprintf
+
+#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
+    char *errno_str = ""; \
+    LOG; \
+}
+
+#endif /* ARCH_COMMON_FREERTOS62541_H_ */

+ 79 - 0
arch/common/lwip62541.h

@@ -0,0 +1,79 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#ifndef ARCH_COMMON_LWIP62541_H_
+#define ARCH_COMMON_LWIP62541_H_
+
+#define LWIP_TIMEVAL_PRIVATE 0
+#define LWIP_POSIX_SOCKETS_IO_NAMES 0
+#ifdef LWIP_COMPAT_SOCKETS
+#undef LWIP_COMPAT_SOCKETS
+#endif
+#define LWIP_COMPAT_SOCKETS 0
+
+#include <lwip/tcpip.h>
+#include <lwip/netdb.h>
+#include <lwip/init.h>
+#include <lwip/sockets.h>
+#define sockaddr_storage sockaddr
+
+#define OPTVAL_TYPE int
+
+#define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds)
+#define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds)
+
+#define UA_IPV6 LWIP_IPV6
+#define UA_SOCKET int
+#define UA_INVALID_SOCKET -1
+#define UA_ERRNO errno
+#define UA_INTERRUPTED EINTR
+#define UA_AGAIN EAGAIN
+#define UA_EAGAIN EAGAIN
+#define UA_WOULDBLOCK EWOULDBLOCK
+#define UA_ERR_CONNECTION_PROGRESS EINPROGRESS
+
+#define UA_send lwip_send
+#define UA_recv lwip_recv
+#define UA_sendto lwip_sendto
+#define UA_recvfrom lwip_recvfrom
+#define UA_htonl lwip_htonl
+#define UA_ntohl lwip_ntohl
+#define UA_close lwip_close
+#define UA_select lwip_select
+#define UA_shutdown lwip_shutdown
+#define UA_socket lwip_socket
+#define UA_bind lwip_bind
+#define UA_listen lwip_listen
+#define UA_accept lwip_accept
+#define UA_connect lwip_connect
+#define UA_getsockopt lwip_getsockopt
+#define UA_setsockopt lwip_setsockopt
+#define UA_freeaddrinfo lwip_freeaddrinfo
+#define UA_gethostname gethostname_lwip
+#define UA_getaddrinfo lwip_getaddrinfo
+
+#if UA_IPV6
+# define UA_inet_pton(af, src, dst) \
+    (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
+     : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
+#else
+# define UA_inet_pton(af, src, dst) \
+     (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
+#endif
+
+#if UA_IPV6
+# define UA_if_nametoindex lwip_if_nametoindex
+
+# if LWIP_VERSION_IS_RELEASE //lwip_if_nametoindex is not yet released
+unsigned int lwip_if_nametoindex(const char *ifname);
+# endif
+#endif
+
+int gethostname_lwip(char* name, size_t len);
+
+#define UA_LOG_SOCKET_ERRNO_GAI_WRAP UA_LOG_SOCKET_ERRNO_WRAP
+
+#endif /* ARCH_COMMON_LWIP62541_H_ */

+ 29 - 0
arch/eCos/CMakeLists.txt

@@ -0,0 +1,29 @@
+SET(SOURCE_GROUP ${SOURCE_GROUP}\\eCos)
+
+ua_add_architecture("eCos")
+
+
+list (FIND UA_AMALGAMATION_ARCHITECUTRES "eCos" _index)
+if (${_index} GREATER -1 OR "${UA_ARCHITECTURE}" STREQUAL "eCos")
+
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture_functions.c)
+
+    if("${UA_ARCHITECTURE}" STREQUAL "eCos")
+
+        ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+        ua_architecture_remove_definitions(-Wpedantic -Wno-static-in-inline -Wc++-compat)
+        ua_architecture_add_definitions(-Wno-sign-conversion -fdata-sections -fno-exceptions -ffunction-sections -DSYSTEM_BUS_WIDTH=32  -mhw-mul -mno-hw-mulx -mhw-div -Wa,-relax-all -W -Wall -Wextra -D_KERNEL -D__ECOS -nostdlib -Wl,--gc-sections -Wl,-static)
+
+        ua_architecture_append_to_library("-L${UA_ECOS_INCLUDES}/lib -Wl,-T,${UA_ECOS_INCLUDES}/lib/target.ld -nostartfiles") #for examples
+
+        SET(UA_ECOS_INCLUDES "" CACHE STRING "Folders to include from the eCos OS")
+
+        ua_include_directories(${UA_ECOS_INCLUDES}/include)
+        
+        set(UA_ECOS_HOSTNAME "eCos-host" CACHE STRING "Define a custom hostname/ip for the endpoint.")
+        ua_architecture_add_definitions(-DUA_ECOS_HOSTNAME="${UA_ECOS_HOSTNAME}")
+    endif()
+
+endif()

+ 88 - 0
arch/eCos/ua_architecture.h

@@ -0,0 +1,88 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ */
+
+#ifndef PLUGINS_ARCH_POSIX_UA_ARCHITECTURE_H_
+#define PLUGINS_ARCH_POSIX_UA_ARCHITECTURE_H_
+
+#include <../deps/queue.h>  //TODO: in some compilers there's already a _SYS_QUEUE_H_ who is included first and doesn't have all functions
+
+#include <pkgconf/system.h>
+#include <cyg/kernel/kapi.h>
+#include <cyg/io/io.h>
+
+#include <network.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <netinet/tcp.h>
+#include <stdlib.h>
+
+#define UA_sleep_ms(X) cyg_thread_delay(1 + ((1000 * X * CYGNUM_HAL_RTC_DENOMINATOR) / (CYGNUM_HAL_RTC_NUMERATOR / 1000)));
+
+#define OPTVAL_TYPE int
+
+#define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds)
+#define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds)
+
+#define UA_access(x,y) 0
+
+#define UA_IPV6 1
+#define UA_SOCKET int
+#define UA_INVALID_SOCKET -1
+#define UA_ERRNO errno
+#define UA_INTERRUPTED EINTR
+#define UA_AGAIN EAGAIN
+#define UA_EAGAIN EAGAIN
+#define UA_WOULDBLOCK EWOULDBLOCK
+#define UA_ERR_CONNECTION_PROGRESS EINPROGRESS
+
+#define UA_getnameinfo getnameinfo
+#define UA_send send
+#define UA_recv recv
+#define UA_sendto sendto
+#define UA_recvfrom recvfrom
+#define UA_htonl htonl
+#define UA_ntohl ntohl
+#define UA_close close
+#define UA_select select
+#define UA_shutdown shutdown
+#define UA_socket socket
+#define UA_bind bind
+#define UA_listen listen
+#define UA_accept accept
+#define UA_connect connect
+#define UA_getaddrinfo getaddrinfo
+#define UA_getsockopt getsockopt
+#define UA_setsockopt setsockopt
+#define UA_freeaddrinfo freeaddrinfo
+#define UA_gethostname gethostname_ecos
+#define UA_inet_pton(af,src,dst) inet_pton(af, src, (char*) dst)
+#if UA_IPV6
+# define UA_if_nametoindex if_nametoindex
+#endif
+
+int gethostname_ecos(char* name, size_t len);
+
+#define UA_free free
+#define UA_malloc malloc
+#define UA_calloc calloc
+#define UA_realloc realloc
+
+#define UA_snprintf snprintf
+
+#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
+    char *errno_str = strerror(errno); \
+    LOG; \
+}
+#define UA_LOG_SOCKET_ERRNO_GAI_WRAP(LOG) { \
+    const char *errno_str = gai_strerror(errno); \
+    LOG; \
+}
+
+#include "../ua_architecture_functions.h"
+
+#endif /* PLUGINS_ARCH_POSIX_UA_ARCHITECTURE_H_ */

+ 37 - 0
arch/eCos/ua_architecture_functions.c

@@ -0,0 +1,37 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#include "ua_types.h"
+
+
+unsigned int UA_socket_set_blocking(UA_SOCKET sockfd){
+  int on = 0;
+  if(ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd){
+  int on = 1;
+  if(ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+void UA_initialize_architecture_network(void){
+  return;
+}
+
+void UA_deinitialize_architecture_network(void){
+  return;
+}
+
+int gethostname_ecos(char* name, size_t len){
+  if(strlen(UA_ECOS_HOSTNAME) > (len))
+    return -1;
+  strcpy(name, UA_ECOS_HOSTNAME);
+  return 0;
+}

+ 35 - 0
arch/eCos/ua_clock.c

@@ -0,0 +1,35 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#include "ua_types.h"
+
+UA_DateTime UA_DateTime_now(void) {
+  return UA_DateTime_nowMonotonic();
+}
+
+/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
+UA_Int64 UA_DateTime_localTimeUtcOffset(void){
+  time_t gmt, rawtime = time(NULL);
+  struct tm *ptm;
+  struct tm gbuf;
+  ptm = gmtime_r(&rawtime, &gbuf);
+  // Request that mktime() looksup dst in timezone database
+  ptm->tm_isdst = -1;
+  gmt = mktime(ptm);
+  return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC);
+}
+
+UA_DateTime UA_DateTime_nowMonotonic(void) {
+
+  cyg_tick_count_t TaskTime = cyg_current_time();
+
+  UA_DateTimeStruct UATime;
+  UATime.milliSec = (UA_UInt16) TaskTime;
+  struct timespec ts;
+  ts.tv_sec = UATime.milliSec / 1000;
+  ts.tv_nsec = (UATime.milliSec % 1000) * 1000000;
+  return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100) + UA_DATETIME_UNIX_EPOCH;
+}

+ 21 - 0
arch/freertosLWIP/CMakeLists.txt

@@ -0,0 +1,21 @@
+SET(SOURCE_GROUP ${SOURCE_GROUP}\\freertosLWIP)
+
+ua_add_architecture("freertosLWIP")
+
+list (FIND UA_AMALGAMATION_ARCHITECUTRES "freertosLWIP" _index)
+if (${_index} GREATER -1 OR "${UA_ARCHITECTURE}" STREQUAL "freertosLWIP")
+
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture_functions.c)
+
+    if("${UA_ARCHITECTURE}" STREQUAL "freertosLWIP")
+        ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+        set(UA_ARCH_FREERTOS_USE_OWN_MEMORY_FUNCTIONS OFF CACHE BOOL "Enable free/malloc/etc from own implementation")
+        if(UA_ARCH_FREERTOS_USE_OWN_MEMORY_FUNCTIONS)
+          ua_architecture_add_definitions("-DOPEN62541_FEERTOS_USE_OWN_MEM")
+        endif(UA_ARCH_FREERTOS_USE_OWN_MEMORY_FUNCTIONS)
+        ua_add_architecture_header_beginning(${CMAKE_CURRENT_SOURCE_DIR}/../common/freeRTOS62541.h
+                                             ${CMAKE_CURRENT_SOURCE_DIR}/../common/lwip62541.h
+                                                                                                  ) 
+    endif()
+endif()

+ 21 - 0
arch/freertosLWIP/ua_architecture.h

@@ -0,0 +1,21 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017-2018 (c) Stefan Profanter, fortiss GmbH
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_FREERTOSLWIP
+
+#ifndef PLUGINS_ARCH_FREERTOSLWIP_UA_ARCHITECTURE_H_
+#define PLUGINS_ARCH_FREERTOSLWIP_UA_ARCHITECTURE_H_
+
+#include "../common/lwip62541.h"
+#include "../common/freeRTOS62541.h"
+
+#include "../ua_architecture_functions.h"
+
+#endif /* PLUGINS_ARCH_FREERTOSLWIP_UA_ARCHITECTURE_H_ */
+
+#endif /* UA_ARCHITECTURE_FREERTOSLWIP */

+ 47 - 0
arch/freertosLWIP/ua_architecture_functions.c

@@ -0,0 +1,47 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ *    Copyright 2018 (c) Stefan Profanter, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_FREERTOSLWIP
+
+#include "ua_types.h"
+
+unsigned int UA_socket_set_blocking(UA_SOCKET sockfd){
+  int on = 0;
+  if(lwip_ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd){
+  int on = 1;
+  if(lwip_ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+int gethostname_lwip(char* name, size_t len){
+  // use UA_ServerConfig_set_customHostname to set your hostname as the IP
+  return -1;
+}
+
+void UA_initialize_architecture_network(void){
+  return;
+}
+
+void UA_deinitialize_architecture_network(void){
+  return;
+}
+
+#if UA_IPV6
+# if LWIP_VERSION_IS_RELEASE //lwip_if_nametoindex is not yet released
+unsigned int lwip_if_nametoindex(const char *ifname){
+  return 1; //TODO: assume for now that it only has one interface
+}
+# endif //LWIP_VERSION_IS_RELEASE
+#endif //UA_IPV6
+
+#endif /* UA_ARCHITECTURE_FREERTOSLWIP */

+ 45 - 0
arch/freertosLWIP/ua_clock.c

@@ -0,0 +1,45 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ *    Copyright 2017 (c) Thomas Stalder
+ */
+
+#ifdef UA_ARCHITECTURE_FREERTOSLWIP
+
+#include "ua_types.h"
+#include <time.h>
+#include <sys/time.h>
+
+#include <task.h>
+
+UA_DateTime UA_DateTime_now(void) {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return (tv.tv_sec * UA_DATETIME_SEC) + (tv.tv_usec * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH;
+}
+
+/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
+UA_Int64 UA_DateTime_localTimeUtcOffset(void) {
+    time_t gmt, rawtime = time(NULL);
+    struct tm *ptm;
+    struct tm gbuf;
+    ptm = gmtime_r(&rawtime, &gbuf);
+    // Request that mktime() looksup dst in timezone database
+    ptm->tm_isdst = -1;
+    gmt = mktime(ptm);
+    return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC);
+}
+
+UA_DateTime UA_DateTime_nowMonotonic(void) {
+    portTickType TaskTime = xTaskGetTickCount();
+    UA_DateTimeStruct UATime;
+    UATime.milliSec = (UA_UInt16) TaskTime;
+    struct timespec ts;
+    ts.tv_sec = UATime.milliSec/1000;
+    ts.tv_nsec = (UATime.milliSec % 1000)* 1000000;
+    return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
+}
+
+#endif /* UA_ARCHITECTURE_FREERTOSLWIP */

+ 35 - 0
arch/posix/CMakeLists.txt

@@ -0,0 +1,35 @@
+SET(SOURCE_GROUP ${SOURCE_GROUP}\\posix)
+
+ua_add_architecture("posix")
+
+list (FIND UA_AMALGAMATION_ARCHITECUTRES "posix" _index)
+if (${_index} GREATER -1 OR "${UA_ARCHITECTURE}" STREQUAL "posix")
+
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture_functions.c)
+
+
+    if("${UA_ARCHITECTURE}" STREQUAL "posix")
+        if(NOT CYGWIN AND NOT QNXNTO AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD"))
+            ua_architecture_add_definitions(-Wshadow -Wconversion -fvisibility=hidden -fPIC)
+        endif()
+
+        if(QNXNTO)
+          ua_architecture_append_to_library(socket c stdc++)
+        elseif(OS9)
+          ua_architecture_append_to_library(netdb ndblib socket)
+        else()
+          ua_architecture_append_to_library(m)
+          if(UA_ENABLE_MULTITHREADING OR UA_BUILD_UNIT_TESTS)
+            ua_architecture_append_to_library(pthread)
+          endif()
+          if(NOT APPLE AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD"))
+            ua_architecture_append_to_library(rt)
+          endif()
+        endif()
+
+        ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+    endif()
+
+
+endif()

+ 137 - 0
arch/posix/ua_architecture.h

@@ -0,0 +1,137 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_POSIX
+
+#ifndef PLUGINS_ARCH_POSIX_UA_ARCHITECTURE_H_
+#define PLUGINS_ARCH_POSIX_UA_ARCHITECTURE_H_
+
+/* Enable POSIX features */
+#if !defined(_XOPEN_SOURCE)
+# define _XOPEN_SOURCE 600
+#endif
+#ifndef _DEFAULT_SOURCE
+# define _DEFAULT_SOURCE
+#endif
+/* On older systems we need to define _BSD_SOURCE.
+ * _DEFAULT_SOURCE is an alias for that. */
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+#endif
+
+#include <../deps/queue.h>  //in some compilers there's already a _SYS_QUEUE_H_ who is included first and doesn't have all functions
+
+#include <errno.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <net/if.h>
+#ifndef UA_sleep_ms
+# define UA_sleep_ms(X) usleep(X * 1000)
+#else /* UA_sleep_ms */
+/* With this one can define its own UA_sleep_ms using a preprocessor define.
+E.g. see unit tests. */
+void UA_sleep_ms(size_t ms);
+#endif
+
+#define OPTVAL_TYPE int
+
+#include <fcntl.h>
+#include <unistd.h> // read, write, close
+
+#ifdef __QNX__
+# include <sys/socket.h>
+#endif
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+# include <sys/param.h>
+# if defined(BSD)
+#  include<sys/socket.h>
+# endif
+#endif
+#if !defined(__CYGWIN__)
+# include <netinet/tcp.h>
+#endif
+
+/* unsigned int for windows and workaround to a glibc bug */
+/* Additionally if GNU_LIBRARY is not defined, it may be using
+ * musl libc (e.g. Docker Alpine) */
+#if  defined(__OpenBSD__) || \
+    (defined(__GNU_LIBRARY__) && (__GNU_LIBRARY__ <= 6) && \
+     (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 16) || \
+    !defined(__GNU_LIBRARY__))
+# define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds)
+# define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds)
+#else
+# define UA_fd_set(fd, fds) FD_SET(fd, fds)
+# define UA_fd_isset(fd, fds) FD_ISSET(fd, fds)
+#endif
+
+#define UA_access access
+
+#define UA_IPV6 1
+#define UA_SOCKET int
+#define UA_INVALID_SOCKET -1
+#define UA_ERRNO errno
+#define UA_INTERRUPTED EINTR
+#define UA_AGAIN EAGAIN
+#define UA_EAGAIN EAGAIN
+#define UA_WOULDBLOCK EWOULDBLOCK
+#define UA_ERR_CONNECTION_PROGRESS EINPROGRESS
+
+#define UA_ENABLE_LOG_COLORS
+
+#define UA_getnameinfo getnameinfo
+#define UA_send send
+#define UA_recv recv
+#define UA_sendto sendto
+#define UA_recvfrom recvfrom
+#define UA_htonl htonl
+#define UA_ntohl ntohl
+#define UA_close close
+#define UA_select select
+#define UA_shutdown shutdown
+#define UA_socket socket
+#define UA_bind bind
+#define UA_listen listen
+#define UA_accept accept
+#define UA_connect connect
+#define UA_getaddrinfo getaddrinfo
+#define UA_getsockopt getsockopt
+#define UA_setsockopt setsockopt
+#define UA_freeaddrinfo freeaddrinfo
+#define UA_gethostname gethostname
+#define UA_inet_pton inet_pton
+#if UA_IPV6
+# define UA_if_nametoindex if_nametoindex
+#endif
+
+#include <stdlib.h>
+#define UA_free free
+#define UA_malloc malloc
+#define UA_calloc calloc
+#define UA_realloc realloc
+
+#include <stdio.h>
+#define UA_snprintf snprintf
+
+#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
+    char *errno_str = strerror(errno); \
+    LOG; \
+}
+#define UA_LOG_SOCKET_ERRNO_GAI_WRAP(LOG) { \
+    const char *errno_str = gai_strerror(errno); \
+    LOG; \
+}
+
+#include "../ua_architecture_functions.h"
+
+#endif /* PLUGINS_ARCH_POSIX_UA_ARCHITECTURE_H_ */
+
+#endif /* UA_ARCHITECTURE_POSIX */

+ 33 - 0
arch/posix/ua_architecture_functions.c

@@ -0,0 +1,33 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_POSIX
+
+#include "ua_types.h"
+
+unsigned int UA_socket_set_blocking(UA_SOCKET sockfd){
+  int opts = fcntl(sockfd, F_GETFL);
+  if(opts < 0 || fcntl(sockfd, F_SETFL, opts & (~O_NONBLOCK)) < 0)
+      return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd){
+  int opts = fcntl(sockfd, F_GETFL);
+  if(opts < 0 || fcntl(sockfd, F_SETFL, opts | O_NONBLOCK) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+void UA_initialize_architecture_network(void){
+  return;
+}
+
+void UA_deinitialize_architecture_network(void){
+  return;
+}
+
+#endif /* UA_ARCHITECTURE_POSIX */

+ 58 - 0
arch/posix/ua_clock.c

@@ -0,0 +1,58 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
+ *
+ *    Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ *    Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
+ */
+
+#ifdef UA_ARCHITECTURE_POSIX
+
+#include "ua_types.h"
+#include <time.h>
+#include <sys/time.h>
+
+#if defined(__APPLE__) || defined(__MACH__)
+# include <mach/clock.h>
+# include <mach/mach.h>
+#endif
+
+UA_DateTime UA_DateTime_now(void) {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return (tv.tv_sec * UA_DATETIME_SEC) + (tv.tv_usec * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH;
+}
+
+/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
+UA_Int64 UA_DateTime_localTimeUtcOffset(void) {
+    time_t gmt, rawtime = time(NULL);
+    struct tm *ptm;
+    struct tm gbuf;
+    ptm = gmtime_r(&rawtime, &gbuf);
+    // Request that mktime() looksup dst in timezone database
+    ptm->tm_isdst = -1;
+    gmt = mktime(ptm);
+    return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC);
+}
+
+UA_DateTime UA_DateTime_nowMonotonic(void) {
+#if defined(__APPLE__) || defined(__MACH__)
+    /* OS X does not have clock_gettime, use clock_get_time */
+    clock_serv_t cclock;
+    mach_timespec_t mts;
+    host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
+    clock_get_time(cclock, &mts);
+    mach_port_deallocate(mach_task_self(), cclock);
+    return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100);
+#elif !defined(CLOCK_MONOTONIC_RAW)
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
+#else
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+    return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
+#endif
+}
+
+#endif /* UA_ARCHITECTURE_POSIX */

+ 208 - 0
arch/ua_architecture_functions.h

@@ -0,0 +1,208 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+/*
+ * This header has all the functions that are architecture dependent. The declaration is behind a ifndef since
+ * they can be previously defined in the ua_architecture.h which include this files at the end
+ */
+
+#ifndef PLUGINS_ARCH_UA_ARCHITECTURE_FUNCTIONS_H_
+#define PLUGINS_ARCH_UA_ARCHITECTURE_FUNCTIONS_H_
+
+#include "ua_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Allocation functions
+ */
+
+#ifndef UA_malloc
+void* UA_malloc(size_t size); //allocate memory in the heap with size bytes
+#endif
+
+#ifndef UA_calloc
+void* UA_calloc(size_t num, size_t size); //allocate memory in the heap with size*num bytes and set the memory to zero
+#endif
+
+#ifndef UA_realloc
+void* UA_realloc(void *ptr, size_t new_size);//re-allocate memory in the heap with new_size bytes from previously allocated memory ptr
+#endif
+
+#ifndef UA_free
+void UA_free(void* ptr); //de-allocate memory previously allocated with UA_malloc, UA_calloc or UA_realloc
+#endif
+
+#ifndef UA_alloca
+# if defined(__GNUC__) || defined(__clang__)
+#  define UA_alloca(size) __builtin_alloca (size)
+# elif defined(_WIN32)
+#  define UA_alloca(SIZE) _alloca(SIZE)
+# else
+#  include <alloca.h>
+#  define UA_alloca(SIZE) alloca(SIZE)
+# endif
+#endif
+
+#ifndef UA_STACKARRAY
+/* Stack-allocation of memory. Use C99 variable-length arrays if possible.
+ * Otherwise revert to alloca. Note that alloca is not supported on some
+ * plattforms. */
+# if defined(__GNUC__) || defined(__clang__)
+#  define UA_STACKARRAY(TYPE, NAME, SIZE) TYPE NAME[SIZE]
+# else
+#  define UA_STACKARRAY(TYPE, NAME, SIZE) \
+    TYPE *NAME = (TYPE*)UA_alloca(sizeof(TYPE) * SIZE)
+# endif
+#endif
+
+/*
+ * Sleep function
+ */
+
+#ifndef UA_sleep_ms
+int UA_sleep_ms(unsigned int miliSeconds); //suspend the thread for a certain amount of mili seconds
+#endif
+
+/*
+ * Socket functions
+ */
+
+#ifndef UA_send
+ssize_t UA_send(UA_SOCKET sockfd, const void *buf, size_t len, int flags); //equivalent to posix send implementation
+#endif
+
+#ifndef UA_sendto
+ssize_t sendto(UA_SOCKET sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); //equivalent to posix sendto implementation
+#endif
+
+#ifndef UA_select
+int UA_select(UA_SOCKET nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); //equivalent to posix select implementation
+#endif
+
+#ifndef UA_recv
+ssize_t UA_recv(UA_SOCKET sockfd, void *buf, size_t len, int flags); //equivalent to posix recv implementation
+#endif
+
+#ifndef UA_recvfrom
+ssize_t recvfrom(UA_SOCKET sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
+#endif
+
+#ifndef UA_shutdown
+int UA_shutdown(UA_SOCKET sockfd, int how); //equivalent to posix shutdown implementation
+#endif
+
+#ifndef UA_socket
+UA_SOCKET UA_socket(int domain, int type, int protocol);//equivalent to posix socket implementation
+#endif
+
+#ifndef UA_bind
+int UA_bind(UA_SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);//equivalent to posix bind implementation
+#endif
+
+#ifndef UA_listen
+int UA_listen(UA_SOCKET sockfd, int backlog);//equivalent to posix listen implementation
+#endif
+
+#ifndef UA_accept
+int UA_accept(UA_SOCKET sockfd, struct sockaddr *addr, socklen_t *addrlen);//equivalent to posix accept implementation
+#endif
+
+#ifndef UA_close
+int UA_close(UA_SOCKET sockfd);//equivalent to posix close implementation
+#endif
+
+#ifndef UA_connect
+int UA_connect(UA_SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);//equivalent to posix connect implementation
+#endif
+
+#ifndef UA_fd_set
+void UA_fd_set(UA_SOCKET fd, fd_set *set); //equivalent to posix FD_SET implementation
+#endif
+
+#ifndef UA_fd_isset
+int UA_fd_isset(UA_SOCKET fd, fd_set *set);//equivalent to posix FD_ISSET implementation
+#endif
+
+#ifndef UA_getaddrinfo
+int UA_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);//equivalent to posix getaddrinfo implementation
+#endif
+
+#ifndef UA_htonl
+uint32_t UA_htonl(uint32_t hostlong);//equivalent to posix UA_htonl implementation
+#endif
+
+#ifndef UA_ntohl
+uint32_t UA_ntohl(uint32_t netlong);//equivalent to posix ntohl implementation
+#endif
+
+#ifndef UA_inet_pton
+int UA_inet_pton(int af, const char *src, void *dst);//equivalent to ANSI inet_pton implementation
+#endif
+
+#if UA_IPV6
+# ifndef UA_if_nametoindex
+unsigned int UA_if_nametoindex(const char *ifname);//equivalent to posix if_nametoindex implementation
+# endif
+#endif
+
+#ifndef UA_socket_set_blocking
+unsigned int UA_socket_set_blocking(UA_SOCKET sockfd);//set a socket as blocking. Returns 0 if OK, other value otherwise
+#endif
+
+#ifndef UA_socket_set_nonblocking
+unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd);//set a socket as non-blocking. Returns 0 if OK, other value otherwise
+#endif
+
+#ifndef UA_getsockopt
+int UA_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); //equivalent to posix getsockopt implementation. Only in non windows architectures
+#endif
+
+#ifndef UA_setsockopt
+int UA_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);//equivalent to posix setsockopt implementation
+#endif
+
+#ifndef UA_freeaddrinfo
+void UA_freeaddrinfo(struct addrinfo *res);//equivalent to posix freeaddrinfo implementatio
+#endif
+
+#ifndef UA_gethostname
+int UA_gethostname(char *name, size_t len);//equivalent to posix gethostname implementatio
+#endif
+
+#ifndef UA_initialize_architecture_network
+void UA_initialize_architecture_network(void);//initializes all needed for using the network interfaces
+#endif
+
+#ifndef UA_deinitialize_architecture_network
+void UA_deinitialize_architecture_network(void);//de-initializes the network interfaces
+#endif
+
+/*
+ * Print function
+ */
+#ifndef UA_snprintf
+int UA_snprintf(char* pa_stream, size_t pa_size, const char* pa_format, ...); //prints text to output
+#endif
+
+/*
+ * Access to file function
+ */
+
+#ifndef UA_access
+int UA_access(const char *pathname, int mode); //equivalent implementation of https://linux.die.net/man/2/access
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif /* PLUGINS_ARCH_UA_ARCHITECTURE_FUNCTIONS_H_ */

+ 103 - 357
plugins/ua_network_tcp.c

@@ -8,173 +8,17 @@
  *    Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
  */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
-/* Disable some security warnings on MSVC */
-#ifdef _MSC_VER
-# define _CRT_SECURE_NO_WARNINGS
-#endif
-
-/* Assume that Windows versions are newer than Windows XP */
-#if defined(__MINGW32__) && (!defined(WINVER) || WINVER < 0x501)
-# undef WINVER
-# undef _WIN32_WINDOWS
-# undef _WIN32_WINNT
-# define WINVER 0x0501
-# define _WIN32_WINDOWS 0x0501
-# define _WIN32_WINNT 0x0501
-#endif
-
 #include "ua_network_tcp.h"
 #include "ua_log_stdout.h"
 #include "../deps/queue.h"
 #include "ua_util.h"
 
-#include <stdio.h> // snprintf
 #include <string.h> // memset
 
-#if !defined(UA_FREERTOS)
-# include <errno.h>
-#else
-# define AI_PASSIVE 0x01
-# define TRUE 1
-# define FALSE 0
-# define ioctl ioctlsocket
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
 #endif
 
-#ifdef _WIN32
-# include <winsock2.h>
-# include <ws2tcpip.h>
-# define CLOSESOCKET(S) closesocket((SOCKET)S)
-# define ssize_t int
-# define WIN32_INT (int)
-# define OPTVAL_TYPE char
-# define ERR_CONNECTION_PROGRESS WSAEWOULDBLOCK
-#else /* _WIN32 */
-# if defined(UA_FREERTOS)
-#  define UA_FREERTOS_HOSTNAME "10.200.4.114"
-static inline int gethostname_freertos(char* name, size_t len){
-  if(strlen(UA_FREERTOS_HOSTNAME) > (len))
-    return -1;
-  strcpy(name, UA_FREERTOS_HOSTNAME);
-  return 0;
-}
-#define gethostname gethostname_freertos
-#  include <lwip/tcpip.h>
-#  include <lwip/netdb.h>
-#  define CLOSESOCKET(S) lwip_close(S)
-#  define sockaddr_storage sockaddr
-#  ifdef BYTE_ORDER
-#   undef BYTE_ORDER
-#  endif
-# else /* Not freeRTOS */
-#  define CLOSESOCKET(S) close(S)
-#  include <arpa/inet.h>
-#  include <netinet/in.h>
-#  include <netdb.h>
-#  include <sys/ioctl.h>
-#  if defined(_WRS_KERNEL)
-#   include <hostLib.h>
-#   include <selectLib.h>
-#  else /* defined(_WRS_KERNEL) */
-#   include <sys/select.h>
-#  endif /* defined(_WRS_KERNEL) */
-# endif /* Not freeRTOS */
-
-# define SOCKET int
-# define WIN32_INT
-# define OPTVAL_TYPE int
-# define ERR_CONNECTION_PROGRESS EINPROGRESS
-
-
-# include <fcntl.h>
-# include <unistd.h> // read, write, close
-
-# ifdef __QNX__
-#  include <sys/socket.h>
-# endif
-# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-#  include <sys/param.h>
-#  if defined(BSD)
-#   include<sys/socket.h>
-#  endif
-# endif
-# if !defined(__CYGWIN__) && !defined(UA_FREERTOS)
-#  include <netinet/tcp.h>
-# endif
-#endif /* _WIN32 */
-
-#ifndef UA_sleep_ms
-# ifdef _WIN32
-#  define UA_sleep_ms(X) Sleep(X)
-# else /* _WIN32 */
-#  if defined(UA_FREERTOS)
-#   define UA_sleep_ms(X) vTaskDelay(pdMS_TO_TICKS(X))
-#  else /* Not freeRTOS */
-#   if defined(_WRS_KERNEL)
-#    include <hostLib.h>
-#    include <selectLib.h>
-#    define UA_sleep_ms(X)                            \
-     {                                                \
-     struct timespec timeToSleep;                     \
-       timeToSleep.tv_sec = X / 1000;                 \
-       timeToSleep.tv_nsec = 1000000 * (X % 1000);    \
-       nanosleep(&timeToSleep, NULL);                 \
-     }
-#   else /* defined(_WRS_KERNEL) */
-#    define UA_sleep_ms(X) usleep(X * 1000)
-#   endif /* defined(_WRS_KERNEL) */
-#  endif /* Not freeRTOS */
-# endif /* _WIN32 */
-#else /* UA_sleep_ms */
-/* With this one can define its own UA_sleep_ms using a preprocessor define.
-E.g. see unit tests. */
-void UA_sleep_ms(size_t);
-#endif
-
-/* unsigned int for windows and workaround to a glibc bug */
-/* Additionally if GNU_LIBRARY is not defined, it may be using
- * musl libc (e.g. Docker Alpine) */
-#if defined(_WIN32) || defined(__OpenBSD__) || \
-    (defined(__GNU_LIBRARY__) && (__GNU_LIBRARY__ <= 6) && \
-     (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 16) || \
-    !defined(__GNU_LIBRARY__))
-# define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds)
-# define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds)
-#else
-# define UA_fd_set(fd, fds) FD_SET(fd, fds)
-# define UA_fd_isset(fd, fds) FD_ISSET(fd, fds)
-#endif
-
-#ifdef UNDER_CE
-# define errno WSAGetLastError()
-#endif
-
-#ifdef _WIN32
-# define errno__ WSAGetLastError()
-# define INTERRUPTED WSAEINTR
-# define WOULDBLOCK WSAEWOULDBLOCK
-# define AGAIN WSAEWOULDBLOCK
-#else
-# define errno__ errno
-# define INTERRUPTED EINTR
-# define WOULDBLOCK EWOULDBLOCK
-# define AGAIN EAGAIN
-#endif
-
-#include "ua_log_socket_error.h"
-
 /****************************/
 /* Generic Socket Functions */
 /****************************/
@@ -208,9 +52,7 @@ connection_write(UA_Connection *connection, UA_ByteString *buf) {
 
     /* Prevent OS signals when sending to a closed socket */
     int flags = 0;
-#ifdef MSG_NOSIGNAL
     flags |= MSG_NOSIGNAL;
-#endif
 
     /* Send the full buffer. This may require several calls to send */
     size_t nWritten = 0;
@@ -218,10 +60,10 @@ connection_write(UA_Connection *connection, UA_ByteString *buf) {
         ssize_t n = 0;
         do {
             size_t bytes_to_send = buf->length - nWritten;
-            n = send((SOCKET)connection->sockfd,
+            n = UA_send(connection->sockfd,
                      (const char*)buf->data + nWritten,
-                     WIN32_INT bytes_to_send, flags);
-            if(n < 0 && errno__ != INTERRUPTED && errno__ != AGAIN) {
+                     bytes_to_send, flags);
+            if(n < 0 && UA_ERRNO != UA_INTERRUPTED && UA_ERRNO != UA_AGAIN) {
                 connection->close(connection);
                 UA_ByteString_deleteMembers(buf);
                 return UA_STATUSCODE_BADCONNECTIONCLOSED;
@@ -249,7 +91,7 @@ connection_recv(UA_Connection *connection, UA_ByteString *response,
         UA_UInt32 timeout_usec = timeout * 1000;
         struct timeval tmptv = {(long int)(timeout_usec / 1000000),
                                 (long int)(timeout_usec % 1000000)};
-        int resultsize = select(connection->sockfd+1, &fdset, NULL,
+        int resultsize = UA_select(connection->sockfd+1, &fdset, NULL,
                                 NULL, &tmptv);
 
         /* No result */
@@ -276,7 +118,7 @@ connection_recv(UA_Connection *connection, UA_ByteString *response,
     }
 
     /* Get the received packet(s) */
-    ssize_t ret = recv(connection->sockfd, (char*)response->data,
+    ssize_t ret = UA_recv(connection->sockfd, (char*)response->data,
                        connection->localConf.recvBufferSize, 0);
 
     /* The remote side closed the connection */
@@ -289,8 +131,8 @@ connection_recv(UA_Connection *connection, UA_ByteString *response,
     /* Error case */
     if(ret < 0) {
         UA_ByteString_deleteMembers(response);
-        if(errno__ == INTERRUPTED || (timeout > 0) ?
-           false : (errno__ == EAGAIN || errno__ == WOULDBLOCK))
+        if(UA_ERRNO == UA_INTERRUPTED || (timeout > 0) ?
+           false : (UA_ERRNO == UA_EAGAIN || UA_ERRNO == UA_WOULDBLOCK))
             return UA_STATUSCODE_GOOD; /* statuscode_good but no data -> retry */
         connection->close(connection);
         return UA_STATUSCODE_BADCONNECTIONCLOSED;
@@ -301,41 +143,6 @@ connection_recv(UA_Connection *connection, UA_ByteString *response,
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode
-socket_set_nonblocking(SOCKET sockfd) {
-#ifdef _WIN32
-    u_long iMode = 1;
-    if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR)
-        return UA_STATUSCODE_BADINTERNALERROR;
-#elif defined(_WRS_KERNEL) || defined(UA_FREERTOS)
-    int on = TRUE;
-    if(ioctl(sockfd, FIONBIO, &on) < 0)
-      return UA_STATUSCODE_BADINTERNALERROR;
-#else
-    int opts = fcntl(sockfd, F_GETFL);
-    if(opts < 0 || fcntl(sockfd, F_SETFL, opts|O_NONBLOCK) < 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
-#endif
-    return UA_STATUSCODE_GOOD;
-}
-
-static UA_StatusCode
-socket_set_blocking(SOCKET sockfd) {
-#ifdef _WIN32
-    u_long iMode = 0;
-    if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR)
-        return UA_STATUSCODE_BADINTERNALERROR;
-#elif defined(_WRS_KERNEL) || defined(UA_FREERTOS)
-    int on = FALSE;
-    if(ioctl(sockfd, FIONBIO, &on) < 0)
-      return UA_STATUSCODE_BADINTERNALERROR;
-#else
-    int opts = fcntl(sockfd, F_GETFL);
-    if(opts < 0 || fcntl(sockfd, F_SETFL, opts & (~O_NONBLOCK)) < 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
-#endif
-    return UA_STATUSCODE_GOOD;
-}
 
 /***************************/
 /* Server NetworkLayer TCP */
@@ -354,7 +161,7 @@ typedef struct {
     UA_Logger logger;
     UA_ConnectionConfig conf;
     UA_UInt16 port;
-    UA_Int32 serverSockets[FD_SETSIZE];
+    UA_SOCKET serverSockets[FD_SETSIZE];
     UA_UInt16 serverSocketsSize;
     LIST_HEAD(, ConnectionEntry) connections;
 } ServerNetworkLayerTCP;
@@ -371,7 +178,7 @@ static void
 ServerNetworkLayerTCP_close(UA_Connection *connection) {
     if (connection->state == UA_CONNECTION_CLOSED)
         return;
-    shutdown((SOCKET)connection->sockfd, 2);
+    UA_shutdown((UA_SOCKET)connection->sockfd, 2);
     connection->state = UA_CONNECTION_CLOSED;
 }
 
@@ -379,11 +186,11 @@ static UA_StatusCode
 ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
                           struct sockaddr_storage *remote) {
     /* Set nonblocking */
-    socket_set_nonblocking(newsockfd);
+    UA_socket_set_nonblocking(newsockfd);//TODO: check return value
 
     /* Do not merge packets on the socket (disable Nagle's algorithm) */
     int dummy = 1;
-    if(setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY,
+    if(UA_setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY,
                (const char *)&dummy, sizeof(dummy)) < 0) {
         UA_LOG_SOCKET_ERRNO_WRAP(
                 UA_LOG_ERROR(layer->logger, UA_LOGCATEGORY_NETWORK,
@@ -392,10 +199,10 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
         return UA_STATUSCODE_BADUNEXPECTEDERROR;
     }
 
-#if !defined(UA_FREERTOS)
+#if defined(UA_getnameinfo)
     /* Get the peer name for logging */
     char remote_name[100];
-    int res = getnameinfo((struct sockaddr*)remote,
+    int res = UA_getnameinfo((struct sockaddr*)remote,
                           sizeof(struct sockaddr_storage),
                           remote_name, sizeof(remote_name),
                           NULL, 0, NI_NUMERICHOST);
@@ -409,11 +216,15 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
                                                         "getnameinfo failed with error: %s",
                                                 (int)newsockfd, errno_str));
     }
+#else
+    UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
+                "Connection %i | New connection over TCP",
+                (int)newsockfd);
 #endif
     /* Allocate and initialize the connection */
     ConnectionEntry *e = (ConnectionEntry*)UA_malloc(sizeof(ConnectionEntry));
     if(!e){
-        CLOSESOCKET(newsockfd);
+        UA_close(newsockfd);
         return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
@@ -440,12 +251,8 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
 static void
 addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
     /* Create the server socket */
-    SOCKET newsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-#ifdef _WIN32
-    if(newsock == INVALID_SOCKET)
-#else
-    if(newsock < 0)
-#endif
+    UA_SOCKET newsock = UA_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+    if(newsock == UA_INVALID_SOCKET)
     {
         UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
                        "Error opening the server socket");
@@ -457,61 +264,57 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
      * AF_INET6 sockets only for IPv6. */
 
     int optval = 1;
-#if !defined(UA_FREERTOS)
+#if UA_IPV6
     if(ai->ai_family == AF_INET6 &&
-       setsockopt(newsock, IPPROTO_IPV6, IPV6_V6ONLY,
+       UA_setsockopt(newsock, IPPROTO_IPV6, IPV6_V6ONLY,
                   (const char*)&optval, sizeof(optval)) == -1) {
         UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
                        "Could not set an IPv6 socket to IPv6 only");
-        CLOSESOCKET(newsock);
+        UA_close(newsock);
         return;
     }
 #endif
-    if(setsockopt(newsock, SOL_SOCKET, SO_REUSEADDR,
+    if(UA_setsockopt(newsock, SOL_SOCKET, SO_REUSEADDR,
                   (const char *)&optval, sizeof(optval)) == -1) {
         UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
                        "Could not make the socket reusable");
-        CLOSESOCKET(newsock);
+        UA_close(newsock);
         return;
     }
 
 
-    if(socket_set_nonblocking(newsock) != UA_STATUSCODE_GOOD) {
+    if(UA_socket_set_nonblocking(newsock) != UA_STATUSCODE_GOOD) {
         UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
                        "Could not set the server socket to nonblocking");
-        CLOSESOCKET(newsock);
+        UA_close(newsock);
         return;
     }
 
     /* Bind socket to address */
-    if(bind(newsock, ai->ai_addr, WIN32_INT ai->ai_addrlen) < 0) {
+    if(UA_bind(newsock, ai->ai_addr, (socklen_t)ai->ai_addrlen) < 0) {
         UA_LOG_SOCKET_ERRNO_WRAP(
             UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
                            "Error binding a server socket: %s", errno_str));
-        CLOSESOCKET(newsock);
+        UA_close(newsock);
         return;
     }
 
     /* Start listening */
-    if(listen(newsock, MAXBACKLOG) < 0) {
+    if(UA_listen(newsock, MAXBACKLOG) < 0) {
         UA_LOG_SOCKET_ERRNO_WRAP(
                 UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
                        "Error listening on server socket: %s", errno_str));
-        CLOSESOCKET(newsock);
+        UA_close(newsock);
         return;
     }
 
-    layer->serverSockets[layer->serverSocketsSize] = (UA_Int32)newsock;
+    layer->serverSockets[layer->serverSocketsSize] = newsock;
     layer->serverSocketsSize++;
 }
 
 static UA_StatusCode
 ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHostname) {
-#ifdef _WIN32
-    WORD wVersionRequested = MAKEWORD(2, 2);
-    WSADATA wsaData;
-    WSAStartup(wVersionRequested, &wsaData);
-#endif
+  UA_initialize_architecture_network();
 
     ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle;
 
@@ -519,55 +322,34 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
     UA_String du = UA_STRING_NULL;
     if (customHostname->length) {
         char discoveryUrl[256];
-#ifndef _MSC_VER
-        du.length = (size_t)snprintf(discoveryUrl, 255, "opc.tcp://%.*s:%d/",
+        du.length = (size_t)UA_snprintf(discoveryUrl, 255, "opc.tcp://%.*s:%d/",
                                      (int)customHostname->length,
                                      customHostname->data,
                                      layer->port);
-#else
-        du.length = (size_t)_snprintf_s(discoveryUrl, 255, _TRUNCATE,
-                                        "opc.tcp://%.*s:%d/",
-                                        (int)customHostname->length,
-                                        customHostname->data,
-                                        layer->port);
-#endif
         du.data = (UA_Byte*)discoveryUrl;
     }else{
         char hostname[256];
-        if(gethostname(hostname, 255) == 0) {
+        if(UA_gethostname(hostname, 255) == 0) {
             char discoveryUrl[256];
-#ifndef _MSC_VER
-            du.length = (size_t)snprintf(discoveryUrl, 255, "opc.tcp://%s:%d/",
+            du.length = (size_t)UA_snprintf(discoveryUrl, 255, "opc.tcp://%s:%d/",
                                          hostname, layer->port);
-#else
-            du.length = (size_t)_snprintf_s(discoveryUrl, 255, _TRUNCATE,
-                                            "opc.tcp://%s:%d/", hostname,
-                                            layer->port);
-#endif
             du.data = (UA_Byte*)discoveryUrl;
+        } else {
+            UA_LOG_ERROR(layer->logger, UA_LOGCATEGORY_NETWORK, "Could not get the hostname");
         }
     }
     UA_String_copy(&du, &nl->discoveryUrl);
 
     /* Get addrinfo of the server and create server sockets */
     char portno[6];
-#ifndef _MSC_VER
-    snprintf(portno, 6, "%d", layer->port);
-#else
-    _snprintf_s(portno, 6, _TRUNCATE, "%d", layer->port);
-#endif
+    UA_snprintf(portno, 6, "%d", layer->port);
     struct addrinfo hints, *res;
     memset(&hints, 0, sizeof hints);
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_flags = AI_PASSIVE;
-#if defined(UA_FREERTOS)
     hints.ai_protocol = IPPROTO_TCP;
-    char hostname[] = UA_FREERTOS_HOSTNAME;
-    if(getaddrinfo(hostname, portno, &hints, &res) != 0)
-#else
-    if(getaddrinfo(NULL, portno, &hints, &res) != 0)
-#endif
+    if(UA_getaddrinfo(NULL, portno, &hints, &res) != 0)
         return UA_STATUSCODE_BADINTERNALERROR;
 
     /* There might be serveral addrinfos (for different network cards,
@@ -577,7 +359,7 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
         layer->serverSocketsSize < FD_SETSIZE && ai != NULL;
         ai = ai->ai_next)
         addServerSocket(layer, ai);
-    freeaddrinfo(res);
+    UA_freeaddrinfo(res);
 
     UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
                 "TCP network layer listening on %.*s",
@@ -592,15 +374,15 @@ setFDSet(ServerNetworkLayerTCP *layer, fd_set *fdset) {
     UA_Int32 highestfd = 0;
     for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) {
         UA_fd_set(layer->serverSockets[i], fdset);
-        if(layer->serverSockets[i] > highestfd)
-            highestfd = layer->serverSockets[i];
+        if((UA_Int32)layer->serverSockets[i] > highestfd)
+            highestfd = (UA_Int32)layer->serverSockets[i];
     }
 
     ConnectionEntry *e;
     LIST_FOREACH(e, &layer->connections, pointers) {
         UA_fd_set(e->connection.sockfd, fdset);
-        if(e->connection.sockfd > highestfd)
-            highestfd = e->connection.sockfd;
+        if((UA_Int32)e->connection.sockfd > highestfd)
+            highestfd = (UA_Int32)e->connection.sockfd;
     }
 
     return highestfd;
@@ -620,7 +402,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
     UA_Int32 highestfd = setFDSet(layer, &fdset);
     setFDSet(layer, &errset);
     struct timeval tmptv = {0, timeout * 1000};
-    if (select(highestfd+1, &fdset, NULL, &errset, &tmptv) < 0) {
+    if (UA_select(highestfd+1, &fdset, NULL, &errset, &tmptv) < 0) {
         UA_LOG_SOCKET_ERRNO_WRAP(
             UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK,
                                   "Socket select failed with %s", errno_str));
@@ -635,13 +417,9 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
 
         struct sockaddr_storage remote;
         socklen_t remote_size = sizeof(remote);
-        SOCKET newsockfd = accept((SOCKET)layer->serverSockets[i],
+        UA_SOCKET newsockfd = UA_accept((UA_SOCKET)layer->serverSockets[i],
                                   (struct sockaddr*)&remote, &remote_size);
-#ifdef _WIN32
-        if(newsockfd == INVALID_SOCKET)
-#else
-        if(newsockfd < 0)
-#endif
+        if(newsockfd == UA_INVALID_SOCKET)
             continue;
 
         UA_LOG_TRACE(layer->logger, UA_LOGCATEGORY_NETWORK,
@@ -661,7 +439,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
                         "Connection %i | Closed by the server (no Hello Message)",
                          e->connection.sockfd);
             LIST_REMOVE(e, pointers);
-            CLOSESOCKET(e->connection.sockfd);
+            UA_close(e->connection.sockfd);
             UA_Server_removeConnection(server, &e->connection);
             continue;
         }
@@ -687,7 +465,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
                         "Connection %i | Closed",
                         e->connection.sockfd);
             LIST_REMOVE(e, pointers);
-            CLOSESOCKET(e->connection.sockfd);
+            UA_close(e->connection.sockfd);
             UA_Server_removeConnection(server, &e->connection);
         }
     }
@@ -702,8 +480,8 @@ ServerNetworkLayerTCP_stop(UA_ServerNetworkLayer *nl, UA_Server *server) {
 
     /* Close the server sockets */
     for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) {
-        shutdown((SOCKET)layer->serverSockets[i], 2);
-        CLOSESOCKET(layer->serverSockets[i]);
+        UA_shutdown(layer->serverSockets[i], 2);
+        UA_close(layer->serverSockets[i]);
     }
     layer->serverSocketsSize = 0;
 
@@ -716,9 +494,7 @@ ServerNetworkLayerTCP_stop(UA_ServerNetworkLayer *nl, UA_Server *server) {
      * the connection. */
     ServerNetworkLayerTCP_listen(nl, server, 0);
 
-#ifdef _WIN32
-    WSACleanup();
-#endif
+    UA_deinitialize_architecture_network();
 }
 
 /* run only when the server is stopped */
@@ -732,7 +508,7 @@ ServerNetworkLayerTCP_deleteMembers(UA_ServerNetworkLayer *nl) {
     ConnectionEntry *e, *e_tmp;
     LIST_FOREACH_SAFE(e, &layer->connections, pointers, e_tmp) {
         LIST_REMOVE(e, pointers);
-        CLOSESOCKET(e->connection.sockfd);
+        UA_close(e->connection.sockfd);
         UA_free(e);
     }
 
@@ -776,8 +552,8 @@ static void
 ClientNetworkLayerTCP_close(UA_Connection *connection) {
     if (connection->state == UA_CONNECTION_CLOSED)
         return;
-    shutdown((SOCKET)connection->sockfd, 2);
-    CLOSESOCKET(connection->sockfd);
+    UA_shutdown(connection->sockfd, 2);
+    UA_close(connection->sockfd);
     connection->state = UA_CONNECTION_CLOSED;
 }
 
@@ -786,7 +562,7 @@ ClientNetworkLayerTCP_free(UA_Connection *connection) {
     if (connection->handle){
         TCPClientConnection *tcpConnection = (TCPClientConnection *)connection->handle;
         if(tcpConnection->server)
-            freeaddrinfo(tcpConnection->server);
+          UA_freeaddrinfo(tcpConnection->server);
         free(tcpConnection);
     }
 }
@@ -801,7 +577,7 @@ UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data) {
                     (TCPClientConnection*) connection->handle;
 
     UA_DateTime connStart = UA_DateTime_nowMonotonic();
-    SOCKET clientsockfd;
+    UA_SOCKET clientsockfd;
 
     if (connection->state == UA_CONNECTION_ESTABLISHED) {
             UA_Client_removeRepeatedCallback(client, connection->connectCallbackID);
@@ -821,24 +597,20 @@ UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data) {
     /* Thus use a loop and retry until timeout is reached */
 
     /* Get a socket */
-    clientsockfd = socket(tcpConnection->server->ai_family,
+    clientsockfd = UA_socket(tcpConnection->server->ai_family,
                     tcpConnection->server->ai_socktype,
                     tcpConnection->server->ai_protocol);
     connection->sockfd = (UA_Int32) clientsockfd; /* cast for win32 */
 
-#ifdef _WIN32
-    if(clientsockfd == INVALID_SOCKET) {
-#else
-    if (clientsockfd < 0) {
-#endif
+    if(clientsockfd == UA_INVALID_SOCKET) {
             UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
-                            "Could not create client socket: %s", strerror(errno__));
+                            "Could not create client socket: %s", strerror(UA_ERRNO));
             ClientNetworkLayerTCP_close(connection);
             return UA_STATUSCODE_BADDISCONNECT;
     }
 
     /* Non blocking connect to be able to timeout */
-    if (socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) {
+    if (UA_socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) {
             UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
                             "Could not set the client socket to nonblocking");
             ClientNetworkLayerTCP_close(connection);
@@ -846,18 +618,18 @@ UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data) {
     }
 
     /* Non blocking connect */
-    int error = connect(clientsockfd, tcpConnection->server->ai_addr,
-                    WIN32_INT tcpConnection->server->ai_addrlen);
+    int error = UA_connect(clientsockfd, tcpConnection->server->ai_addr,
+                    tcpConnection->server->ai_addrlen);
 
-    if ((error == -1) && (errno__ != ERR_CONNECTION_PROGRESS)) {
+    if ((error == -1) && (UA_ERRNO != UA_ERR_CONNECTION_PROGRESS)) {
             ClientNetworkLayerTCP_close(connection);
             UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
-                            "Connection to  failed with error: %s", strerror(errno__));
+                            "Connection to  failed with error: %s", strerror(UA_ERRNO));
             return UA_STATUSCODE_BADDISCONNECT;
     }
 
     /* Use select to wait and check if connected */
-    if (error == -1 && (errno__ == ERR_CONNECTION_PROGRESS)) {
+    if (error == -1 && (UA_ERRNO == UA_ERR_CONNECTION_PROGRESS)) {
         /* connection in progress. Wait until connected using select */
 
         UA_UInt32 timeSinceStart =
@@ -896,7 +668,7 @@ UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data) {
         struct timeval tmptv = { (long int) (timeout_usec / 1000000),
                         (long int) (timeout_usec % 1000000) };
 
-        int resultsize = select((UA_Int32) (clientsockfd + 1), NULL, &fdset,
+        int resultsize = UA_select((UA_Int32) (clientsockfd + 1), NULL, &fdset,
         NULL, &tmptv);
 #endif
         if (resultsize == 1) {
@@ -909,7 +681,7 @@ UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data) {
             OPTVAL_TYPE so_error;
             socklen_t len = sizeof so_error;
 
-            int ret = getsockopt(clientsockfd, SOL_SOCKET, SO_ERROR, &so_error,
+            int ret = UA_getsockopt(clientsockfd, SOL_SOCKET, SO_ERROR, &so_error,
                             &len);
 
             if (ret != 0 || so_error != 0) {
@@ -920,7 +692,7 @@ UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data) {
                         ClientNetworkLayerTCP_close(connection);
                         UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
                                         "Connection to failed with error: %s",
-                                        strerror(ret == 0 ? so_error : errno__));
+                                        strerror(ret == 0 ? so_error : UA_ERRNO));
                         return UA_STATUSCODE_BADDISCONNECT;
                 }
                 /* wait until we try a again. Do not make this too small, otherwise the
@@ -998,18 +770,13 @@ UA_Connection UA_ClientConnectionTCP_init(UA_ConnectionConfig conf,
     tcpClientConnection->hints.ai_family = AF_UNSPEC;
     tcpClientConnection->hints.ai_socktype = SOCK_STREAM;
     char portStr[6];
-#ifndef _MSC_VER
-    snprintf(portStr, 6, "%d", port);
-#else
-    _snprintf_s(portStr, 6, _TRUNCATE, "%d", port);
-#endif
-    int error = getaddrinfo(hostname, portStr, &tcpClientConnection->hints,
+    UA_snprintf(portStr, 6, "%d", port);
+    int error = UA_getaddrinfo(hostname, portStr, &tcpClientConnection->hints,
                     &tcpClientConnection->server);
     if (error != 0 || !tcpClientConnection->server) {
-            UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
-                            "DNS lookup of %s failed with error %s", hostname,
-                            gai_strerror(error));
-            return connection;
+      UA_LOG_SOCKET_ERRNO_GAI_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
+                                                 "DNS lookup of %s failed with error %s", hostname, errno_str));
+      return connection;
     }
     return connection;
 }
@@ -1018,12 +785,8 @@ UA_Connection
 UA_ClientConnectionTCP(UA_ConnectionConfig conf,
                        const char *endpointUrl, const UA_UInt32 timeout,
                        UA_Logger logger) {
-#ifdef _WIN32
-    WORD wVersionRequested;
-    WSADATA wsaData;
-    wVersionRequested = MAKEWORD(2, 2);
-    WSAStartup(wVersionRequested, &wsaData);
-#endif
+
+    UA_initialize_architecture_network();
 
     if(logger == NULL) {
         logger = UA_Log_Stdout;
@@ -1070,83 +833,65 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
     memset(&hints, 0, sizeof(hints));
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
-#if defined(UA_FREERTOS)
     hints.ai_protocol = IPPROTO_TCP;
-#endif
     char portStr[6];
-#ifndef _MSC_VER
-    snprintf(portStr, 6, "%d", port);
-#else
-    _snprintf_s(portStr, 6, _TRUNCATE, "%d", port);
-#endif
-    int error = getaddrinfo(hostname, portStr, &hints, &server);
+    UA_snprintf(portStr, 6, "%d", port);
+    int error = UA_getaddrinfo(hostname, portStr, &hints, &server);
     if(error != 0 || !server) {
-#if !defined(UA_FREERTOS)
-        UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
-
-                       "DNS lookup of %s failed with error %s",
-                       hostname, gai_strerror(error));
-#else
-        UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
-                        "DNS lookup of %s failed with error",
-                        hostname);
-#endif
+        UA_LOG_SOCKET_ERRNO_GAI_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
+                                              "DNS lookup of %s failed with error %s", hostname, errno_str));
         return connection;
     }
 
     UA_Boolean connected = UA_FALSE;
     UA_DateTime dtTimeout = timeout * UA_DATETIME_MSEC;
     UA_DateTime connStart = UA_DateTime_nowMonotonic();
-    SOCKET clientsockfd;
+    UA_SOCKET clientsockfd;
 
     /* On linux connect may immediately return with ECONNREFUSED but we still
      * want to try to connect. So use a loop and retry until timeout is
      * reached. */
     do {
         /* Get a socket */
-        clientsockfd = socket(server->ai_family,
+        clientsockfd = UA_socket(server->ai_family,
                               server->ai_socktype,
                               server->ai_protocol);
-    #ifdef _WIN32
-        if(clientsockfd == INVALID_SOCKET) {
-    #else
-        if(clientsockfd < 0) {
-    #endif
+        if(clientsockfd == UA_INVALID_SOCKET) {
             UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
                                                     "Could not create client socket: %s", errno_str));
-            freeaddrinfo(server);
+            UA_freeaddrinfo(server);
             return connection;
         }
 
         connection.state = UA_CONNECTION_OPENING;
 
         /* Connect to the server */
-        connection.sockfd = (UA_Int32) clientsockfd; /* cast for win32 */
+        connection.sockfd = clientsockfd;
 
         /* Non blocking connect to be able to timeout */
-        if (socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) {
+        if (UA_socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) {
             UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
                            "Could not set the client socket to nonblocking");
             ClientNetworkLayerTCP_close(&connection);
-            freeaddrinfo(server);
+            UA_freeaddrinfo(server);
             return connection;
         }
 
         /* Non blocking connect */
-        error = connect(clientsockfd, server->ai_addr, WIN32_INT server->ai_addrlen);
+        error = UA_connect(clientsockfd, server->ai_addr, (socklen_t)server->ai_addrlen);
 
-        if ((error == -1) && (errno__ != ERR_CONNECTION_PROGRESS)) {
+        if ((error == -1) && (UA_ERRNO != UA_ERR_CONNECTION_PROGRESS)) {
             ClientNetworkLayerTCP_close(&connection);
             UA_LOG_SOCKET_ERRNO_WRAP(
                     UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
                                    "Connection to %s failed with error: %s",
                                    endpointUrl, errno_str));
-            freeaddrinfo(server);
+            UA_freeaddrinfo(server);
             return connection;
         }
 
         /* Use select to wait and check if connected */
-        if (error == -1 && (errno__ == ERR_CONNECTION_PROGRESS)) {
+        if (error == -1 && (UA_ERRNO == UA_ERR_CONNECTION_PROGRESS)) {
             /* connection in progress. Wait until connected using select */
             UA_DateTime timeSinceStart = UA_DateTime_nowMonotonic() - connStart;
             if(timeSinceStart > dtTimeout)
@@ -1174,7 +919,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
                     break;
             }
             while(resultsize == 0);
-#else 
+#else
             fd_set fdset;
             FD_ZERO(&fdset);
             UA_fd_set(clientsockfd, &fdset);
@@ -1182,8 +927,9 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
             struct timeval tmptv = {(long int) (timeout_usec / 1000000),
                                     (long int) (timeout_usec % 1000000)};
 
-            int resultsize = select((UA_Int32)(clientsockfd + 1), NULL, &fdset, NULL, &tmptv);
+            int resultsize = UA_select((UA_Int32)(clientsockfd + 1), NULL, &fdset, NULL, &tmptv);
 #endif
+
             if(resultsize == 1) {
 #ifdef _WIN32
                 /* Windows does not have any getsockopt equivalent and it is not
@@ -1194,7 +940,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
                 OPTVAL_TYPE so_error;
                 socklen_t len = sizeof so_error;
 
-                int ret = getsockopt(clientsockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
+                int ret = UA_getsockopt(clientsockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
 
                 if (ret != 0 || so_error != 0) {
                     /* on connection refused we should still try to connect */
@@ -1203,8 +949,8 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
                         ClientNetworkLayerTCP_close(&connection);
                         UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
                                        "Connection to %s failed with error: %s",
-                                       endpointUrl, strerror(ret == 0 ? so_error : errno__));
-                        freeaddrinfo(server);
+                                       endpointUrl, strerror(ret == 0 ? so_error : UA_ERRNO));
+                        UA_freeaddrinfo(server);
                         return connection;
                     }
                     /* wait until we try a again. Do not make this too small, otherwise the
@@ -1224,7 +970,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
 
     } while ((UA_DateTime_nowMonotonic() - connStart) < dtTimeout);
 
-    freeaddrinfo(server);
+    UA_freeaddrinfo(server);
 
     if(!connected) {
         /* connection timeout */
@@ -1238,7 +984,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
 
 
     /* We are connected. Reset socket to blocking */
-    if(socket_set_blocking(clientsockfd) != UA_STATUSCODE_GOOD) {
+    if(UA_socket_set_blocking(clientsockfd) != UA_STATUSCODE_GOOD) {
         UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
                        "Could not set the client socket to blocking");
         ClientNetworkLayerTCP_close(&connection);
@@ -1247,7 +993,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
 
 #ifdef SO_NOSIGPIPE
     int val = 1;
-    int sso_result = setsockopt(connection.sockfd, SOL_SOCKET,
+    int sso_result = UA_setsockopt(connection.sockfd, SOL_SOCKET,
                                 SO_NOSIGPIPE, (void*)&val, sizeof(val));
     if(sso_result < 0)
         UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,

plugins/ua_network_tcp.h → arch/ua_network_tcp.h


+ 1 - 8
plugins/ua_network_udp.c

@@ -117,13 +117,6 @@ static UA_StatusCode sendUDP(UA_Connection *connection, UA_ByteString *buf) {
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode socket_set_nonblocking(UA_Int32 sockfd) {
-    int opts = fcntl(sockfd, F_GETFL);
-    if(opts < 0 || fcntl(sockfd, F_SETFL, opts|O_NONBLOCK) < 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
-    return UA_STATUSCODE_GOOD;
-}
-
 static void setFDSet(ServerNetworkLayerUDP *layer) {
     FD_ZERO(&layer->fdset);
     FD_SET(layer->serversockfd, &layer->fdset);
@@ -159,7 +152,7 @@ static UA_StatusCode ServerNetworkLayerUDP_start(UA_ServerNetworkLayer *nl, UA_L
         CLOSESOCKET(layer->serversockfd);
         return UA_STATUSCODE_BADINTERNALERROR;
     }
-    socket_set_nonblocking(layer->serversockfd);
+    UA_socket_set_nonblocking(layer->serversockfd);
     UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "Listening for UDP connections on %s:%d",
                    inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port));
     return UA_STATUSCODE_GOOD;

plugins/ua_network_udp.h → arch/ua_network_udp.h


+ 20 - 0
arch/vxworks/CMakeLists.txt

@@ -0,0 +1,20 @@
+SET(SOURCE_GROUP ${SOURCE_GROUP}\\vxworks)
+
+ua_add_architecture("vxworks")
+
+list (FIND UA_AMALGAMATION_ARCHITECUTRES "vxworks" _index)
+if (${_index} GREATER -1 OR "${UA_ARCHITECTURE}" STREQUAL "vxworks")
+
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture_functions.c)
+
+    if("${UA_ARCHITECTURE}" STREQUAL "vxworks")
+
+        ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+        ua_architecture_remove_definitions(-Werror -Wpedantic -Wno-static-in-inline)
+        ua_architecture_add_definitions(-D_WRS_KERNEL)
+
+    endif()
+
+endif()

+ 114 - 0
arch/vxworks/ua_architecture.h

@@ -0,0 +1,114 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_VXWORKS
+
+#ifndef PLUGINS_ARCH_VXWORKS_UA_ARCHITECTURE_H_
+#define PLUGINS_ARCH_VXWORKS_UA_ARCHITECTURE_H_
+
+#include <../deps/queue.h>  //in some compilers there's already a _SYS_QUEUE_H_ who is included first and doesn't have all functions
+
+#include <errno.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+
+#include <hostLib.h>
+#include <selectLib.h>
+
+#define UA_sleep_ms(X)                            \
+ {                                                \
+ struct timespec timeToSleep;                     \
+   timeToSleep.tv_sec = X / 1000;                 \
+   timeToSleep.tv_nsec = 1000000 * (X % 1000);    \
+   nanosleep(&timeToSleep, NULL);                 \
+ }
+
+#ifdef UINT32_C
+# undef UINT32_C
+#endif
+
+#define UINT32_C(x) ((x) + (UINT32_MAX - UINT32_MAX))
+
+#ifdef UA_BINARY_OVERLAYABLE_FLOAT
+# undef UA_BINARY_OVERLAYABLE_FLOAT
+#endif
+#define UA_BINARY_OVERLAYABLE_FLOAT 1
+
+#define OPTVAL_TYPE int
+
+#include <fcntl.h>
+#include <unistd.h> // read, write, close
+#include <netinet/tcp.h>
+
+#define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds)
+#define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds)
+
+#define UA_access access
+
+#define UA_IPV6 1
+#define UA_SOCKET int
+#define UA_INVALID_SOCKET -1
+#define UA_ERRNO errno
+#define UA_INTERRUPTED EINTR
+#define UA_AGAIN EAGAIN
+#define UA_EAGAIN EAGAIN
+#define UA_WOULDBLOCK EWOULDBLOCK
+#define UA_ERR_CONNECTION_PROGRESS EINPROGRESS
+
+#define UA_ENABLE_LOG_COLORS
+
+#define UA_getnameinfo getnameinfo
+#define UA_send send
+#define UA_recv recv
+#define UA_sendto sendto
+#define UA_recvfrom recvfrom
+#define UA_htonl htonl
+#define UA_ntohl ntohl
+#define UA_close close
+#define UA_select select
+#define UA_shutdown shutdown
+#define UA_socket socket
+#define UA_bind bind
+#define UA_listen listen
+#define UA_accept accept
+#define UA_connect connect
+#define UA_getaddrinfo getaddrinfo
+#define UA_getsockopt getsockopt
+#define UA_setsockopt setsockopt
+#define UA_freeaddrinfo freeaddrinfo
+#define UA_gethostname gethostname
+#define UA_inet_pton inet_pton
+#if UA_IPV6
+# define UA_if_nametoindex if_nametoindex
+#endif
+
+#include <stdlib.h>
+#define UA_free free
+#define UA_malloc malloc
+#define UA_calloc calloc
+#define UA_realloc realloc
+
+#include <stdio.h>
+#define UA_snprintf snprintf
+
+#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
+    char *errno_str = strerror(errno); \
+    LOG; \
+}
+#define UA_LOG_SOCKET_ERRNO_GAI_WRAP(LOG) { \
+    char *errno_str = gai_strerror(errno); \
+    LOG; \
+}
+
+#include "../ua_architecture_functions.h"
+
+#endif /* PLUGINS_ARCH_VXWORKS_UA_ARCHITECTURE_H_ */
+
+#endif /* UA_ARCHITECTURE_VXWORKS */

+ 33 - 0
arch/vxworks/ua_architecture_functions.c

@@ -0,0 +1,33 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_VXWORKS
+
+#include "ua_types.h"
+
+unsigned int UA_socket_set_blocking(UA_SOCKET sockfd){
+  int on = FALSE;
+  if(ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd){
+  int on = TRUE;
+  if(ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+void UA_initialize_architecture_network(void){
+  return;
+}
+
+void UA_deinitialize_architecture_network(void){
+  return;
+}
+
+#endif /* UA_ARCHITECTURE_VXWORKS */

+ 56 - 0
arch/vxworks/ua_clock.c

@@ -0,0 +1,56 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ *    Copyright 2017 (c) Thomas Stalder
+ */
+
+#ifdef UA_ARCHITECTURE_VXWORKS
+
+#ifndef _DEFAULT_SOURCE
+# define _DEFAULT_SOURCE
+#endif
+/* On older systems we need to define _BSD_SOURCE.
+ * _DEFAULT_SOURCE is an alias for that. */
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+#endif
+
+#include <time.h>
+#include <sys/time.h>
+
+#include "ua_types.h"
+
+UA_DateTime UA_DateTime_now(void){
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return (tv.tv_sec * UA_DATETIME_SEC) + (tv.tv_usec * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH;
+}
+
+/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
+UA_Int64 UA_DateTime_localTimeUtcOffset(void){
+  time_t gmt, rawtime = time(NULL);
+
+  struct tm *ptm;
+  struct tm gbuf;
+  ptm = gmtime_r(&rawtime, &gbuf);
+  // Request that mktime() looksup dst in timezone database
+  ptm->tm_isdst = -1;
+  gmt = mktime(ptm);
+
+  return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC);
+}
+
+UA_DateTime UA_DateTime_nowMonotonic(void) {
+  struct timespec ts;
+#if !defined(CLOCK_MONOTONIC_RAW)
+  clock_gettime(CLOCK_MONOTONIC, &ts);
+#else
+  clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+#endif
+  return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
+}
+
+#endif /* UA_ARCHITECTURE_VXWORKS */
+

+ 21 - 0
arch/win32/CMakeLists.txt

@@ -0,0 +1,21 @@
+SET(SOURCE_GROUP ${SOURCE_GROUP}\\win32)
+
+ua_add_architecture("win32")
+
+list (FIND UA_AMALGAMATION_ARCHITECUTRES "win32" _index)
+if (${_index} GREATER -1 OR "${UA_ARCHITECTURE}" STREQUAL "win32")
+
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture_functions.c)
+
+    if("${UA_ARCHITECTURE}" STREQUAL "win32")
+        ua_architecture_append_to_library(ws2_32)
+
+        if(UA_ENABLE_DISCOVERY_MULTICAST OR UA_ENABLE_PUBSUB)
+            ua_architecture_append_to_library(iphlpapi)
+        endif()
+    endif()
+
+    ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+endif()

+ 147 - 0
arch/win32/ua_architecture.h

@@ -0,0 +1,147 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_WIN32
+
+#ifndef PLUGINS_ARCH_WIN32_UA_ARCHITECTURE_H_
+#define PLUGINS_ARCH_WIN32_UA_ARCHITECTURE_H_
+
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+#endif
+
+/* Disable some security warnings on MSVC */
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_WARNINGS
+#endif
+
+/* Assume that Windows versions are newer than Windows XP */
+#if defined(__MINGW32__) && (!defined(WINVER) || WINVER < 0x501)
+# undef WINVER
+# undef _WIN32_WINDOWS
+# undef _WIN32_WINNT
+# define WINVER 0x0600
+# define _WIN32_WINDOWS 0x0600
+# define _WIN32_WINNT 0x0600 //windows vista version, which included InepPton
+#endif
+
+#include <stdlib.h>
+#if defined(_WIN32) && !defined(__clang__)
+# include <malloc.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <winsock2.h>
+#include <windows.h>
+#include <ws2tcpip.h>
+
+#ifdef _MSC_VER
+# ifndef UNDER_CE
+#  include <io.h> //access
+#  define UA_access _access
+# endif
+#else
+# include <unistd.h> //access and tests
+# define UA_access access
+#endif
+
+#define ssize_t int
+#define OPTVAL_TYPE char
+#ifndef UA_sleep_ms
+# define UA_sleep_ms(X) Sleep(X)
+#else /* UA_sleep_ms */
+/* With this one can define its own UA_sleep_ms using a preprocessor define.
+E.g. see unit tests. */
+void UA_sleep_ms(size_t ms);
+#endif
+
+// Windows does not support ansi colors
+// #define UA_ENABLE_LOG_COLORS
+
+#define UA_IPV6 1
+
+#if defined(__MINGW32__) //mingw defines SOCKET as long long unsigned int, giving errors in logging and when comparing with UA_Int32
+# define UA_SOCKET int
+# define UA_INVALID_SOCKET -1
+#else
+# define UA_SOCKET SOCKET
+# define UA_INVALID_SOCKET INVALID_SOCKET
+#endif
+#define UA_ERRNO WSAGetLastError()
+#define UA_INTERRUPTED WSAEINTR
+#define UA_AGAIN WSAEWOULDBLOCK
+#define UA_EAGAIN EAGAIN
+#define UA_WOULDBLOCK WSAEWOULDBLOCK
+#define UA_ERR_CONNECTION_PROGRESS WSAEWOULDBLOCK
+
+#define UA_fd_set(fd, fds) FD_SET((UA_SOCKET)fd, fds)
+#define UA_fd_isset(fd, fds) FD_ISSET((UA_SOCKET)fd, fds)
+
+#ifdef UNDER_CE
+# define errno
+#endif
+
+#define UA_getnameinfo getnameinfo
+#define UA_send(sockfd, buf, len, flags) send(sockfd, buf, (int)(len), flags)
+#define UA_recv recv
+#define UA_sendto(sockfd, buf, len, flags, dest_addr, addrlen) sendto(sockfd, (const char*)(buf), (int)(len), flags, dest_addr, (int) (addrlen))
+#define UA_recvfrom(sockfd, buf, len, flags, src_addr, addrlen) recvfrom(sockfd, (char*)(buf), (int)(len), flags, src_addr, addrlen)
+#define UA_htonl htonl
+#define UA_ntohl ntohl
+#define UA_close closesocket
+#define UA_select(nfds, readfds, writefds, exceptfds, timeout) select((int)(nfds), readfds, writefds, exceptfds, timeout)
+#define UA_shutdown shutdown
+#define UA_socket socket
+#define UA_bind bind
+#define UA_listen listen
+#define UA_accept accept
+#define UA_connect(sockfd, addr, addrlen) connect(sockfd, addr, (int)(addrlen))
+#define UA_getaddrinfo getaddrinfo
+#define UA_getsockopt getsockopt
+#define UA_setsockopt(sockfd, level, optname, optval, optlen) setsockopt(sockfd, level, optname, (const char*) (optval), optlen)
+#define UA_freeaddrinfo freeaddrinfo
+#define UA_gethostname gethostname
+#define UA_inet_pton InetPton
+
+#if UA_IPV6
+# include <iphlpapi.h>
+# define UA_if_nametoindex if_nametoindex
+#endif
+
+#ifdef maxStringLength //defined in mingw64
+# undef maxStringLength
+#endif
+
+#define UA_free free
+#define UA_malloc malloc
+#define UA_calloc calloc
+#define UA_realloc realloc
+
+#define UA_snprintf(source, size, string, ...) _snprintf_s(source, size, _TRUNCATE, string, __VA_ARGS__)
+
+#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
+    char *errno_str = NULL; \
+    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, \
+    NULL, WSAGetLastError(), \
+    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \
+    (LPSTR)&errno_str, 0, NULL); \
+    LOG; \
+    LocalFree(errno_str); \
+}
+#define UA_LOG_SOCKET_ERRNO_GAI_WRAP UA_LOG_SOCKET_ERRNO_WRAP
+
+#include "../ua_architecture_functions.h"
+
+/* Fix redefinition of SLIST_ENTRY on mingw winnt.h */
+#ifdef SLIST_ENTRY
+# undef SLIST_ENTRY
+#endif
+
+#endif /* PLUGINS_ARCH_WIN32_UA_ARCHITECTURE_H_ */
+
+#endif /* UA_ARCHITECTURE_WIN32 */

+ 34 - 0
arch/win32/ua_architecture_functions.c

@@ -0,0 +1,34 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
+ *
+ *    Copyright 2018 (c) Jose Cabral, fortiss GmbH
+ */
+
+#ifdef UA_ARCHITECTURE_WIN32
+
+#include "ua_types.h"
+
+unsigned int UA_socket_set_blocking(UA_SOCKET sockfd){
+  u_long iMode = 0;
+  if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;;
+}
+
+unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd){
+  u_long iMode = 1;
+  if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;;
+}
+
+void UA_initialize_architecture_network(void){
+  WSADATA wsaData;
+  WSAStartup(MAKEWORD(2, 2), &wsaData);
+}
+
+void UA_deinitialize_architecture_network(void){
+  WSACleanup();
+}
+
+#endif /* UA_ARCHITECTURE_WIN32 */

+ 64 - 0
arch/win32/ua_clock.c

@@ -0,0 +1,64 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
+ *
+ *    Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
+ *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
+ *    Copyright 2017 (c) Thomas Stalder
+ */
+
+#ifdef UA_ARCHITECTURE_WIN32
+
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+#endif
+
+#include "ua_types.h"
+#include <time.h>
+/* Backup definition of SLIST_ENTRY on mingw winnt.h */
+# ifdef SLIST_ENTRY
+#  pragma push_macro("SLIST_ENTRY")
+#  undef SLIST_ENTRY
+#  define POP_SLIST_ENTRY
+# endif
+# include <windows.h>
+/* restore definition */
+# ifdef POP_SLIST_ENTRY
+#  undef SLIST_ENTRY
+#  undef POP_SLIST_ENTRY
+#  pragma pop_macro("SLIST_ENTRY")
+# endif
+
+UA_DateTime UA_DateTime_now(void) {
+    /* Windows filetime has the same definition as UA_DateTime */
+    FILETIME ft;
+    SYSTEMTIME st;
+    GetSystemTime(&st);
+    SystemTimeToFileTime(&st, &ft);
+    ULARGE_INTEGER ul;
+    ul.LowPart = ft.dwLowDateTime;
+    ul.HighPart = ft.dwHighDateTime;
+    return (UA_DateTime)ul.QuadPart;
+}
+
+/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
+UA_Int64 UA_DateTime_localTimeUtcOffset(void) {
+    time_t gmt, rawtime = time(NULL);
+
+    struct tm ptm;
+    gmtime_s(&ptm, &rawtime);
+    // Request that mktime() looksup dst in timezone database
+    ptm.tm_isdst = -1;
+    gmt = mktime(&ptm);
+
+    return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC);
+}
+
+UA_DateTime UA_DateTime_nowMonotonic(void) {
+    LARGE_INTEGER freq, ticks;
+    QueryPerformanceFrequency(&freq);
+    QueryPerformanceCounter(&ticks);
+    UA_Double ticks2dt = UA_DATETIME_SEC / (UA_Double)freq.QuadPart;
+    return (UA_DateTime)(ticks.QuadPart * ticks2dt);
+}
+
+#endif /* UA_ARCHITECTURE_WIN32 */

+ 0 - 5
deps/queue.h

@@ -99,11 +99,6 @@ struct name {								\
 #define	SLIST_HEAD_INITIALIZER(head)					\
     { NULL }
 
-/* Fix redefinition of SLIST_ENTRY on mingw winnt.h */
-# ifdef SLIST_ENTRY
-#  undef SLIST_ENTRY
-# endif
-
 #define SLIST_ENTRY(type)						\
 struct {								\
     struct type *sle_next;	/* next element */			\

+ 1 - 1
doc/building.rst

@@ -12,7 +12,7 @@ Using the GCC compiler, the following calls build the examples on Linux.
 
    cp /path-to/open62541.* . # copy single-file distribution to the local directory
    cp /path-to/examples/server_variable.c . # copy the example server
-   gcc -std=c99 open62541.c server_variable.c -o server
+   gcc -std=c99 -DUA_ARCHITECTURE_POSIX open62541.c server_variable.c -o server
 
 Building the Library
 --------------------

+ 0 - 8
examples/client_async.c

@@ -16,14 +16,6 @@
 #include <stdio.h>
 #include "open62541.h"
 
-#ifdef _WIN32
-# include <windows.h>
-# define UA_sleep_ms(X) Sleep(X)
-#else
-# include <unistd.h>
-# define UA_sleep_ms(X) usleep(X * 1000)
-#endif
-
 #define NODES_EXIST
 /* async connection callback, it only gets called after the completion of the whole
  * connection process*/

+ 0 - 21
examples/client_connect_loop.c

@@ -1,19 +1,6 @@
 /* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
  * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
 /**
  * Client disconnect handling
  * --------------------------
@@ -26,14 +13,6 @@
 #include "open62541.h"
 #include <signal.h>
 
-#ifdef _WIN32
-# include <windows.h>
-# define UA_sleep_ms(X) Sleep(X)
-#else
-# include <unistd.h>
-# define UA_sleep_ms(X) usleep(X * 1000)
-#endif
-
 UA_Boolean running = true;
 UA_Logger logger = UA_Log_Stdout;
 

+ 0 - 21
examples/client_connectivitycheck_loop.c

@@ -1,30 +1,9 @@
 /* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
  * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
 #include "open62541.h"
 #include <signal.h>
 
-#ifdef _WIN32
-# include <windows.h>
-# define UA_sleep_ms(X) Sleep(X)
-#else
-# include <unistd.h>
-# define UA_sleep_ms(X) usleep(X * 1000)
-#endif
-
 UA_Boolean running = true;
 UA_Logger logger = UA_Log_Stdout;
 

+ 0 - 21
examples/client_subscription_loop.c

@@ -1,19 +1,6 @@
 /* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
  * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
 /**
  * Client disconnect handling
  * --------------------------
@@ -26,14 +13,6 @@
 #include "open62541.h"
 #include <signal.h>
 
-#ifdef _WIN32
-# include <windows.h>
-# define UA_sleep_ms(X) Sleep(X)
-#else
-# include <unistd.h>
-# define UA_sleep_ms(X) usleep(X * 1000)
-#endif
-
 UA_Boolean running = true;
 UA_Logger logger = UA_Log_Stdout;
 

+ 2 - 10
examples/server_ctt.c

@@ -251,11 +251,7 @@ setInformationModel(UA_Server *server) {
         attr.dataType = UA_TYPES[type].typeId;
 #ifndef UA_ENABLE_TYPENAMES
         char name[15];
-#if defined(_WIN32) && !defined(__MINGW32__)
-        sprintf_s(name, 15, "%02d", type);
-#else
-        sprintf(name, "%02d", type);
-#endif
+        UA_snprintf(name, 15, "%02d", type);
         attr.displayName = UA_LOCALIZEDTEXT("en-US", name);
         UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME(1, name);
 #else
@@ -320,11 +316,7 @@ setInformationModel(UA_Server *server) {
     id = DEPTHID; // running id in namespace 0 - Start with Matrix NODE
     for(UA_UInt32 i = 1; i <= 20; i++) {
         char name[15];
-#if defined(_WIN32) && !defined(__MINGW32__)
-        sprintf_s(name, 15, "depth%i", i);
-#else
-        sprintf(name, "depth%i", i);
-#endif
+        UA_snprintf(name, 15, "depth%i", i);
         object_attr.description = UA_LOCALIZEDTEXT("en-US", name);
         object_attr.displayName = UA_LOCALIZEDTEXT("en-US", name);
         UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, id + i),

+ 1 - 6
examples/server_mainloop.c

@@ -3,13 +3,8 @@
  * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
  */
 
+#include "open62541.h"
 #include <signal.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#else
-# include <sys/select.h>
-#endif
-# include "open62541.h"
 
 UA_Boolean running = true;
 static void stopHandler(int sign) {

+ 2 - 46
include/ua_config.h.in

@@ -59,6 +59,8 @@ extern "C" {
 #cmakedefine UA_DEBUG
 #cmakedefine UA_DEBUG_DUMP_PKGS
 
+#include "ua_architecture.h"
+
 /**
  * C99 Definitions
  * --------------- */
@@ -69,9 +71,6 @@ extern "C" {
 #if !defined(_MSC_VER) || _MSC_VER >= 1600
 # include <stdint.h>
 # include <stdbool.h> /* C99 Boolean */
-# if defined(_WRS_KERNEL)
-# define UINT32_C(x) ((x) + (UINT32_MAX - UINT32_MAX)) 
-# endif
 #else
 # include "ms_stdint.h"
 # if !defined(__bool_true_false_are_defined)
@@ -117,49 +116,6 @@ extern "C" {
 # define UA_STATIC_ASSERT(cond,msg) typedef char static_assertion_##msg[(cond)?1:-1]
 #endif
 
-/**
- * Memory Management
- * -----------------
- * The default is to use the malloc implementation from ``stdlib.h``. Override
- * if required. Changing the settings has no effect on a pre-compiled
- * library. */
-#include <stdlib.h>
-#if defined(_WIN32) && !defined(__clang__)
-# include <malloc.h>
-#endif
-
-#if !defined(UA_FREERTOS)
-
-# define UA_free(ptr) free(ptr)
-# define UA_malloc(size) malloc(size)
-# define UA_calloc(num, size) calloc(num, size)
-# define UA_realloc(ptr, size) realloc(ptr, size)
-
-#else
-
-# include <FreeRTOS.h>
-
-# define UA_free(ptr) vPortFree(ptr)
-# define UA_malloc(size) pvPortMalloc(size)
-# define UA_calloc(num, size) pvPortCalloc(num, size)
-# define UA_realloc(ptr, size) pvPortRealloc(ptr, size)
-
-#endif
-
-/* Stack-allocation of memory. Use C99 variable-length arrays if possible.
- * Otherwise revert to alloca. Note that alloca is not supported on some
- * plattforms. */
-#if defined(__GNUC__) || defined(__clang__)
-# define UA_STACKARRAY(TYPE, NAME, SIZE) TYPE NAME[SIZE]
-#elif defined(_WIN32)
-# define UA_STACKARRAY(TYPE, NAME, SIZE) \
-    TYPE *NAME = (TYPE*)_alloca(sizeof(TYPE) * SIZE)
-#else
-# include <alloca.h>
-# define UA_STACKARRAY(TYPE, NAME, SIZE) \
-    TYPE *NAME = (TYPE*)alloca(sizeof(TYPE) * SIZE)
-#endif
-
 /**
  * Function Export
  * ---------------

+ 1 - 1
include/ua_plugin_network.h

@@ -66,7 +66,7 @@ struct UA_Connection {
     UA_ConnectionConfig remoteConf;
     UA_SecureChannel *channel;       /* The securechannel that is attached to
                                       * this connection */
-    UA_Int32 sockfd;                 /* Most connectivity solutions run on
+    UA_SOCKET sockfd;                 /* Most connectivity solutions run on
                                       * sockets. Having the socket id here
                                       * simplifies the design. */
     UA_DateTime openingDate;         /* The date the connection was created */

+ 1 - 1
include/ua_plugin_pubsub.h

@@ -49,7 +49,7 @@ struct UA_PubSubChannel{
     UA_UInt32 publisherId;                                  // unique identifier
     UA_PubSubChannelState state;
     UA_PubSubConnectionConfig *connectionConfig;            //link to parent connection config
-    UA_Int32 sockfd;
+    UA_SOCKET sockfd;
     void *handle;                                           //implementation specific data
     /*@info for handle: each network implementation should provide an structure
     * UA_PubSubChannelData[ImplementationName] This structure can be used by the

+ 0 - 10
include/ua_util.h

@@ -50,16 +50,6 @@ UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname,
 #define UA_PRINTF_STRING_FORMAT "\"%.*s\""
 #define UA_PRINTF_STRING_DATA(STRING) (int)(STRING).length, (STRING).data
 
-//TODO remove when we merge architectures pull request
-#ifndef UA_snprintf
-# include <stdio.h>
-# if defined(_WIN32)
-#  define UA_snprintf(source, size, string, ...) _snprintf_s(source, size, _TRUNCATE, string, __VA_ARGS__)
-# else
-#  define UA_snprintf snprintf
-# endif
-#endif
-
 /**
  * Helper functions for converting data types
  * ------------------------------------ */

+ 0 - 126
plugins/ua_clock.c

@@ -1,126 +0,0 @@
-/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
- * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
- *
- *    Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
- *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
- *    Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
- */
-
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
-#include <time.h>
-#ifdef _WIN32
-/* Backup definition of SLIST_ENTRY on mingw winnt.h */
-# ifdef SLIST_ENTRY
-#  pragma push_macro("SLIST_ENTRY")
-#  undef SLIST_ENTRY
-#  define POP_SLIST_ENTRY
-# endif
-# include <windows.h>
-/* restore definition */
-# ifdef POP_SLIST_ENTRY
-#  undef SLIST_ENTRY
-#  undef POP_SLIST_ENTRY
-#  pragma pop_macro("SLIST_ENTRY")
-# endif
-#else
-# include <sys/time.h>
-#endif
-
-#if defined(__APPLE__) || defined(__MACH__)
-# include <mach/clock.h>
-# include <mach/mach.h>
-#endif
-
-#include "ua_types.h"
-
-#if defined(UA_FREERTOS)
-#include <task.h>
-#endif
-
-UA_DateTime UA_DateTime_now(void) {
-#if defined(_WIN32)
-    /* Windows filetime has the same definition as UA_DateTime */
-    FILETIME ft;
-    SYSTEMTIME st;
-    GetSystemTime(&st);
-    SystemTimeToFileTime(&st, &ft);
-    ULARGE_INTEGER ul;
-    ul.LowPart = ft.dwLowDateTime;
-    ul.HighPart = ft.dwHighDateTime;
-    return (UA_DateTime)ul.QuadPart;
-#else
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return (tv.tv_sec * UA_DATETIME_SEC) + (tv.tv_usec * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH;
-#endif
-}
-
-/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
-UA_Int64 UA_DateTime_localTimeUtcOffset(void) {
-    time_t gmt, rawtime = time(NULL);
-
-#ifdef _WIN32
-    struct tm ptm;
-    gmtime_s(&ptm, &rawtime);
-    // Request that mktime() looksup dst in timezone database
-    ptm.tm_isdst = -1;
-    gmt = mktime(&ptm);
-#else
-    struct tm *ptm;
-    struct tm gbuf;
-    ptm = gmtime_r(&rawtime, &gbuf);
-    // Request that mktime() looksup dst in timezone database
-    ptm->tm_isdst = -1;
-    gmt = mktime(ptm);
-#endif
-
-    return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC);
-}
-
-UA_DateTime UA_DateTime_nowMonotonic(void) {
-#if defined(_WIN32)
-    LARGE_INTEGER freq, ticks;
-    QueryPerformanceFrequency(&freq);
-    QueryPerformanceCounter(&ticks);
-    UA_Double ticks2dt = UA_DATETIME_SEC / (UA_Double)freq.QuadPart;
-    return (UA_DateTime)(ticks.QuadPart * ticks2dt);
-#elif defined(__APPLE__) || defined(__MACH__)
-    /* OS X does not have clock_gettime, use clock_get_time */
-    clock_serv_t cclock;
-    mach_timespec_t mts;
-    host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
-    clock_get_time(cclock, &mts);
-    mach_port_deallocate(mach_task_self(), cclock);
-    return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100);
-#elif !defined(CLOCK_MONOTONIC_RAW)
-# if defined(UA_FREERTOS)
-    portTickType TaskTime = xTaskGetTickCount();
-    UA_DateTimeStruct UATime;
-    UATime.milliSec = (UA_UInt16) TaskTime;
-    struct timespec ts;
-    ts.tv_sec = UATime.milliSec/1000;
-    ts.tv_nsec = (UATime.milliSec % 1000)* 1000000;
-    return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
-# else
-    struct timespec ts;
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-    return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
-# endif
-#else
-    struct timespec ts;
-    clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
-    return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
-#endif
-}

+ 16 - 8
plugins/ua_config_default.c

@@ -309,23 +309,31 @@ createDefaultConfig(void) {
 }
 
 static UA_StatusCode
-addDefaultNetworkLayers(UA_ServerConfig *conf, UA_UInt16 portNumber) {
+addDefaultNetworkLayers(UA_ServerConfig *conf, UA_UInt16 portNumber, UA_UInt32 sendBufferSize, UA_UInt32 recvBufferSize) {
     /* Add a network layer */
     conf->networkLayers = (UA_ServerNetworkLayer *)
         UA_malloc(sizeof(UA_ServerNetworkLayer));
     if(!conf->networkLayers)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
+    UA_ConnectionConfig config = UA_ConnectionConfig_default;
+    if (sendBufferSize > 0)
+        config.sendBufferSize = sendBufferSize;
+    if (recvBufferSize > 0)
+        config.recvBufferSize = recvBufferSize;
+
     conf->networkLayers[0] =
-        UA_ServerNetworkLayerTCP(UA_ConnectionConfig_default, portNumber, conf->logger);
+        UA_ServerNetworkLayerTCP(config, portNumber, conf->logger);
     conf->networkLayersSize = 1;
 
     return UA_STATUSCODE_GOOD;
 }
 
 UA_ServerConfig *
-UA_ServerConfig_new_minimal(UA_UInt16 portNumber,
-                            const UA_ByteString *certificate) {
+UA_ServerConfig_new_customBuffer(UA_UInt16 portNumber,
+                                 const UA_ByteString *certificate,
+                                 UA_UInt32 sendBufferSize,
+                                 UA_UInt32 recvBufferSize) {
     UA_ServerConfig *conf = createDefaultConfig();
 
     UA_StatusCode retval = UA_Nodestore_default_new(&conf->nodestore);
@@ -334,7 +342,7 @@ UA_ServerConfig_new_minimal(UA_UInt16 portNumber,
         return NULL;
     }
 
-    if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) {
+    if(addDefaultNetworkLayers(conf, portNumber, sendBufferSize, recvBufferSize) != UA_STATUSCODE_GOOD) {
         UA_ServerConfig_delete(conf);
         return NULL;
     }
@@ -387,7 +395,7 @@ UA_ServerConfig_new_basic128rsa15(UA_UInt16 portNumber,
         return NULL;
     }
 
-    if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) {
+    if(addDefaultNetworkLayers(conf, portNumber, 0, 0) != UA_STATUSCODE_GOOD) {
         UA_ServerConfig_delete(conf);
         return NULL;
     }
@@ -457,7 +465,7 @@ UA_ServerConfig_new_basic256sha256(UA_UInt16 portNumber,
         return NULL;
     }
 
-    if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) {
+    if(addDefaultNetworkLayers(conf, portNumber, 0, 0) != UA_STATUSCODE_GOOD) {
         UA_ServerConfig_delete(conf);
         return NULL;
     }
@@ -527,7 +535,7 @@ UA_ServerConfig_new_allSecurityPolicies(UA_UInt16 portNumber,
         return NULL;
     }
 
-    if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) {
+    if(addDefaultNetworkLayers(conf, portNumber, 0, 0) != UA_STATUSCODE_GOOD) {
         UA_ServerConfig_delete(conf);
         return NULL;
     }

+ 23 - 2
plugins/ua_config_default.h

@@ -27,6 +27,25 @@ extern const UA_EXPORT UA_ConnectionConfig UA_ConnectionConfig_default;
 /* Default Server Config */
 /*************************/
 
+
+
+/* Creates a new server config with one endpoint and custom buffer size.
+ *
+ * The config will set the tcp network layer to the given port and adds a single
+ * endpoint with the security policy ``SecurityPolicy#None`` to the server. A
+ * server certificate may be supplied but is optional.
+ * Additionally you can define a custom buffer size for send and receive buffer.
+ *
+ * @param portNumber The port number for the tcp network layer
+ * @param certificate Optional certificate for the server endpoint. Can be
+ *        ``NULL``.
+ * @param sendBufferSize The size in bytes for the network send buffer
+ * @param recvBufferSize The size in bytes for the network receive buffer
+ *
+ */
+UA_EXPORT UA_ServerConfig *
+UA_ServerConfig_new_customBuffer(UA_UInt16 portNumber, const UA_ByteString *certificate, UA_UInt32 sendBufferSize, UA_UInt32 recvBufferSize);
+
 /* Creates a new server config with one endpoint.
  * 
  * The config will set the tcp network layer to the given port and adds a single
@@ -36,8 +55,10 @@ extern const UA_EXPORT UA_ConnectionConfig UA_ConnectionConfig_default;
  * @param portNumber The port number for the tcp network layer
  * @param certificate Optional certificate for the server endpoint. Can be
  *        ``NULL``. */
-UA_EXPORT UA_ServerConfig *
-UA_ServerConfig_new_minimal(UA_UInt16 portNumber, const UA_ByteString *certificate);
+static UA_INLINE UA_ServerConfig *
+UA_ServerConfig_new_minimal(UA_UInt16 portNumber, const UA_ByteString *certificate) {
+    return UA_ServerConfig_new_customBuffer(portNumber, certificate, 0 ,0);
+}
 
 #ifdef UA_ENABLE_ENCRYPTION
 

+ 0 - 37
plugins/ua_log_socket_error.h

@@ -1,37 +0,0 @@
-/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
- * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. 
- *
- *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
- */
-
-#ifndef UA_LOG_SOCKET_ERROR_H_
-#define UA_LOG_SOCKET_ERROR_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef _WIN32
-#include <winsock2.h>
-#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
-    char *errno_str = NULL; \
-    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, \
-    NULL, WSAGetLastError(), \
-    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \
-    (LPSTR)&errno_str, 0, NULL); \
-    LOG; \
-    LocalFree(errno_str); \
-}
-#else
-#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
-    char *errno_str = strerror(errno); \
-    LOG; \
-}
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* UA_LOG_SOCKET_ERROR_H_ */

+ 9 - 9
plugins/ua_log_stdout.c

@@ -13,15 +13,7 @@
 /* ANSI escape sequences for color output taken from here:
  * https://stackoverflow.com/questions/3219393/stdlib-and-colored-output-in-c*/
 
-#ifdef _WIN32
-# define ANSI_COLOR_RED     ""
-# define ANSI_COLOR_GREEN   ""
-# define ANSI_COLOR_YELLOW  ""
-# define ANSI_COLOR_BLUE    ""
-# define ANSI_COLOR_MAGENTA ""
-# define ANSI_COLOR_CYAN    ""
-# define ANSI_COLOR_RESET   ""
-#else
+#ifdef UA_ENABLE_LOG_COLORS
 # define ANSI_COLOR_RED     "\x1b[31m"
 # define ANSI_COLOR_GREEN   "\x1b[32m"
 # define ANSI_COLOR_YELLOW  "\x1b[33m"
@@ -29,6 +21,14 @@
 # define ANSI_COLOR_MAGENTA "\x1b[35m"
 # define ANSI_COLOR_CYAN    "\x1b[36m"
 # define ANSI_COLOR_RESET   "\x1b[0m"
+#else
+# define ANSI_COLOR_RED     ""
+# define ANSI_COLOR_GREEN   ""
+# define ANSI_COLOR_YELLOW  ""
+# define ANSI_COLOR_BLUE    ""
+# define ANSI_COLOR_MAGENTA ""
+# define ANSI_COLOR_CYAN    ""
+# define ANSI_COLOR_RESET   ""
 #endif
 
 #ifdef UA_ENABLE_MULTITHREADING

+ 76 - 95
plugins/ua_network_pubsub_udp.c

@@ -3,58 +3,9 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner)
+ * Copyright 2018 (c) Jose Cabral, fortiss GmbH
  */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
- /* Disable some security warnings on MSVC */
-#ifdef _MSC_VER
-# define _CRT_SECURE_NO_WARNINGS
-#endif
-
- /* Assume that Windows versions are newer than Windows XP */
-#if defined(__MINGW32__) && (!defined(WINVER) || WINVER < 0x501)
-# undef WINVER
-# undef _WIN32_WINDOWS
-# undef _WIN32_WINNT
-# define WINVER 0x0501
-# define _WIN32_WINDOWS 0x0501
-# define _WIN32_WINNT 0x0501
-#endif
-
-#ifdef _WIN32
-# include <winsock2.h>
-# include <ws2tcpip.h>
-# include <Iphlpapi.h>
-# define CLOSESOCKET(S) closesocket((SOCKET)S)
-# define ssize_t int
-# define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds)
-# define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds)
-#else /* _WIN32 */
-#  define CLOSESOCKET(S) close(S)
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-# define UA_fd_set(fd, fds) FD_SET(fd, fds)
-# define UA_fd_isset(fd, fds) FD_ISSET(fd, fds)
-# endif /* Not Windows */
-
-#include <stdio.h>
 #include "ua_plugin_network.h"
 #include "ua_network_pubsub_udp.h"
 #include "ua_util.h"
@@ -78,10 +29,7 @@ typedef struct {
  */
 static UA_PubSubChannel *
 UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
-    #ifdef _WIN32
-        WSADATA wsaData;
-        WSAStartup(MAKEWORD(2, 2), &wsaData);
-    #endif /* Not Windows */
+    UA_initialize_architecture_network();
 
     UA_NetworkAddressUrlDataType address;
     if(UA_Variant_hasScalarType(&connectionConfig->address, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE])){
@@ -155,7 +103,7 @@ UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
     char port[6];
     sprintf(port, "%u", networkPort);
 
-    if(getaddrinfo(addressAsChar, port, &hints, &requestResult) != 0) {
+    if(UA_getaddrinfo(addressAsChar, port, &hints, &requestResult) != 0) {
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
                      "PubSub Connection creation failed. Internal error.");
         UA_free(channelDataUDPMC);
@@ -166,11 +114,11 @@ UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
     //check if the ip address is a multicast address
     if(requestResult->ai_family == PF_INET){
         struct in_addr imr_interface;
-        inet_pton(AF_INET, addressAsChar, &imr_interface);
-        if((ntohl(imr_interface.s_addr) & 0xF0000000) != 0xE0000000){
+        UA_inet_pton(AF_INET, addressAsChar, &imr_interface);
+        if((UA_ntohl(imr_interface.s_addr) & 0xF0000000) != 0xE0000000){
             UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
                          "PubSub Connection creation failed. No multicast address.");
-            freeaddrinfo(requestResult);
+            UA_freeaddrinfo(requestResult);
             UA_free(channelDataUDPMC);
             UA_free(newChannel);
             return NULL;
@@ -180,15 +128,15 @@ UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
     }
 
     for(rp = requestResult; rp != NULL; rp = rp->ai_next){
-        newChannel->sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
-        if(newChannel->sockfd != -1){
+        newChannel->sockfd = UA_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+        if(newChannel->sockfd != UA_INVALID_SOCKET){
             break; /*success*/
         }
     }
     if(!rp){
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
                      "PubSub Connection creation failed. Internal error.");
-        freeaddrinfo(requestResult);
+        UA_freeaddrinfo(requestResult);
         UA_free(channelDataUDPMC);
         UA_free(newChannel);
         return NULL;
@@ -198,8 +146,8 @@ UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
     if(!channelDataUDPMC->ai_addr){
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
                      "PubSub Connection creation failed. Out of memory.");
-        CLOSESOCKET(newChannel->sockfd);
-        freeaddrinfo(requestResult);
+        UA_close(newChannel->sockfd);
+        UA_freeaddrinfo(requestResult);
         UA_free(channelDataUDPMC);
         UA_free(newChannel);
         return NULL;
@@ -209,24 +157,41 @@ UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
     newChannel->handle = channelDataUDPMC;
 
     //Set loop back data to your host
-    if(setsockopt(newChannel->sockfd,
-                     requestResult->ai_family == PF_INET6 ? IPPROTO_IPV6:IPPROTO_IP,
+#if UA_IPV6
+    if(UA_setsockopt(newChannel->sockfd,
+                     requestResult->ai_family == PF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP,
                      requestResult->ai_family == PF_INET6 ? IPV6_MULTICAST_LOOP : IP_MULTICAST_LOOP,
-                     (const char *)&channelDataUDPMC->enableLoopback, sizeof (channelDataUDPMC->enableLoopback)) < 0) {
+                     (const char *)&channelDataUDPMC->enableLoopback, sizeof (channelDataUDPMC->enableLoopback))
+#else
+    if(UA_setsockopt(newChannel->sockfd,
+                     IPPROTO_IP,
+                     IP_MULTICAST_LOOP,
+                     (const char *)&channelDataUDPMC->enableLoopback, sizeof (channelDataUDPMC->enableLoopback))
+#endif
+                      < 0) {
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
                      "PubSub Connection creation failed. Loopback setup failed.");
-        CLOSESOCKET(newChannel->sockfd);
-        freeaddrinfo(requestResult);
+        UA_close(newChannel->sockfd);
+        UA_freeaddrinfo(requestResult);
         UA_free(channelDataUDPMC);
         UA_free(newChannel);
         return NULL;
     }
 
     //Set Time to live (TTL). Value of 1 prevent forward beyond the local network.
-    if(setsockopt(newChannel->sockfd,
-                  requestResult->ai_family == PF_INET6 ? IPPROTO_IPV6:IPPROTO_IP,
-                  requestResult->ai_family == PF_INET6 ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL,
-                  (const char *)&channelDataUDPMC->messageTTL, sizeof(channelDataUDPMC->messageTTL)) < 0) {
+#if UA_IPV6
+    if(UA_setsockopt(newChannel->sockfd,
+                     requestResult->ai_family == PF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP,
+                     requestResult->ai_family == PF_INET6 ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL,
+                     (const char *)&channelDataUDPMC->messageTTL, sizeof(channelDataUDPMC->messageTTL))
+#else
+    if(UA_setsockopt(newChannel->sockfd,
+                     IPPROTO_IP,
+                     IP_MULTICAST_TTL,
+                     (const char *)&channelDataUDPMC->messageTTL, sizeof(channelDataUDPMC->messageTTL))
+#endif
+
+                      < 0) {
         UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
                      "PubSub Connection creation problem. Time to live setup failed.");
     }
@@ -234,7 +199,7 @@ UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
     //Set reuse address -> enables sharing of the same listening address on different sockets.
     if(channelDataUDPMC->enableReuse){
         int enableReuse = 1;
-        if(setsockopt(newChannel->sockfd,
+        if(UA_setsockopt(newChannel->sockfd,
                       SOL_SOCKET, SO_REUSEADDR,
                       (const char*)&enableReuse, sizeof(enableReuse)) < 0){
             UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
@@ -249,32 +214,47 @@ UA_PubSubChannelUDPMC_open(const UA_PubSubConnectionConfig *connectionConfig) {
         interfaceAsChar[address.networkInterface.length] = 0;
         enum{
             IPv4,
+#if UA_IPV6
             IPv6,
+#endif
             INVALID
         } ipVersion;
         union {
             struct ip_mreq ipv4;
+#if UA_IPV6
             struct ipv6_mreq ipv6;
+#endif
         } group;
-        if(inet_pton(AF_INET, interfaceAsChar, &group.ipv4.imr_interface)){
+        if(UA_inet_pton(AF_INET, interfaceAsChar, &group.ipv4.imr_interface)){
             ipVersion = IPv4;
-        } else if (inet_pton(AF_INET6, interfaceAsChar, &group.ipv6.ipv6mr_multiaddr)){
-            group.ipv6.ipv6mr_interface = if_nametoindex(interfaceAsChar);
+#if UA_IPV6
+        } else if (UA_inet_pton(AF_INET6, interfaceAsChar, &group.ipv6.ipv6mr_multiaddr)){
+            group.ipv6.ipv6mr_interface = UA_if_nametoindex(interfaceAsChar);
             ipVersion = IPv6;
+#endif
         } else {
             ipVersion = INVALID;
         }
         if(ipVersion == INVALID ||
-                setsockopt(newChannel->sockfd,
+#if UA_IPV6
+                UA_setsockopt(newChannel->sockfd,
                            requestResult->ai_family == PF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP,
                            requestResult->ai_family == PF_INET6 ? IPV6_MULTICAST_IF : IP_MULTICAST_IF,
-                           ipVersion == IPv6 ? (void *) &group.ipv6.ipv6mr_interface : &group.ipv4.imr_interface,
-                           ipVersion == IPv6 ? sizeof(group.ipv6.ipv6mr_interface) : sizeof(struct in_addr)) < 0){
+                           ipVersion == IPv6 ? (const void *) &group.ipv6.ipv6mr_interface : &group.ipv4.imr_interface,
+                           ipVersion == IPv6 ? sizeof(group.ipv6.ipv6mr_interface) : sizeof(struct in_addr))
+#else
+                UA_setsockopt(newChannel->sockfd,
+                           IPPROTO_IP,
+                           IP_MULTICAST_IF,
+                           &group.ipv4.imr_interface,
+                           sizeof(struct in_addr))
+#endif
+                                                         < 0) {
             UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
                            "PubSub Connection creation problem. Interface selection failed.");
         };
     }
-    freeaddrinfo(requestResult);
+    UA_freeaddrinfo(requestResult);
     newChannel->state = UA_PUBSUB_CHANNEL_PUB;
     return newChannel;
 }
@@ -295,22 +275,23 @@ UA_PubSubChannelUDPMC_regist(UA_PubSubChannel *channel, UA_ExtensionObject *tran
         struct sockaddr_in addr;
         memcpy(&addr, connectionConfig->ai_addr, sizeof(struct sockaddr_in));
         addr.sin_addr.s_addr = INADDR_ANY;
-        if (bind(channel->sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0){
+        if (UA_bind(channel->sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0){
             UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection regist failed.");
             return UA_STATUSCODE_BADINTERNALERROR;
         }
         struct ip_mreq groupV4;
         memcpy(&groupV4.imr_multiaddr, &((const struct sockaddr_in *)connectionConfig->ai_addr)->sin_addr, sizeof(struct ip_mreq));
-        groupV4.imr_interface.s_addr = htonl(INADDR_ANY);
+        groupV4.imr_interface.s_addr = UA_htonl(INADDR_ANY);
         //multihomed hosts can join several groups on different IF, INADDR_ANY -> kernel decides
 
-        if(setsockopt(channel->sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &groupV4, sizeof(groupV4)) != 0){
+        if(UA_setsockopt(channel->sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &groupV4, sizeof(groupV4)) != 0){
             UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection regist failed.");
             return UA_STATUSCODE_BADINTERNALERROR;
         }
-
+#if UA_IPV6
     } else if (connectionConfig->ai_family == PF_INET6) {//IPv6 handling
         //TODO implement regist for IPv6
+#endif
     } else {
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection regist failed.");
         return UA_STATUSCODE_BADINTERNALERROR;
@@ -333,14 +314,16 @@ UA_PubSubChannelUDPMC_unregist(UA_PubSubChannel *channel, UA_ExtensionObject *tr
     if(connectionConfig->ai_family == PF_INET){//IPv4 handling
         struct ip_mreq groupV4;
         memcpy(&groupV4.imr_multiaddr, &((const struct sockaddr_in *)connectionConfig->ai_addr)->sin_addr, sizeof(struct ip_mreq));
-        groupV4.imr_interface.s_addr = htonl(INADDR_ANY);
+        groupV4.imr_interface.s_addr = UA_htonl(INADDR_ANY);
 
-        if(setsockopt(channel->sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &groupV4, sizeof(groupV4)) != 0){
+        if(UA_setsockopt(channel->sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &groupV4, sizeof(groupV4)) != 0){
             UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection unregist failed.");
             return UA_STATUSCODE_BADINTERNALERROR;
         }
+#if UA_IPV6
     } else if (connectionConfig->ai_family == PF_INET6) {//IPv6 handling
         //TODO implement unregist for IPv6
+#endif
     } else {
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection unregist failed.");
         return UA_STATUSCODE_BADINTERNALERROR;
@@ -363,7 +346,7 @@ UA_PubSubChannelUDPMC_send(UA_PubSubChannel *channel, UA_ExtensionObject *transp
     //TODO evalute: chunk messages or check against MTU?
     long nWritten = 0;
     while (nWritten < (long)buf->length) {
-        long n = sendto(channel->sockfd, buf->data, buf->length, 0,
+        long n = (long)UA_sendto(channel->sockfd, buf->data, buf->length, 0,
                         (struct sockaddr *) channelConfigUDPMC->ai_addr, sizeof(struct sockaddr_storage));
         if(n == -1L) {
             UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection sending failed.");
@@ -394,7 +377,7 @@ UA_PubSubChannelUDPMC_receive(UA_PubSubChannel *channel, UA_ByteString *message,
         UA_fd_set(channel->sockfd, &fdset);
         struct timeval tmptv = {(long int)(timeout / 1000000),
                                 (long int)(timeout % 1000000)};
-        int resultsize = select(channel->sockfd+1, &fdset, NULL,
+        int resultsize = UA_select(channel->sockfd+1, &fdset, NULL,
                                 NULL, &tmptv);
         if(resultsize == 0) {
             message->length = 0;
@@ -408,14 +391,16 @@ UA_PubSubChannelUDPMC_receive(UA_PubSubChannel *channel, UA_ByteString *message,
 
     if(channelConfigUDPMC->ai_family == PF_INET){
         ssize_t messageLength;
-        messageLength = recvfrom(channel->sockfd, message->data, message->length, 0, NULL, NULL);
+        messageLength = UA_recvfrom(channel->sockfd, message->data, message->length, 0, NULL, NULL);
         if(messageLength > 0){
             message->length = (size_t) messageLength;
         } else {
             message->length = 0;
         }
+#if UA_IPV6
     } else {
         //TODO implement recieve for IPv6
+#endif
     }
     return UA_STATUSCODE_GOOD;
 }
@@ -427,10 +412,8 @@ UA_PubSubChannelUDPMC_receive(UA_PubSubChannel *channel, UA_ByteString *message,
  */
 static UA_StatusCode
 UA_PubSubChannelUDPMC_close(UA_PubSubChannel *channel) {
-#ifdef _WIN32
-    WSACleanup();
-#endif /* Not Windows */
-    if(CLOSESOCKET(channel->sockfd) != 0){
+    UA_deinitialize_architecture_network();
+    if(UA_close(channel->sockfd) != 0){
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "PubSub Connection delete failed.");
         return UA_STATUSCODE_BADINTERNALERROR;
     }
@@ -471,5 +454,3 @@ UA_PubSubTransportLayerUDPMP() {
     pubSubTransportLayer.createPubSubChannel = &TransportLayerUDPMC_addChannel;
     return pubSubTransportLayer;
 }
-
-#undef _POSIX_C_SOURCE

+ 1 - 1
src/client/ua_client_internal.h

@@ -16,8 +16,8 @@
 #include "ua_securechannel.h"
 #include "ua_client_highlevel.h"
 #include "ua_client_subscriptions.h"
-#include "../../deps/queue.h"
 #include "ua_timer.h"
+#include "../../deps/queue.h"
 
 /**************************/
 /* Subscriptions Handling */

+ 1 - 1
src/pubsub/ua_pubsub.h

@@ -12,11 +12,11 @@
 extern "C" {
 #endif
 
-#include "../deps/queue.h"
 #include "ua_plugin_pubsub.h"
 #include "ua_pubsub_networkmessage.h"
 #include "ua_server.h"
 #include "ua_server_pubsub.h"
+#include "../deps/queue.h"
 
 #ifdef UA_ENABLE_PUBSUB /* conditional compilation */
 

+ 1 - 1
src/pubsub/ua_pubsub_manager.c

@@ -197,7 +197,7 @@ UA_Server_addPublishedDataSet(UA_Server *server, const UA_PublishedDataSetConfig
 }
 
 UA_StatusCode
-UA_Server_removePublishedDataSet(UA_Server *server, UA_NodeId pds) {
+UA_Server_removePublishedDataSet(UA_Server *server, const UA_NodeId pds) {
     //search the identified PublishedDataSet and store the PDS index
     UA_PublishedDataSet *publishedDataSet = NULL;
     size_t publishedDataSetIndex;

+ 1 - 20
src/server/ua_mdns.c

@@ -6,19 +6,6 @@
  *    Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
  */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
 #include "ua_server_internal.h"
 #include "ua_mdns_internal.h"
 #include "ua_util.h"
@@ -246,14 +233,8 @@ setSrv(UA_Server *server, const struct resource *r,
 
     // todo: malloc may fail: return a statuscode
     char *newUrl = (char*)UA_malloc(10 + srvNameLen + 8);
-    #ifndef _MSC_VER
-    snprintf(newUrl, 10 + srvNameLen + 8, "opc.tcp://%.*s:%d/", (int) srvNameLen,
-             r->known.srv.name, r->known.srv.port);
-    #else
-    _snprintf_s(newUrl, 10 + srvNameLen + 8, _TRUNCATE, "opc.tcp://%.*s:%d/", (int) srvNameLen,
+    UA_snprintf(newUrl, 10 + srvNameLen + 8, "opc.tcp://%.*s:%d/", (int) srvNameLen,
              r->known.srv.name, r->known.srv.port);
-    #endif
-
     UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER,
                 "Multicast DNS: found server: %s", newUrl);
     entry->serverOnNetwork.discoveryUrl = UA_String_fromChars(newUrl);

+ 1 - 5
src/server/ua_server.c

@@ -279,11 +279,7 @@ UA_Server_new(const UA_ServerConfig *config) {
     /* Initialize multicast discovery */
 #if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST)
     server->mdnsDaemon = NULL;
-#ifdef _WIN32
-    server->mdnsSocket = INVALID_SOCKET;
-#else
-    server->mdnsSocket = -1;
-#endif
+    server->mdnsSocket = UA_INVALID_SOCKET;
     server->mdnsMainSrvAdded = UA_FALSE;
     if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER)
         initMulticastDiscoveryServer(server);

+ 1 - 5
src/server/ua_server_internal.h

@@ -112,11 +112,7 @@ struct UA_Server {
     void* registerServerCallbackData;
 # ifdef UA_ENABLE_DISCOVERY_MULTICAST
     mdns_daemon_t *mdnsDaemon;
-#ifdef _WIN32
-    SOCKET mdnsSocket;
-#else
-    int mdnsSocket;
-#endif
+    UA_SOCKET mdnsSocket;
     UA_Boolean mdnsMainSrvAdded;
 #  ifdef UA_ENABLE_MULTITHREADING
     pthread_t mdnsThread;

+ 2 - 11
src/server/ua_services_discovery.c

@@ -15,15 +15,6 @@
 #include "ua_services.h"
 #include "ua_mdns_internal.h"
 
-#ifdef _MSC_VER
-# ifndef UNDER_CE
-#  include <io.h> //access
-#  define access _access
-# endif
-#else
-# include <unistd.h> //access
-#endif
-
 #ifdef UA_ENABLE_DISCOVERY
 
 #include "ua_client_internal.h"
@@ -370,7 +361,7 @@ process_RegisterServer(UA_Server *server, UA_Session *session,
         }
         memcpy(filePath, requestServer->semaphoreFilePath.data, requestServer->semaphoreFilePath.length );
         filePath[requestServer->semaphoreFilePath.length] = '\0';
-        if(access( filePath, 0 ) == -1) {
+        if(UA_access( filePath, 0 ) == -1) {
             responseHeader->serviceResult = UA_STATUSCODE_BADSEMPAHOREFILEMISSING;
             UA_free(filePath);
             return;
@@ -507,7 +498,7 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) {
                 if(fp)
                     fclose(fp);
 #else
-                semaphoreDeleted = access( filePath, 0 ) == -1;
+                semaphoreDeleted = UA_access( filePath, 0 ) == -1;
 #endif
                 UA_free(filePath);
             } else {

+ 21 - 101
src/server/ua_services_discovery_multicast.c

@@ -7,47 +7,12 @@
  *    Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
  */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
 #include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_mdns_internal.h"
 
 #if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST)
 
-#ifdef _MSC_VER
-# ifndef UNDER_CE
-#  include <io.h> //access
-#  define access _access
-# endif
-#else
-# include <unistd.h> //access
-# include <sys/time.h> // struct timeval
-#endif
-
-#include <fcntl.h>
-#include <errno.h>
-#ifdef _WIN32
-# define CLOSESOCKET(S) closesocket((SOCKET)S)
-# define errno__ WSAGetLastError()
-#else
-# define CLOSESOCKET(S) close(S)
-# define errno__ errno
-#endif
-
-#include "ua_log_socket_error.h"
-
 #ifdef UA_ENABLE_MULTITHREADING
 
 static void *
@@ -58,7 +23,7 @@ multicastWorkerLoop(UA_Server *server) {
 
     while(*running) {
         FD_ZERO(&fds);
-        FD_SET(server->mdnsSocket, &fds);
+        UA_fd_set(server->mdnsSocket, &fds);
         select(server->mdnsSocket + 1, &fds, 0, 0, &next_sleep);
 
         if(!*running)
@@ -98,7 +63,7 @@ static UA_StatusCode
 multicastListenStop(UA_Server* server) {
     mdnsd_shutdown(server->mdnsDaemon);
     // wake up select
-    if(write(server->mdnsSocket, "\0", 1)){};
+    if(write(server->mdnsSocket, "\0", 1)){}; //TODO: move to arch?
     if(pthread_join(server->mdnsThread, NULL)) {
         UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
                      "Multicast error: Can not stop thread.");
@@ -145,7 +110,7 @@ void startMulticastDiscoveryServer(UA_Server *server) {
 
 void stopMulticastDiscoveryServer(UA_Server *server) {
     char hostname[256];
-    if(gethostname(hostname, 255) == 0) {
+    if(UA_gethostname(hostname, 255) == 0) {
         UA_String hnString = UA_STRING(hostname);
         UA_Discovery_removeRecord(server, &server->config.mdnsServerName,
                                   &hnString, 4840, UA_TRUE);
@@ -277,29 +242,9 @@ UA_Server_setServerOnNetworkCallback(UA_Server *server,
     server->serverOnNetworkCallbackData = data;
 }
 
-static void
-socket_mdns_set_nonblocking(int sockfd) {
-#ifdef _WIN32
-    u_long iMode = 1;
-    ioctlsocket(sockfd, FIONBIO, &iMode);
-#else
-    int opts = fcntl(sockfd, F_GETFL);
-    fcntl(sockfd, F_SETFL, opts|O_NONBLOCK);
-#endif
-}
-
 /* Create multicast 224.0.0.251:5353 socket */
-#ifdef _WIN32
-static SOCKET
-#else
-static int
-#endif
-discovery_createMulticastSocket(void) {
-#ifdef _WIN32
-    SOCKET s;
-#else
-    int s;
-#endif
+static UA_SOCKET discovery_createMulticastSocket(void) {
+    UA_SOCKET s;
     int flag = 1, ittl = 255;
     struct sockaddr_in in;
     struct ip_mreq mc;
@@ -311,34 +256,25 @@ discovery_createMulticastSocket(void) {
     in.sin_port = htons(5353);
     in.sin_addr.s_addr = 0;
 
-#ifdef _WIN32
-    if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
-        return INVALID_SOCKET;
-#else
-    if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-        return -1;
-#endif
+    if((s = UA_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == UA_INVALID_SOCKET)
+        return UA_INVALID_SOCKET;
 
 #ifdef SO_REUSEPORT
-    setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag));
-#endif
-    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
-    if(bind(s, (struct sockaddr *)&in, sizeof(in))) {
-        CLOSESOCKET(s);
-#ifdef _WIN32
-        return INVALID_SOCKET;
-#else
-        return -1;
+    UA_setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag));
 #endif
+    UA_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
+    if(UA_bind(s, (struct sockaddr *)&in, sizeof(in))) {
+        UA_close(s);
+        return UA_INVALID_SOCKET;
     }
 
     mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
     mc.imr_interface.s_addr = htonl(INADDR_ANY);
-    setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mc, sizeof(mc));
-    setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl));
-    setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl, sizeof(ittl));
+    UA_setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mc, sizeof(mc));
+    UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl));
+    UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl, sizeof(ittl));
 
-    socket_mdns_set_nonblocking(s);
+    UA_socket_set_nonblocking(s); //TODO: check return value
     return s;
 }
 
@@ -346,17 +282,9 @@ discovery_createMulticastSocket(void) {
 UA_StatusCode
 initMulticastDiscoveryServer(UA_Server* server) {
     server->mdnsDaemon = mdnsd_new(QCLASS_IN, 1000);
-#ifdef _WIN32
-    WORD wVersionRequested = MAKEWORD(2, 2);
-    WSADATA wsaData;
-    WSAStartup(wVersionRequested, &wsaData);
-#endif
+    UA_initialize_architecture_network();
 
-#ifdef _WIN32
-    if((server->mdnsSocket = discovery_createMulticastSocket()) == INVALID_SOCKET) {
-#else
-    if((server->mdnsSocket = discovery_createMulticastSocket()) < 0) {
-#endif
+    if((server->mdnsSocket = discovery_createMulticastSocket()) == UA_INVALID_SOCKET) {
         UA_LOG_SOCKET_ERRNO_WRAP(
                 UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
                      "Could not create multicast socket. Error: %s", errno_str));
@@ -370,17 +298,9 @@ initMulticastDiscoveryServer(UA_Server* server) {
 void destroyMulticastDiscoveryServer(UA_Server* server) {
     mdnsd_shutdown(server->mdnsDaemon);
     mdnsd_free(server->mdnsDaemon);
-#ifdef _WIN32
-    if(server->mdnsSocket != INVALID_SOCKET) {
-#else
-    if(server->mdnsSocket >= 0) {
-#endif
-        CLOSESOCKET(server->mdnsSocket);
-#ifdef _WIN32
-        server->mdnsSocket = INVALID_SOCKET;
-#else
-        server->mdnsSocket = -1;
-#endif
+    if(server->mdnsSocket != UA_INVALID_SOCKET) {
+        UA_close(server->mdnsSocket);
+        server->mdnsSocket = UA_INVALID_SOCKET;
     }
 }
 

+ 0 - 1
src/server/ua_session.h

@@ -12,7 +12,6 @@
 extern "C" {
 #endif
 
-#include "../deps/queue.h"
 #include "ua_securechannel.h"
 #include "ua_util.h"
 

+ 1 - 1
src/server/ua_session_manager.h

@@ -16,10 +16,10 @@
 extern "C" {
 #endif
 
-#include "../../deps/queue.h"
 #include "ua_server.h"
 #include "ua_util_internal.h"
 #include "ua_session.h"
+#include "../../deps/queue.h"
 
 typedef struct session_list_entry {
     LIST_ENTRY(session_list_entry) pointers;

+ 1 - 1
src/ua_securechannel.h

@@ -15,12 +15,12 @@
 extern "C" {
 #endif
 
-#include "../deps/queue.h"
 #include "ua_types.h"
 #include "ua_transport_generated.h"
 #include "ua_connection_internal.h"
 #include "ua_plugin_securitypolicy.h"
 #include "ua_plugin_log.h"
+#include "../deps/queue.h"
 
 #define UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH 12
 #define UA_SECURE_MESSAGE_HEADER_LENGTH 24

+ 6 - 2
src/ua_util_internal.h

@@ -14,13 +14,12 @@
 #ifndef UA_UTIL_H_
 #define UA_UTIL_H_
 
-#include "ua_types.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* BSD Queue Macros */
+#include "ua_types.h"
 #include "../deps/queue.h"
 
 /* Macro-Expand for MSVC workarounds */
@@ -152,8 +151,13 @@ UA_atomic_subSize(volatile size_t *addr, size_t decrease) {
  * up to that point. */
 size_t UA_readNumber(u8 *buf, size_t buflen, u32 *number);
 
+#ifndef UA_MIN
 #define UA_MIN(A,B) (A > B ? B : A)
+#endif
+
+#ifndef UA_MAX
 #define UA_MAX(A,B) (A > B ? A : B)
+#endif
 
 #ifdef UA_DEBUG_DUMP_PKGS
 void UA_EXPORT UA_dump_hex_pkg(UA_Byte* buffer, size_t bufferLen);

+ 2 - 2
tests/CMakeLists.txt

@@ -31,7 +31,7 @@ endif()
 
 
 # Use different plugins for testing
-set(test_plugin_sources ${PROJECT_SOURCE_DIR}/plugins/ua_network_tcp.c
+set(test_plugin_sources ${PROJECT_SOURCE_DIR}/arch/ua_network_tcp.c
                         ${PROJECT_SOURCE_DIR}/tests/testing-plugins/testing_clock.c
                         ${PROJECT_SOURCE_DIR}/plugins/ua_log_stdout.c
                         ${PROJECT_SOURCE_DIR}/plugins/ua_config_default.c
@@ -51,7 +51,7 @@ if(UA_ENABLE_ENCRYPTION)
         ${PROJECT_SOURCE_DIR}/plugins/ua_securitypolicy_basic256sha256.c)
 endif()
 
-add_library(open62541-testplugins OBJECT ${test_plugin_sources})
+add_library(open62541-testplugins OBJECT ${test_plugin_sources} ${PROJECT_SOURCE_DIR}/arch/${UA_ARCHITECTURE}/ua_architecture_functions.c)
 add_dependencies(open62541-testplugins open62541)
 target_compile_definitions(open62541-testplugins PRIVATE -DUA_DYNAMIC_LINKING_EXPORT)
 

+ 0 - 4
tests/client/check_client_async.c

@@ -5,10 +5,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#ifndef WIN32
-#include <unistd.h>
-#endif
-
 #include "ua_types.h"
 #include "ua_server.h"
 #include "ua_client.h"

+ 0 - 4
tests/client/check_client_async_connect.c

@@ -5,10 +5,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#ifndef WIN32
-#include <unistd.h>
-#endif
-
 #include "ua_types.h"
 #include "ua_server.h"
 #include "ua_client.h"

+ 2 - 2
tests/fuzz/CMakeLists.txt

@@ -52,7 +52,7 @@ endif()
 list(APPEND LIBS "${open62541_LIBRARIES}")
 
 # Use different plugins for testing
-set(fuzzing_plugin_sources ${PROJECT_SOURCE_DIR}/plugins/ua_network_tcp.c
+set(fuzzing_plugin_sources ${PROJECT_SOURCE_DIR}/arch/ua_network_tcp.c
         ${PROJECT_SOURCE_DIR}/tests/testing-plugins/testing_clock.c
         ${PROJECT_SOURCE_DIR}/tests/testing-plugins/testing_networklayers.c
         ${PROJECT_SOURCE_DIR}/plugins/ua_log_stdout.c
@@ -70,7 +70,7 @@ if(UA_ENABLE_ENCRYPTION)
         ${PROJECT_SOURCE_DIR}/plugins/ua_securitypolicy_basic256sha256.c)
 endif()
 
-add_library(open62541-fuzzplugins OBJECT ${fuzzing_plugin_sources})
+add_library(open62541-fuzzplugins OBJECT ${fuzzing_plugin_sources} ${PROJECT_SOURCE_DIR}/arch/${UA_ARCHITECTURE}/ua_architecture_functions.c)
 add_dependencies(open62541-fuzzplugins open62541)
 
 # the fuzzer test are built directly on the open62541 object files. so they can

+ 3 - 20
tests/server/check_discovery.c

@@ -2,26 +2,6 @@
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 500
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-
-// On older systems we need to define _BSD_SOURCE
-// _DEFAULT_SOURCE is an alias for that
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <check.h>
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
 #include "server/ua_server_internal.h"
 #include "ua_client.h"
 #include "ua_config_default.h"
@@ -29,6 +9,9 @@
 #include "testing_clock.h"
 #include "thread_wrapper.h"
 
+#include <fcntl.h>
+#include <check.h>
+
 // set register timeout to 1 second so we are able to test it.
 #define registerTimeout 1
 // cleanup is only triggered every 10 seconds, thus wait a bit longer to check

+ 4 - 21
tests/testing-plugins/testing_clock.c

@@ -2,25 +2,8 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
-#include <time.h>
-#ifdef _WIN32
-# include <windows.h>
-#endif
 #include "testing_clock.h"
-
+#include <time.h>
 
 UA_DateTime testingClock = 0;
 
@@ -59,7 +42,7 @@ UA_realSleep(UA_UInt32 duration) {
 }
 
 void
-UA_comboSleep(UA_UInt32 duration) {
-    UA_fakeSleep(duration);
-    UA_realSleep(duration);
+UA_comboSleep(size_t duration) {
+    UA_fakeSleep((UA_UInt32)duration);
+    UA_realSleep((UA_UInt32)duration);
 }

+ 0 - 5
tests/testing-plugins/testing_clock.h

@@ -24,9 +24,4 @@ void UA_fakeSleep(UA_UInt32 duration);
 /* Sleep for the duration in milliseconds. Used to wait for workers to complete. */
 void UA_realSleep(UA_UInt32 duration);
 
-/* Sleep for the duration in milliseconds and update the current time.
- * combines fakeSleep and realSleep.
- * */
-void UA_comboSleep(UA_UInt32 duration);
-
 #endif /* TESTING_CLOCK_H_ */

+ 0 - 13
tools/amalgamate.py

@@ -53,19 +53,6 @@ if is_c:
 # define MDNSD_DYNAMIC_LINKING
 #endif
 
-/* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef _DEFAULT_SOURCE
-# define _DEFAULT_SOURCE
-#endif
-/* On older systems we need to define _BSD_SOURCE.
- * _DEFAULT_SOURCE is an alias for that. */
-#ifndef _BSD_SOURCE
-# define _BSD_SOURCE
-#endif
-
 /* Disable security warnings for BSD sockets on MSVC */
 #ifdef _MSC_VER
 # define _CRT_SECURE_NO_WARNINGS

+ 55 - 0
tools/cmake/macros.cmake

@@ -0,0 +1,55 @@
+#Add a new architecture to to the lists of available architectures
+FUNCTION(ua_add_architecture)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURES ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture)
+
+#Include folders to the compilation
+FUNCTION(ua_include_directories)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_INCLUDE_DIRECTORIES ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_include_directories)
+
+#Add a new header file to the architecture group
+FUNCTION(ua_add_architecture_header)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_HEADERS ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture_header)
+
+#Add a new header file to the architecture group at the beginning of it
+FUNCTION(ua_add_architecture_header_beginning)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_HEADERS_BEGINNING ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture_header_beginning)
+
+#Add a new source file to the architecture group
+FUNCTION(ua_add_architecture_file)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_SOURCES ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture_file)
+
+#Add definitions to the compilations that are exclusive for the selected architecture
+FUNCTION(ua_architecture_add_definitions)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_ADD_DEFINITIONS ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_architecture_add_definitions)
+
+#Remove definitions from the compilations that are exclusive for the selected architecture
+FUNCTION(ua_architecture_remove_definitions)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_REMOVE_DEFINITIONS ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_architecture_remove_definitions)
+
+#Add libraries to be linked to the comnpilation that are exclusive for the selected architecture
+FUNCTION(ua_architecture_append_to_library)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_APPEND_TO_LIBRARY ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_architecture_append_to_library)

+ 2 - 2
tools/nodeset_compiler/backend_open62541.py

@@ -130,7 +130,7 @@ def sortNodes(nodeset):
 # Generate C Code #
 ###################
 
-def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_headers=False, typesArray=[], max_string_length=0):
+def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_headers=False, typesArray=[], max_string_length=0, encode_binary_size=32000):
     outfilebase = basename(outfilename)
     # Printing functions
     outfileh = codecs.open(outfilename + ".h", r"w+", encoding='utf-8')
@@ -234,7 +234,7 @@ extern UA_StatusCode %s(UA_Server *server);
         parentref = node.popParentRef(parentreftypes)
         if not node.hidden:
             writec("\n/* " + str(node.displayName) + " - " + str(node.id) + " */")
-            code = generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref)
+            code = generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref, encode_binary_size)
             if code is None:
                 writec("/* Ignored. No parent */")
                 nodeset.hide_node(node.id)

+ 15 - 13
tools/nodeset_compiler/backend_open62541_nodes.py

@@ -72,7 +72,7 @@ def generateObjectNodeCode(node):
         code.append("attr.eventNotifier = true;")
     return code
 
-def generateVariableNodeCode(node, nodeset, max_string_length):
+def generateVariableNodeCode(node, nodeset, max_string_length, encode_binary_size):
     code = []
     codeCleanup = []
     code.append("UA_VariableAttributes attr = UA_VariableAttributes_default;")
@@ -111,7 +111,7 @@ def generateVariableNodeCode(node, nodeset, max_string_length):
 
             if dataTypeNode.isEncodable():
                 if node.value is not None:
-                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length=max_string_length)
+                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length=max_string_length, encode_binary_size=encode_binary_size)
                     code += code1
                     codeCleanup += codeCleanup1
                     if node.valueRank > 0 and len(node.arrayDimensions) == node.valueRank:
@@ -121,7 +121,7 @@ def generateVariableNodeCode(node, nodeset, max_string_length):
                     code += generateValueCodeDummy(dataTypeNode, nodeset.nodes[node.id], nodeset)
     return [code, codeCleanup]
 
-def generateVariableTypeNodeCode(node, nodeset, max_string_length):
+def generateVariableTypeNodeCode(node, nodeset, max_string_length, encode_binary_size):
     code = []
     codeCleanup = []
     code.append("UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;")
@@ -140,14 +140,14 @@ def generateVariableTypeNodeCode(node, nodeset, max_string_length):
             code.append("attr.dataType = %s;" % generateNodeIdCode(dataTypeNode.id))
             if dataTypeNode.isEncodable():
                 if node.value is not None:
-                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length)
+                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length, encode_binary_size)
                     code += code1
                     codeCleanup += codeCleanup1
                 else:
                     code += generateValueCodeDummy(dataTypeNode, nodeset.nodes[node.id], nodeset)
     return [code, codeCleanup]
 
-def generateExtensionObjectSubtypeCode(node, parent, nodeset, recursionDepth=0, arrayIndex=0, max_string_length=0):
+def generateExtensionObjectSubtypeCode(node, parent, nodeset, recursionDepth=0, arrayIndex=0, max_string_length=0, encode_binary_size=32000):
     code = [""]
     codeCleanup = [""]
 
@@ -223,11 +223,11 @@ def generateExtensionObjectSubtypeCode(node, parent, nodeset, recursionDepth=0,
         instanceName + "->content.encoded.typeId = UA_NODEID_NUMERIC(" + str(binaryEncodingId.ns) + ", " +
         str(binaryEncodingId.i) + ");")
     code.append(
-        "UA_ByteString_allocBuffer(&" + instanceName + "->content.encoded.body, 65000);")
+        "UA_ByteString_allocBuffer(&" + instanceName + "->content.encoded.body, " + str(encode_binary_size) + ");")
 
     # Encode each value as a bytestring separately.
     code.append("UA_Byte *pos" + instanceName + " = " + instanceName + "->content.encoded.body.data;")
-    code.append("const UA_Byte *end" + instanceName + " = &" + instanceName + "->content.encoded.body.data[65000];")
+    code.append("const UA_Byte *end" + instanceName + " = &" + instanceName + "->content.encoded.body.data[" + str(encode_binary_size) + "];")
     encFieldIdx = 0
     code.append("{")
     for subv in node.value:
@@ -295,7 +295,7 @@ def getTypesArrayForValue(nodeset, value):
     return "&" + typesArray + "[" + typesArray + "_" + \
                     value.__class__.__name__.upper() + "]"
 
-def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_length=0):
+def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_length=0, encode_binary_size=32000):
     code = []
     codeCleanup = []
     valueName = generateNodeIdPrintable(parentNode) + "_variant_DataContents"
@@ -330,7 +330,8 @@ def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_
             if isinstance(node.value[0], ExtensionObject):
                 for idx, v in enumerate(node.value):
                     logger.debug("Building extObj array index " + str(idx))
-                    [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(v, parent=parentNode, nodeset=nodeset, arrayIndex=idx, max_string_length=max_string_length)
+                    [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(v, parent=parentNode, nodeset=nodeset, arrayIndex=idx, max_string_length=max_string_length,
+                                                                               encode_binary_size=encode_binary_size)
                     code = code + code1
                     codeCleanup = codeCleanup + codeCleanup1
             code.append("UA_" + node.value[0].__class__.__name__ + " " + valueName + "[" + str(len(node.value)) + "];")
@@ -361,7 +362,8 @@ def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_
         else:
             # The following strategy applies to all other types, in particular strings and numerics.
             if isinstance(node.value[0], ExtensionObject):
-                [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(node.value[0], parent=parentNode, nodeset=nodeset, max_string_length=max_string_length)
+                [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(node.value[0], parent=parentNode, nodeset=nodeset, max_string_length=max_string_length,
+                                                                           encode_binary_size=encode_binary_size)
                 code = code + code1
                 codeCleanup = codeCleanup + codeCleanup1
             instanceName = generateNodeValueInstanceName(node.value[0], parentNode, 0, 0)
@@ -430,7 +432,7 @@ def generateSubtypeOfDefinitionCode(node):
             return generateNodeIdCode(ref.target)
     return "UA_NODEID_NULL"
 
-def generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref):
+def generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref, encode_binary_size):
     code = []
     codeCleanup = []
     code.append("UA_StatusCode retVal = UA_STATUSCODE_GOOD;")
@@ -441,11 +443,11 @@ def generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, paren
     elif isinstance(node, ObjectNode):
         code.extend(generateObjectNodeCode(node))
     elif isinstance(node, VariableNode) and not isinstance(node, VariableTypeNode):
-        [code1, codeCleanup1] = generateVariableNodeCode(node, nodeset, max_string_length)
+        [code1, codeCleanup1] = generateVariableNodeCode(node, nodeset, max_string_length, encode_binary_size)
         code.extend(code1)
         codeCleanup.extend(codeCleanup1)
     elif isinstance(node, VariableTypeNode):
-        [code1, codeCleanup1] = generateVariableTypeNodeCode(node, nodeset, max_string_length)
+        [code1, codeCleanup1] = generateVariableTypeNodeCode(node, nodeset, max_string_length, encode_binary_size)
         code.extend(code1)
         codeCleanup.extend(codeCleanup1)
     elif isinstance(node, MethodNode):

+ 7 - 1
tools/nodeset_compiler/nodeset_compiler.py

@@ -88,6 +88,12 @@ parser.add_argument('--max-string-length',
                     default=0,
                     help='Maximum allowed length of a string literal. If longer, it will be set to an empty string')
 
+parser.add_argument('--encode-binary-size',
+                    type=int,
+                    dest="encode_binary_size",
+                    default=32000,
+                    help='Size of the temporary array used to encode custom datatypes. If you don\'t know what it is, do not use this option')
+
 parser.add_argument('-v', '--verbose', action='count',
                     default=1,
                     help='Make the script more verbose. Can be applied up to 4 times')
@@ -182,5 +188,5 @@ ns.allocateVariables()
 
 # Create the C code with the open62541 backend of the compiler
 logger.info("Generating Code")
-generateOpen62541Code(ns, args.outputFile, args.generate_ns0, args.internal_headers, args.typesArray, args.max_string_length)
+generateOpen62541Code(ns, args.outputFile, args.generate_ns0, args.internal_headers, args.typesArray, args.max_string_length, args.encode_binary_size)
 logger.info("NodeSet generation code successfully printed")

+ 2 - 2
tools/travis/travis_linux_script.sh

@@ -177,8 +177,8 @@ else
     echo -e "\r\n== Building the C++ example =="  && echo -en 'travis_fold:start:script.build.example\\r'
     mkdir -p build && cd build
     cp ../../open62541.* .
-    gcc -std=c99 -c open62541.c
-    g++ ../examples/server.cpp -I./ open62541.o -lrt -o cpp-server
+    gcc -std=c99  -DUA_ARCHITECTURE_POSIX  -c open62541.c
+    g++ ../examples/server.cpp -DUA_ARCHITECTURE_POSIX -I./ open62541.o -lrt -o cpp-server
     if [ $? -ne 0 ] ; then exit 1 ; fi
     cd .. && rm build -rf
     echo -en 'travis_fold:end:script.build.example\\r'