ua_subscription_manager.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "ua_types.h"
  2. #include "ua_server_internal.h"
  3. #include "ua_nodestore.h"
  4. #include "ua_subscription_manager.h"
  5. void SubscriptionManager_init(UA_Session *session) {
  6. UA_SubscriptionManager *manager = &(session->subscriptionManager);
  7. /* FIXME: These init values are empirical. Maybe they should be part
  8. * of the server config? */
  9. manager->globalPublishingInterval = (UA_Int32_BoundedValue) { .maxValue = 10000, .minValue = 0, .currentValue=0 };
  10. manager->globalLifeTimeCount = (UA_UInt32_BoundedValue) { .maxValue = 15000, .minValue = 0, .currentValue=0 };
  11. manager->globalKeepAliveCount = (UA_UInt32_BoundedValue) { .maxValue = 100, .minValue = 0, .currentValue=0 };
  12. manager->globalNotificationsPerPublish = (UA_Int32_BoundedValue) { .maxValue = 1000, .minValue = 1, .currentValue=0 };
  13. manager->globalSamplingInterval = (UA_UInt32_BoundedValue) { .maxValue = 1000, .minValue = 5, .currentValue=0 };
  14. manager->globalQueueSize = (UA_UInt32_BoundedValue) { .maxValue = 100, .minValue = 0, .currentValue=0 };
  15. LIST_INIT(&manager->serverSubscriptions);
  16. manager->lastSessionID = (UA_UInt32) UA_DateTime_now();
  17. // Initialize a GUID with a 2^64 time dependant part, then fold the time in on itself to provide a more randomish
  18. // Counter
  19. // NOTE: On a 32 bit plattform, assigning 64 bit (2 regs) is allowed by the compiler, but shifting though multiple
  20. // regs is usually not. To support both 32 and 64bit, the struct splits the 64Bit timestamp into two parts.
  21. typedef union {
  22. struct {
  23. UA_UInt32 ui32h;
  24. UA_UInt32 ui32l;
  25. } individual;
  26. UA_UInt64 ui64;
  27. } guidInit;
  28. guidInit guidInitH;
  29. guidInitH.ui64 = (UA_UInt64) UA_DateTime_now();
  30. manager->lastJobGuid.data1 = guidInitH.individual.ui32h;
  31. manager->lastJobGuid.data2 = (UA_UInt16) (guidInitH.individual.ui32l >> 16);
  32. manager->lastJobGuid.data3 = (UA_UInt16) (guidInitH.individual.ui32l);
  33. guidInit guidInitL;
  34. guidInitL.ui64 = (UA_UInt64) UA_DateTime_now();
  35. manager->lastJobGuid.data4[0] = (UA_Byte) guidInitL.individual.ui32l;
  36. manager->lastJobGuid.data4[1] = (UA_Byte) (guidInitL.individual.ui32l >> 8);
  37. manager->lastJobGuid.data4[2] = (UA_Byte) (guidInitL.individual.ui32l >> 16);
  38. manager->lastJobGuid.data4[3] = (UA_Byte) (guidInitL.individual.ui32l >> 24);
  39. manager->lastJobGuid.data4[4] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.individual.ui32h);
  40. manager->lastJobGuid.data4[5] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.individual.ui32h >> 8);
  41. manager->lastJobGuid.data4[6] = (UA_Byte) (manager->lastJobGuid.data4[1]) ^ (guidInitL.individual.ui32h >> 16);
  42. manager->lastJobGuid.data4[7] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.individual.ui32h >> 24);
  43. }
  44. void SubscriptionManager_deleteMembers(UA_Session *session, UA_Server *server) {
  45. UA_SubscriptionManager *manager = &session->subscriptionManager;
  46. UA_Subscription *current, *temp;
  47. LIST_FOREACH_SAFE(current, &manager->serverSubscriptions, listEntry, temp) {
  48. LIST_REMOVE(current, listEntry);
  49. UA_Subscription_deleteMembers(current, server);
  50. UA_free(current);
  51. }
  52. }
  53. void SubscriptionManager_addSubscription(UA_SubscriptionManager *manager, UA_Subscription *newSubscription) {
  54. LIST_INSERT_HEAD(&manager->serverSubscriptions, newSubscription, listEntry);
  55. }
  56. UA_Subscription *SubscriptionManager_getSubscriptionByID(UA_SubscriptionManager *manager,
  57. UA_Int32 subscriptionID) {
  58. UA_Subscription *sub;
  59. LIST_FOREACH(sub, &manager->serverSubscriptions, listEntry) {
  60. if(sub->subscriptionID == subscriptionID)
  61. break;
  62. }
  63. return sub;
  64. }
  65. UA_Int32 SubscriptionManager_deleteMonitoredItem(UA_SubscriptionManager *manager, UA_Int32 subscriptionID,
  66. UA_UInt32 monitoredItemID) {
  67. UA_Subscription *sub = SubscriptionManager_getSubscriptionByID(manager, subscriptionID);
  68. if(!sub)
  69. return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
  70. UA_MonitoredItem *mon, *tmp_mon;
  71. LIST_FOREACH_SAFE(mon, &sub->MonitoredItems, listEntry, tmp_mon) {
  72. if (mon->itemId == monitoredItemID) {
  73. LIST_REMOVE(mon, listEntry);
  74. MonitoredItem_delete(mon);
  75. return UA_STATUSCODE_GOOD;
  76. }
  77. }
  78. return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
  79. }
  80. UA_Int32 SubscriptionManager_deleteSubscription(UA_Server *server, UA_SubscriptionManager *manager, UA_Int32 subscriptionID) {
  81. UA_Subscription *sub = SubscriptionManager_getSubscriptionByID(manager, subscriptionID);
  82. if(!sub)
  83. return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
  84. LIST_REMOVE(sub, listEntry);
  85. UA_Subscription_deleteMembers(sub, server);
  86. UA_free(sub);
  87. return UA_STATUSCODE_GOOD;
  88. }
  89. UA_UInt32 SubscriptionManager_getUniqueUIntID(UA_SubscriptionManager *manager) {
  90. UA_UInt32 id = ++(manager->lastSessionID);
  91. return id;
  92. }
  93. UA_Guid SubscriptionManager_getUniqueGUID(UA_SubscriptionManager *manager) {
  94. UA_Guid id;
  95. unsigned long *incremental = (unsigned long *) &manager->lastJobGuid.data4[0];
  96. incremental++;
  97. UA_Guid_copy(&(manager->lastJobGuid), &id);
  98. return id;
  99. }