ua_subscription_manager.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. union {
  22. struct {
  23. UA_UInt32 ui32h;
  24. UA_UInt32 ui32l;
  25. };
  26. UA_UInt64 ui64;
  27. } guidInitH;
  28. guidInitH.ui64 = (UA_UInt64) UA_DateTime_now();
  29. manager->lastJobGuid.data1 = guidInitH.ui32h;
  30. manager->lastJobGuid.data2 = (UA_UInt16) (guidInitH.ui32l >> 16);
  31. manager->lastJobGuid.data3 = (UA_UInt16) (guidInitH.ui32l);
  32. union {
  33. struct {
  34. UA_UInt32 ui32h;
  35. UA_UInt32 ui32l;
  36. };
  37. UA_UInt64 ui64;
  38. } guidInitL;
  39. guidInitL.ui64 = (UA_UInt64) UA_DateTime_now();
  40. manager->lastJobGuid.data4[0] = (UA_Byte) guidInitL.ui32l;
  41. manager->lastJobGuid.data4[1] = (UA_Byte) (guidInitL.ui32l >> 8);
  42. manager->lastJobGuid.data4[2] = (UA_Byte) (guidInitL.ui32l >> 16);
  43. manager->lastJobGuid.data4[3] = (UA_Byte) (guidInitL.ui32l >> 24);
  44. manager->lastJobGuid.data4[4] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.ui32h);
  45. manager->lastJobGuid.data4[5] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.ui32h >> 8);
  46. manager->lastJobGuid.data4[6] = (UA_Byte) (manager->lastJobGuid.data4[1]) ^ (guidInitL.ui32h >> 16);
  47. manager->lastJobGuid.data4[7] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.ui32h >> 24);
  48. }
  49. void SubscriptionManager_deleteMembers(UA_Session *session, UA_Server *server) {
  50. UA_SubscriptionManager *manager = &(session->subscriptionManager);
  51. UA_Subscription *current;
  52. while((current = LIST_FIRST(&manager->serverSubscriptions))) {
  53. LIST_REMOVE(current, listEntry);
  54. UA_Subscription_deleteMembers(current, server);
  55. UA_free(current);
  56. }
  57. }
  58. void SubscriptionManager_addSubscription(UA_SubscriptionManager *manager, UA_Subscription *newSubscription) {
  59. LIST_INSERT_HEAD(&manager->serverSubscriptions, newSubscription, listEntry);
  60. }
  61. UA_Subscription *SubscriptionManager_getSubscriptionByID(UA_SubscriptionManager *manager,
  62. UA_Int32 subscriptionID) {
  63. UA_Subscription *sub;
  64. LIST_FOREACH(sub, &manager->serverSubscriptions, listEntry) {
  65. if(sub->subscriptionID == subscriptionID)
  66. break;
  67. }
  68. return sub;
  69. }
  70. UA_Int32 SubscriptionManager_deleteMonitoredItem(UA_SubscriptionManager *manager, UA_Int32 subscriptionID,
  71. UA_UInt32 monitoredItemID) {
  72. UA_Subscription *sub = SubscriptionManager_getSubscriptionByID(manager, subscriptionID);
  73. if(!sub)
  74. return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
  75. UA_MonitoredItem *mon;
  76. LIST_FOREACH(mon, &sub->MonitoredItems, listEntry) {
  77. if (mon->itemId == monitoredItemID) {
  78. // FIXME!! don't we need to remove the list entry?
  79. MonitoredItem_delete(mon);
  80. return UA_STATUSCODE_GOOD;
  81. }
  82. }
  83. return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
  84. }
  85. UA_Int32 SubscriptionManager_deleteSubscription(UA_Server *server, UA_SubscriptionManager *manager, UA_Int32 subscriptionID) {
  86. UA_Subscription *sub = SubscriptionManager_getSubscriptionByID(manager, subscriptionID);
  87. if(!sub)
  88. return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
  89. LIST_REMOVE(sub, listEntry);
  90. UA_Subscription_deleteMembers(sub, server);
  91. UA_free(sub);
  92. return UA_STATUSCODE_GOOD;
  93. }
  94. UA_UInt32 SubscriptionManager_getUniqueUIntID(UA_SubscriptionManager *manager) {
  95. UA_UInt32 id = ++(manager->lastSessionID);
  96. return id;
  97. }
  98. UA_Guid SubscriptionManager_getUniqueGUID(UA_SubscriptionManager *manager) {
  99. UA_Guid id;
  100. unsigned long *incremental = (unsigned long *) &manager->lastJobGuid.data4[0];
  101. incremental++;
  102. UA_Guid_copy(&(manager->lastJobGuid), &id);
  103. return id;
  104. }