ua_session_manager.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "ua_session_manager.h"
  2. #include "util/ua_list.h"
  3. struct UA_SessionManager {
  4. UA_list_List sessions;
  5. UA_UInt32 maxSessionCount;
  6. UA_Int32 lastSessionId;
  7. UA_UInt32 currentSessionCount;
  8. UA_DateTime maxSessionLifeTime;
  9. UA_DateTime sessionTimeout;
  10. };
  11. UA_Int32 UA_SessionManager_new(UA_SessionManager **sessionManager, UA_UInt32 maxSessionCount,
  12. UA_UInt32 sessionTimeout, UA_UInt32 startSessionId) {
  13. UA_Int32 retval = UA_SUCCESS;
  14. retval |= UA_alloc((void**)sessionManager,sizeof(UA_SessionManager));
  15. retval |= UA_list_init(&(*sessionManager)->sessions);
  16. (*sessionManager)->maxSessionCount = maxSessionCount;
  17. (*sessionManager)->lastSessionId = startSessionId;
  18. (*sessionManager)->sessionTimeout = sessionTimeout;
  19. return retval;
  20. }
  21. UA_Int32 UA_SessionManager_delete(UA_SessionManager *sessionManager) {
  22. // todo
  23. return UA_SUCCESS;
  24. }
  25. UA_Int32 UA_SessionManager_generateSessionId(UA_SessionManager *sessionManager,
  26. UA_NodeId *sessionId) {
  27. sessionId->namespaceIndex = 0;
  28. sessionId->identifierType = UA_NODEIDTYPE_NUMERIC;
  29. sessionId->identifier.numeric = sessionManager->lastSessionId++;
  30. return UA_SUCCESS;
  31. }
  32. UA_Boolean UA_SessionManager_sessionExists(UA_SessionManager *sessionManager,
  33. UA_Session *session) {
  34. if(sessionManager == UA_NULL)
  35. return UA_FALSE;
  36. if(UA_list_search(&sessionManager->sessions,
  37. (UA_list_PayloadComparer)UA_Session_compare,(void*)session)) {
  38. UA_Double pendingLifetime;
  39. UA_Session_getPendingLifetime(session,&pendingLifetime);
  40. if(pendingLifetime>0)
  41. return UA_TRUE;
  42. //timeout of session reached so remove it
  43. UA_NodeId *sessionId = &session->sessionId;
  44. UA_SessionManager_removeSession(sessionManager, sessionId);
  45. }
  46. return UA_FALSE;
  47. }
  48. UA_Int32 UA_SessionManager_getSessionById(UA_SessionManager *sessionManager,
  49. UA_NodeId *sessionId, UA_Session **session) {
  50. if(sessionManager == UA_NULL) {
  51. *session = UA_NULL;
  52. return UA_ERROR;
  53. }
  54. UA_list_Element* current = sessionManager->sessions.first;
  55. while (current) {
  56. if (current->payload) {
  57. UA_list_Element* elem = (UA_list_Element*) current;
  58. *session = ((UA_Session*) (elem->payload));
  59. if(UA_NodeId_equal(&(*session)->sessionId, sessionId) == UA_EQUAL){
  60. UA_Double pendingLifetime;
  61. UA_Session_getPendingLifetime(*session, &pendingLifetime);
  62. if(pendingLifetime > 0)
  63. return UA_SUCCESS;
  64. //session not valid anymore -> remove it
  65. UA_list_removeElement(elem, (UA_list_PayloadVisitor)UA_Session_delete);
  66. *session = UA_NULL;
  67. return UA_ERROR;
  68. }
  69. }
  70. current = current->next;
  71. }
  72. *session = UA_NULL;
  73. return UA_ERROR;
  74. }
  75. UA_Int32 UA_SessionManager_getSessionByToken(UA_SessionManager *sessionManager,
  76. UA_NodeId *token, UA_Session **session) {
  77. if(sessionManager == UA_NULL) {
  78. *session = UA_NULL;
  79. return UA_ERROR;
  80. }
  81. UA_list_Element* current = sessionManager->sessions.first;
  82. while (current) {
  83. if (current->payload) {
  84. UA_list_Element* elem = (UA_list_Element*) current;
  85. *session = ((UA_Session*) (elem->payload));
  86. if(UA_NodeId_equal(&(*session)->authenticationToken, token) == UA_EQUAL) {
  87. UA_Double pendingLifetime;
  88. UA_Session_getPendingLifetime(*session, &pendingLifetime);
  89. if(pendingLifetime > 0)
  90. return UA_SUCCESS;
  91. //session not valid anymore -> remove it
  92. UA_list_removeElement(elem, (UA_list_PayloadVisitor)UA_Session_delete);
  93. *session = UA_NULL;
  94. return UA_ERROR;
  95. }
  96. }
  97. current = current->next;
  98. }
  99. *session = UA_NULL;
  100. return UA_ERROR;
  101. }
  102. /** Creates and adds a session. */
  103. UA_Int32 UA_SessionManager_addSession(UA_SessionManager *sessionManager,
  104. UA_SecureChannel *channel, UA_Session **session) {
  105. UA_Int32 retval = UA_SUCCESS;
  106. if(sessionManager->currentSessionCount >= sessionManager->maxSessionCount)
  107. return UA_ERROR;
  108. UA_Session_new(session);
  109. (*session)->sessionId = (UA_NodeId){.namespaceIndex = 1, .identifierType = UA_NODEIDTYPE_NUMERIC,
  110. .identifier.numeric = sessionManager->lastSessionId++};
  111. (*session)->channel = channel;
  112. channel->session = *session;
  113. sessionManager->currentSessionCount++;
  114. return retval;
  115. }
  116. UA_Int32 UA_SessionManager_removeSession(UA_SessionManager *sessionManager,
  117. UA_NodeId *sessionId) {
  118. UA_Int32 retval = UA_SUCCESS;
  119. UA_list_Element *element = UA_list_search(&sessionManager->sessions,(UA_list_PayloadComparer)UA_Session_compare,sessionId);
  120. if(element) {
  121. UA_Session *session = element->payload;
  122. session->channel->session = UA_NULL;
  123. retval |= UA_list_removeElement(element,(UA_list_PayloadVisitor)UA_Session_delete);
  124. printf("UA_SessionManager_removeSession - session removed, current count: %i \n",sessionManager->sessions.size);
  125. }
  126. return retval;
  127. }
  128. UA_Int32 UA_SessionManager_getSessionTimeout(UA_SessionManager *sessionManager,
  129. UA_Int64 *timeout_ms) {
  130. if(sessionManager) {
  131. *timeout_ms = sessionManager->sessionTimeout;
  132. return UA_SUCCESS;
  133. }
  134. *timeout_ms = 0;
  135. return UA_ERROR;
  136. }