ua_session.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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) Julius Pfrommer, Fraunhofer IOSB
  6. * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA
  7. */
  8. #include "ua_session.h"
  9. #ifdef UA_ENABLE_SUBSCRIPTIONS
  10. #include "ua_subscription.h"
  11. #include "ua_server_internal.h"
  12. #endif
  13. UA_Session adminSession = {
  14. {{NULL, NULL}, /* .pointers */
  15. {0,UA_NODEIDTYPE_NUMERIC,{1}}, /* .authenticationToken */
  16. NULL,}, /* .channel */
  17. {{0, NULL},{0, NULL},
  18. {{0, NULL},{0, NULL}},
  19. UA_APPLICATIONTYPE_CLIENT,
  20. {0, NULL},{0, NULL},
  21. 0, NULL}, /* .clientDescription */
  22. {sizeof("Administrator Session")-1, (UA_Byte*)"Administrator Session"}, /* .sessionName */
  23. false, /* .activated */
  24. NULL, /* .sessionHandle */
  25. {0,UA_NODEIDTYPE_NUMERIC,{1}}, /* .sessionId */
  26. UA_UINT32_MAX, /* .maxRequestMessageSize */
  27. UA_UINT32_MAX, /* .maxResponseMessageSize */
  28. (UA_Double)UA_INT64_MAX, /* .timeout */
  29. UA_INT64_MAX, /* .validTill */
  30. {0, NULL},
  31. UA_MAXCONTINUATIONPOINTS, /* .availableContinuationPoints */
  32. {NULL}, /* .continuationPoints */
  33. #ifdef UA_ENABLE_SUBSCRIPTIONS
  34. 0, /* .lastSubscriptionId */
  35. 0, /* .lastSeenSubscriptionId */
  36. {NULL}, /* .serverSubscriptions */
  37. {NULL, NULL}, /* .responseQueue */
  38. 0, /* numSubscriptions */
  39. 0 /* numPublishReq */
  40. #endif
  41. };
  42. void UA_Session_init(UA_Session *session) {
  43. memset(session, 0, sizeof(UA_Session));
  44. session->availableContinuationPoints = UA_MAXCONTINUATIONPOINTS;
  45. #ifdef UA_ENABLE_SUBSCRIPTIONS
  46. SIMPLEQ_INIT(&session->responseQueue);
  47. #endif
  48. }
  49. void UA_Session_deleteMembersCleanup(UA_Session *session, UA_Server* server) {
  50. UA_Session_detachFromSecureChannel(session);
  51. UA_ApplicationDescription_deleteMembers(&session->clientDescription);
  52. UA_NodeId_deleteMembers(&session->header.authenticationToken);
  53. UA_NodeId_deleteMembers(&session->sessionId);
  54. UA_String_deleteMembers(&session->sessionName);
  55. UA_ByteString_deleteMembers(&session->serverNonce);
  56. struct ContinuationPointEntry *cp, *temp;
  57. LIST_FOREACH_SAFE(cp, &session->continuationPoints, pointers, temp) {
  58. LIST_REMOVE(cp, pointers);
  59. UA_ByteString_deleteMembers(&cp->identifier);
  60. UA_BrowseDescription_deleteMembers(&cp->browseDescription);
  61. UA_free(cp);
  62. }
  63. #ifdef UA_ENABLE_SUBSCRIPTIONS
  64. UA_Subscription *currents, *temps;
  65. LIST_FOREACH_SAFE(currents, &session->serverSubscriptions, listEntry, temps) {
  66. LIST_REMOVE(currents, listEntry);
  67. UA_Subscription_deleteMembers(currents, server);
  68. UA_free(currents);
  69. }
  70. UA_PublishResponseEntry *entry;
  71. while((entry = UA_Session_getPublishReq(session))) {
  72. UA_Session_removePublishReq(session,entry);
  73. UA_PublishResponse_deleteMembers(&entry->response);
  74. UA_free(entry);
  75. }
  76. #endif
  77. }
  78. void UA_Session_attachToSecureChannel(UA_Session *session, UA_SecureChannel *channel) {
  79. LIST_INSERT_HEAD(&channel->sessions, &session->header, pointers);
  80. session->header.channel = channel;
  81. }
  82. void UA_Session_detachFromSecureChannel(UA_Session *session) {
  83. if(!session->header.channel)
  84. return;
  85. session->header.channel = NULL;
  86. LIST_REMOVE(&session->header, pointers);
  87. }
  88. void UA_Session_updateLifetime(UA_Session *session) {
  89. session->validTill = UA_DateTime_nowMonotonic() +
  90. (UA_DateTime)(session->timeout * UA_DATETIME_MSEC);
  91. }
  92. #ifdef UA_ENABLE_SUBSCRIPTIONS
  93. void UA_Session_addSubscription(UA_Session *session, UA_Subscription *newSubscription) {
  94. session->numSubscriptions++;
  95. LIST_INSERT_HEAD(&session->serverSubscriptions, newSubscription, listEntry);
  96. }
  97. /* Delayed callback to free the subscription memory */
  98. static void
  99. removeSubscriptionCallback(UA_Server *server, void *data) {
  100. UA_Subscription *sub = (UA_Subscription*)data;
  101. UA_Subscription_deleteMembers(sub, server);
  102. UA_free(sub);
  103. }
  104. UA_StatusCode
  105. UA_Session_deleteSubscription(UA_Server *server, UA_Session *session,
  106. UA_UInt32 subscriptionId) {
  107. UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId);
  108. if(!sub)
  109. return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
  110. /* Add a delayed callback to remove the subscription when the currently
  111. * scheduled jobs have completed */
  112. UA_StatusCode retval = UA_Server_delayedCallback(server, removeSubscriptionCallback, sub);
  113. if(retval != UA_STATUSCODE_GOOD) {
  114. UA_LOG_WARNING_SESSION(server->config.logger, session,
  115. "Could not remove subscription with error code %s",
  116. UA_StatusCode_name(retval));
  117. return retval; /* Try again next time */
  118. }
  119. LIST_REMOVE(sub, listEntry);
  120. if(session->numSubscriptions > 0) {
  121. session->numSubscriptions--;
  122. }
  123. else {
  124. return UA_STATUSCODE_BADINTERNALERROR;
  125. }
  126. return UA_STATUSCODE_GOOD;
  127. }
  128. UA_UInt32
  129. UA_Session_getNumSubscriptions( UA_Session *session ) {
  130. return session->numSubscriptions;
  131. }
  132. UA_Subscription *
  133. UA_Session_getSubscriptionById(UA_Session *session, UA_UInt32 subscriptionId) {
  134. UA_Subscription *sub;
  135. LIST_FOREACH(sub, &session->serverSubscriptions, listEntry) {
  136. if(sub->subscriptionId == subscriptionId)
  137. break;
  138. }
  139. return sub;
  140. }
  141. UA_UInt32 UA_Session_getUniqueSubscriptionId(UA_Session *session) {
  142. return ++(session->lastSubscriptionId);
  143. }
  144. UA_UInt32
  145. UA_Session_getNumPublishReq(UA_Session *session) {
  146. return session->numPublishReq;
  147. }
  148. UA_PublishResponseEntry*
  149. UA_Session_getPublishReq(UA_Session *session) {
  150. return SIMPLEQ_FIRST(&session->responseQueue);
  151. }
  152. void
  153. UA_Session_removePublishReq( UA_Session *session, UA_PublishResponseEntry* entry) {
  154. UA_PublishResponseEntry* firstEntry;
  155. firstEntry = SIMPLEQ_FIRST(&session->responseQueue);
  156. /* Remove the response from the response queue */
  157. if((firstEntry != 0) && (firstEntry == entry)) {
  158. SIMPLEQ_REMOVE_HEAD(&session->responseQueue, listEntry);
  159. session->numPublishReq--;
  160. }
  161. }
  162. void UA_Session_addPublishReq( UA_Session *session, UA_PublishResponseEntry* entry) {
  163. SIMPLEQ_INSERT_TAIL(&session->responseQueue, entry, listEntry);
  164. session->numPublishReq++;
  165. }
  166. #endif