Ver código fonte

add printf-format function attributes for gcc; fix all logging warnings

Julius Pfrommer 7 anos atrás
pai
commit
934496a84a

+ 1 - 1
examples/discovery/client_find_servers.c

@@ -119,7 +119,7 @@ int main(void) {
         if (description->discoveryUrlsSize == 0) {
             UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
                         "[GetEndpoints] Server %.*s did not provide any discovery urls. Skipping.",
-                        description->applicationUri);
+                        (int)description->applicationUri.length, description->applicationUri.data);
             continue;
         }
 

+ 3 - 3
examples/discovery/server_multicast.c

@@ -27,7 +27,7 @@ readInteger(void *handle, const UA_NodeId nodeid, UA_Boolean sourceTimeStamp,
     UA_Variant_setScalarCopy(&dataValue->value, (UA_UInt32 *) handle, &UA_TYPES[UA_TYPES_INT32]);
     // we know the nodeid is a string
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "Node read %.*s",
-                nodeid.identifier.string.length, nodeid.identifier.string.data);
+                (int)nodeid.identifier.string.length, nodeid.identifier.string.data);
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "read value %i", *(UA_UInt32 *) handle);
     return UA_STATUSCODE_GOOD;
 }
@@ -40,7 +40,7 @@ writeInteger(void *handle, const UA_NodeId nodeid,
     }
     // we know the nodeid is a string
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "Node written %.*s",
-                nodeid.identifier.string.length, nodeid.identifier.string.data);
+                (int)nodeid.identifier.string.length, nodeid.identifier.string.data);
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "written value %i", *(UA_UInt32 *) handle);
     return UA_STATUSCODE_GOOD;
 }
@@ -73,7 +73,7 @@ serverOnNetworkCallback(const UA_ServerOnNetwork *serverOnNetwork, UA_Boolean is
     // the serverOnNetwork to make sure you are registering with the correct
     // LDS. We will ignore this for now
     UA_LOG_INFO(logger, UA_LOGCATEGORY_SERVER, "Another server announced itself on %.*s",
-                serverOnNetwork->discoveryUrl.length, serverOnNetwork->discoveryUrl.data);
+                (int)serverOnNetwork->discoveryUrl.length, serverOnNetwork->discoveryUrl.data);
 
     if (discovery_url != NULL)
         UA_free(discovery_url);

+ 2 - 2
examples/discovery/server_register.c

@@ -28,7 +28,7 @@ readInteger(void *handle, const UA_NodeId nodeid, UA_Boolean sourceTimeStamp,
     UA_Variant_setScalarCopy(&dataValue->value, (UA_UInt32 *) handle, &UA_TYPES[UA_TYPES_INT32]);
     // we know the nodeid is a string
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "Node read %.*s",
-                nodeid.identifier.string.length, nodeid.identifier.string.data);
+                (int)nodeid.identifier.string.length, nodeid.identifier.string.data);
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "read value %i", *(UA_UInt32 *) handle);
     return UA_STATUSCODE_GOOD;
 }
@@ -41,7 +41,7 @@ writeInteger(void *handle, const UA_NodeId nodeid,
     }
     // we know the nodeid is a string
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "Node written %.*s",
-                nodeid.identifier.string.length, nodeid.identifier.string.data);
+                (int)nodeid.identifier.string.length, nodeid.identifier.string.data);
     UA_LOG_INFO(logger, UA_LOGCATEGORY_USERLAND, "written value %i", *(UA_UInt32 *) handle);
     return UA_STATUSCODE_GOOD;
 }

+ 2 - 0
include/ua_config.h.in

@@ -165,11 +165,13 @@ typedef uint8_t bool;
 # define UA_FUNC_ATTR_PURE __attribute__ ((pure))
 # define UA_FUNC_ATTR_CONST __attribute__((const))
 # define UA_FUNC_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+# define UA_FORMAT(X,Y) __attribute__ ((format (printf, X, Y)))
 #else
 # define UA_FUNC_ATTR_MALLOC
 # define UA_FUNC_ATTR_PURE
 # define UA_FUNC_ATTR_CONST
 # define UA_FUNC_ATTR_WARN_UNUSED_RESULT
+# define UA_FORMAT(X,Y)
 #endif
 
 #ifdef __GNUC__

+ 7 - 7
include/ua_plugin_log.h

@@ -48,7 +48,7 @@ typedef enum {
 typedef void (*UA_Logger)(UA_LogLevel level, UA_LogCategory category,
                           const char *msg, va_list args);
 
-static UA_INLINE void
+static UA_INLINE UA_FORMAT(3,4) void
 UA_LOG_TRACE(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #if UA_LOGLEVEL <= 100
     va_list args; va_start(args, msg);
@@ -57,7 +57,7 @@ UA_LOG_TRACE(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #endif
 }
 
-static UA_INLINE void
+static UA_INLINE UA_FORMAT(3,4) void
 UA_LOG_DEBUG(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #if UA_LOGLEVEL <= 200
     va_list args; va_start(args, msg);
@@ -66,7 +66,7 @@ UA_LOG_DEBUG(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #endif
 }
 
-static UA_INLINE void
+static UA_INLINE UA_FORMAT(3,4) void
 UA_LOG_INFO(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #if UA_LOGLEVEL <= 300
     va_list args; va_start(args, msg);
@@ -75,7 +75,7 @@ UA_LOG_INFO(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #endif
 }
 
-static UA_INLINE void
+static UA_INLINE UA_FORMAT(3,4) void
 UA_LOG_WARNING(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #if UA_LOGLEVEL <= 400
     va_list args; va_start(args, msg);
@@ -84,7 +84,7 @@ UA_LOG_WARNING(UA_Logger logger, UA_LogCategory category, const char *msg, ...)
 #endif
 }
 
-static UA_INLINE void
+static UA_INLINE UA_FORMAT(3,4) void
 UA_LOG_ERROR(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #if UA_LOGLEVEL <= 500
     va_list args; va_start(args, msg);
@@ -93,7 +93,7 @@ UA_LOG_ERROR(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #endif
 }
 
-static UA_INLINE void
+static UA_INLINE UA_FORMAT(3,4) void
 UA_LOG_FATAL(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #if UA_LOGLEVEL <= 600
     va_list args; va_start(args, msg);
@@ -111,7 +111,7 @@ UA_LOG_FATAL(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
         (GUID).data4[4], (GUID).data4[5], (GUID).data4[6], (GUID).data4[7]
 
 #define UA_PRINTF_STRING_FORMAT "\"%.*s\""
-#define UA_PRINTF_STRING_DATA(STRING) (STRING).length, (STRING).data
+#define UA_PRINTF_STRING_DATA(STRING) (int)(STRING).length, (STRING).data
 
 #ifdef __cplusplus
 } // extern "C"

+ 5 - 5
plugins/ua_network_tcp.c

@@ -51,7 +51,7 @@
 #endif
 
 /* unsigned int for windows and workaround to a glibc bug */
-/* Additionally if GNU_LIBRARY is not defined, it may be using 
+/* Additionally if GNU_LIBRARY is not defined, it may be using
  * musl libc (e.g. Docker Alpine) */
 #if defined(_WIN32) || defined(__OpenBSD__) || \
     (defined(__GNU_LIBRARY__) && (__GNU_LIBRARY__ <= 6) && \
@@ -257,12 +257,12 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer,
     if(res == 0) {
         UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
                     "Connection %i | New connection over TCP from %s",
-                    newsockfd, remote_name);
+                    (int)newsockfd, remote_name);
     } else {
         UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
                        "Connection %i | New connection over TCP, "
                        "getnameinfo failed with errno %i",
-                       newsockfd, errno__);
+                       (int)newsockfd, errno__);
     }
 
     /* Allocate and initialize the connection */
@@ -403,7 +403,7 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl) {
 
     UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
                 "TCP network layer listening on %.*s",
-                nl->discoveryUrl.length, nl->discoveryUrl.data);
+                (int)nl->discoveryUrl.length, nl->discoveryUrl.data);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -461,7 +461,7 @@ ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server,
 
         UA_LOG_TRACE(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
                     "Connection %i | New TCP connection on server socket %i",
-                    newsockfd, layer->serverSockets[i]);
+                    (int)newsockfd, layer->serverSockets[i]);
 
         ServerNetworkLayerTCP_add(layer, (UA_Int32)newsockfd, &remote);
     }

+ 1 - 1
src/client/ua_client.c

@@ -760,7 +760,7 @@ processServiceResponse(SyncResponseDescription *rd, UA_SecureChannel *channel,
         UA_TcpErrorMessage *msg = (UA_TcpErrorMessage*)message;
         UA_LOG_ERROR(rd->client->config.logger, UA_LOGCATEGORY_CLIENT,
                      "Server replied with an error message: %s %.*s",
-                     UA_StatusCode_name(msg->error), msg->reason.length,
+                     UA_StatusCode_name(msg->error), (int)msg->reason.length,
                      msg->reason.data);
         retval = msg->error;
         goto finish;

+ 1 - 1
src/client/ua_client_highlevel_subscriptions.c

@@ -238,7 +238,7 @@ UA_Client_processPublishResponse(UA_Client *client, UA_PublishRequest *request,
 
     UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_CLIENT,
                  "Processing a publish response on subscription %u with %u notifications",
-                 sub->subscriptionID, response->notificationMessage.notificationDataSize);
+                 sub->subscriptionID, (unsigned int)response->notificationMessage.notificationDataSize);
 
     /* Check if the server has acknowledged any of the sent ACKs */
     for(size_t i = 0; i < response->resultsSize && i < request->subscriptionAcknowledgementsSize; ++i) {

+ 1 - 1
src/server/ua_mdns.c

@@ -273,7 +273,7 @@ void mdns_record_received(const struct resource *r, void *data) {
     if(r->ttl == 0) {
         UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER,
                     "Multicast DNS: remove server (TTL=0): %.*s",
-                    entry->serverOnNetwork.discoveryUrl.length,
+                    (int)entry->serverOnNetwork.discoveryUrl.length,
                     entry->serverOnNetwork.discoveryUrl.data);
         mdns_record_remove(server, r->name, entry);
         return;

+ 2 - 2
src/server/ua_securechannel_manager.c

@@ -62,7 +62,7 @@ UA_SecureChannelManager_cleanupTimedOut(UA_SecureChannelManager *cm, UA_DateTime
             (UA_DateTime)(entry->channel.securityToken.revisedLifetime * UA_MSEC_TO_DATETIME);
         if(timeout < nowMonotonic || !entry->channel.connection) {
             UA_LOG_INFO_CHANNEL(cm->server->config.logger, &entry->channel,
-                                "SecureChannel has timed out", NULL);
+                                "SecureChannel has timed out");
             removeSecureChannel(cm, entry);
         } else if(entry->channel.nextSecurityToken.tokenId > 0) {
             UA_SecureChannel_revolveTokens(&entry->channel);
@@ -77,7 +77,7 @@ static UA_Boolean purgeFirstChannelWithoutSession(UA_SecureChannelManager *cm) {
         if(LIST_EMPTY(&(entry->channel.sessions))){
             UA_LOG_DEBUG_CHANNEL(cm->server->config.logger, &entry->channel,
                                  "Channel was purged since maxSecureChannels was "
-                                 "reached and channel had no session attached", NULL);
+                                 "reached and channel had no session attached");
             removeSecureChannel(cm, entry);
             UA_assert(entry != LIST_FIRST(&cm->channels));
             return true;

+ 12 - 11
src/server/ua_server_binary.c

@@ -410,7 +410,7 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
         if(requestTypeId.identifier.numeric == 787) {
             UA_LOG_INFO_CHANNEL(server->config.logger, channel,
                                 "Client requested a subscription, " \
-                                "but those are not enabled in the build", NULL);
+                                "but those are not enabled in the build");
         } else {
             UA_LOG_INFO_CHANNEL(server->config.logger, channel,
                                 "Unknown request with type identifier %i",
@@ -435,7 +435,7 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
                              server->config.customDataTypes);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_LOG_DEBUG_CHANNEL(server->config.logger, channel,
-                             "Could not decode the request", NULL);
+                             "Could not decode the request");
         sendError(channel, msg, requestPos, responseType, requestId, retval);
         return;
     }
@@ -463,7 +463,7 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
         if(!session) {
             UA_LOG_DEBUG_CHANNEL(server->config.logger, channel,
                                  "Trying to activate a session that is " \
-                                 "not known in the server", NULL);
+                                 "not known in the server");
             sendError(channel, msg, requestPos, responseType,
                       requestId, UA_STATUSCODE_BADSESSIONIDINVALID);
             UA_deleteMembers(request, requestType);
@@ -509,7 +509,7 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
     /* The session is bound to another channel */
     if(session->channel != channel) {
         UA_LOG_DEBUG_CHANNEL(server->config.logger, channel,
-                             "Client tries to use an obsolete securechannel", NULL);
+                             "Client tries to use an obsolete securechannel");
         sendError(channel, msg, requestPos, responseType,
                   requestId, UA_STATUSCODE_BADSECURECHANNELIDINVALID);
         UA_deleteMembers(request, requestType);
@@ -563,7 +563,7 @@ static void processERR(UA_Server *server, UA_Connection *connection, const UA_By
     UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_NETWORK,
                  "Connection %i | Client replied with an error message: %s %.*s",
                  connection->sockfd, UA_StatusCode_name(errorMessage.error),
-                 errorMessage.reason.length, errorMessage.reason.data);
+                 (int)errorMessage.reason.length, errorMessage.reason.data);
 
     UA_TcpErrorMessage_deleteMembers(&errorMessage);
 }
@@ -582,29 +582,30 @@ UA_Server_processSecureChannelMessage(UA_Server *server, UA_SecureChannel *chann
         const UA_TcpErrorMessage *msg = (const UA_TcpErrorMessage *) message;
         UA_LOG_ERROR_CHANNEL(server->config.logger, channel,
                              "Client replied with an error message: %s %.*s",
-                             UA_StatusCode_name(msg->error), msg->reason.length, msg->reason.data);
+                             UA_StatusCode_name(msg->error), (int)msg->reason.length,
+                             msg->reason.data);
         break;
     }
     case UA_MESSAGETYPE_HEL:
         UA_LOG_TRACE_CHANNEL(server->config.logger, channel,
-                             "Cannot process a HEL on an open channel", NULL);
+                             "Cannot process a HEL on an open channel");
         break;
     case UA_MESSAGETYPE_OPN:
         UA_LOG_TRACE_CHANNEL(server->config.logger, channel,
-                             "Process an OPN on an open channel", NULL);
+                             "Process an OPN on an open channel");
         processOPN(server, channel->connection, channel->securityToken.channelId, message);
         break;
     case UA_MESSAGETYPE_MSG:
-        UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Process a MSG", NULL);
+        UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Process a MSG");
         processMSG(server, channel, requestId, message);
         break;
     case UA_MESSAGETYPE_CLO:
-        UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Process a CLO", NULL);
+        UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Process a CLO");
         Service_CloseSecureChannel(server, channel);
         break;
     default:
         UA_LOG_TRACE_CHANNEL(server->config.logger, channel,
-                             "Unknown message type", NULL);
+                             "Unknown message type");
     }
 }
 

+ 2 - 2
src/server/ua_services_attribute.c

@@ -905,7 +905,7 @@ Operation_Read(UA_Server *server, UA_Session *session,
 void Service_Read(UA_Server *server, UA_Session *session,
                   const UA_ReadRequest *request, UA_ReadResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing ReadRequest", NULL);
+                         "Processing ReadRequest");
 
     /* Check if the timestampstoreturn is valid */
     op_timestampsToReturn = request->timestampsToReturn;
@@ -1225,7 +1225,7 @@ Service_Write(UA_Server *server, UA_Session *session,
               const UA_WriteRequest *request,
               UA_WriteResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing WriteRequest", NULL);
+                         "Processing WriteRequest");
 
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,

+ 1 - 1
src/server/ua_services_call.c

@@ -175,7 +175,7 @@ void Service_Call(UA_Server *server, UA_Session *session,
                   const UA_CallRequest *request,
                   UA_CallResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing CallRequest", NULL);
+                         "Processing CallRequest");
 
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,

+ 7 - 6
src/server/ua_services_discovery.c

@@ -105,7 +105,7 @@ void Service_FindServers(UA_Server *server, UA_Session *session,
                          const UA_FindServersRequest *request,
                          UA_FindServersResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing FindServersRequest", NULL);
+                         "Processing FindServersRequest");
 
     size_t foundServersSize = 0;
     UA_ApplicationDescription *foundServers = NULL;
@@ -242,7 +242,7 @@ void Service_GetEndpoints(UA_Server *server, UA_Session *session,
                              UA_PRINTF_STRING_FORMAT, UA_PRINTF_STRING_DATA(*endpointUrl));
     } else {
         UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "Processing GetEndpointsRequest with an empty endpointUrl", NULL);
+                             "Processing GetEndpointsRequest with an empty endpointUrl");
     }
 
     /* test if the supported binary profile shall be returned */
@@ -386,10 +386,11 @@ process_RegisterServer(UA_Server *server, UA_Session *session,
 
     if(requestServer->semaphoreFilePath.length) {
 #ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
-        char* filePath = (char *)UA_malloc(sizeof(char)*requestServer->semaphoreFilePath.length+1);
+        char* filePath = (char*)
+            UA_malloc(sizeof(char)*requestServer->semaphoreFilePath.length+1);
         if (!filePath) {
             UA_LOG_ERROR_SESSION(server->config.logger, session,
-                                   "Cannot allocate memory for semaphore path. Out of memory.", NULL);
+                                   "Cannot allocate memory for semaphore path. Out of memory.");
             responseHeader->serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
             return;
         }
@@ -485,7 +486,7 @@ void Service_RegisterServer(UA_Server *server, UA_Session *session,
                             const UA_RegisterServerRequest *request,
                             UA_RegisterServerResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing RegisterServerRequest", NULL);
+                         "Processing RegisterServerRequest");
     process_RegisterServer(server, session, &request->requestHeader, &request->server, 0,
                            NULL, &response->responseHeader, 0, NULL, 0, NULL);
 }
@@ -494,7 +495,7 @@ void Service_RegisterServer2(UA_Server *server, UA_Session *session,
                             const UA_RegisterServer2Request *request,
                              UA_RegisterServer2Response *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing RegisterServer2Request", NULL);
+                         "Processing RegisterServer2Request");
     process_RegisterServer(server, session, &request->requestHeader, &request->server,
                            request->discoveryConfigurationSize, request->discoveryConfiguration,
                            &response->responseHeader, &response->configurationResultsSize,

+ 7 - 6
src/server/ua_services_discovery_multicast.c

@@ -96,8 +96,8 @@ addMdnsRecordForNetworkLayer(UA_Server *server, const UA_String *appName,
                                                &port, &path);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_NETWORK,
-                       "Server url is invalid: %.*s" ,
-                       nl->discoveryUrl.length, nl->discoveryUrl.data);
+                       "Server url is invalid: %.*s",
+                       (int)nl->discoveryUrl.length, nl->discoveryUrl.data);
         return retval;
     }
     UA_Discovery_addRecord(server, appName, &hostname, port,
@@ -215,7 +215,7 @@ UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serv
     if(retval != UA_STATUSCODE_GOOD) {
         UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_NETWORK,
                        "Server url invalid: %.*s",
-                       discoveryUrl->length, discoveryUrl->data);
+                       (int)discoveryUrl->length, discoveryUrl->data);
         return;
     }
 
@@ -225,8 +225,8 @@ UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serv
                                           port, updateTxt);
         if(removeRetval != UA_STATUSCODE_GOOD)
             UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER,
-                           "Could not remove mDNS record for hostname %s.",
-                           serverName);
+                           "Could not remove mDNS record for hostname %.*s.",
+                           (int)serverName->length, serverName->data);
         return;
     }
     
@@ -243,7 +243,8 @@ UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serv
                                capabilities, &capabilitiesSize);
     if(addRetval != UA_STATUSCODE_GOOD)
         UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER,
-                       "Could not add mDNS record for hostname %s.", serverName);
+                       "Could not add mDNS record for hostname %.*s.",
+                       (int)serverName->length, serverName->data);
 }
 
 void

+ 19 - 19
src/server/ua_services_nodemanagement.c

@@ -57,7 +57,7 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
     const UA_Node *parent = UA_NodeStore_get(server->nodestore, parentNodeId);
     if(!parent) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Parent node not found", NULL);
+                            "AddNodes: Parent node not found");
         return UA_STATUSCODE_BADPARENTNODEIDINVALID;
     }
 
@@ -66,21 +66,21 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
         (const UA_ReferenceTypeNode*)UA_NodeStore_get(server->nodestore, referenceTypeId);
     if(!referenceType) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Reference type to the parent not found", NULL);
+                            "AddNodes: Reference type to the parent not found");
         return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
     }
 
     /* Check if the referencetype is a reference type node */
     if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Reference type to the parent invalid", NULL);
+                            "AddNodes: Reference type to the parent invalid");
         return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
     }
 
     /* Check that the reference type is not abstract */
     if(referenceType->isAbstract == true) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Abstract reference type to the parent not allowed", NULL);
+                            "AddNodes: Abstract reference type to the parent not allowed");
         return UA_STATUSCODE_BADREFERENCENOTALLOWED;
     }
 
@@ -94,14 +94,14 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
         if(!UA_NodeId_equal(referenceTypeId, &subtypeId)) {
             UA_LOG_INFO_SESSION(server->config.logger, session,
                                 "AddNodes: New type node need to have a "
-                                "HasSubType reference", NULL);
+                                "HasSubType reference");
             return UA_STATUSCODE_BADREFERENCENOTALLOWED;
         }
         /* supertype needs to be of the same node type  */
         if(parent->nodeClass != nodeClass) {
             UA_LOG_INFO_SESSION(server->config.logger, session,
                                 "AddNodes: New type node needs to be of the same "
-                                "node type as the parent", NULL);
+                                "node type as the parent");
             return UA_STATUSCODE_BADPARENTNODEIDINVALID;
         }
         return UA_STATUSCODE_GOOD;
@@ -113,7 +113,7 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
     if(!isNodeInTree(server->nodestore, referenceTypeId,
                      &hierarchicalReference, &subtypeId, 1)) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Reference type is not hierarchical", NULL);
+                            "AddNodes: Reference type is not hierarchical");
         return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
     }
 
@@ -195,7 +195,7 @@ typeCheckVariableNode(UA_Server *server, UA_Session *session,
     if(node->valueRank == 0 &&
        (!value.hasValue || !value.value.type || UA_Variant_isScalar(&value.value))) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Use a default ValueRank of -2", NULL);
+                            "AddNodes: Use a default ValueRank of -2");
         UA_RCU_UNLOCK();
         retval = UA_Server_writeValueRank(server, node->nodeId, -2);
         UA_RCU_LOCK();
@@ -224,7 +224,7 @@ typeCheckVariableNode(UA_Server *server, UA_Session *session,
     /* Fix the variable: If no datatype is given, use the datatype of the vt */
     if(UA_NodeId_isNull(&node->dataType)) {
         UA_LOG_INFO_SESSION(server->config.logger, session, "AddNodes: "
-                            "Use a default DataType (from the TypeDefinition)", NULL);
+                            "Use a default DataType (from the TypeDefinition)");
         UA_RCU_UNLOCK();
         retval = UA_Server_writeDataType(server, node->nodeId, vt->dataType);
         UA_RCU_LOCK();
@@ -753,7 +753,7 @@ Service_AddNode_begin(UA_Server *server, UA_Session *session,
     /* Check the namespaceindex */
     if(item->requestedNewNodeId.nodeId.namespaceIndex >= server->namespacesSize) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Namespace invalid", NULL);
+                            "AddNodes: Namespace invalid");
         result->statusCode = UA_STATUSCODE_BADNODEIDINVALID;
         return;
     }
@@ -775,7 +775,7 @@ Service_AddNode_begin(UA_Server *server, UA_Session *session,
     result->statusCode = UA_NodeId_copy(&node->nodeId, &result->addedNodeId);
     if(result->statusCode != UA_STATUSCODE_GOOD) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: Could not copy the nodeid", NULL);
+                            "AddNodes: Could not copy the nodeid");
         deleteNode(server, &adminSession, &node->nodeId, true);
     }
 }
@@ -806,7 +806,7 @@ Service_AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *
     if((node->nodeClass == UA_NODECLASS_VARIABLE || node->nodeClass == UA_NODECLASS_OBJECT) &&
        UA_NodeId_isNull(typeDefinition)) {
         UA_LOG_INFO_SESSION(server->config.logger, session, "AddNodes: Use a default "
-                            "TypeDefinition for the Variable/Object", NULL);
+                            "TypeDefinition for the Variable/Object");
         if(node->nodeClass == UA_NODECLASS_VARIABLE)
             typeDefinition = &baseDataVariableType;
         else
@@ -818,7 +818,7 @@ Service_AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *
                                                 parentNodeId, referenceTypeId);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "AddNodes: The parent reference is invalid", NULL);
+                            "AddNodes: The parent reference is invalid");
         deleteNode(server, &adminSession, nodeId, true);
         return retval;
     }
@@ -852,7 +852,7 @@ Service_AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *
             const UA_VariableNode *vn = (const UA_VariableNode*)node;
             if(!(vn->accessLevel & (UA_ACCESSLEVELMASK_READ))) {
                 UA_LOG_INFO_SESSION(server->config.logger, session,
-                                    "AddNodes: Set the AccessLevel to readable by default", NULL);
+                                    "AddNodes: Set the AccessLevel to readable by default");
                 UA_Byte readable = vn->accessLevel | (UA_ACCESSLEVELMASK_READ);
                 UA_Server_writeAccessLevel(server, vn->nodeId, readable);
             }
@@ -870,7 +870,7 @@ Service_AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *
         addReference(server, session, &ref_item, &retval);
         if(retval != UA_STATUSCODE_GOOD) {
             UA_LOG_INFO_SESSION(server->config.logger, session,
-                                "AddNodes: Adding reference to parent failed", NULL);
+                                "AddNodes: Adding reference to parent failed");
             deleteNode(server, &adminSession, nodeId, true);
             return retval;
         }
@@ -904,7 +904,7 @@ void Service_AddNodes(UA_Server *server, UA_Session *session,
                       const UA_AddNodesRequest *request,
                       UA_AddNodesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing AddNodesRequest", NULL);
+                         "Processing AddNodesRequest");
 
     if(request->nodesToAddSize <= 0) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
@@ -1333,7 +1333,7 @@ void Service_AddReferences(UA_Server *server, UA_Session *session,
                            const UA_AddReferencesRequest *request,
                            UA_AddReferencesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing AddReferencesRequest", NULL);
+                         "Processing AddReferencesRequest");
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
                                            (UA_ServiceOperation) addReference,
@@ -1425,7 +1425,7 @@ void Service_DeleteNodes(UA_Server *server, UA_Session *session,
                          const UA_DeleteNodesRequest *request,
                          UA_DeleteNodesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing DeleteNodesRequest", NULL);
+                         "Processing DeleteNodesRequest");
 
     if(request->nodesToDeleteSize == 0) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
@@ -1536,7 +1536,7 @@ Service_DeleteReferences(UA_Server *server, UA_Session *session,
                          const UA_DeleteReferencesRequest *request,
                          UA_DeleteReferencesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing DeleteReferencesRequest", NULL);
+                         "Processing DeleteReferencesRequest");
     response->responseHeader.serviceResult =
         UA_Server_processServiceOperations(server, session,
                                            (UA_ServiceOperation)deleteReference,

+ 3 - 2
src/server/ua_services_securechannel.c

@@ -42,6 +42,7 @@ void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
 /* The server does not send a CloseSecureChannel response */
 void Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel) {
     UA_LOG_INFO_CHANNEL(server->config.logger, channel,
-                        "CloseSecureChannel", NULL);
-    UA_SecureChannelManager_close(&server->secureChannelManager, channel->securityToken.channelId);
+                        "CloseSecureChannel");
+    UA_SecureChannelManager_close(&server->secureChannelManager,
+                                  channel->securityToken.channelId);
 }

+ 6 - 6
src/server/ua_services_session.c

@@ -32,7 +32,7 @@ void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
         UA_SessionManager_createSession(&server->sessionManager, channel, request, &newSession);
     if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
         UA_LOG_DEBUG_CHANNEL(server->config.logger, channel,
-                             "Processing CreateSessionRequest failed", NULL);
+                             "Processing CreateSessionRequest failed");
         return;
     }
 
@@ -83,7 +83,7 @@ Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
     /* Detach the old SecureChannel */
     if(session->channel && session->channel != channel) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
-                            "ActivateSession: Detach from old channel", NULL);
+                            "ActivateSession: Detach from old channel");
         UA_SecureChannel_detachSession(session->channel, session);
     }
 
@@ -92,14 +92,14 @@ Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
     session->activated = true;
     UA_Session_updateLifetime(session);
     UA_LOG_INFO_SESSION(server->config.logger, session,
-                        "ActivateSession: Session activated", NULL);
+                        "ActivateSession: Session activated");
 }
 
 void
-Service_CloseSession(UA_Server *server, UA_Session *session, const UA_CloseSessionRequest *request,
+Service_CloseSession(UA_Server *server, UA_Session *session,
+                     const UA_CloseSessionRequest *request,
                      UA_CloseSessionResponse *response) {
-    UA_LOG_INFO_SESSION(server->config.logger, session,
-                        "CloseSession", NULL);
+    UA_LOG_INFO_SESSION(server->config.logger, session, "CloseSession");
     /* Callback into userland access control */
     server->config.accessControl.closeSession(&session->sessionId, session->sessionHandle);
     response->responseHeader.serviceResult =

+ 12 - 14
src/server/ua_services_subscription.c

@@ -61,7 +61,7 @@ Service_CreateSubscription(UA_Server *server, UA_Session *session,
     UA_Subscription *newSubscription = UA_Subscription_new(session, response->subscriptionId);
     if(!newSubscription) {
         UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "Processing CreateSubscriptionRequest failed", NULL);
+                             "Processing CreateSubscriptionRequest failed");
         response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
         return;
     }
@@ -92,7 +92,7 @@ Service_ModifySubscription(UA_Server *server, UA_Session *session,
                            const UA_ModifySubscriptionRequest *request,
                            UA_ModifySubscriptionResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing ModifySubscriptionRequest", NULL);
+                         "Processing ModifySubscriptionRequest");
 
     UA_Subscription *sub = UA_Session_getSubscriptionByID(session, request->subscriptionId);
     if(!sub) {
@@ -134,7 +134,7 @@ Service_SetPublishingMode(UA_Server *server, UA_Session *session,
                           const UA_SetPublishingModeRequest *request,
                           UA_SetPublishingModeResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing SetPublishingModeRequest", NULL);
+                         "Processing SetPublishingModeRequest");
 
     op_publishingEnabled = request->publishingEnabled;
     response->responseHeader.serviceResult = 
@@ -272,7 +272,7 @@ Service_CreateMonitoredItems(UA_Server *server, UA_Session *session,
                              const UA_CreateMonitoredItemsRequest *request,
                              UA_CreateMonitoredItemsResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing CreateMonitoredItemsRequest", NULL);
+                         "Processing CreateMonitoredItemsRequest");
 
     /* Check if the timestampstoreturn is valid */
     op_timestampsToReturn2 = request->timestampsToReturn;
@@ -320,7 +320,7 @@ void Service_ModifyMonitoredItems(UA_Server *server, UA_Session *session,
                                   const UA_ModifyMonitoredItemsRequest *request,
                                   UA_ModifyMonitoredItemsResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing ModifyMonitoredItemsRequest", NULL);
+                         "Processing ModifyMonitoredItemsRequest");
 
     /* Check if the timestampstoreturn is valid */
     if(request->timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) {
@@ -373,7 +373,7 @@ void Service_SetMonitoringMode(UA_Server *server, UA_Session *session,
                                const UA_SetMonitoringModeRequest *request,
                                UA_SetMonitoringModeResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing SetMonitoringMode", NULL);
+                         "Processing SetMonitoringMode");
 
     /* Get the subscription */
     op_sub = UA_Session_getSubscriptionByID(session, request->subscriptionId);
@@ -410,7 +410,7 @@ void
 Service_Publish(UA_Server *server, UA_Session *session,
                 const UA_PublishRequest *request, UA_UInt32 requestId) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing PublishRequest", NULL);
+                         "Processing PublishRequest");
 
     /* Return an error if the session has no subscription */
     if(LIST_EMPTY(&session->serverSubscriptions)) {
@@ -465,16 +465,14 @@ Service_Publish(UA_Server *server, UA_Session *session,
 
     /* Queue the publish response */
     SIMPLEQ_INSERT_TAIL(&session->responseQueue, entry, listEntry);
-    UA_LOG_DEBUG_SESSION(server->config.logger, session, "Queued a publication message",
-                         session->authenticationToken.identifier.numeric);
+    UA_LOG_DEBUG_SESSION(server->config.logger, session, "Queued a publication message");
 
     /* Answer immediately to a late subscription */
     UA_Subscription *immediate;
     LIST_FOREACH(immediate, &session->serverSubscriptions, listEntry) {
         if(immediate->state == UA_SUBSCRIPTIONSTATE_LATE) {
             UA_LOG_DEBUG_SESSION(server->config.logger, session, "Subscription %u | "
-                                 "Response on a late subscription", immediate->subscriptionID,
-                                 session->authenticationToken.identifier.numeric);
+                                 "Response on a late subscription", immediate->subscriptionID);
             UA_Subscription_publishCallback(server, immediate);
             break;
         }
@@ -501,7 +499,7 @@ Service_DeleteSubscriptions(UA_Server *server, UA_Session *session,
                             const UA_DeleteSubscriptionsRequest *request,
                             UA_DeleteSubscriptionsResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing DeleteSubscriptionsRequest", NULL);
+                         "Processing DeleteSubscriptionsRequest");
 
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
@@ -531,7 +529,7 @@ void Service_DeleteMonitoredItems(UA_Server *server, UA_Session *session,
                                   const UA_DeleteMonitoredItemsRequest *request,
                                   UA_DeleteMonitoredItemsResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing DeleteMonitoredItemsRequest", NULL);
+                         "Processing DeleteMonitoredItemsRequest");
 
     /* Get the subscription */
     op_sub = UA_Session_getSubscriptionByID(session, request->subscriptionId);
@@ -554,7 +552,7 @@ void Service_Republish(UA_Server *server, UA_Session *session,
                        const UA_RepublishRequest *request,
                        UA_RepublishResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing RepublishRequest", NULL);
+                         "Processing RepublishRequest");
 
     /* Get the subscription */
     UA_Subscription *sub = UA_Session_getSubscriptionByID(session, request->subscriptionId);

+ 5 - 5
src/server/ua_services_view.c

@@ -267,7 +267,7 @@ void Service_Browse(UA_Server *server, UA_Session *session,
                     const UA_BrowseRequest *request,
                     UA_BrowseResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing BrowseRequest", NULL);
+                         "Processing BrowseRequest");
 
     if(!UA_NodeId_isNull(&request->view.viewId)) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADVIEWIDUNKNOWN;
@@ -335,7 +335,7 @@ Service_BrowseNext(UA_Server *server, UA_Session *session,
                    const UA_BrowseNextRequest *request,
                    UA_BrowseNextResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing BrowseNextRequest", NULL);
+                         "Processing BrowseNextRequest");
 
     op_releaseContinuationPoint = request->releaseContinuationPoints;
 
@@ -656,7 +656,7 @@ Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
                                       const UA_TranslateBrowsePathsToNodeIdsRequest *request,
                                       UA_TranslateBrowsePathsToNodeIdsResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing TranslateBrowsePathsToNodeIdsRequest", NULL);
+                         "Processing TranslateBrowsePathsToNodeIdsRequest");
 
     response->responseHeader.serviceResult = 
         UA_Server_processServiceOperations(server, session,
@@ -669,7 +669,7 @@ void Service_RegisterNodes(UA_Server *server, UA_Session *session,
                            const UA_RegisterNodesRequest *request,
                            UA_RegisterNodesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing RegisterNodesRequest", NULL);
+                         "Processing RegisterNodesRequest");
 
     //TODO: hang the nodeids to the session if really needed
     if(request->nodesToRegisterSize == 0) {
@@ -688,7 +688,7 @@ void Service_UnregisterNodes(UA_Server *server, UA_Session *session,
                              const UA_UnregisterNodesRequest *request,
                              UA_UnregisterNodesResponse *response) {
     UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                         "Processing UnRegisterNodesRequest", NULL);
+                         "Processing UnRegisterNodesRequest");
 
     //TODO: remove the nodeids from the session if really needed
     if(request->nodesToUnregisterSize == 0)

+ 2 - 2
src/server/ua_session_manager.c

@@ -60,7 +60,7 @@ UA_SessionManager_cleanupTimedOut(UA_SessionManager *sm,
         if(sentry->session.validTill >= nowMonotonic)
             continue;
         UA_LOG_INFO_SESSION(sm->server->config.logger, &sentry->session,
-                            "Session has timed out", NULL);
+                            "Session has timed out");
         sm->server->config.accessControl.closeSession(&sentry->session.sessionId,
                                                       sentry->session.sessionHandle);
         removeSession(sm, sentry);
@@ -78,7 +78,7 @@ UA_SessionManager_getSession(UA_SessionManager *sm, const UA_NodeId *token) {
         /* Session has timed out */
         if(UA_DateTime_nowMonotonic() > current->session.validTill) {
             UA_LOG_INFO_SESSION(sm->server->config.logger, &current->session,
-                                "Client tries to use a session that has timed out", NULL);
+                                "Client tries to use a session that has timed out");
             return NULL;
         }
 

+ 2 - 2
src/server/ua_subscription.c

@@ -202,7 +202,7 @@ UA_Subscription_publishCallback(UA_Server *server, UA_Subscription *sub) {
             return;
         UA_LOG_DEBUG_SESSION(server->config.logger, sub->session,
                              "Subscription %u | Sending a KeepAlive",
-                             sub->subscriptionID)
+                             sub->subscriptionID);
     }
 
     /* Check if the securechannel is valid */
@@ -217,7 +217,7 @@ UA_Subscription_publishCallback(UA_Server *server, UA_Subscription *sub) {
     if(!pre) {
         UA_LOG_DEBUG_SESSION(server->config.logger, sub->session,
                              "Subscription %u | Cannot send a publish response "
-                             "since the publish queue is empty", sub->subscriptionID)
+                             "since the publish queue is empty", sub->subscriptionID);
         if(sub->state != UA_SUBSCRIPTIONSTATE_LATE) {
             sub->state = UA_SUBSCRIPTIONSTATE_LATE;
         } else {

+ 52 - 22
src/ua_securechannel.h

@@ -13,6 +13,7 @@ extern "C" {
 #include "ua_types.h"
 #include "ua_transport_generated.h"
 #include "ua_connection_internal.h"
+#include "ua_util.h"
 
 struct UA_Session;
 typedef struct UA_Session UA_Session;
@@ -87,37 +88,66 @@ UA_SecureChannel_processChunks(UA_SecureChannel *channel, const UA_ByteString *c
  * ----------
  * C99 requires at least one element for the variadic argument. If the log
  * statement has no variable arguments, supply an additional NULL. It will be
- * ignored by printf. */
+ * ignored by printf.
+ *
+ * We have to jump through some hoops to enable the use of format strings
+ * without arguments since (pedantic) C99 does not allow variadic macros with
+ * zero arguments. So we add a dummy argument that is not printed (%.0s is
+ * string of length zero). */
+
+#define UA_LOG_TRACE_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...)              \
+    UA_LOG_TRACE(LOGGER, UA_LOGCATEGORY_SECURECHANNEL,                        \
+                 "Connection %i | SecureChannel %i | " MSG "%.0s",            \
+                 ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
+                 (CHANNEL)->securityToken.channelId, __VA_ARGS__)
+
+#define UA_LOG_TRACE_CHANNEL(LOGGER, CHANNEL, ...)        \
+    UA_MACRO_EXPAND(UA_LOG_TRACE_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, (const char*)0x01))
+
+#define UA_LOG_DEBUG_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...)              \
+    UA_LOG_DEBUG(LOGGER, UA_LOGCATEGORY_SECURECHANNEL,                        \
+                 "Connection %i | SecureChannel %i | " MSG "%.0s",            \
+                 ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
+                 (CHANNEL)->securityToken.channelId, __VA_ARGS__)
 
-#define UA_LOG_TRACE_CHANNEL(LOGGER, CHANNEL, MSG, ...)                 \
-    UA_LOG_TRACE(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, "Connection %i | SecureChannel %i | " MSG, \
-                 ((CHANNEL)->connection ? CHANNEL->connection->sockfd : 0), \
-                 (CHANNEL)->securityToken.channelId, __VA_ARGS__);
+#define UA_LOG_DEBUG_CHANNEL(LOGGER, CHANNEL, ...)        \
+    UA_MACRO_EXPAND(UA_LOG_DEBUG_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, (const char*)0x01))
 
-#define UA_LOG_DEBUG_CHANNEL(LOGGER, CHANNEL, MSG, ...)                 \
-    UA_LOG_DEBUG(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, "Connection %i | SecureChannel %i | " MSG, \
+#define UA_LOG_INFO_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...)               \
+    UA_LOG_INFO(LOGGER, UA_LOGCATEGORY_SECURECHANNEL,                         \
+                 "Connection %i | SecureChannel %i | " MSG "%.0s",            \
                  ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
-                 (CHANNEL)->securityToken.channelId, __VA_ARGS__);
+                 (CHANNEL)->securityToken.channelId, __VA_ARGS__)
 
-#define UA_LOG_INFO_CHANNEL(LOGGER, CHANNEL, MSG, ...)                   \
-    UA_LOG_INFO(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, "Connection %i | SecureChannel %i | " MSG, \
-                ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
-                (CHANNEL)->securityToken.channelId, __VA_ARGS__);
+#define UA_LOG_INFO_CHANNEL(LOGGER, CHANNEL, ...)        \
+    UA_MACRO_EXPAND(UA_LOG_INFO_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, (const char*)0x01))
 
-#define UA_LOG_WARNING_CHANNEL(LOGGER, CHANNEL, MSG, ...)               \
-    UA_LOG_WARNING(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, "Connection %i | SecureChannel %i | " MSG, \
-                   ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
-                   (CHANNEL)->securityToken.channelId, __VA_ARGS__);
+#define UA_LOG_WARNING_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...)            \
+    UA_LOG_WARNING(LOGGER, UA_LOGCATEGORY_SECURECHANNEL,                      \
+                 "Connection %i | SecureChannel %i | " MSG "%.0s",            \
+                 ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
+                 (CHANNEL)->securityToken.channelId, __VA_ARGS__)
+
+#define UA_LOG_WARNING_CHANNEL(LOGGER, CHANNEL, ...)        \
+    UA_MACRO_EXPAND(UA_LOG_WARNING_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, (const char*)0x01))
 
-#define UA_LOG_ERROR_CHANNEL(LOGGER, CHANNEL, MSG, ...)                 \
-    UA_LOG_ERROR(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, "Connection %i | SecureChannel %i | " MSG, \
+#define UA_LOG_ERROR_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...)              \
+    UA_LOG_ERROR(LOGGER, UA_LOGCATEGORY_SECURECHANNEL,                        \
+                 "Connection %i | SecureChannel %i | " MSG "%.0s",            \
                  ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
-                 (CHANNEL)->securityToken.channelId, __VA_ARGS__);
+                 (CHANNEL)->securityToken.channelId, __VA_ARGS__)
 
-#define UA_LOG_FATAL_CHANNEL(LOGGER, CHANNEL, MSG, ...)                 \
-    UA_LOG_FATAL(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, "Connection %i | SecureChannel %i | " MSG, \
+#define UA_LOG_ERROR_CHANNEL(LOGGER, CHANNEL, ...)        \
+    UA_MACRO_EXPAND(UA_LOG_ERROR_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, (const char*)0x01))
+
+#define UA_LOG_FATAL_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...)              \
+    UA_LOG_FATAL(LOGGER, UA_LOGCATEGORY_SECURECHANNEL,                        \
+                 "Connection %i | SecureChannel %i | " MSG "%.0s",            \
                  ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \
-                 (CHANNEL)->securityToken.channelId, __VA_ARGS__);
+                 (CHANNEL)->securityToken.channelId, __VA_ARGS__)
+
+#define UA_LOG_FATAL_CHANNEL(LOGGER, CHANNEL, ...)        \
+    UA_MACRO_EXPAND(UA_LOG_FATAL_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, (const char*)0x01))
 
 #ifdef __cplusplus
 } // extern "C"

+ 51 - 31
src/ua_session.h

@@ -13,6 +13,7 @@ extern "C" {
 #include "ua_types.h"
 #include "ua_securechannel.h"
 #include "ua_server.h"
+#include "ua_util.h"
 
 #define UA_MAXCONTINUATIONPOINTS 5
 
@@ -86,51 +87,70 @@ UA_Session_getUniqueSubscriptionID(UA_Session *session);
 /**
  * Log Helper
  * ----------
- * C99 requires at least one element for the variadic argument. If the log
- * statement has no variable arguments, supply an additional NULL. It will be
- * ignored by printf. */
+ * We have to jump through some hoops to enable the use of format strings
+ * without arguments since (pedantic) C99 does not allow variadic macros with
+ * zero arguments. So we add a dummy argument that is not printed (%.0s is
+ * string of length zero). */
+
+#define UA_LOG_TRACE_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...)        \
+    UA_LOG_TRACE(LOGGER, UA_LOGCATEGORY_SESSION,                        \
+                 "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \
+                 ((SESSION)->channel ? ((SESSION)->channel->connection ? (SESSION)->channel->connection->sockfd : 0) : 0), \
+                 ((SESSION)->channel ? (SESSION)->channel->securityToken.channelId : 0), \
+                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__)
+
+#define UA_LOG_TRACE_SESSION(LOGGER, SESSION, ...)                      \
+    UA_MACRO_EXPAND(UA_LOG_TRACE_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, (const char*)0x01))
 
-#define UA_LOG_TRACE_SESSION(LOGGER, SESSION, MSG, ...)                 \
-    UA_LOG_TRACE(LOGGER, UA_LOGCATEGORY_SESSION, "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG, \
+#define UA_LOG_DEBUG_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...)        \
+    UA_LOG_DEBUG(LOGGER, UA_LOGCATEGORY_SESSION,                        \
+                 "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \
                  ((SESSION)->channel ? ((SESSION)->channel->connection ? (SESSION)->channel->connection->sockfd : 0) : 0), \
                  ((SESSION)->channel ? (SESSION)->channel->securityToken.channelId : 0), \
-                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), \
-                 __VA_ARGS__);
+                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__)
 
-#define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, MSG, ...)                 \
-    UA_LOG_DEBUG(LOGGER, UA_LOGCATEGORY_SESSION, "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG, \
+#define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, ...)                      \
+    UA_MACRO_EXPAND(UA_LOG_DEBUG_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, (const char*)0x01))
+
+#define UA_LOG_INFO_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...)        \
+    UA_LOG_INFO(LOGGER, UA_LOGCATEGORY_SESSION,                        \
+                 "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \
                  ((SESSION)->channel ? ((SESSION)->channel->connection ? (SESSION)->channel->connection->sockfd : 0) : 0), \
                  ((SESSION)->channel ? (SESSION)->channel->securityToken.channelId : 0), \
-                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), \
-                 __VA_ARGS__);
+                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__)
+
+#define UA_LOG_INFO_SESSION(LOGGER, SESSION, ...)                      \
+    UA_MACRO_EXPAND(UA_LOG_INFO_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, (const char*)0x01))
 
-#define UA_LOG_INFO_SESSION(LOGGER, SESSION, MSG, ...)                  \
-    UA_LOG_INFO(LOGGER, UA_LOGCATEGORY_SESSION, "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG, \
+#define UA_LOG_WARNING_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...)        \
+    UA_LOG_WARNING(LOGGER, UA_LOGCATEGORY_SESSION,                        \
+                 "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \
                  ((SESSION)->channel ? ((SESSION)->channel->connection ? (SESSION)->channel->connection->sockfd : 0) : 0), \
                  ((SESSION)->channel ? (SESSION)->channel->securityToken.channelId : 0), \
-                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), \
-                 __VA_ARGS__);
-
-#define UA_LOG_WARNING_SESSION(LOGGER, SESSION, MSG, ...)               \
-    UA_LOG_WARNING(LOGGER, UA_LOGCATEGORY_SESSION, "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG, \
-                   ((SESSION)->channel ? ((SESSION)->channel->connection ? (SESSION)->channel->connection->sockfd : 0) : 0), \
-                   ((SESSION)->channel ? (SESSION)->channel->securityToken.channelId : 0), \
-                   UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), \
-                   __VA_ARGS__);
-
-#define UA_LOG_ERROR_SESSION(LOGGER, SESSION, MSG, ...)                 \
-    UA_LOG_ERROR(LOGGER, UA_LOGCATEGORY_SESSION, "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG, \
+                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__)
+
+#define UA_LOG_WARNING_SESSION(LOGGER, SESSION, ...)                      \
+    UA_MACRO_EXPAND(UA_LOG_WARNING_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, (const char*)0x01))
+
+#define UA_LOG_ERROR_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...)        \
+    UA_LOG_ERROR(LOGGER, UA_LOGCATEGORY_SESSION,                        \
+                 "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \
                  ((SESSION)->channel ? ((SESSION)->channel->connection ? (SESSION)->channel->connection->sockfd : 0) : 0), \
                  ((SESSION)->channel ? (SESSION)->channel->securityToken.channelId : 0), \
-                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), \
-                 __VA_ARGS__);
+                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__)
 
-#define UA_LOG_FATAL_SESSION(LOGGER, SESSION, MSG, ...)                 \
-    UA_LOG_FATAL(LOGGER, UA_LOGCATEGORY_SESSION, "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG, \
+#define UA_LOG_ERROR_SESSION(LOGGER, SESSION, ...)                      \
+    UA_MACRO_EXPAND(UA_LOG_ERROR_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, (const char*)0x01))
+
+#define UA_LOG_FATAL_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...)        \
+    UA_LOG_FATAL(LOGGER, UA_LOGCATEGORY_SESSION,                        \
+                 "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \
                  ((SESSION)->channel ? ((SESSION)->channel->connection ? (SESSION)->channel->connection->sockfd : 0) : 0), \
                  ((SESSION)->channel ? (SESSION)->channel->securityToken.channelId : 0), \
-                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), \
-                 __VA_ARGS__);
+                 UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__)
+
+#define UA_LOG_FATAL_SESSION(LOGGER, SESSION, ...)                      \
+    UA_MACRO_EXPAND(UA_LOG_FATAL_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, (const char*)0x01))
 
 #ifdef __cplusplus
 } // extern "C"

+ 3 - 0
src/ua_util.h

@@ -18,6 +18,9 @@ extern "C" {
 /* BSD Queue Macros */
 #include "queue.h"
 
+/* Macro-Expand for MSVC workarounds */
+#define UA_MACRO_EXPAND(x) x
+
 /* container_of */
 #define container_of(ptr, type, member) \
     (type *)((uintptr_t)ptr - offsetof(type,member))