blob: 5a1a20281d0fd24e3993aab1651a6c64a7109d64 [file] [log] [blame]
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
*/
#ifndef UA_SESSION_H_
#define UA_SESSION_H_
#include <open62541/util.h>
#include "ua_securechannel.h"
_UA_BEGIN_DECLS
#define UA_MAXCONTINUATIONPOINTS 5
struct ContinuationPoint;
typedef struct ContinuationPoint ContinuationPoint;
/* Returns the next entry in the linked list */
ContinuationPoint *
ContinuationPoint_clear(ContinuationPoint *cp);
struct UA_Subscription;
typedef struct UA_Subscription UA_Subscription;
#ifdef UA_ENABLE_SUBSCRIPTIONS
typedef struct UA_PublishResponseEntry {
SIMPLEQ_ENTRY(UA_PublishResponseEntry) listEntry;
UA_UInt32 requestId;
UA_PublishResponse response;
} UA_PublishResponseEntry;
#endif
typedef struct {
UA_SessionHeader header;
UA_ApplicationDescription clientDescription;
UA_String sessionName;
UA_Boolean activated;
void *sessionHandle; // pointer assigned in userland-callback
UA_NodeId sessionId;
UA_UInt32 maxRequestMessageSize;
UA_UInt32 maxResponseMessageSize;
UA_Double timeout; // [ms]
UA_DateTime validTill;
UA_ByteString serverNonce;
UA_UInt16 availableContinuationPoints;
ContinuationPoint *continuationPoints;
#ifdef UA_ENABLE_SUBSCRIPTIONS
UA_UInt32 lastSubscriptionId;
UA_UInt32 lastSeenSubscriptionId;
LIST_HEAD(UA_ListOfUASubscriptions, UA_Subscription) serverSubscriptions;
SIMPLEQ_HEAD(UA_ListOfQueuedPublishResponses, UA_PublishResponseEntry) responseQueue;
UA_UInt32 numSubscriptions;
UA_UInt32 numPublishReq;
size_t totalRetransmissionQueueSize; /* Retransmissions of all subscriptions */
#endif
} UA_Session;
/**
* Session Lifecycle
* ----------------- */
void UA_Session_init(UA_Session *session);
void UA_Session_deleteMembersCleanup(UA_Session *session, UA_Server *server);
void UA_Session_attachToSecureChannel(UA_Session *session, UA_SecureChannel *channel);
void UA_Session_detachFromSecureChannel(UA_Session *session);
UA_StatusCode UA_Session_generateNonce(UA_Session *session);
/* If any activity on a session happens, the timeout is extended */
void UA_Session_updateLifetime(UA_Session *session);
/**
* Subscription handling
* --------------------- */
#ifdef UA_ENABLE_SUBSCRIPTIONS
void
UA_Session_addSubscription(UA_Server *server,
UA_Session *session,
UA_Subscription *newSubscription);
UA_Subscription *
UA_Session_getSubscriptionById(UA_Session *session,
UA_UInt32 subscriptionId);
UA_StatusCode
UA_Session_deleteSubscription(UA_Server *server, UA_Session *session,
UA_UInt32 subscriptionId);
void
UA_Session_queuePublishReq(UA_Session *session,
UA_PublishResponseEntry* entry,
UA_Boolean head);
UA_PublishResponseEntry *
UA_Session_dequeuePublishReq(UA_Session *session);
#endif
/**
* Log Helper
* ----------
* 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_SESSION_INTERNAL(LOGGER, LEVEL, SESSION, MSG, ...) do { \
UA_String idString = UA_STRING_NULL; \
UA_NodeId_toString(&(SESSION)->sessionId, &idString); \
UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_SESSION, \
"Connection %i | SecureChannel %i | Session %.*s | " MSG "%.0s", \
((SESSION)->header.channel ? \
((SESSION)->header.channel->connection ? \
(int)((SESSION)->header.channel->connection->sockfd) : 0) : 0), \
((SESSION)->header.channel ? \
(SESSION)->header.channel->securityToken.channelId : 0), \
(int)idString.length, idString.data, __VA_ARGS__); \
UA_String_deleteMembers(&idString); \
} while(0)
#if UA_LOGLEVEL <= 100
#define UA_LOG_TRACE_SESSION(LOGGER, SESSION, ...) \
UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, TRACE, SESSION, __VA_ARGS__, ""))
#else
#define UA_LOG_TRACE_SESSION(LOGGER, SESSION, ...) do {} while(0)
#endif
#if UA_LOGLEVEL <= 200
#define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, ...) \
UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, DEBUG, SESSION, __VA_ARGS__, ""))
#else
#define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, ...) do {} while(0)
#endif
#if UA_LOGLEVEL <= 300
#define UA_LOG_INFO_SESSION(LOGGER, SESSION, ...) \
UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, INFO, SESSION, __VA_ARGS__, ""))
#else
#define UA_LOG_INFO_SESSION(LOGGER, SESSION, ...) do {} while(0)
#endif
#if UA_LOGLEVEL <= 400
#define UA_LOG_WARNING_SESSION(LOGGER, SESSION, ...) \
UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, WARNING, SESSION, __VA_ARGS__, ""))
#else
#define UA_LOG_WARNING_SESSION(LOGGER, SESSION, ...) do {} while(0)
#endif
#if UA_LOGLEVEL <= 500
#define UA_LOG_ERROR_SESSION(LOGGER, SESSION, ...) \
UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, ERROR, SESSION, __VA_ARGS__, ""))
#else
#define UA_LOG_ERROR_SESSION(LOGGER, SESSION, ...) do {} while(0)
#endif
#if UA_LOGLEVEL <= 600
#define UA_LOG_FATAL_SESSION(LOGGER, SESSION, ...) \
UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, FATAL, SESSION, __VA_ARGS__, ""))
#else
#define UA_LOG_FATAL_SESSION(LOGGER, SESSION, ...) do {} while(0)
#endif
_UA_END_DECLS
#endif /* UA_SESSION_H_ */