/src/open62541/src/server/ua_session.h
Line | Count | Source |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | | * |
5 | | * Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) |
6 | | * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green) |
7 | | */ |
8 | | |
9 | | #ifndef UA_SESSION_H_ |
10 | | #define UA_SESSION_H_ |
11 | | |
12 | | #include <open62541/util.h> |
13 | | |
14 | | #include "../ua_securechannel.h" |
15 | | |
16 | | _UA_BEGIN_DECLS |
17 | | |
18 | 0 | #define UA_MAXCONTINUATIONPOINTS 5 |
19 | | |
20 | | struct ContinuationPoint; |
21 | | typedef struct ContinuationPoint ContinuationPoint; |
22 | | |
23 | | /* Returns the next entry in the linked list */ |
24 | | ContinuationPoint * |
25 | | ContinuationPoint_clear(ContinuationPoint *cp); |
26 | | |
27 | | struct UA_Subscription; |
28 | | typedef struct UA_Subscription UA_Subscription; |
29 | | |
30 | | #ifdef UA_ENABLE_SUBSCRIPTIONS |
31 | | typedef struct UA_PublishResponseEntry { |
32 | | SIMPLEQ_ENTRY(UA_PublishResponseEntry) listEntry; |
33 | | UA_UInt32 requestId; |
34 | | UA_DateTime maxTime; /* Based on the TimeoutHint of the request */ |
35 | | UA_PublishResponse response; |
36 | | } UA_PublishResponseEntry; |
37 | | #endif |
38 | | |
39 | | struct UA_Session { |
40 | | UA_Session *next; /* singly-linked list */ |
41 | | UA_SecureChannel *channel; /* The pointer back to the SecureChannel in the session. */ |
42 | | |
43 | | UA_NodeId sessionId; |
44 | | UA_NodeId authenticationToken; |
45 | | UA_String sessionName; |
46 | | UA_Boolean activated; |
47 | | |
48 | | void *context; /* Pointer assigned by the user in the |
49 | | * accessControl->activateSession context */ |
50 | | |
51 | | UA_ByteString serverNonce; |
52 | | |
53 | | UA_ApplicationDescription clientDescription; |
54 | | UA_String clientUserIdOfSession; |
55 | | UA_Double timeout; /* in ms */ |
56 | | UA_DateTime validTill; |
57 | | |
58 | | UA_KeyValueMap *attributes; |
59 | | |
60 | | /* TODO: Currently unused */ |
61 | | UA_UInt32 maxRequestMessageSize; |
62 | | UA_UInt32 maxResponseMessageSize; |
63 | | |
64 | | UA_UInt16 availableContinuationPoints; |
65 | | ContinuationPoint *continuationPoints; |
66 | | |
67 | | /* Localization information */ |
68 | | size_t localeIdsSize; |
69 | | UA_String *localeIds; |
70 | | |
71 | | #ifdef UA_ENABLE_SUBSCRIPTIONS |
72 | | /* The queue is ordered according to the priority byte (higher bytes come |
73 | | * first). When a late subscription finally publishes, then it is pushed to |
74 | | * the back within the sub-set of subscriptions that has the same priority |
75 | | * (round-robin scheduling). */ |
76 | | size_t subscriptionsSize; |
77 | | TAILQ_HEAD(, UA_Subscription) subscriptions; |
78 | | |
79 | | size_t responseQueueSize; |
80 | | SIMPLEQ_HEAD(, UA_PublishResponseEntry) responseQueue; |
81 | | |
82 | | size_t totalRetransmissionQueueSize; /* Retransmissions of all subscriptions */ |
83 | | #endif |
84 | | |
85 | | #ifdef UA_ENABLE_DIAGNOSTICS |
86 | | UA_SessionSecurityDiagnosticsDataType securityDiagnostics; |
87 | | UA_SessionDiagnosticsDataType diagnostics; |
88 | | #endif |
89 | | }; |
90 | | |
91 | | /** |
92 | | * Session Lifecycle |
93 | | * ----------------- */ |
94 | | |
95 | | void UA_Session_init(UA_Session *session); |
96 | | void UA_Session_clear(UA_Session *session, UA_Server *server); |
97 | | void UA_Session_attachToSecureChannel(UA_Session *session, UA_SecureChannel *channel); |
98 | | void UA_Session_detachFromSecureChannel(UA_Session *session); |
99 | | UA_StatusCode UA_Session_generateNonce(UA_Session *session); |
100 | | |
101 | | /* If any activity on a session happens, the timeout is extended */ |
102 | | void UA_Session_updateLifetime(UA_Session *session, UA_DateTime now, |
103 | | UA_DateTime nowMonotonic); |
104 | | |
105 | | /** |
106 | | * Subscription handling |
107 | | * --------------------- */ |
108 | | |
109 | | #ifdef UA_ENABLE_SUBSCRIPTIONS |
110 | | |
111 | | void |
112 | | UA_Session_attachSubscription(UA_Session *session, UA_Subscription *sub); |
113 | | |
114 | | /* If releasePublishResponses is true and the last subscription is removed, all |
115 | | * outstanding PublishResponse are sent with a StatusCode. But we don't do that |
116 | | * if a Subscription is only detached for modification. */ |
117 | | void |
118 | | UA_Session_detachSubscription(UA_Server *server, UA_Session *session, |
119 | | UA_Subscription *sub, UA_Boolean releasePublishResponses); |
120 | | |
121 | | UA_Subscription * |
122 | | UA_Session_getSubscriptionById(UA_Session *session, |
123 | | UA_UInt32 subscriptionId); |
124 | | |
125 | | |
126 | | void |
127 | | UA_Session_queuePublishReq(UA_Session *session, |
128 | | UA_PublishResponseEntry* entry, |
129 | | UA_Boolean head); |
130 | | |
131 | | UA_PublishResponseEntry * |
132 | | UA_Session_dequeuePublishReq(UA_Session *session); |
133 | | |
134 | | #endif |
135 | | |
136 | | /** |
137 | | * Log Helper |
138 | | * ---------- |
139 | | * We have to jump through some hoops to enable the use of format strings |
140 | | * without arguments since (pedantic) C99 does not allow variadic macros with |
141 | | * zero arguments. So we add a dummy argument that is not printed (%.0s is |
142 | | * string of length zero). */ |
143 | | |
144 | | #define UA_LOG_SESSION_INTERNAL(LOGGER, LEVEL, SESSION, MSG, ...) \ |
145 | | do { \ |
146 | | if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \ |
147 | | UA_String sessionName = (SESSION) ? (SESSION)->sessionName: UA_STRING_NULL; \ |
148 | | unsigned long sockId = ((SESSION) && (SESSION)->channel) ? \ |
149 | | (unsigned long)(SESSION)->channel->connectionId : 0; \ |
150 | | UA_UInt32 chanId = ((SESSION) && (SESSION)->channel) ? \ |
151 | | (SESSION)->channel->securityToken.channelId : 0; \ |
152 | | UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_SESSION, \ |
153 | | "TCP %lu\t| SC %" PRIu32 "\t| Session \"%S\"\t| " MSG "%.0s", \ |
154 | | sockId, chanId, sessionName, __VA_ARGS__); \ |
155 | | } \ |
156 | | } while (0) |
157 | | |
158 | | #define UA_LOG_TRACE_SESSION(LOGGER, SESSION, ...) \ |
159 | 0 | UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, TRACE, SESSION, __VA_ARGS__, "")) |
160 | | #define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, ...) \ |
161 | 0 | UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, DEBUG, SESSION, __VA_ARGS__, "")) |
162 | | #define UA_LOG_INFO_SESSION(LOGGER, SESSION, ...) \ |
163 | 0 | UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, INFO, SESSION, __VA_ARGS__, "")) |
164 | | #define UA_LOG_WARNING_SESSION(LOGGER, SESSION, ...) \ |
165 | 0 | UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, WARNING, SESSION, __VA_ARGS__, "")) |
166 | | #define UA_LOG_ERROR_SESSION(LOGGER, SESSION, ...) \ |
167 | 0 | UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, ERROR, SESSION, __VA_ARGS__, "")) |
168 | | #define UA_LOG_FATAL_SESSION(LOGGER, SESSION, ...) \ |
169 | | UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, FATAL, SESSION, __VA_ARGS__, "")) |
170 | | |
171 | | _UA_END_DECLS |
172 | | |
173 | | #endif /* UA_SESSION_H_ */ |