소스 검색

Adapt network plugins for architecture implementation

Jose Cabral 7 년 전
부모
커밋
e1d3955e91

+ 5 - 5
CMakeLists.txt

@@ -354,11 +354,12 @@ include_directories(${PROJECT_SOURCE_DIR}/include
                     ${MBEDTLS_INCLUDE_DIRS})
 
 set(exported_headers ${PROJECT_BINARY_DIR}/src_generated/ua_config.h
-                     ${PROJECT_SOURCE_DIR}/deps/ms_stdint.h
-                     ${PROJECT_SOURCE_DIR}/include/ua_constants.h
+                     ${PROJECT_SOURCE_DIR}/include/ua_types.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids.h
-                     ${PROJECT_SOURCE_DIR}/include/ua_types.h
+                     ${PROJECT_SOURCE_DIR}/include/ua_constants.h
+                     ${PROJECT_SOURCE_DIR}/plugins/arch/${UA_ARCHITECTURE}/ua_architecture.h
+                     ${PROJECT_SOURCE_DIR}/deps/ms_stdint.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h
                      ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated_handling.h
                      ${PROJECT_SOURCE_DIR}/include/ua_server.h
@@ -452,7 +453,6 @@ set(default_plugin_headers ${PROJECT_SOURCE_DIR}/plugins/ua_network_tcp.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
                            ${PROJECT_SOURCE_DIR}/plugins/ua_accesscontrol_default.c
                            ${PROJECT_SOURCE_DIR}/plugins/ua_pki_certificate.c
@@ -623,7 +623,7 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/open62541.c
                            ${OPEN62541_VER_COMMIT} ${CMAKE_CURRENT_BINARY_DIR}/open62541.c
                            ${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} ${ua_architecture_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)

+ 3 - 1
include/ua_plugin_network.h

@@ -13,6 +13,8 @@
 extern "C" {
 #endif
 
+#include "ua_architecture.h"
+
 #include "ua_server.h"
 #include "ua_plugin_log.h"
 
@@ -65,7 +67,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
plugins/arch/freertos/CMakeLists.txt

@@ -5,7 +5,7 @@ ua_add_architecture("freertos")
 if("${UA_ARCHITECTURE}" STREQUAL "freertos")
 
     ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-    ua_add_architecture_header(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture.h)
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
     
     SET(UA_FREERTOS_INCLUDES "" CACHE STRING "Folders to include from the freeRTOS OS")
     ua_include_directories(${UA_FREERTOS_INCLUDES})

+ 75 - 29
plugins/arch/freertos/ua_architecture.h

@@ -13,59 +13,105 @@
 // NOT WORKING YET!!!!!!!!!!!!!!!!!!!!!
 //------------------------------------------------------------------
 
-
-/*
- * Set LWIP_COMPAT_SOCKETS to 2 in lwipoptions.h
- */
-
-
 #define AI_PASSIVE 0x01
-#define TRUE 1
-#define FALSE 0
-#define ioctl ioctlsocket
 
 #define UA_FREERTOS_HOSTNAME "10.200.4.114"
 
 #include <stdlib.h>
 #include <string.h>
 
-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
-
 #define LWIP_TIMEVAL_PRIVATE 0
 #define LWIP_COMPAT_MUTEX 0
 #define LWIP_POSIX_SOCKETS_IO_NAMES 0
+#ifdef LWIP_COMPAT_SOCKETS
+#undef LWIP_COMPAT_SOCKETS
+#endif
+#define LWIP_COMPAT_SOCKETS 0
 //#define __USE_W32_SOCKETS 1 //needed to avoid redefining of select in sys/select.h
 
 #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
 #define UA_sleep_ms(X) vTaskDelay(pdMS_TO_TICKS(X))
 
-#define SOCKET int
-#define WIN32_INT
 #define OPTVAL_TYPE int
-#define ERR_CONNECTION_PROGRESS EINPROGRESS
 
+#include <unistd.h> // read, write, close
 
-//# include <fcntl.h>
-# include <unistd.h> // read, write, close
+#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_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 0
+#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
+
+#include "ua_types.h"
+
+static UA_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
+
+#define ua_send lwip_send
+#define ua_recv lwip_recv
+#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_translate_error(x) ""
+#define ua_freeaddrinfo lwip_freeaddrinfo
+
+static UA_INLINE int ua_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res){
+  if(NULL == node){
+    const char* hostname = UA_FREERTOS_HOSTNAME;
+    return lwip_getaddrinfo(hostname, service, hints, res);
+  }else{
+    return lwip_getaddrinfo(node, service, hints, res);
+  }
+}
+
+static UA_INLINE uint32_t socket_set_blocking(UA_SOCKET sockfd){
+  int on = 0;
+  if(lwip_ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+static UA_INLINE uint32_t socket_set_nonblocking(UA_SOCKET sockfd){
+  int on = 1;
+  if(lwip_ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+#include <stdio.h>
+#define ua_snprintf snprintf
+
+static UA_INLINE void ua_initialize_architecture_network(void){
+  return;
+}
+
+static UA_INLINE void ua_deinitialize_architecture_network(void){
+  return;
+}
 
-#define errno__ errno
-#define INTERRUPTED EINTR
-#define WOULDBLOCK EWOULDBLOCK
-#define AGAIN EAGAIN
 
 #endif /* PLUGINS_ARCH_FREERTOS_UA_ARCHITECTURE_H_ */

+ 55 - 0
plugins/arch/freertos/ua_clock.c

@@ -0,0 +1,55 @@
+/* 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
+ */
+
+/* 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 <time.h>
+#include <sys/time.h>
+
+#include "ua_types.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);
+}

+ 1 - 1
plugins/arch/posix/CMakeLists.txt

@@ -5,6 +5,6 @@ ua_add_architecture("posix")
 if("${UA_ARCHITECTURE}" STREQUAL "posix")
 
 ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-ua_add_architecture_header(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture.h)
+ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
 
 endif()

+ 55 - 12
plugins/arch/posix/ua_architecture.h

@@ -22,19 +22,14 @@
 #endif
 
 #include <errno.h>
-
-#define CLOSESOCKET(S) close(S)
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #include <sys/ioctl.h>
-# include <sys/select.h>
-# define UA_sleep_ms(X) usleep(X * 1000)
+#include <sys/select.h>
+#define UA_sleep_ms(X) usleep(X * 1000)
 
-#define SOCKET int
-#define WIN32_INT
 #define OPTVAL_TYPE int
-#define ERR_CONNECTION_PROGRESS EINPROGRESS
 
 
 #include <fcntl.h>
@@ -56,7 +51,7 @@
 /* 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__) || \
+#if  defined(__OpenBSD__) || \
     (defined(__GNU_LIBRARY__) && (__GNU_LIBRARY__ <= 6) && \
      (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 16) || \
     !defined(__GNU_LIBRARY__))
@@ -67,9 +62,57 @@
 # define UA_fd_isset(fd, fds) FD_ISSET(fd, fds)
 #endif
 
-# define errno__ errno
-# define INTERRUPTED EINTR
-# define WOULDBLOCK EWOULDBLOCK
-# define AGAIN EAGAIN
+#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
+
+#include "ua_types.h"
+
+#define ua_send send
+#define ua_recv recv
+#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_translate_error gai_strerror
+#define ua_getaddrinfo getaddrinfo
+#define ua_getsockopt getsockopt
+#define ua_setsockopt setsockopt
+#define ua_freeaddrinfo freeaddrinfo
+
+static UA_INLINE uint32_t 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;
+}
+
+static UA_INLINE uint32_t 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;
+}
+
+#include <stdio.h>
+#define ua_snprintf snprintf
+
+static UA_INLINE void ua_initialize_architecture_network(void){
+  return;
+}
+
+static UA_INLINE void ua_deinitialize_architecture_network(void){
+  return;
+}
 
 #endif /* PLUGINS_ARCH_POSIX_UA_ARCHITECTURE_H_ */

+ 3 - 61
plugins/ua_clock.c

@@ -7,7 +7,7 @@
  */
 
 /* Enable POSIX features */
-#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL)
+#if !defined(_XOPEN_SOURCE)
 # define _XOPEN_SOURCE 600
 #endif
 #ifndef _DEFAULT_SOURCE
@@ -20,23 +20,7 @@
 #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
+#include <sys/time.h>
 
 #if defined(__APPLE__) || defined(__MACH__)
 # include <mach/clock.h>
@@ -45,58 +29,26 @@
 
 #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__)
+#if defined(__APPLE__) || defined(__MACH__)
     /* OS X does not have clock_gettime, use clock_get_time */
     clock_serv_t cclock;
     mach_timespec_t mts;
@@ -105,19 +57,9 @@ UA_DateTime UA_DateTime_nowMonotonic(void) {
     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);

+ 141 - 0
plugins/arch/readme.txt

@@ -0,0 +1,141 @@
+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)
+
+
+# ---------------------------------------------------
+# ---- 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
+   
+
+/* 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
+*/
+
+
+
+/*
+* Implement int UA_sleep_ms(unsigned int miliSeconds);
+*/ 
+
+/*
+* Define OPTVAL_TYPE for non windows systems. In doubt, use int //TODO: Is this really necessary
+*/
+
+
+/*
+* Define the following network options for ipv4 and ipv6 if they are enabled or not
+*/
+
+
+//#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
+
+
+
+/*
+* Implement the following socket functions (you can #define them): 
+*/ 
+
+#include "ua_types.h"
+
+/* ssize_t ua_send(UA_SOCKET sockfd, const void *buf, size_t len, int flags);
+* int ua_select(UA_SOCKET nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
+* ssize_t ua_recv(UA_SOCKET sockfd, void *buf, size_t len, int flags);
+* int ua_shutdown(UA_SOCKET sockfd, int how);
+* UA_SOCKET ua_socket(int domain, int type, int protocol);
+* int ua_bind(UA_SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);
+* int ua_listen(UA_SOCKET sockfd, int backlog);
+* int ua_accept(UA_SOCKET sockfd, struct sockaddr *addr, socklen_t *addrlen);
+* int ua_close(UA_SOCKET sockfd);
+* int ua_connect(UA_SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);
+* void UA_fd_set(UA_SOCKET fd, fd_set *set);
+* int UA_fd_isset(UA_SOCKET fd, fd_set *set)
+* const char* ua_translate_error(int errorCode)
+* int ua_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
+* UA_StatusCode socket_set_blocking(UA_SOCKET sockfd); 
+* UA_StatusCode socket_set_nonblocking(UA_SOCKET sockfd); 
+* int ua_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); //Only in non windows architectures
+* int ua_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
+* void ua_freeaddrinfo(struct addrinfo *res);
+*/
+
+/*
+* Define int ua_snprintf(char* pa_stream, size_t pa_size, const char* pa_format, ...);
+*/
+
+
+/*
+* Define
+* void ua_initialize_architecture_network(void);
+* void ua_deinitialize_architecture_network(void);
+*/
+
+
+
+#endif /* PLUGINS_ARCH_NEW_ARCH_UA_ARCHITECTURE_H_ */
+

+ 1 - 1
plugins/arch/vxworks/CMakeLists.txt

@@ -5,7 +5,7 @@ ua_add_architecture("vxworks")
 if("${UA_ARCHITECTURE}" STREQUAL "vxworks")
 
     ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-    ua_add_architecture_header(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture.h)
+    ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
     
     ua_architecture_remove_definitions(-Werror -Wpedantic -Wno-static-in-inline -fPIC)
     ua_architecture_add_definitions(-D_WRS_KERNEL)

+ 52 - 8
plugins/arch/vxworks/ua_architecture.h

@@ -12,7 +12,6 @@
 
 #include <errno.h>
 
-#define CLOSESOCKET(S) close(S)
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netdb.h>
@@ -28,10 +27,7 @@
    nanosleep(&timeToSleep, NULL);                 \
  }
 
-#define SOCKET int
-#define WIN32_INT
 #define OPTVAL_TYPE int
-#define ERR_CONNECTION_PROGRESS EINPROGRESS
 
 #include <fcntl.h>
 #include <unistd.h> // read, write, close
@@ -40,9 +36,57 @@
 #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 errno__ errno
-#define INTERRUPTED EINTR
-#define WOULDBLOCK EWOULDBLOCK
-#define AGAIN EAGAIN
+#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
+
+#include "ua_types.h"
+
+#define ua_send send
+#define ua_recv recv
+#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_translate_error gai_strerror
+#define ua_getaddrinfo getaddrinfo
+#define ua_getsockopt getsockopt
+#define ua_setsockopt setsockopt
+#define ua_freeaddrinfo freeaddrinfo
+
+static UA_INLINE uint32_t socket_set_blocking(UA_SOCKET sockfd){
+  int on = FALSE;
+  if(ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+static UA_INLINE uint32_t socket_set_nonblocking(UA_SOCKET sockfd){
+  int on = TRUE;
+  if(ioctl(sockfd, FIONBIO, &on) < 0)
+    return UA_STATUSCODE_BADINTERNALERROR;
+  return UA_STATUSCODE_GOOD;
+}
+
+#include <stdio.h>
+#define ua_snprintf snprintf
+
+static UA_INLINE void ua_initialize_architecture_network(void){
+  return;
+}
+
+static UA_INLINE void ua_deinitialize_architecture_network(void){
+  return;
+}
 
 #endif /* PLUGINS_ARCH_VXWORKS_UA_ARCHITECTURE_H_ */

+ 51 - 0
plugins/arch/vxworks/ua_clock.c

@@ -0,0 +1,51 @@
+/* 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
+ */
+
+#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);
+}

+ 1 - 1
plugins/arch/win32/CMakeLists.txt

@@ -5,6 +5,6 @@ ua_add_architecture("win32")
 if("${UA_ARCHITECTURE}" STREQUAL "win32")
 
 ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-ua_add_architecture_header(${CMAKE_CURRENT_SOURCE_DIR}/ua_architecture.h)
+ua_add_architecture_file(${CMAKE_CURRENT_SOURCE_DIR}/ua_clock.c)
 
 endif()

+ 66 - 28
plugins/arch/win32/ua_architecture.h

@@ -27,37 +27,75 @@
 # define _WIN32_WINNT 0x0501
 #endif
 
-# include <errno.h>
-# 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
-# define UA_sleep_ms(X) Sleep(X)
-
-/* 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
+#include <errno.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define ssize_t int
+#define OPTVAL_TYPE char
+#define UA_sleep_ms(X) Sleep(X)
+
+#define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds)
+#define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds)
 
 #ifdef UNDER_CE
-# define errno WSAGetLastError()
+# define errno
 #endif
 
-# define errno__ WSAGetLastError()
-# define INTERRUPTED WSAEINTR
-# define WOULDBLOCK WSAEWOULDBLOCK
-# define AGAIN WSAEWOULDBLOCK
+#define UA_IPV6 1
+#define UA_SOCKET int
+#define UA_INVALID_SOCKET -1
+#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
+
+#include "ua_types.h"
+
+#define ua_send send
+#define ua_recv recv
+#define ua_close closesocket
+#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_translate_error gai_strerror
+#define ua_getaddrinfo getaddrinfo
+#define ua_getsockopt getsockopt
+#define ua_setsockopt setsockopt
+#define ua_freeaddrinfo freeaddrinfo
+
+
+static UA_INLINE UA_StatusCode 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;;
+}
+
+static UA_INLINE UA_StatusCode 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;;
+}
+
+
+#include <stdio.h>
+#define ua_snprintf(source, size, string, ...) _snprintf_s(source, size, _TRUNCATE, string, __VA_ARGS__)
+
+static UA_INLINE void ua_initialize_architecture_network(void){
+  WSADATA wsaData;
+  WORD wVersionRequested = MAKEWORD(2, 2);
+  WSAStartup(wVersionRequested, &wsaData);
+}
+
+static UA_INLINE void ua_deinitialize_architecture_network(void){
+  WSACleanup();
+}
 
 #endif /* PLUGINS_ARCH_WIN32_UA_ARCHITECTURE_H_ */

+ 61 - 0
plugins/arch/win32/ua_clock.c

@@ -0,0 +1,61 @@
+/* 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
+ */
+
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+#endif
+
+#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
+
+#include "ua_types.h"
+
+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);
+}

+ 66 - 157
plugins/ua_network_tcp.c

@@ -11,11 +11,14 @@
 
 #include "ua_architecture.h"
 
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
 #include "ua_network_tcp.h"
 #include "ua_log_stdout.h"
 #include "../deps/queue.h"
 
-#include <stdio.h> // snprintf
 #include <string.h> // memset
 
 #include "ua_log_socket_error.h"
@@ -53,9 +56,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;
@@ -63,10 +64,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;
@@ -94,7 +95,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 */
@@ -121,7 +122,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 */
@@ -134,8 +135,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;
@@ -146,41 +147,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 */
@@ -199,7 +165,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;
@@ -216,7 +182,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;
 }
 
@@ -228,7 +194,7 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
 
     /* 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,
@@ -258,7 +224,7 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
     /* Allocate and initialize the connection */
     ConnectionEntry *e = (ConnectionEntry*)UA_malloc(sizeof(ConnectionEntry));
     if(!e){
-        CLOSESOCKET(newsockfd);
+        ua_close(newsockfd);
         return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
@@ -285,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");
@@ -302,21 +264,21 @@ 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;
     }
 
@@ -324,39 +286,35 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
     if(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;
 
@@ -364,31 +322,17 @@ 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) {
             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;
         }
     }
@@ -396,23 +340,14 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
 
     /* 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,
@@ -422,7 +357,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",
@@ -465,7 +400,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));
@@ -480,13 +415,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,
@@ -506,7 +437,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;
         }
@@ -532,7 +463,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);
         }
     }
@@ -547,8 +478,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;
 
@@ -561,9 +492,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 */
@@ -577,7 +506,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);
     }
 
@@ -614,8 +543,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;
 }
 
@@ -623,12 +552,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;
@@ -674,83 +599,67 @@ 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
+                       hostname, ua_translate_error(error));
         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) {
             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)
@@ -763,7 +672,7 @@ 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(clientsockfd + 1, NULL, &fdset, NULL, &tmptv);
 
             if(resultsize == 1) {
 #ifdef _WIN32
@@ -775,7 +684,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 */
@@ -784,8 +693,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
@@ -805,7 +714,7 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
 
     } while ((UA_DateTime_nowMonotonic() - connStart) < dtTimeout);
 
-    freeaddrinfo(server);
+    ua_freeaddrinfo(server);
 
     if(!connected) {
         /* connection timeout */
@@ -828,7 +737,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,