Browse Source

add compiler flags to enforce stricter compatibility and fix warnings

Julius Pfrommer 10 years ago
parent
commit
dd2797952a

+ 2 - 1
CMakeLists.txt

@@ -49,6 +49,7 @@ set(lib_sources src/ua_types.c
 if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
 add_definitions(-std=c99 -pedantic -pipe -Wall -Wextra -Werror -Wformat
                 -Wno-unused-parameter -Wno-unused-function -Wno-unused-label -Wpointer-arith -Wreturn-type -Wsign-compare -Wmultichar
+                -Wshadow -Wcast-align -Wcast-qual -Wmissing-prototypes -Wstrict-prototypes # -Wconversion 
                 -Winit-self -Wuninitialized -Wno-deprecated -Wformat-security -ffunction-sections -fdata-sections)
     if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
         add_definitions(-Wformat-nonliteral)
@@ -255,4 +256,4 @@ if(GENERATE_DOCUMENTATION)
                       ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
                       WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
                       COMMENT "Generating API documentation with Doxygen")
-endif()
+endif()

+ 2 - 2
examples/logger_stdout.c

@@ -9,7 +9,7 @@
 #include "logger_stdout.h"
 #include "ua_types.h"
 
-void print_time() {
+static void print_time(void) {
 	UA_DateTime now = UA_DateTime_now();
 	UA_ByteString str;
 	UA_DateTime_toString(now, &str);
@@ -18,7 +18,7 @@ void print_time() {
 }
 
 #define LOG_FUNCTION(LEVEL) \
-	void log_##LEVEL(UA_LoggerCategory category, const char *msg, ...) { \
+	static void log_##LEVEL(UA_LoggerCategory category, const char *msg, ...) { \
 		va_list args;												   \
 		puts("##LEVEL - ");											   \
 		print_time();												   \

+ 5 - 5
examples/networklayer_tcp.c

@@ -240,7 +240,7 @@ void writeCallback(TCPConnection *handle, UA_ByteStringArray gather_buf) {
 #endif
 }
 
-UA_StatusCode NetworkLayerTCP_start(NetworkLayerTCP *layer) {
+static UA_StatusCode NetworkLayerTCP_start(NetworkLayerTCP *layer) {
 #ifdef _WIN32
 	WORD wVersionRequested;
 	WSADATA wsaData;
@@ -285,8 +285,8 @@ UA_StatusCode NetworkLayerTCP_start(NetworkLayerTCP *layer) {
     return UA_STATUSCODE_GOOD;
 }
 
-UA_Int32 NetworkLayerTCP_getWork(NetworkLayerTCP *layer, UA_WorkItem **workItems,
-                                 UA_UInt16 timeout) {
+static UA_Int32 NetworkLayerTCP_getWork(NetworkLayerTCP *layer, UA_WorkItem **workItems,
+                                        UA_UInt16 timeout) {
     UA_WorkItem *items = UA_NULL;
     UA_Int32 itemsCount = batchDeleteLinks(layer, &items);
     setFDSet(layer);
@@ -351,7 +351,7 @@ UA_Int32 NetworkLayerTCP_getWork(NetworkLayerTCP *layer, UA_WorkItem **workItems
     return j;
 }
 
-UA_Int32 NetworkLayerTCP_stop(NetworkLayerTCP * layer, UA_WorkItem **workItems) {
+static UA_Int32 NetworkLayerTCP_stop(NetworkLayerTCP * layer, UA_WorkItem **workItems) {
 	for(UA_Int32 index = 0;index < layer->conLinksSize;index++)
         closeConnection(layer->conLinks[index].connection);
 #ifdef _WIN32
@@ -360,7 +360,7 @@ UA_Int32 NetworkLayerTCP_stop(NetworkLayerTCP * layer, UA_WorkItem **workItems)
     return batchDeleteLinks(layer, workItems);
 }
 
-void NetworkLayerTCP_delete(NetworkLayerTCP *layer) {
+static void NetworkLayerTCP_delete(NetworkLayerTCP *layer) {
 	free(layer->conLinks);
 	free(layer);
 }

+ 18 - 9
examples/networklayer_udp.c

@@ -71,9 +71,10 @@ static void setFDSet(NetworkLayerUDP *layer) {
 }
 
 // the callbacks are thread-safe if UA_MULTITHREADING is defined
-void closeConnectionUDP(UDPConnection *handle){
+static void closeConnectionUDP(UDPConnection *handle) {
 	free(handle);
 }
+
 void writeCallbackUDP(UDPConnection *handle, UA_ByteStringArray gather_buf);
 
 /** Accesses only the sockfd in the handle. Can be run from parallel threads. */
@@ -108,10 +109,18 @@ void writeCallbackUDP(UDPConnection *handle, UA_ByteStringArray gather_buf) {
 
 
 	struct sockaddr_in *sin = UA_NULL;
-	if (handle->from.sa_family == AF_INET)
-	{
+	if (handle->from.sa_family == AF_INET) {
+        
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
 	    sin = (struct sockaddr_in *) &(handle->from);
-	}else{
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+	} else {
 		//FIXME:
 		return;
 	}
@@ -132,7 +141,7 @@ void writeCallbackUDP(UDPConnection *handle, UA_ByteStringArray gather_buf) {
 #endif
 }
 
-UA_StatusCode NetworkLayerUDP_start(NetworkLayerUDP *layer) {
+static UA_StatusCode NetworkLayerUDP_start(NetworkLayerUDP *layer) {
 #ifdef _WIN32
 	WORD wVersionRequested;
 	WSADATA wsaData;
@@ -177,8 +186,8 @@ UA_StatusCode NetworkLayerUDP_start(NetworkLayerUDP *layer) {
     return UA_STATUSCODE_GOOD;
 }
 
-UA_Int32 NetworkLayerUDP_getWork(NetworkLayerUDP *layer, UA_WorkItem **workItems,
-                                 UA_UInt16 timeout) {
+static UA_Int32 NetworkLayerUDP_getWork(NetworkLayerUDP *layer, UA_WorkItem **workItems,
+                                        UA_UInt16 timeout) {
     UA_WorkItem *items = UA_NULL;
     setFDSet(layer);
     struct timeval tmptv = {0, timeout};
@@ -249,12 +258,12 @@ UA_Int32 NetworkLayerUDP_getWork(NetworkLayerUDP *layer, UA_WorkItem **workItems
     return j;
 }
 
-UA_Int32 NetworkLayerUDP_stop(NetworkLayerUDP * layer, UA_WorkItem **workItems) {
+static UA_Int32 NetworkLayerUDP_stop(NetworkLayerUDP * layer, UA_WorkItem **workItems) {
 	CLOSESOCKET(layer->serversockfd);
 	return 0;
 }
 
-void NetworkLayerUDP_delete(NetworkLayerUDP *layer) {
+static void NetworkLayerUDP_delete(NetworkLayerUDP *layer) {
 	free(layer);
 }
 

+ 15 - 16
examples/opcuaClient.c

@@ -14,15 +14,15 @@
 #include "ua_namespace_0.h"
 #include "ua_util.h"
 
-typedef struct ConnectionInfo{
+typedef struct ConnectionInfo {
 	UA_Int32 socket;
 	UA_UInt32 channelId;
 	UA_SequenceHeader sequenceHdr;
 	UA_NodeId authenticationToken;
 	UA_UInt32 tokenId;
-}ConnectionInfo;
+} ConnectionInfo;
 
-UA_Int32 sendHello(UA_Int32 sock, UA_String *endpointURL) {
+static UA_Int32 sendHello(UA_Int32 sock, UA_String *endpointURL) {
 
 	UA_TcpMessageHeader messageHeader;
 	messageHeader.isFinal = 'F';
@@ -54,7 +54,7 @@ UA_Int32 sendHello(UA_Int32 sock, UA_String *endpointURL) {
 	return 0;
 }
 
-int sendOpenSecureChannel(UA_Int32 sock) {
+static int sendOpenSecureChannel(UA_Int32 sock) {
 	UA_TcpMessageHeader msghdr;
 	msghdr.isFinal = 'F';
 	msghdr.messageType = UA_MESSAGETYPE_OPN;
@@ -120,8 +120,8 @@ int sendOpenSecureChannel(UA_Int32 sock) {
 	return 0;
 }
 
-UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
-                           UA_UInt32 requestId, UA_String *endpointUrl) {
+static UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
+                                  UA_UInt32 requestId, UA_String *endpointUrl) {
     UA_ByteString message;
 	UA_ByteString_newMembers(&message, 65536);
 	UA_UInt32 tmpChannelId = channelId;
@@ -173,7 +173,7 @@ UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId
 	return 0;
 }
 
-UA_Int32 closeSession(ConnectionInfo *connectionInfo){
+static UA_Int32 closeSession(ConnectionInfo *connectionInfo) {
 	UA_UInt32 offset = 0;
 
 	UA_ByteString message;
@@ -213,7 +213,7 @@ UA_Int32 closeSession(ConnectionInfo *connectionInfo){
 	UA_Int32 sendret = send(connectionInfo->socket, message.data, offset, 0);
 	UA_ByteString_deleteMembers(&message);
 	UA_CloseSessionRequest_deleteMembers(&rq);
-	if (sendret < 0) {
+	if(sendret < 0) {
 		printf("send closesessionrequest failed");
 		return 1;
 	}
@@ -221,7 +221,7 @@ UA_Int32 closeSession(ConnectionInfo *connectionInfo){
     return 0;
 }
 
-UA_Int32 closeSecureChannel(ConnectionInfo *connectionInfo){
+static UA_Int32 closeSecureChannel(ConnectionInfo *connectionInfo) {
 	UA_UInt32 offset = 0;
 
 	UA_ByteString message;
@@ -241,7 +241,6 @@ UA_Int32 closeSecureChannel(ConnectionInfo *connectionInfo){
 	msghdr.isFinal = 'F';
 	msghdr.messageType = UA_MESSAGETYPE_CLO;
 
-
 	msghdr.messageSize = 4 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) +
                          UA_CloseSecureChannelRequest_calcSizeBinary(&rq);
 
@@ -252,7 +251,7 @@ UA_Int32 closeSecureChannel(ConnectionInfo *connectionInfo){
 	UA_Int32 sendret = send(connectionInfo->socket, message.data, offset, 0);
 	UA_ByteString_deleteMembers(&message);
 	UA_CloseSecureChannelRequest_deleteMembers(&rq);
-	if (sendret < 0) {
+	if(sendret < 0) {
 		printf("send CloseSecureChannelRequest failed");
 		return 1;
 	}
@@ -260,8 +259,8 @@ UA_Int32 closeSecureChannel(ConnectionInfo *connectionInfo){
     return 0;
 }
 
-UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
-                             UA_UInt32 requestId, UA_NodeId authenticationToken) {
+static UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
+                                    UA_UInt32 requestId, UA_NodeId authenticationToken) {
 	UA_ByteString *message = UA_ByteString_new();
 	UA_ByteString_newMembers(message, 65536);
 	UA_UInt32 tmpChannelId = channelId;
@@ -306,7 +305,7 @@ UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 token
 
 }
 
-UA_Int64 sendReadRequest(ConnectionInfo *connectionInfo, UA_Int32 nodeIds_size,UA_NodeId* nodeIds){
+static UA_Int64 sendReadRequest(ConnectionInfo *connectionInfo, UA_Int32 nodeIds_size,UA_NodeId* nodeIds){
 		/*UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId,
                          UA_NodeId authenticationToken, UA_Int32 nodeIds_size,UA_NodeId* nodeIds) {
                          */
@@ -365,8 +364,8 @@ UA_Int64 sendReadRequest(ConnectionInfo *connectionInfo, UA_Int32 nodeIds_size,U
 	return tic;
 }
 
-int ua_client_connectUA(char* ipaddress,int port, UA_String *endpointUrl, ConnectionInfo *connectionInfo, UA_Boolean stateless, UA_Boolean udp)
-{
+static int ua_client_connectUA(char* ipaddress,int port, UA_String *endpointUrl, ConnectionInfo *connectionInfo,
+                               UA_Boolean stateless, UA_Boolean udp) {
 	UA_ByteString reply;
 	UA_ByteString_newMembers(&reply, 65536);
 	int sock;

+ 3 - 3
examples/opcuaServer.c

@@ -22,12 +22,12 @@
 
 UA_Boolean running = 1;
 
-void stopHandler(int sign) {
+static void stopHandler(int sign) {
     printf("Received Ctrl-C\n");
 	running = 0;
 }
 
-UA_ByteString loadCertificate() {
+static UA_ByteString loadCertificate(void) {
     UA_ByteString certificate = UA_STRING_NULL;
 	FILE *fp = NULL;
 	//FIXME: a potiential bug of locating the certificate, we need to get the path from the server's config
@@ -52,7 +52,7 @@ UA_ByteString loadCertificate() {
     return certificate;
 }
 
-void testCallback(UA_Server *server, void *data) {
+static void testCallback(UA_Server *server, void *data) {
        printf("testcallback\n");
 }
 

+ 1 - 1
include/ua_server.h

@@ -35,7 +35,7 @@ extern "C" {
 struct UA_Server;
 typedef struct UA_Server UA_Server;
 
-UA_Server UA_EXPORT * UA_Server_new();
+UA_Server UA_EXPORT * UA_Server_new(void);
 void UA_EXPORT UA_Server_setServerCertificate(UA_Server *server, UA_ByteString certificate);
 void UA_EXPORT UA_Server_delete(UA_Server *server);
 

+ 7 - 6
include/ua_types.h

@@ -23,6 +23,7 @@ extern "C" {
 #include "ua_config.h"
 
 #include <stdint.h>
+#include <stdbool.h>
 #ifdef UA_DEBUG
 #include <stdio.h>
 #endif
@@ -61,7 +62,7 @@ extern "C" {
  */
 
 /** @brief A two-state logical value (true or false). */
-typedef _Bool UA_Boolean;
+typedef bool UA_Boolean;
 
 /** @brief An integer value between -129 and 127. */
 typedef int8_t UA_SByte;
@@ -288,7 +289,7 @@ typedef void UA_InvalidType;
 #endif
 
 #define UA_TYPE_PROTOTYPES(TYPE)                                     \
-    TYPE UA_EXPORT * TYPE##_new();                                   \
+    TYPE UA_EXPORT * TYPE##_new(void);                               \
     void UA_EXPORT TYPE##_init(TYPE * p);                            \
     void UA_EXPORT TYPE##_delete(TYPE * p);                          \
     void UA_EXPORT TYPE##_deleteMembers(TYPE * p);                   \
@@ -296,7 +297,7 @@ typedef void UA_InvalidType;
     PRINTTYPE(TYPE)
 
 #define UA_TYPE_PROTOTYPES_NOEXPORT(TYPE)                            \
-    TYPE * TYPE##_new();                                             \
+    TYPE * TYPE##_new(void);                                         \
     void TYPE##_init(TYPE * p);                                      \
     void TYPE##_delete(TYPE * p);                                    \
     void TYPE##_deleteMembers(TYPE * p);                             \
@@ -351,7 +352,7 @@ void UA_EXPORT UA_String_printx_hex(char const *label, const UA_String *string);
 #endif
 
 /* DateTime */
-UA_DateTime UA_EXPORT UA_DateTime_now();
+UA_DateTime UA_EXPORT UA_DateTime_now(void);
 typedef struct UA_DateTimeStruct {
     UA_Int16 nanoSec;
     UA_Int16 microSec;
@@ -424,7 +425,7 @@ void UA_EXPORT UA_Array_print(const void *p, UA_Int32 noElements, const UA_TypeV
 
 typedef struct UA_Encoding {
     /**  Returns the size of the encoded element.*/
-    UA_Int32 (*calcSize)(const void *p);
+    UA_UInt32 (*calcSize)(const void *p);
     /** Encodes the type into the destination bytestring. */
     UA_StatusCode (*encode)(const void *src, UA_ByteString *dst, UA_UInt32 *offset);
     /** Decodes a ByteString into an UA datatype. */
@@ -436,7 +437,7 @@ typedef struct UA_Encoding {
 struct UA_TypeVTable {
     UA_NodeId     typeId;
     UA_Byte       *name;
-    void *        (*new)();
+    void *        (*new)(void);
     void          (*init)(void *p);
     UA_StatusCode (*copy)(void const *src, void *dst);
     void          (*delete)(void *p);

+ 56 - 23
src/server/ua_nodestore.c

@@ -13,7 +13,7 @@
 #define ALIVE_BIT (1 << 15) /* Alive bit in the refcount */
 struct nodeEntry {
     UA_UInt16 refcount;
-    const UA_Node node;
+    UA_Node node; // could be const, but then we cannot free it without compilers warnings
 };
 
 struct UA_NodeStore {
@@ -130,31 +130,31 @@ static UA_StatusCode expand(UA_NodeStore *ns) {
 static void deleteEntry(struct nodeEntry *entry) {
     if(entry->refcount > 0)
         return;
-    const UA_Node *node = &entry->node;
-    switch(node->nodeClass) {
+
+    switch(entry->node.nodeClass) {
     case UA_NODECLASS_OBJECT:
-        UA_ObjectNode_deleteMembers((UA_ObjectNode *)node);
+        UA_ObjectNode_deleteMembers((UA_ObjectNode*)&entry->node);
         break;
     case UA_NODECLASS_VARIABLE:
-        UA_VariableNode_deleteMembers((UA_VariableNode *)node);
+        UA_VariableNode_deleteMembers((UA_VariableNode*)&entry->node);
         break;
     case UA_NODECLASS_METHOD:
-        UA_MethodNode_deleteMembers((UA_MethodNode *)node);
+        UA_MethodNode_deleteMembers((UA_MethodNode *)&entry->node);
         break;
     case UA_NODECLASS_OBJECTTYPE:
-        UA_ObjectTypeNode_deleteMembers((UA_ObjectTypeNode *)node);
+        UA_ObjectTypeNode_deleteMembers((UA_ObjectTypeNode*)&entry->node);
         break;
     case UA_NODECLASS_VARIABLETYPE:
-        UA_VariableTypeNode_deleteMembers((UA_VariableTypeNode *)node);
+        UA_VariableTypeNode_deleteMembers((UA_VariableTypeNode*)&entry->node);
         break;
     case UA_NODECLASS_REFERENCETYPE:
-        UA_ReferenceTypeNode_deleteMembers((UA_ReferenceTypeNode *)node);
+        UA_ReferenceTypeNode_deleteMembers((UA_ReferenceTypeNode*)&entry->node);
         break;
     case UA_NODECLASS_DATATYPE:
-        UA_DataTypeNode_deleteMembers((UA_DataTypeNode *)node);
+        UA_DataTypeNode_deleteMembers((UA_DataTypeNode*)&entry->node);
         break;
     case UA_NODECLASS_VIEW:
-        UA_ViewNode_deleteMembers((UA_ViewNode *)node);
+        UA_ViewNode_deleteMembers((UA_ViewNode*)&entry->node);
         break;
     default:
         UA_assert(UA_FALSE);
@@ -163,9 +163,10 @@ static void deleteEntry(struct nodeEntry *entry) {
     UA_free(entry);
 }
 
-static INLINE struct nodeEntry * nodeEntryFromNode(const UA_Node *node) {
+/** Copies the node into the entry. Then free the original node (but not its content). */
+static INLINE struct nodeEntry * nodeEntryFromNode(UA_Node *node) {
     UA_UInt32 nodesize = 0;
-    /* Copy the node into the entry. Then reset the original node. It shall no longer be used. */
+    
     switch(node->nodeClass) {
     case UA_NODECLASS_OBJECT:
         nodesize = sizeof(UA_ObjectNode);
@@ -195,19 +196,20 @@ static INLINE struct nodeEntry * nodeEntryFromNode(const UA_Node *node) {
         UA_assert(UA_FALSE);
     }
 
-    struct nodeEntry *entry;
-    if(!(entry = UA_malloc(sizeof(struct nodeEntry) - sizeof(UA_Node) + nodesize)))
+    struct nodeEntry *newEntry;
+    if(!(newEntry = UA_malloc(sizeof(struct nodeEntry) - sizeof(UA_Node) + nodesize)))
         return UA_NULL;
-    UA_memcpy((void *)&entry->node, node, nodesize);
-    UA_free((void*)node);
-    return entry;
+
+    UA_memcpy(&newEntry->node, node, nodesize);
+    UA_free(node);
+    return newEntry;
 }
 
 /**********************/
 /* Exported functions */
 /**********************/
 
-UA_NodeStore * UA_NodeStore_new() {
+UA_NodeStore * UA_NodeStore_new(void) {
     UA_NodeStore *ns;
     if(!(ns = UA_malloc(sizeof(UA_NodeStore))))
         return UA_NULL;
@@ -244,10 +246,22 @@ UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boo
         if(expand(ns) != UA_STATUSCODE_GOOD)
             return UA_STATUSCODE_BADINTERNALERROR;
     }
+    
+    /* The node is const so the user gets a const pointer back. Still, we want
+       to make small changes to the node internally, then add it to the hashmap
+       and return a new const pointer. */
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+    UA_Node *editableNode = (UA_Node*)*node;
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
 
     // get a free slot
     struct nodeEntry **slot;
-    UA_NodeId *nodeId = (UA_NodeId *)&(*node)->nodeId;
+    UA_NodeId *nodeId = &editableNode->nodeId;
     if(UA_NodeId_isNull(nodeId)) {
         // find a unique nodeid that is not taken
         nodeId->identifierType = UA_NODEIDTYPE_NUMERIC;
@@ -268,7 +282,7 @@ UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boo
             return UA_STATUSCODE_BADNODEIDEXISTS;
     }
     
-    struct nodeEntry *entry = nodeEntryFromNode(*node);
+    struct nodeEntry *entry = nodeEntryFromNode(editableNode);
     if(!entry)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
@@ -298,7 +312,16 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
     if(&(*slot)->node != oldNode)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    struct nodeEntry *entry = nodeEntryFromNode(*node);
+    /* We need to able to free the new node when copying it into the entry. */
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+    struct nodeEntry *entry = nodeEntryFromNode((UA_Node *)*node);
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
     if(!entry)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
@@ -349,7 +372,17 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
 }
 
 void UA_NodeStore_release(const UA_Node *managed) {
-    struct nodeEntry *entry = (struct nodeEntry *) ((char*)managed - offsetof(struct nodeEntry, node));
+    /* We know what we are doing here and remove a compiler warning. Nobody has
+       a reference to the const pointer, so we can free it. */
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
+    struct nodeEntry *entry = (struct nodeEntry *) ((UA_Byte*)managed - offsetof(struct nodeEntry, node));
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
     entry->refcount--;
     deleteEntry(entry);
 }

+ 1 - 1
src/server/ua_nodestore.h

@@ -28,7 +28,7 @@ struct UA_NodeStore;
 typedef struct UA_NodeStore UA_NodeStore;
 
 /** Create a new namespace */
-UA_NodeStore * UA_NodeStore_new();
+UA_NodeStore * UA_NodeStore_new(void);
 
 /** Delete the namespace and all nodes in it */
 void UA_NodeStore_delete(UA_NodeStore *ns);

+ 58 - 4
src/server/ua_nodestore_concurrent.c

@@ -13,7 +13,7 @@ struct nodeEntry {
     struct cds_lfht_node htn;      /* contains next-ptr for urcu-hashmap */
     struct rcu_head      rcu_head; /* For call-rcu */
     UA_UInt16 refcount;            /* Counts the amount of readers on it [alive-bit, 15 counter-bits] */
-    const UA_Node node;            /* Might be cast from any _bigger_ UA_Node* type. Allocate enough memory! */
+    UA_Node node;                  /* Might be cast from any _bigger_ UA_Node* type. Allocate enough memory! */
 };
 
 struct UA_NodeStore {
@@ -22,7 +22,7 @@ struct UA_NodeStore {
 
 #include "ua_nodestore_hash.inc"
 
-static inline void node_deleteMembers(const UA_Node *node) {
+static void node_deleteMembers(UA_Node *node) {
     switch(node->nodeClass) {
     case UA_NODECLASS_OBJECT:
         UA_ObjectNode_deleteMembers((UA_ObjectNode *)node);
@@ -66,7 +66,15 @@ static int compare(struct cds_lfht_node *htn, const void *orig) {
    section) increased the refcount, we only need to wait for the refcount
    to reach zero. */
 static void markDead(struct rcu_head *head) {
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
     struct nodeEntry *entry = caa_container_of(head, struct nodeEntry, rcu_head);
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
     uatomic_and(&entry->refcount, ~ALIVE_BIT); // set the alive bit to zero
     if(uatomic_read(&entry->refcount) > 0)
         return;
@@ -77,11 +85,19 @@ static void markDead(struct rcu_head *head) {
 
 /* Free the entry if it is dead and nobody uses it anymore */
 void UA_NodeStore_release(const UA_Node *managed) {
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
     struct nodeEntry *entry = caa_container_of(managed, struct nodeEntry, node); // pointer to the first entry
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
     if(uatomic_sub_return(&entry->refcount, 1) > 0)
         return;
 
-    node_deleteMembers(managed);
+    node_deleteMembers(&entry->node);
     UA_free(entry);
 }
 
@@ -107,7 +123,14 @@ void UA_NodeStore_delete(UA_NodeStore *ns) {
     cds_lfht_first(ht, &iter);
     while(iter.node) {
         if(!cds_lfht_del(ht, iter.node)) {
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
             struct nodeEntry *entry = caa_container_of(iter.node, struct nodeEntry, htn);
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
             call_rcu(&entry->rcu_head, markDead);
         }
         cds_lfht_next(ht, &iter);
@@ -194,7 +217,15 @@ UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boo
         rcu_read_unlock();
     }
 
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
     UA_free((UA_Node *)*node);     /* The old node is replaced by a managed node. */
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
     if(getManaged)
         *node = &entry->node;
     else
@@ -258,7 +289,14 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
     }
 
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
     struct nodeEntry *oldEntry = caa_container_of(iter.node, struct nodeEntry, htn);
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
     /* The node we found is obsolete*/
     if(&oldEntry->node != oldNode) {
         rcu_read_unlock();
@@ -278,7 +316,15 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
     call_rcu(&oldEntry->rcu_head, markDead);
     rcu_read_unlock();
 
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
     UA_free((UA_Node *)*node); // was copied to newEntry and is obsolete
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
     if(getManaged)
         *node = &newEntry->node;
     else
@@ -299,7 +345,15 @@ UA_StatusCode UA_NodeStore_remove(UA_NodeStore *ns, const UA_NodeId *nodeid) {
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
     }
 
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
     struct nodeEntry *entry = caa_container_of(iter.node, struct nodeEntry, htn);
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
     call_rcu(&entry->rcu_head, markDead);
     rcu_read_unlock();
 
@@ -337,7 +391,7 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
         const UA_Node      *node = &found_entry->node;
         rcu_read_unlock();
         visitor(node);
-        UA_NodeStore_release((UA_Node *)node);
+        UA_NodeStore_release((const UA_Node *)node);
         rcu_read_lock();
         cds_lfht_next(ht, &iter);
     }

+ 10 - 2
src/server/ua_nodestore_hash.inc

@@ -17,7 +17,15 @@ static hash_t hash_array(const UA_Byte *data, UA_UInt32 len, UA_UInt32 seed) {
     static const uint32_t m  = 5;
     static const uint32_t n  = 0xe6546b64;
     hash_t hash = seed;
+    /* Somce compilers emit a warning when casting from a byte array to ints. */
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#endif
     blocks = (const uint32_t *)data;
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
     for(int32_t i = 0;i < nblocks;i++) {
         uint32_t k = blocks[i];
         k    *= c1;
@@ -59,9 +67,9 @@ static hash_t hash(const UA_NodeId *n) {
     case UA_NODEIDTYPE_STRING:
         return hash_array(n->identifier.string.data, n->identifier.string.length, n->namespaceIndex);
     case UA_NODEIDTYPE_GUID:
-        return hash_array((UA_Byte *)&(n->identifier.guid), sizeof(UA_Guid), n->namespaceIndex);
+        return hash_array((const UA_Byte *)&(n->identifier.guid), sizeof(UA_Guid), n->namespaceIndex);
     case UA_NODEIDTYPE_BYTESTRING:
-        return hash_array((UA_Byte *)n->identifier.byteString.data, n->identifier.byteString.length, n->namespaceIndex);
+        return hash_array((const UA_Byte *)n->identifier.byteString.data, n->identifier.byteString.length, n->namespaceIndex);
     default:
         UA_assert(UA_FALSE);
         return 0;

+ 1 - 1
src/server/ua_server.c

@@ -68,7 +68,7 @@ void UA_Server_delete(UA_Server *server) {
 #endif
 }
 
-UA_Server * UA_Server_new() {
+UA_Server * UA_Server_new(void) {
     UA_Server *server = UA_malloc(sizeof(UA_Server));
     if(!server)
         return UA_NULL;

+ 6 - 5
src/server/ua_server_addressspace.c

@@ -2,7 +2,7 @@
 #include "ua_server_internal.h"
 #include "ua_namespace_0.h"
 
-const UA_TypeVTable * UA_Node_getTypeVT(const UA_Node *node) {
+static const UA_TypeVTable * UA_Node_getTypeVT(const UA_Node *node) {
     switch(node->nodeClass) {
     case UA_NODECLASS_OBJECT:
         return &UA_TYPES[UA_OBJECTNODE];
@@ -43,8 +43,8 @@ void UA_Server_addScalarVariableNode(UA_Server *server, UA_QualifiedName *browse
 }
 
 /* Adds a one-way reference to the local nodestore */
-UA_StatusCode addOneWayReferenceWithSession(UA_Server *server, UA_Session *session,
-                                            const UA_AddReferencesItem *item) {
+static UA_StatusCode addOneWayReferenceWithSession(UA_Server *server, UA_Session *session,
+                                                   const UA_AddReferencesItem *item) {
     // use the servers nodestore
     const UA_Node *node = UA_NodeStore_get(server->nodestore, &item->sourceNodeId);
     // todo differentiate between error codes
@@ -84,7 +84,8 @@ UA_StatusCode addOneWayReferenceWithSession(UA_Server *server, UA_Session *sessi
     UA_free(old_refs);
     newNode->references = new_refs;
     newNode->referencesSize = ++count;
-    retval = UA_NodeStore_replace(server->nodestore, node, (const UA_Node **)&newNode, UA_FALSE);
+    const UA_Node *constNode = newNode;
+    retval = UA_NodeStore_replace(server->nodestore, node, (const UA_Node **)&constNode, UA_FALSE);
     UA_NodeStore_release(node);
     if(retval != UA_STATUSCODE_BADINTERNALERROR)
         return retval;
@@ -205,7 +206,7 @@ UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *se
     *node = UA_NULL;
     
  ret2:
-    UA_NodeStore_release((UA_Node*)referenceType);
+    UA_NodeStore_release((const UA_Node*)referenceType);
  ret:
     UA_NodeStore_release(parent);
 

+ 6 - 6
src/server/ua_server_worker.c

@@ -207,10 +207,10 @@ static UA_UInt16 processTimedWork(UA_Server *server) {
 
             UA_TimedWork *prevTw = tw; // after which tw do we insert?
             while(UA_TRUE) {
-                UA_TimedWork *next = LIST_NEXT(prevTw, pointers);
-                if(!next || next->time > tw->time)
+                UA_TimedWork *n = LIST_NEXT(prevTw, pointers);
+                if(!n || n->time > tw->time)
                     break;
-                prevTw = next;
+                prevTw = n;
             }
             if(prevTw != tw) {
                 LIST_REMOVE(tw, pointers);
@@ -228,10 +228,10 @@ static UA_UInt16 processTimedWork(UA_Server *server) {
             tw->time += tw->repetitionInterval;
             UA_TimedWork *prevTw = tw;
             while(UA_TRUE) {
-                UA_TimedWork *next = LIST_NEXT(prevTw, pointers);
-                if(!next || next->time > tw->time)
+                UA_TimedWork *n = LIST_NEXT(prevTw, pointers);
+                if(!n || n->time > tw->time)
                     break;
-                prevTw = next;
+                prevTw = n;
             }
             if(prevTw != tw) {
                 LIST_REMOVE(tw, pointers);

+ 229 - 130
src/server/ua_services_attribute.c

@@ -64,105 +64,106 @@ static void readValue(UA_Server *server, const UA_ReadValueId *id, UA_DataValue
         CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE | UA_NODECLASS_OBJECTTYPE | UA_NODECLASS_VARIABLETYPE |
                         UA_NODECLASS_DATATYPE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BOOLEAN], &((UA_ReferenceTypeNode *)node)->isAbstract);
+        retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BOOLEAN],
+                                          &((const UA_ReferenceTypeNode *)node)->isAbstract);
         break;
 
     case UA_ATTRIBUTEID_SYMMETRIC:
         CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BOOLEAN],
-                                          &((UA_ReferenceTypeNode *)node)->symmetric);
+                                          &((const UA_ReferenceTypeNode *)node)->symmetric);
         break;
 
     case UA_ATTRIBUTEID_INVERSENAME:
         CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_LOCALIZEDTEXT],
-                                          &((UA_ReferenceTypeNode *)node)->inverseName);
+                                          &((const UA_ReferenceTypeNode *)node)->inverseName);
         break;
 
     case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
         CHECK_NODECLASS(UA_NODECLASS_VIEW);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BOOLEAN],
-                                          &((UA_ViewNode *)node)->containsNoLoops);
+                                          &((const UA_ViewNode *)node)->containsNoLoops);
         break;
 
     case UA_ATTRIBUTEID_EVENTNOTIFIER:
         CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BYTE],
-                                          &((UA_ViewNode *)node)->eventNotifier);
+                                          &((const UA_ViewNode *)node)->eventNotifier);
         break;
 
     case UA_ATTRIBUTEID_VALUE:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copy(&((UA_VariableNode *)node)->value, &v->value); // todo: zero-copy
+        retval |= UA_Variant_copy(&((const UA_VariableNode *)node)->value, &v->value); // todo: zero-copy
         break;
 
     case UA_ATTRIBUTEID_DATATYPE:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_NODEID],
-                                          &((UA_VariableTypeNode *)node)->dataType);
+                                          &((const UA_VariableTypeNode *)node)->dataType);
         break;
 
     case UA_ATTRIBUTEID_VALUERANK:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_INT32],
-                                          &((UA_VariableTypeNode *)node)->valueRank);
+                                          &((const UA_VariableTypeNode *)node)->valueRank);
         break;
 
     case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         UA_Variant_copySetArray(&v->value, &UA_TYPES[UA_UINT32],
-                                ((UA_VariableTypeNode *)node)->arrayDimensionsSize,
-                                &((UA_VariableTypeNode *)node)->arrayDimensions);
+                                ((const UA_VariableTypeNode *)node)->arrayDimensionsSize,
+                                &((const UA_VariableTypeNode *)node)->arrayDimensions);
         break;
 
     case UA_ATTRIBUTEID_ACCESSLEVEL:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BYTE],
-                                          &((UA_VariableNode *)node)->accessLevel);
+                                          &((const UA_VariableNode *)node)->accessLevel);
         break;
 
     case UA_ATTRIBUTEID_USERACCESSLEVEL:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BYTE],
-                                          &((UA_VariableNode *)node)->userAccessLevel);
+                                          &((const UA_VariableNode *)node)->userAccessLevel);
         break;
 
     case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_DOUBLE],
-                                          &((UA_VariableNode *)node)->minimumSamplingInterval);
+                                          &((const UA_VariableNode *)node)->minimumSamplingInterval);
         break;
 
     case UA_ATTRIBUTEID_HISTORIZING:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BOOLEAN],
-                                          &((UA_VariableNode *)node)->historizing);
+                                          &((const UA_VariableNode *)node)->historizing);
         break;
 
     case UA_ATTRIBUTEID_EXECUTABLE:
         CHECK_NODECLASS(UA_NODECLASS_METHOD);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BOOLEAN],
-                                          &((UA_MethodNode *)node)->executable);
+                                          &((const UA_MethodNode *)node)->executable);
         break;
 
     case UA_ATTRIBUTEID_USEREXECUTABLE:
         CHECK_NODECLASS(UA_NODECLASS_METHOD);
         v->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |= UA_Variant_copySetValue(&v->value, &UA_TYPES[UA_BOOLEAN],
-                                          &((UA_MethodNode *)node)->userExecutable);
+                                          &((const UA_MethodNode *)node)->userExecutable);
         break;
 
     default:
@@ -256,129 +257,227 @@ void Service_Read(UA_Server *server, UA_Session *session, const UA_ReadRequest *
 }
 
 static UA_StatusCode writeValue(UA_Server *server, UA_WriteValue *writeValue) {
-    const UA_Node *node = UA_NodeStore_get(server->nodestore, &writeValue->nodeId);
-    if(!node)
-        return UA_STATUSCODE_BADNODEIDUNKNOWN;
-
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
-    switch(writeValue->attributeId) {
-    case UA_ATTRIBUTEID_NODEID:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){ } */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_NODECLASS:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){ } */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_BROWSENAME:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
 
-    case UA_ATTRIBUTEID_DISPLAYNAME:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_DESCRIPTION:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_WRITEMASK:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_USERWRITEMASK:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_ISABSTRACT:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_SYMMETRIC:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_INVERSENAME:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_EVENTNOTIFIER:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_VALUE:
-        if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT) {
-            retval |= UA_Variant_copy(&writeValue->value.value, &((UA_VariableNode *)node)->value); // todo: zero-copy
+    do {
+        const UA_Node *node = UA_NodeStore_get(server->nodestore, &writeValue->nodeId);
+        if(!node)
+            return UA_STATUSCODE_BADNODEIDUNKNOWN;
+
+        UA_Node *newNode;
+        switch(node->nodeClass) {
+        case UA_NODECLASS_OBJECT:
+            newNode = (UA_Node *)UA_ObjectNode_new();
+            UA_ObjectNode_copy((const UA_ObjectNode*)node, (UA_ObjectNode *)newNode);
+            break;
+
+        case UA_NODECLASS_VARIABLE:
+            newNode = (UA_Node *)UA_VariableNode_new();
+            UA_VariableNode_copy((const UA_VariableNode*)node, (UA_VariableNode *)newNode);
+            break;
+
+        case UA_NODECLASS_METHOD:
+            newNode = (UA_Node *)UA_MethodNode_new();
+            UA_MethodNode_copy((const UA_MethodNode*)node, (UA_MethodNode *)newNode);
+            break;
+
+        case UA_NODECLASS_OBJECTTYPE:
+            newNode = (UA_Node *)UA_ObjectTypeNode_new();
+            UA_ObjectTypeNode_copy((const UA_ObjectTypeNode*)node, (UA_ObjectTypeNode *)newNode);
+            break;
+
+        case UA_NODECLASS_VARIABLETYPE:
+            newNode = (UA_Node *)UA_VariableTypeNode_new();
+            UA_VariableTypeNode_copy((const UA_VariableTypeNode*)node, (UA_VariableTypeNode *)newNode);
+            break;
+
+        case UA_NODECLASS_REFERENCETYPE:
+            newNode = (UA_Node *)UA_ReferenceTypeNode_new();
+            UA_ReferenceTypeNode_copy((const UA_ReferenceTypeNode*)node, (UA_ReferenceTypeNode *)newNode);
+            break;
+
+        case UA_NODECLASS_DATATYPE:
+            newNode = (UA_Node *)UA_DataTypeNode_new();
+            UA_DataTypeNode_copy((const UA_DataTypeNode*)node, (UA_DataTypeNode *)newNode);
+            break;
+
+        case UA_NODECLASS_VIEW:
+            newNode = (UA_Node *)UA_ViewNode_new();
+            UA_ViewNode_copy((const UA_ViewNode*)node, (UA_ViewNode *)newNode);
+            break;
+
+        default:
+            return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+            break;
         }
-        break;
-
-    case UA_ATTRIBUTEID_DATATYPE:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_VALUERANK:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_ACCESSLEVEL:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
-
-    case UA_ATTRIBUTEID_USERACCESSLEVEL:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
 
-    case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
+        switch(writeValue->attributeId) {
+        case UA_ATTRIBUTEID_NODEID:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){ } */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_NODECLASS:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){ } */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_BROWSENAME:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_DISPLAYNAME:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_DESCRIPTION:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_WRITEMASK:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_USERWRITEMASK:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_ISABSTRACT:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_SYMMETRIC:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_INVERSENAME:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_EVENTNOTIFIER:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_VALUE:
+            if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT) {
+                retval |= UA_Variant_copy(&writeValue->value.value, &((UA_VariableNode *)newNode)->value); // todo: zero-copy
+            }
+            break;
+
+        case UA_ATTRIBUTEID_DATATYPE:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_VALUERANK:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_ACCESSLEVEL:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_USERACCESSLEVEL:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_HISTORIZING:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_EXECUTABLE:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        case UA_ATTRIBUTEID_USEREXECUTABLE:
+            /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
+            retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
+            break;
+
+        default:
+            retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+            break;
+        }
 
-    case UA_ATTRIBUTEID_HISTORIZING:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
+        if(retval != UA_STATUSCODE_GOOD)
+            break;
 
-    case UA_ATTRIBUTEID_EXECUTABLE:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
+        const UA_Node *constPtr = newNode; // compilers complain if we directly cast
+        if(UA_NodeStore_replace(server->nodestore, node, &constPtr, UA_FALSE) == UA_STATUSCODE_GOOD) {
+            UA_NodeStore_release(node);
+            break;
+        }
 
-    case UA_ATTRIBUTEID_USEREXECUTABLE:
-        /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){} */
-        retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
-        break;
+        /* The node was replaced in another thread. Restart. */
+        UA_NodeStore_release(node);
+        switch(node->nodeClass) {
+        case UA_NODECLASS_OBJECT:
+            UA_ObjectNode_delete((UA_ObjectNode *)newNode);
+            break;
+
+        case UA_NODECLASS_VARIABLE:
+            UA_VariableNode_delete((UA_VariableNode *)newNode);
+            break;
+
+        case UA_NODECLASS_METHOD:
+            UA_MethodNode_delete((UA_MethodNode *)newNode);
+            break;
+            
+        case UA_NODECLASS_OBJECTTYPE:
+            UA_ObjectTypeNode_delete((UA_ObjectTypeNode *)newNode);
+            break;
+            
+        case UA_NODECLASS_VARIABLETYPE:
+            UA_VariableTypeNode_delete((UA_VariableTypeNode *)newNode);
+            break;
+            
+        case UA_NODECLASS_REFERENCETYPE:
+            UA_ReferenceTypeNode_delete((UA_ReferenceTypeNode *)newNode);
+            break;
+            
+        case UA_NODECLASS_DATATYPE:
+            UA_DataTypeNode_delete((UA_DataTypeNode *)newNode);
+            break;
+            
+        case UA_NODECLASS_VIEW:
+            UA_ViewNode_delete((UA_ViewNode *)newNode);
+            break;
+
+        default:
+            break;
+        }
 
-    default:
-        retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
-        break;
-    }
+    } while(UA_TRUE);
 
-    UA_NodeStore_release(node);
     return retval;
 }
 

+ 4 - 3
src/server/ua_services_nodemanagement.c

@@ -197,7 +197,7 @@ static void addNodeFromAttributes(UA_Server *server, UA_Session *session, UA_Add
     }
 
     // parse the node
-    UA_Node *node;
+    UA_Node *node = UA_NULL;
     const UA_TypeVTable *nodeVT = UA_NULL;
 
     switch (item->nodeClass) {
@@ -221,8 +221,9 @@ static void addNodeFromAttributes(UA_Server *server, UA_Session *session, UA_Add
         return;
 
     // add the node
-    *result = UA_Server_addNodeWithSession(server, session, (const UA_Node **)&node,
-                                           &item->parentNodeId, &item->referenceTypeId);
+    const UA_Node *constNode = node; // compilers complain if we cast directly
+    *result = UA_Server_addNodeWithSession(server, session, &constNode, &item->parentNodeId,
+                                           &item->referenceTypeId);
     if(result->statusCode != UA_STATUSCODE_GOOD)
         nodeVT->delete(node);
 }

+ 2 - 2
src/server/ua_services_session.c

@@ -35,7 +35,7 @@ void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
     // make the channel know about the session
 	UA_Session *foundSession;
 	UA_SessionManager_getSessionByToken(&server->sessionManager,
-                                        (UA_NodeId*)&request->requestHeader.authenticationToken,
+                                        (const UA_NodeId*)&request->requestHeader.authenticationToken,
                                         &foundSession);
 
 	if(foundSession == UA_NULL)
@@ -48,7 +48,7 @@ void Service_CloseSession(UA_Server *server, const UA_CloseSessionRequest *reque
                               UA_CloseSessionResponse *response) {
 	UA_Session *foundSession;
 	UA_SessionManager_getSessionByToken(&server->sessionManager,
-			(UA_NodeId*)&request->requestHeader.authenticationToken,
+			(const UA_NodeId*)&request->requestHeader.authenticationToken,
 			&foundSession);
 
 	if(foundSession == UA_NULL){

+ 4 - 3
src/server/ua_services_view.c

@@ -129,7 +129,7 @@ static UA_StatusCode findRelevantReferenceTypes(UA_NodeStore *ns, const UA_NodeI
             if(retval)
                 currentLastIndex--; // undo if we need to delete the typeArray
         }
-        UA_NodeStore_release((UA_Node*)node);
+        UA_NodeStore_release((const UA_Node*)node);
     } while(++currentIndex <= currentLastIndex && retval == UA_STATUSCODE_GOOD);
 
     if(retval)
@@ -158,7 +158,8 @@ static void getBrowseResult(UA_NodeStore *ns, const UA_BrowseDescription *browse
             if(browseResult->statusCode != UA_STATUSCODE_GOOD)
                 return;
         } else {
-            relevantReferenceTypes = (UA_NodeId*)&browseDescription->referenceTypeId; // is const
+            relevantReferenceTypes = UA_NodeId_new();
+            UA_NodeId_copy(&browseDescription->referenceTypeId, relevantReferenceTypes);
             relevantReferenceTypesSize = 1;
         }
     }
@@ -219,7 +220,7 @@ static void getBrowseResult(UA_NodeStore *ns, const UA_BrowseDescription *browse
     }
 
     UA_NodeStore_release(parentNode);
-    if(!returnAll && browseDescription->includeSubtypes)
+    if(!returnAll)
         UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesSize, &UA_TYPES[UA_NODEID]);
 }
 

+ 5 - 3
src/server/ua_session_manager.c

@@ -35,7 +35,8 @@ void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager) {
     }
 }
 
-UA_StatusCode UA_SessionManager_getSessionById(UA_SessionManager *sessionManager, UA_NodeId *sessionId, UA_Session **session) {
+UA_StatusCode UA_SessionManager_getSessionById(UA_SessionManager *sessionManager, const UA_NodeId *sessionId,
+                                               UA_Session **session) {
     if(sessionManager == UA_NULL) {
         *session = UA_NULL;
         return UA_STATUSCODE_BADINTERNALERROR;
@@ -58,7 +59,8 @@ UA_StatusCode UA_SessionManager_getSessionById(UA_SessionManager *sessionManager
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_SessionManager_getSessionByToken(UA_SessionManager *sessionManager, UA_NodeId *token, UA_Session **session) {
+UA_StatusCode UA_SessionManager_getSessionByToken(UA_SessionManager *sessionManager, const UA_NodeId *token,
+                                                  UA_Session **session) {
     if(sessionManager == UA_NULL) {
         *session = UA_NULL;
         return UA_STATUSCODE_BADINTERNALERROR;
@@ -107,7 +109,7 @@ UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, UA_NodeId  *sessionId) {
+UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, const UA_NodeId *sessionId) {
     struct session_list_entry *current = UA_NULL;
     LIST_FOREACH(current, &sessionManager->sessions, pointers) {
         if(UA_NodeId_equal(&current->session.sessionId, sessionId))

+ 3 - 3
src/server/ua_session_manager.h

@@ -23,14 +23,14 @@ UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
                                               UA_SecureChannel *channel, UA_Session **session);
 
 UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager,
-                                              UA_NodeId         *sessionId);
+                                              const UA_NodeId *sessionId);
 
 /** Finds the session which is identified by the sessionId */
 UA_StatusCode UA_SessionManager_getSessionById(UA_SessionManager *sessionManager,
-                                               UA_NodeId *sessionId, UA_Session **session);
+                                               const UA_NodeId *sessionId, UA_Session **session);
 
 UA_StatusCode UA_SessionManager_getSessionByToken(UA_SessionManager *sessionManager,
-                                                  UA_NodeId *token, UA_Session **session);
+                                                  const UA_NodeId *token, UA_Session **session);
 
 //UA_Int32 UA_SessionManager_updateSessions();
 //UA_Int32 UA_SessionManager_generateToken(UA_Session session, UA_Int32 requestedLifeTime, SecurityTokenRequestType requestType, UA_ChannelSecurityToken* newToken);

+ 22 - 22
src/ua_config.h.in

@@ -14,27 +14,27 @@
 
 /* Function Export */
 #ifdef _WIN32
-  #ifdef UA_DYNAMIC_LINKING
-    #ifdef __GNUC__
-      #define UA_EXPORT __attribute__ ((dllexport))
-    #else
-      #define UA_EXPORT __declspec(dllexport)
-    #endif
-  #else
-    #ifndef STATIC_LINKING
-    	#ifdef __GNUC__
-      		#define UA_EXPORT __attribute__ ((dllimport))
-    	#else
-      		#define UA_EXPORT __declspec(dllimport)
-    	#endif
-    #else
-    	#define UA_EXPORT
-    #endif
-  #endif
+#  ifdef UA_DYNAMIC_LINKING
+#    ifdef __GNUC__
+#      define UA_EXPORT __attribute__ ((dllexport))
+#    else
+#      define UA_EXPORT __declspec(dllexport)
+#    endif
+#  else
+#    ifndef STATIC_LINKING
+#      ifdef __GNUC__
+#        define UA_EXPORT __attribute__ ((dllimport))
+#      else
+#        define UA_EXPORT __declspec(dllimport)
+#      endif
+#    else
+#      define UA_EXPORT
+#    endif
+#  endif
 #else
-  #if __GNUC__ >= 4 || __clang__
-    #define UA_EXPORT __attribute__ ((visibility ("default")))
-  #else
-    #define UA_EXPORT
-  #endif
+#  if __GNUC__ >= 4 || __clang__
+#    define UA_EXPORT __attribute__ ((visibility ("default")))
+#  else
+#    define UA_EXPORT
+#  endif
 #endif

+ 2 - 2
src/ua_session.c

@@ -42,14 +42,14 @@ UA_Session adminSession = {
     .validTill = UA_INT64_MAX,
     .channel = UA_NULL};
 
-UA_Session * UA_Session_new() {
+UA_Session * UA_Session_new(void) {
     UA_Session *s = UA_malloc(sizeof(UA_Session));
     if(s) UA_Session_init(s);
     return s;
 }
 
 /* TODO: Nobody seems to call this function right now */
-UA_StatusCode UA_Session_generateToken(UA_NodeId *newToken, UA_UInt32 *seed) {
+static UA_StatusCode UA_Session_generateToken(UA_NodeId *newToken, UA_UInt32 *seed) {
     newToken->namespaceIndex = 0; // where else?
     newToken->identifierType = UA_NODEIDTYPE_GUID;
     newToken->identifier.guid = UA_Guid_random(seed);

+ 1 - 1
src/ua_session.h

@@ -25,7 +25,7 @@ struct UA_Session {
 extern UA_Session anonymousSession; ///< If anonymous access is allowed, this session is used internally (Session ID: 0)
 extern UA_Session adminSession; ///< Local access to the services (for startup and maintenance) uses this Session with all possible access rights (Session ID: 1)
 
-UA_Session * UA_Session_new();
+UA_Session * UA_Session_new(void);
 void UA_Session_init(UA_Session *session);
 void UA_Session_delete(UA_Session *session);
 void UA_Session_deleteMembers(UA_Session *session);

+ 1 - 1
src/ua_transport.c

@@ -44,7 +44,7 @@ UA_StatusCode UA_MessageType_decodeBinary(UA_ByteString const *src, UA_UInt32 *o
 
 #ifdef UA_DEBUG
 void UA_MessageType_print(const UA_MessageType *p, FILE *stream) {
-    UA_Byte *b = (UA_Byte *)p;
+    const UA_Byte *b = (const UA_Byte *)p;
     fprintf(stream, "%c%c%c", b[2], b[1], b[0]);
 }
 #endif

+ 49 - 49
src/ua_types.c

@@ -14,9 +14,9 @@
 #include "ua_util.h"
 
 #ifdef _MSC_VER
-#define RAND(SEED) rand()
+#define RAND(SEED) (UA_UInt32)rand()
 #else
-#define RAND(SEED) rand_r(SEED)
+#define RAND(SEED) (UA_UInt32)rand_r(SEED)
 #endif
 
 #ifdef UA_DEBUG
@@ -147,15 +147,14 @@ void UA_String_init(UA_String *p) {
 UA_TYPE_DELETE_DEFAULT(UA_String)
 void UA_String_deleteMembers(UA_String *p) {
     UA_free(p->data);
-    UA_String_init(p);
 }
 
 UA_StatusCode UA_String_copy(UA_String const *src, UA_String *dst) {
     UA_String_init(dst);
     if(src->length > 0) {
-        if(!(dst->data = UA_malloc(src->length)))
+        if(!(dst->data = UA_malloc((UA_UInt32)src->length)))
             return UA_STATUSCODE_BADOUTOFMEMORY;
-        UA_memcpy((void *)dst->data, src->data, src->length);
+        UA_memcpy((void *)dst->data, src->data, (UA_UInt32)src->length);
     }
     dst->length = src->length;
     return UA_STATUSCODE_GOOD;
@@ -173,7 +172,7 @@ void UA_String_print(const UA_String *p, FILE *stream) {
 
 /* The c-string needs to be null-terminated. the string cannot be smaller than zero. */
 UA_Int32 UA_String_copycstring(char const *src, UA_String *dst) {
-    UA_Int32 length = strlen(src);
+    UA_UInt32 length = (UA_UInt32) strlen(src);
     if(length == 0) {
         dst->length = 0;
         dst->data = UA_NULL;
@@ -182,7 +181,7 @@ UA_Int32 UA_String_copycstring(char const *src, UA_String *dst) {
     dst->data = UA_malloc(length);
     if(dst->data != UA_NULL) {
         UA_memcpy(dst->data, src, length);
-        dst->length = length;
+        dst->length = (UA_Int32) (length & ~(1<<31)); // the highest bit is always zero to avoid overflows into negative values
     } else {
         dst->length = -1;
         return UA_STATUSCODE_BADOUTOFMEMORY;
@@ -195,23 +194,23 @@ UA_StatusCode UA_String_copyprintf(char const *fmt, UA_String *dst, ...) {
     char src[UA_STRING_COPYPRINTF_BUFSIZE];
     va_list ap;
     va_start(ap, dst);
-#ifndef WIN32
+#if defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
 #endif
     // vsnprintf should only take a literal and no variable to be secure
     UA_Int32 len = vsnprintf(src, UA_STRING_COPYPRINTF_BUFSIZE, fmt, ap);
-#ifndef WIN32
+#if defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic pop
 #endif
     va_end(ap);
     if(len < 0)  // FIXME: old glibc 2.0 would return -1 when truncated
         return UA_STATUSCODE_BADINTERNALERROR;
-    // since glibc 2.1 vsnprintf returns len that would have resulted if buf were large enough
+    // since glibc 2.1 vsnprintf returns the len that would have resulted if buf were large enough
     len = ( len > UA_STRING_COPYPRINTF_BUFSIZE ? UA_STRING_COPYPRINTF_BUFSIZE : len );
-    if(!(dst->data = UA_malloc(dst->length)))
+    if(!(dst->data = UA_malloc((UA_UInt32)len)))
         return UA_STATUSCODE_BADOUTOFMEMORY;
-    UA_memcpy((void *)dst->data, src, len);
+    UA_memcpy((void *)dst->data, src, (UA_UInt32)len);
     dst->length = len;
     return UA_STATUSCODE_GOOD;
 }
@@ -223,7 +222,7 @@ UA_Boolean UA_String_equal(const UA_String *string1, const UA_String *string2) {
         return UA_FALSE;
 
     // casts are needed to overcome signed warnings
-    UA_Int32 is = strncmp((char const *)string1->data, (char const *)string2->data, string1->length);
+    UA_Int32 is = strncmp((char const *)string1->data, (char const *)string2->data, (size_t)string1->length);
     return (is == 0) ? UA_TRUE : UA_FALSE;
 }
 
@@ -295,19 +294,19 @@ UA_DateTime UA_DateTime_now() {
 UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time) {
     UA_DateTimeStruct dateTimeStruct;
     //calcualting the the milli-, micro- and nanoseconds
-    dateTimeStruct.nanoSec = (time % 10) * 100;
-    dateTimeStruct.microSec = (time % 10000) / 10;
-    dateTimeStruct.milliSec = (time % 10000000) / 10000;
+    dateTimeStruct.nanoSec  = (UA_Int16)((time % 10) * 100);
+    dateTimeStruct.microSec = (UA_Int16)((time % 10000) / 10);
+    dateTimeStruct.milliSec = (UA_Int16)((time % 10000000) / 10000);
 
     //calculating the unix time with #include <time.h>
     time_t secSinceUnixEpoch = (time/10000000) - UNIX_EPOCH_BIAS_SEC;
     struct tm ts = *gmtime(&secSinceUnixEpoch);
-    dateTimeStruct.sec    = ts.tm_sec;
-    dateTimeStruct.min    = ts.tm_min;
-    dateTimeStruct.hour   = ts.tm_hour;
-    dateTimeStruct.day    = ts.tm_mday;
-    dateTimeStruct.month  = ts.tm_mon+1;
-    dateTimeStruct.year   = ts.tm_year + 1900;
+    dateTimeStruct.sec    = (UA_Int16)ts.tm_sec;
+    dateTimeStruct.min    = (UA_Int16)ts.tm_min;
+    dateTimeStruct.hour   = (UA_Int16)ts.tm_hour;
+    dateTimeStruct.day    = (UA_Int16)ts.tm_mday;
+    dateTimeStruct.month  = (UA_Int16)(ts.tm_mon + 1);
+    dateTimeStruct.year   = (UA_Int16)(ts.tm_year + 1900);
     return dateTimeStruct;
 }
 
@@ -337,12 +336,18 @@ UA_Guid UA_Guid_random(UA_UInt32 *seed) {
     UA_Guid result;
     result.data1 = RAND(seed);
     UA_UInt32 r = RAND(seed);
-    result.data2 = r;
-    result.data3 = r >> 16;
-    UA_UInt32 *fake_int = (UA_UInt32*) &result.data4[0];
-    *fake_int = RAND(seed);
-    fake_int = (UA_UInt32*) &result.data4[4];
-    *fake_int = RAND(seed);
+    result.data2 = (UA_UInt16) r;
+    result.data3 = (UA_UInt16) (r >> 16);
+    r = RAND(seed);
+    result.data4[0] = (UA_Byte)r;
+    result.data4[1] = (UA_Byte)(r >> 4);
+    result.data4[2] = (UA_Byte)(r >> 8);
+    result.data4[3] = (UA_Byte)(r >> 12);
+    r = RAND(seed);
+    result.data4[4] = (UA_Byte)r;
+    result.data4[5] = (UA_Byte)(r >> 4);
+    result.data4[6] = (UA_Byte)(r >> 8);
+    result.data4[7] = (UA_Byte)(r >> 12);
     return result;
 }
 
@@ -355,7 +360,7 @@ void UA_Guid_init(UA_Guid *p) {
 
 UA_TYPE_NEW_DEFAULT(UA_Guid)
 UA_StatusCode UA_Guid_copy(UA_Guid const *src, UA_Guid *dst) {
-    UA_memcpy((void *)dst, (void *)src, sizeof(UA_Guid));
+    UA_memcpy((void *)dst, (const void *)src, sizeof(UA_Guid));
     return UA_STATUSCODE_GOOD;
 }
 
@@ -374,41 +379,35 @@ UA_Boolean UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString
 
 #ifdef UA_DEBUG
 void UA_ByteString_printf(char *label, const UA_ByteString *string) {
-    UA_String_printf(label, (UA_String *)string);
+    UA_String_printf(label, (const UA_String *)string);
 }
 #endif
 
 #ifdef UA_DEBUG
 void UA_ByteString_printx(char *label, const UA_ByteString *string) {
-    UA_String_printx(label, (UA_String *)string);
+    UA_String_printx(label, (const UA_String *)string);
 }
 #endif
 
 #ifdef UA_DEBUG
 void UA_ByteString_printx_hex(char *label, const UA_ByteString *string) {
-    UA_String_printx_hex(label, (UA_String *)string);
+    UA_String_printx_hex(label, (const UA_String *)string);
 }
 #endif
 
-UA_Byte       UA_Byte_securityPoliceNoneData[] = "http://opcfoundation.org/UA/SecurityPolicy#None";
-// sizeof()-1 : discard the implicit null-terminator of the c-char-string
-UA_ByteString UA_ByteString_securityPoliceNone =
-{ sizeof(UA_Byte_securityPoliceNoneData)-1, UA_Byte_securityPoliceNoneData };
-
 /** Creates a ByteString of the indicated length. The content is not set to zero. */
 UA_StatusCode UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length) {
     if(length > 0) {
-        if(!(p->data = UA_malloc(length)))
+        if(!(p->data = UA_malloc((UA_UInt32)length)))
             return UA_STATUSCODE_BADOUTOFMEMORY;
         p->length = length;
-        return UA_STATUSCODE_GOOD;
+    } else {
+        p->data = UA_NULL;
+        if(length == 0)
+            p->length = 0;
+        else
+            p->length = -1;
     }
-
-    p->data   = UA_NULL;
-    if(length < 0)
-        p->length = -1;
-    else
-        p->length = 0;
     return UA_STATUSCODE_GOOD;
 }
 
@@ -453,7 +452,7 @@ UA_StatusCode UA_NodeId_copy(UA_NodeId const *src, UA_NodeId *dst) {
     return retval;
 }
 
-UA_Boolean UA_NodeId_isBasicType(UA_NodeId const *id) {
+static UA_Boolean UA_NodeId_isBasicType(UA_NodeId const *id) {
     return id->namespaceIndex == 0 &&
            id->identifierType == UA_NODEIDTYPE_NUMERIC &&
            id->identifier.numeric <= UA_DIAGNOSTICINFO;
@@ -1039,7 +1038,8 @@ UA_StatusCode UA_Array_new(void **p, UA_Int32 noElements, const UA_TypeVTable *v
         return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
-    if(!(*p = UA_malloc(vt->memSize * noElements)))
+    /* the cast to UInt32 can be made since noElements is positive */
+    if(!(*p = UA_malloc(vt->memSize * (UA_UInt32)noElements)))
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
     UA_Array_init(*p, noElements, vt);
@@ -1071,7 +1071,7 @@ UA_StatusCode UA_Array_copy(const void *src, UA_Int32 noElements, const UA_TypeV
     if(retval)
         return retval;
 
-    UA_Byte *csrc = (UA_Byte *)src; // so compilers allow pointer arithmetic
+    const UA_Byte *csrc = (const UA_Byte *)src; // so compilers allow pointer arithmetic
     UA_Byte *cdst = (UA_Byte *)*dst;
     UA_UInt32 memSize = vt->memSize;
     UA_Int32  i       = 0;
@@ -1093,7 +1093,7 @@ UA_StatusCode UA_Array_copy(const void *src, UA_Int32 noElements, const UA_TypeV
 #ifdef UA_DEBUG
 void UA_Array_print(const void *p, UA_Int32 noElements, const UA_TypeVTable *vt, FILE *stream) {
     fprintf(stream, "(%s){", vt->name);
-    char     *cp      = (char *)p; // so compilers allow pointer arithmetic
+    const char *cp = (const char *)p; // so compilers allow pointer arithmetic
     UA_UInt32 memSize = vt->memSize;
     for(UA_Int32 i = 0;i < noElements;i++) {
         vt->print(cp, stream);

+ 44 - 42
src/ua_types_encoding_binary.c

@@ -31,8 +31,8 @@ UA_UInt32 UA_Array_calcSizeBinary(UA_Int32 length, const UA_TypeVTable *vt, cons
 /** The data-pointer may be null. Then the array is assumed to be empy. */
 static UA_UInt32 UA_Array_calcSizeBinary_asExtensionObject(UA_Int32 length, const UA_TypeVTable *vt, const void *data) {
     UA_UInt32 l = UA_Array_calcSizeBinary(length, vt, data);
-    if(!is_builtin(&vt->typeId))
-        l += 9*length;  // extensionobject header for each element
+    if(!is_builtin(&vt->typeId) && length > 0)
+        l += 9*(UA_UInt32)length;  // extensionobject header for each element
     return l;
 }
 
@@ -55,7 +55,7 @@ UA_StatusCode UA_Array_encodeBinary(const void *src, UA_Int32 length, const UA_T
 
 static UA_StatusCode UA_Array_encodeBinary_asExtensionObject(const void *src, UA_Int32 length, const UA_TypeVTable *vt,
                                                              UA_ByteString *dst, UA_UInt32 *offset) {
-    //Null Arrays are encoded with length = -1 // part 6 - §5.24
+    /* null arrays are encoded with length -1 */
     if(length < -1)
         length = -1;
 
@@ -65,15 +65,15 @@ static UA_StatusCode UA_Array_encodeBinary_asExtensionObject(const void *src, UA
     UA_Boolean isBuiltin = is_builtin(&vt->typeId);
     for(UA_Int32 i = 0;i < length && !retval;i++) {
         if(!isBuiltin) {
-            // print the extensionobject header
+            /* print the extensionobject header */
             UA_NodeId_encodeBinary(&vt->typeId, dst, offset);
-            UA_Byte  eoEncoding       = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
+            UA_Byte eoEncoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
             UA_Byte_encodeBinary(&eoEncoding, dst, offset);
-            UA_Int32 eoEncodingLength = vt->encodings[UA_ENCODING_BINARY].calcSize(csrc);
-            UA_Int32_encodeBinary(&eoEncodingLength, dst, offset);
+            UA_UInt32 eoEncodingLength = vt->encodings[UA_ENCODING_BINARY].calcSize(csrc);
+            UA_UInt32_encodeBinary(&eoEncodingLength, dst, offset);
         }
         retval |= vt->encodings[UA_ENCODING_BINARY].encode(csrc, dst, offset);
-        csrc   += memSize;
+        csrc += memSize;
     }
     return retval;
 }
@@ -147,11 +147,11 @@ UA_TYPE_DECODEBINARY(UA_Boolean,
 
 /* SByte */
 UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_SByte)
-UA_TYPE_ENCODEBINARY(UA_SByte, dst->data[(*offset)++] = *src; )
+UA_TYPE_ENCODEBINARY(UA_SByte, dst->data[(*offset)++] = (UA_Byte)*src; )
 UA_TYPE_DECODEBINARY(UA_SByte,
                      if(*offset + sizeof(UA_SByte) > (UA_UInt32)src->length )
                          return UA_STATUSCODE_BADDECODINGERROR;
-                     *dst = src->data[(*offset)++]; )
+                     *dst = (UA_SByte)src->data[(*offset)++]; )
 
 /* Byte */
 UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Byte)
@@ -163,31 +163,31 @@ UA_TYPE_DECODEBINARY(UA_Byte,
 
 /* Int16 */
 UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Int16)
-UA_TYPE_ENCODEBINARY(UA_Int16, retval = UA_UInt16_encodeBinary((UA_UInt16 const *)src, dst, offset); )
+UA_TYPE_ENCODEBINARY(UA_Int16, retval = UA_UInt16_encodeBinary((const UA_UInt16 *)src, dst, offset); )
 UA_TYPE_DECODEBINARY(UA_Int16,
-                     if(*offset + sizeof(UA_Int16) > (UA_UInt32)src->length )
+                     if(*offset + sizeof(UA_Int16) > (UA_UInt32)src->length)
                          return UA_STATUSCODE_BADDECODINGERROR;
-                     *dst  = (UA_Int16)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 0);
-                     *dst |= (UA_Int16)(((UA_SByte)(src->data[(*offset)++]) & 0xFF) << 8); )
+                     *dst = (UA_Int16)((src->data[(*offset)++] & 0xFF) << 0);
+                     *dst |= (UA_Int16)((src->data[(*offset)++] & 0xFF) << 8); )
 
 /* UInt16 */
 UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_UInt16)
 UA_TYPE_ENCODEBINARY(UA_UInt16,
-                     dst->data[(*offset)++] = (*src & 0x00FF) >> 0;
-                     dst->data[(*offset)++] = (*src & 0xFF00) >> 8; )
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x00FF) >> 0);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0xFF00) >> 8); )
 UA_TYPE_DECODEBINARY(UA_UInt16,
                      if(*offset + sizeof(UA_UInt16) > (UA_UInt32)src->length )
                          return UA_STATUSCODE_BADDECODINGERROR;
-                     *dst =  (UA_UInt16)src->data[(*offset)++] << 0;
-                     *dst |= (UA_UInt16)src->data[(*offset)++] << 8; )
+                     *dst =  (UA_UInt16)(src->data[(*offset)++] << 0);
+                     *dst |= (UA_UInt16)(src->data[(*offset)++] << 8); )
 
 /* Int32 */
 UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Int32)
 UA_TYPE_ENCODEBINARY(UA_Int32,
-                     dst->data[(*offset)++] = (*src & 0x000000FF) >> 0;
-                     dst->data[(*offset)++] = (*src & 0x0000FF00) >> 8;
-                     dst->data[(*offset)++] = (*src & 0x00FF0000) >> 16;
-                     dst->data[(*offset)++] = (*src & 0xFF000000) >> 24; )
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x000000FF) >> 0);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x0000FF00) >> 8);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x00FF0000) >> 16);
+                     dst->data[(*offset)++] = (UA_Byte)((((UA_UInt32)*src) & 0xFF000000) >> 24); )
 UA_TYPE_DECODEBINARY(UA_Int32,
                      if(*offset + sizeof(UA_Int32) > (UA_UInt32)src->length )
                          return UA_STATUSCODE_BADDECODINGERROR;
@@ -211,14 +211,14 @@ UA_TYPE_DECODEBINARY(UA_UInt32,
 /* Int64 */
 UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Int64)
 UA_TYPE_ENCODEBINARY(UA_Int64,
-                     dst->data[(*offset)++] = (*src & 0x00000000000000FF) >> 0;
-                     dst->data[(*offset)++] = (*src & 0x000000000000FF00) >> 8;
-                     dst->data[(*offset)++] = (*src & 0x0000000000FF0000) >> 16;
-                     dst->data[(*offset)++] = (*src & 0x00000000FF000000) >> 24;
-                     dst->data[(*offset)++] = (*src & 0x000000FF00000000) >> 32;
-                     dst->data[(*offset)++] = (*src & 0x0000FF0000000000) >> 40;
-                     dst->data[(*offset)++] = (*src & 0x00FF000000000000) >> 48;
-                     dst->data[(*offset)++] = (*src & 0xFF00000000000000) >> 56; )
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x00000000000000FF) >> 0);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x000000000000FF00) >> 8);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x0000000000FF0000) >> 16);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x00000000FF000000) >> 24);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x000000FF00000000) >> 32);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x0000FF0000000000) >> 40);
+                     dst->data[(*offset)++] = (UA_Byte)((*src & 0x00FF000000000000) >> 48);
+                     dst->data[(*offset)++] = (UA_Byte)((((UA_UInt64)*src) & 0xFF00000000000000) >> 56); )
 UA_TYPE_DECODEBINARY(UA_Int64,
                      if(*offset + sizeof(UA_Int64) > (UA_UInt32)src->length )
                          return UA_STATUSCODE_BADDECODINGERROR;
@@ -259,19 +259,20 @@ UA_TYPE_DECODEBINARY(UA_Float,
                      UA_Float sign;
                      if(memcmp(&src->data[*offset], UA_FLOAT_ZERO, 4) == 0) return UA_Int32_decodeBinary(src, offset, (UA_Int32 *)dst);
 
-                     mantissa = (UA_Float)(src->data[*offset] & 0xFF);                         // bits 0-7
-                     mantissa = (mantissa / 256.0 ) + (UA_Float)(src->data[*offset+1] & 0xFF); // bits 8-15
-                     mantissa = (mantissa / 256.0 ) + (UA_Float)(src->data[*offset+2] & 0x7F); // bits 16-22
-                     biasedExponent  = (src->data[*offset+2] & 0x80) >>  7;                    // bits 23
-                     biasedExponent |= (src->data[*offset+3] & 0x7F) <<  1;                    // bits 24-30
-                     sign = ( src->data[*offset+ 3] & 0x80 ) ? -1.0 : 1.0;                     // bit 31
+                     mantissa = (UA_Float)(src->data[*offset] & 0xFF);                                   // bits 0-7
+                     mantissa = (mantissa / (UA_Float)256.0 ) + (UA_Float)(src->data[*offset+1] & 0xFF); // bits 8-15
+                     mantissa = (mantissa / (UA_Float)256.0 ) + (UA_Float)(src->data[*offset+2] & 0x7F); // bits 16-22
+                     biasedExponent  = (src->data[*offset+2] & 0x80) >>  7;                              // bits 23
+                     biasedExponent |= (UA_UInt32)(src->data[*offset+3] & 0x7F) <<  1;                   // bits 24-30
+                     sign = ( src->data[*offset+ 3] & 0x80 ) ? -1.0 : 1.0;                               // bit 31
                      if(biasedExponent >= 127)
                          *dst = (UA_Float)sign * (1 << (biasedExponent-127)) * (1.0 + mantissa / 128.0 );
                      else
-                         *dst = (UA_Float)sign * 2.0 *
-                                (1.0 + mantissa / 128.0 ) / ((UA_Float)(biasedExponent-127));
+                         *dst = (UA_Float)sign * 2.0 * (1.0 + mantissa / 128.0 ) / ((UA_Float)(biasedExponent-127));
                      *offset += 4; )
-UA_TYPE_ENCODEBINARY(UA_Float, return UA_UInt32_encodeBinary((UA_UInt32 *)src, dst, offset); )
+
+/* todo: the encoding does not handle big endian. */
+UA_TYPE_ENCODEBINARY(UA_Float, return UA_UInt32_encodeBinary((const UA_UInt32 *)src, dst, offset); )
 
 /* Double */
 UA_TYPE_CALCSIZEBINARY_SIZEOF(UA_Double)
@@ -300,7 +301,8 @@ UA_TYPE_DECODEBINARY(UA_Double,
                          *dst = (UA_Double)sign * 2.0 *
                                 (1.0 + mantissa / 8.0 ) / ((UA_Double)(biasedExponent-1023));
                      *offset += 8; )
-UA_TYPE_ENCODEBINARY(UA_Double, return UA_UInt64_encodeBinary((UA_UInt64 *)src, dst, offset); )
+/* todo: this does not handle big endian */
+UA_TYPE_ENCODEBINARY(UA_Double, return UA_UInt64_encodeBinary((const UA_UInt64 *)src, dst, offset); )
 
 /* String */
 UA_UInt32 UA_String_calcSizeBinary(UA_String const *string) {
@@ -415,7 +417,7 @@ UA_TYPE_ENCODEBINARY(UA_NodeId,
                      UA_Byte srcByte;
                      UA_UInt16 srcUInt16;
 
-                     UA_StatusCode retval = UA_STATUSCODE_GOOD;
+                     retval = UA_STATUSCODE_GOOD;
                      switch(src->identifierType) {
                      case UA_NODEIDTYPE_NUMERIC:
                          if(src->identifier.numeric > UA_UINT16_MAX || src->namespaceIndex > UA_BYTE_MAX) {
@@ -648,7 +650,7 @@ UA_UInt32 UA_ExtensionObject_calcSizeBinary(UA_ExtensionObject const *p) {
         break;
 
     case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML:
-        length += UA_XmlElement_calcSizeBinary((UA_XmlElement *)&p->body);
+        length += UA_XmlElement_calcSizeBinary((const UA_XmlElement *)&p->body);
         break;
 
     default:

+ 2 - 2
src/ua_types_encoding_binary.h

@@ -32,12 +32,12 @@
 
 #define UA_TYPE_CALCSIZEBINARY_AS(TYPE, TYPE_AS)        \
     UA_UInt32 TYPE##_calcSizeBinary(TYPE const *p) {    \
-        return TYPE_AS##_calcSizeBinary((TYPE_AS *)p);  \
+        return TYPE_AS##_calcSizeBinary((const TYPE_AS *)p);  \
     }
 
 #define UA_TYPE_ENCODEBINARY_AS(TYPE, TYPE_AS)                          \
     UA_StatusCode TYPE##_encodeBinary(TYPE const *src, UA_ByteString *dst, UA_UInt32 *offset) { \
-        return TYPE_AS##_encodeBinary((TYPE_AS *)src, dst, offset);     \
+        return TYPE_AS##_encodeBinary((const TYPE_AS *)src, dst, offset);     \
     }
 
 #define UA_TYPE_DECODEBINARY_AS(TYPE, TYPE_AS)                          \

+ 5 - 5
src/ua_types_macros.h

@@ -52,14 +52,14 @@
     }
 
 #define UA_TYPE_COPY_AS(TYPE, TYPE_AS)                         \
-    UA_StatusCode TYPE##_copy(TYPE const *src, TYPE *dst) {    \
-        return TYPE_AS##_copy((TYPE_AS *)src, (TYPE_AS *)dst); \
+    UA_StatusCode TYPE##_copy(const TYPE *src, TYPE *dst) {    \
+        return TYPE_AS##_copy((const TYPE_AS *)src, (TYPE_AS *)dst); \
     }
 
 #ifdef UA_DEBUG //print functions only in debug mode
-#define UA_TYPE_PRINT_AS(TYPE, TYPE_AS)              \
-    void TYPE##_print(TYPE const *p, FILE *stream) { \
-        TYPE_AS##_print((TYPE_AS *)p, stream);       \
+#define UA_TYPE_PRINT_AS(TYPE, TYPE_AS)                    \
+    void TYPE##_print(const TYPE *p, FILE *stream) {       \
+        TYPE_AS##_print((const TYPE_AS *)p, stream);       \
     }
 #else
 #define UA_TYPE_PRINT_AS(TYPE, TYPE_AS)

+ 4 - 4
tests/check_builtin.c

@@ -642,7 +642,7 @@ START_TEST(UA_Variant_decodeWithOutArrayFlagSetShallSetVTAndAllocateMemoryForArr
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(pos, 5);
-	ck_assert_ptr_eq((void *)dst.vt, (void *)&UA_TYPES[UA_INT32]);
+	ck_assert_ptr_eq((const void *)dst.vt, (const void *)&UA_TYPES[UA_INT32]);
 	ck_assert_int_eq(dst.storage.data.arrayLength, 1);
 	ck_assert_int_eq(*(UA_Int32 *)dst.storage.data.dataPtr, 255);
 	// finally
@@ -664,7 +664,7 @@ START_TEST(UA_Variant_decodeWithArrayFlagSetShallSetVTAndAllocateMemoryForArray)
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(pos, 1+4+2*4);
-	ck_assert_ptr_eq((void*)dst.vt, (void*)&UA_TYPES[UA_INT32]);
+	ck_assert_ptr_eq((const void*)dst.vt, (const void*)&UA_TYPES[UA_INT32]);
 	ck_assert_int_eq(dst.storage.data.arrayLength, 2);
 	ck_assert_int_eq(((UA_Int32 *)dst.storage.data.dataPtr)[0], 255);
 	ck_assert_int_eq(((UA_Int32 *)dst.storage.data.dataPtr)[1], -1);
@@ -1499,7 +1499,7 @@ START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 	UA_Variant_init(&copiedValue);
 
 	value.storage.data.arrayLength = 6;
-	value.storage.data.dataPtr     = (void **)srcArray;
+	value.storage.data.dataPtr     = srcArray;
 	value.storage.data.arrayDimensionsLength = 2;
 	value.storage.data.arrayDimensions       = dimensions;
 	value.vt = &UA_TYPES[UA_INT32];
@@ -1604,7 +1604,7 @@ START_TEST(UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject) {
 }
 END_TEST
 
-Suite *testSuite_builtin(void) {
+static Suite *testSuite_builtin(void) {
 	Suite *s = suite_create("Built-in Data Types 62541-6 Table 1");
 
 	TCase *tc_calcSize = tcase_create("calcSize");

+ 1 - 1
tests/check_memory.c

@@ -174,7 +174,7 @@ START_TEST(decodeComplexTypeFromRandomBufferShallSurvive) {
 }
 END_TEST
 
-int main() {
+int main(void) {
 	int number_failed = 0;
 	SRunner *sr;
 

+ 75 - 75
tests/check_nodestore.c

@@ -14,30 +14,30 @@
 
 int zeroCnt = 0;
 int visitCnt = 0;
-void checkZeroVisitor(const UA_Node* node) {
+static void checkZeroVisitor(const UA_Node* node) {
 	visitCnt++;
 	if (node == UA_NULL) zeroCnt++;
 }
 
-void printVisitor(const UA_Node* node) {
+static void printVisitor(const UA_Node* node) {
 	printf("%d\n", node->nodeId.identifier.numeric);
 }
 
-UA_StatusCode createNode(UA_Node** p, UA_Int16 nsid, UA_Int32 id) {
-	*p = (UA_Node *)UA_VariableNode_new();
-	(*p)->nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
-	(*p)->nodeId.namespaceIndex = nsid;
-	(*p)->nodeId.identifier.numeric = id;
-	(*p)->nodeClass = UA_NODECLASS_VARIABLE;
-	return UA_STATUSCODE_GOOD;
+static UA_Node* createNode(UA_Int16 nsid, UA_Int32 id) {
+	UA_Node *p = (UA_Node *)UA_VariableNode_new();
+	p->nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
+	p->nodeId.namespaceIndex = nsid;
+	p->nodeId.identifier.numeric = id;
+	p->nodeClass = UA_NODECLASS_VARIABLE;
+	return p;
 }
 
 START_TEST(replaceExistingNode) {
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n1; createNode(&n1,0,2253);
-	UA_NodeStore_insert(ns, (const UA_Node **)&n1, UA_TRUE);
-	UA_Node* n2; createNode(&n2,0,2253);
-    UA_StatusCode retval = UA_NodeStore_replace(ns, n1, (const UA_Node **)&n2, UA_FALSE);
+	const UA_Node* n1 = createNode(0,2253);
+	UA_NodeStore_insert(ns, &n1, UA_TRUE);
+	const UA_Node* n2 = createNode(0,2253);
+    UA_StatusCode retval = UA_NodeStore_replace(ns, n1, &n2, UA_FALSE);
     UA_NodeStore_release(n1);
     
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
@@ -48,9 +48,10 @@ END_TEST
 
 START_TEST(replaceNonExistingNode) {
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n1; createNode(&n1,0,2253);
-	UA_Node* n2; createNode(&n2,0,2253);
-    UA_StatusCode retval = UA_NodeStore_replace(ns, n1, (const UA_Node **)&n2, UA_FALSE);
+	const UA_Node* n1 = createNode(0,2253);
+	UA_Node* n2 = createNode(0,2253);
+    const UA_Node *dummy = n2;
+    UA_StatusCode retval = UA_NodeStore_replace(ns, n1, (const UA_Node **)&dummy, UA_FALSE);
     
 	ck_assert_int_ne(retval, UA_STATUSCODE_GOOD);
     
@@ -65,11 +66,11 @@ START_TEST(findNodeInUA_NodeStoreWithSingleEntry) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n1; createNode(&n1,0,2253);
-	UA_NodeStore_insert(ns, (const UA_Node **)&n1, UA_TRUE);
+	const UA_Node* n1 = createNode(0,2253);
+	UA_NodeStore_insert(ns, &n1, UA_TRUE);
 	const UA_Node* nr = UA_NodeStore_get(ns,&n1->nodeId);
 	// then
-	ck_assert_ptr_eq((void*)nr, (void*)n1);
+	ck_assert_ptr_eq((const void*)nr, (const void*)n1);
 	// finally
 	UA_NodeStore_release(n1);
 	UA_NodeStore_release(nr);
@@ -87,14 +88,14 @@ START_TEST(failToFindNodeInOtherUA_NodeStore) {
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
 
-	UA_Node* n1; createNode(&n1,0,2255);
+	const UA_Node* n1 = createNode(0,2255);
     UA_NodeStore_insert(ns, (const UA_Node **)&n1, UA_FALSE);
 
 	// when
-	UA_Node* n; createNode(&n,1,2255);
+	UA_Node* n = createNode(1,2255);
 	const UA_Node* nr = UA_NodeStore_get(ns,&n->nodeId);
 	// then
-	ck_assert_ptr_eq(nr, UA_NULL);
+	ck_assert_ptr_eq((const void*)nr, UA_NULL);
 	// finally
 	UA_Node_delete(n);
 	UA_NodeStore_delete(ns);
@@ -110,23 +111,23 @@ START_TEST(findNodeInUA_NodeStoreWithSeveralEntries) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n1; createNode(&n1,0,2253);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n1, UA_FALSE);
-	UA_Node* n2; createNode(&n2,0,2255);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n2, UA_FALSE);
-	UA_Node* n3; createNode(&n3,0,2257);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n3, UA_TRUE);
-	UA_Node* n4; createNode(&n4,0,2200);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n4, UA_FALSE);
-	UA_Node* n5; createNode(&n5,0,1);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n5, UA_FALSE);
-	UA_Node* n6; createNode(&n6,0,12);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n6, UA_FALSE);
+	const UA_Node* n1 = createNode(0,2253);
+    UA_NodeStore_insert(ns, &n1, UA_FALSE);
+	const UA_Node* n2 = createNode(0,2255);
+    UA_NodeStore_insert(ns, &n2, UA_FALSE);
+	const UA_Node* n3 = createNode(0,2257);
+    UA_NodeStore_insert(ns, &n3, UA_TRUE);
+	const UA_Node* n4 = createNode(0,2200);
+    UA_NodeStore_insert(ns, &n4, UA_FALSE);
+	const UA_Node* n5 = createNode(0,1);
+    UA_NodeStore_insert(ns, &n5, UA_FALSE);
+	const UA_Node* n6 = createNode(0,12);
+    UA_NodeStore_insert(ns, &n6, UA_FALSE);
 
 	// when
 	const UA_Node* nr = UA_NodeStore_get(ns,&(n3->nodeId));
 	// then
-	ck_assert_ptr_eq((void*)nr, (void*)n3);
+	ck_assert_ptr_eq((const void*)nr, (const void*)n3);
 	// finally
 	UA_NodeStore_release(n3);
 	UA_NodeStore_release(nr);
@@ -143,18 +144,18 @@ START_TEST(iterateOverUA_NodeStoreShallNotVisitEmptyNodes) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n1; createNode(&n1,0,2253);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n1, 0);
-	UA_Node* n2; createNode(&n2,0,2255);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n2, 0);
-	UA_Node* n3; createNode(&n3,0,2257);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n3, 0);
-	UA_Node* n4; createNode(&n4,0,2200);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n4, 0);
-	UA_Node* n5; createNode(&n5,0,1);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n5, 0);
-	UA_Node* n6; createNode(&n6,0,12);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n6, 0);
+	const UA_Node* n1 = createNode(0,2253);
+    UA_NodeStore_insert(ns, &n1, 0);
+	const UA_Node* n2 = createNode(0,2255);
+    UA_NodeStore_insert(ns, &n2, 0);
+	const UA_Node* n3 = createNode(0,2257);
+    UA_NodeStore_insert(ns, &n3, 0);
+	const UA_Node* n4 = createNode(0,2200);
+    UA_NodeStore_insert(ns, &n4, 0);
+	const UA_Node* n5 = createNode(0,1);
+    UA_NodeStore_insert(ns, &n5, 0);
+	const UA_Node* n6 = createNode(0,12);
+    UA_NodeStore_insert(ns, &n6, 0);
 
 	// when
 	zeroCnt = 0;
@@ -177,19 +178,19 @@ START_TEST(findNodeInExpandedNamespace) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n;
+	const UA_Node* n;
 	UA_Int32 i=0;
 	for (; i<200; i++) {
-		createNode(&n,0,i);
+		n = createNode(0,i);
         UA_NodeStore_insert(ns, (const UA_Node **)&n, UA_FALSE);
 	}
 	// when
-	createNode(&n,0,25);
-	const UA_Node* nr = UA_NodeStore_get(ns,&(n->nodeId));
+	UA_Node *n2 = createNode(0,25);
+	const UA_Node* nr = UA_NodeStore_get(ns,&n2->nodeId);
 	// then
-	ck_assert_int_eq(nr->nodeId.identifier.numeric,n->nodeId.identifier.numeric);
+	ck_assert_int_eq(nr->nodeId.identifier.numeric,n2->nodeId.identifier.numeric);
 	// finally
-	UA_free((void*)n);
+	UA_free((void*)n2);
 	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef UA_MULTITHREADING
@@ -204,11 +205,11 @@ START_TEST(iterateOverExpandedNamespaceShallNotVisitEmptyNodes) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n;
+	const UA_Node* n;
 	UA_Int32 i=0;
 	for (; i<200; i++) {
-		createNode(&n,0,i);
-        UA_NodeStore_insert(ns, (const UA_Node **)&n, UA_FALSE);
+		n = createNode(0,i);
+        UA_NodeStore_insert(ns, &n, UA_FALSE);
 	}
 	// when
 	zeroCnt = 0;
@@ -231,22 +232,22 @@ START_TEST(failToFindNonExistantNodeInUA_NodeStoreWithSeveralEntries) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Node* n1; createNode(&n1,0,2253);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n1, UA_FALSE);
-	UA_Node* n2; createNode(&n2,0,2255);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n2, UA_FALSE);
-	UA_Node* n3; createNode(&n3,0,2257);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n3, UA_FALSE);
-	UA_Node* n4; createNode(&n4,0,2200);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n4, UA_FALSE);
-	UA_Node* n5; createNode(&n5,0,1);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n5, UA_FALSE);
-	UA_Node* n6; createNode(&n6,0,12); 
+	const UA_Node* n1 = createNode(0,2253);
+    UA_NodeStore_insert(ns, &n1, UA_FALSE);
+	const UA_Node* n2 = createNode(0,2255);
+    UA_NodeStore_insert(ns, &n2, UA_FALSE);
+	const UA_Node* n3 = createNode(0,2257);
+    UA_NodeStore_insert(ns, &n3, UA_FALSE);
+	const UA_Node* n4 = createNode(0,2200);
+    UA_NodeStore_insert(ns, &n4, UA_FALSE);
+	const UA_Node* n5 = createNode(0,1);
+    UA_NodeStore_insert(ns, &n5, UA_FALSE);
+	UA_Node* n6 = createNode(0,12); 
 
 	// when
 	const UA_Node* nr = UA_NodeStore_get(ns, &n6->nodeId);
 	// then
-	ck_assert_ptr_eq(nr, UA_NULL);
+	ck_assert_ptr_eq((const void*)nr, UA_NULL);
 	// finally
 	UA_free((void *)n6);
 	UA_NodeStore_delete(ns);
@@ -268,7 +269,7 @@ struct UA_NodeStoreProfileTest {
 	UA_Int32 rounds;
 };
 
-void *profileGetThread(void *arg) {
+static void *profileGetThread(void *arg) {
    	rcu_register_thread();
 	struct UA_NodeStoreProfileTest *test = (struct UA_NodeStoreProfileTest*) arg;
 	UA_NodeId id;
@@ -296,10 +297,9 @@ START_TEST(profileGetDelete) {
 
 #define N 1000000
 	UA_NodeStore *ns = UA_NodeStore_new();
-	UA_Int32 i=0;
-	UA_Node *n;
-	for (; i<N; i++) {
-		createNode(&n,0,i);
+	const UA_Node *n;
+	for (int i=0; i<N; i++) {
+		n = createNode(0,i);
         UA_NodeStore_insert(ns, (const UA_Node **)&n, UA_FALSE);
 	}
 	clock_t begin, end;
@@ -321,7 +321,7 @@ START_TEST(profileGetDelete) {
 	UA_NodeId id;
     UA_NodeId_init(&id);
 	for(UA_Int32 x = 0; x<50; x++) {
-	    for(i=0; i<N; i++) {
+	    for(int i=0; i<N; i++) {
 	        id.identifier.numeric = i;
 			cn = UA_NodeStore_get(ns,&id);
 			UA_NodeStore_release(cn);
@@ -339,7 +339,7 @@ START_TEST(profileGetDelete) {
 }
 END_TEST
 
-Suite * namespace_suite (void) {
+static Suite * namespace_suite (void) {
 	Suite *s = suite_create ("UA_NodeStore");
 
 	TCase* tc_find = tcase_create ("Find");

+ 2 - 5
tests/check_services_view.c

@@ -28,8 +28,7 @@
 }
 END_TEST */
 
-Suite* testSuite_Service_TranslateBrowsePathsToNodeIds()
-{
+static Suite* testSuite_Service_TranslateBrowsePathsToNodeIds(void) {
 	Suite *s = suite_create("Service_TranslateBrowsePathsToNodeIds");
 	TCase *tc_core = tcase_create("Core");
 	//tcase_add_test(tc_core, Service_TranslateBrowsePathsToNodeIds_SmokeTest);
@@ -37,14 +36,12 @@ Suite* testSuite_Service_TranslateBrowsePathsToNodeIds()
 	return s;
 }
 
-int main (void)
-{
+int main(void) {
 	int number_failed = 0;
 
 	Suite *s;
 	SRunner *sr;
 
-
 	s = testSuite_Service_TranslateBrowsePathsToNodeIds();
 	sr = srunner_create(s);
 	srunner_run_all(sr,CK_NORMAL);

+ 4 - 4
tools/generate_namespace.py

@@ -131,7 +131,7 @@ printh('''/**********************************************************
  * @retval the corresponding index into UA_VTable
  */
 
-UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id);\n
+UA_UInt32 UA_ns0ToVTableIndex(const UA_NodeId *id);\n
 extern const UA_TypeVTable UA_EXPORT *UA_TYPES;
 extern const UA_NodeId UA_EXPORT *UA_NODEIDS;
 extern const UA_ExpandedNodeId UA_EXPORT *UA_EXPANDEDNODEIDS;
@@ -147,7 +147,7 @@ printc('''/**********************************************************
  **********************************************************/\n
 #include "''' + args.outfile.split("/")[-1] + '''.h"\n
 #include "ua_util.h"
-UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
+UA_UInt32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
 	UA_Int32 retval = 0; // InvalidType
         if(id->namespaceIndex != 0) return retval;
 	switch (id->identifier.numeric) {''')
@@ -183,7 +183,7 @@ for row in rows:
     name = "UA_" + row[0]
     printc("\t{.typeId={.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric=" + row[1] + "}" + 
            ",\n.name=(UA_Byte*)&\"%(name)s\"" +
-           ",\n.new=(void *(*)())%(name)s_new" +
+           ",\n.new=(void *(*)(void))%(name)s_new" +
            ",\n.init=(void(*)(void *))%(name)s_init"+
            ",\n.copy=(UA_StatusCode(*)(void const * ,void*))%(name)s_copy" +
            ",\n.delete=(void(*)(void *))%(name)s_delete" +
@@ -193,7 +193,7 @@ for row in rows:
            "\n#endif" + 
            "\n.memSize=" + ("sizeof(%(name)s)" if (name != "UA_InvalidType") else "0") +
            ",\n.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
-           ",\n.encodings={{.calcSize=(UA_Int32(*)(const void*))%(name)s_calcSizeBinary" +
+           ",\n.encodings={{.calcSize=(UA_UInt32(*)(const void*))%(name)s_calcSizeBinary" +
            ",\n.encode=(UA_StatusCode(*)(const void*,UA_ByteString*,UA_UInt32*))%(name)s_encodeBinary" +
            ",\n.decode=(UA_StatusCode(*)(const UA_ByteString*,UA_UInt32*,void*))%(name)s_decodeBinary}" +
            (",\n{.calcSize=(UA_Int32(*)(const void*))%(name)s_calcSizeXml" +