PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/sipsorcery-core/SIPSorcery.SIP.App/SIPNotifications/SIPPresenceEventSubscription.cs

https://github.com/thecc4re/sipsorcery-mono
C# | 184 lines | 152 code | 21 blank | 11 comment | 22 complexity | 9116411334b2afe99f68c1c13b970cb5 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using SIPSorcery.Persistence;
  6. namespace SIPSorcery.SIP.App
  7. {
  8. public class SIPPresenceEventSubscription : SIPEventSubscription
  9. {
  10. private const int MAX_SIPACCOUNTS_TO_RETRIEVE = 25;
  11. public const string SWITCHBOARD_FILTER = "switchboard"; // If a client specifies this value as a filter it's only interested in SIP accounts that are switchboard enabled.
  12. private static string m_wildcardUser = SIPMonitorFilter.WILDCARD;
  13. private static string m_contentType = SIPMIMETypes.PRESENCE_NOTIFY_CONTENT_TYPE;
  14. private SIPEventPresence Presence;
  15. private SIPAssetCountDelegate<SIPRegistrarBinding> GetSIPRegistrarBindingsCount_External;
  16. private SIPAssetPersistor<SIPAccount> m_sipAccountPersistor;
  17. private bool m_switchboardSIPAccountsOnly; // If true means this subscription should only generate notifications for SIP accounts that are switchboard enabled.
  18. public override SIPEventPackage SubscriptionEventPackage
  19. {
  20. get { return SIPEventPackage.Presence; }
  21. }
  22. public override string MonitorFilter
  23. {
  24. get { return "presence " + ResourceURI.ToString(); }
  25. }
  26. public override string NotifyContentType
  27. {
  28. get { return m_contentType; }
  29. }
  30. public SIPPresenceEventSubscription(
  31. SIPMonitorLogDelegate log,
  32. string sessionID,
  33. SIPURI resourceURI,
  34. SIPURI canonincalResourceURI,
  35. string filter,
  36. SIPDialogue subscriptionDialogue,
  37. int expiry,
  38. SIPAssetPersistor<SIPAccount> sipAccountPersistor,
  39. SIPAssetCountDelegate<SIPRegistrarBinding> getBindingsCount,
  40. bool switchboardSIPAccountsOnly
  41. )
  42. : base(log, sessionID, resourceURI, canonincalResourceURI, filter, subscriptionDialogue, expiry)
  43. {
  44. m_sipAccountPersistor = sipAccountPersistor;
  45. GetSIPRegistrarBindingsCount_External = getBindingsCount;
  46. Presence = new SIPEventPresence(resourceURI);
  47. m_switchboardSIPAccountsOnly = switchboardSIPAccountsOnly;
  48. }
  49. public override void GetFullState()
  50. {
  51. try
  52. {
  53. List<SIPAccount> sipAccounts = null;
  54. if (ResourceURI.User == m_wildcardUser)
  55. {
  56. if (m_switchboardSIPAccountsOnly)
  57. {
  58. sipAccounts = m_sipAccountPersistor.Get(s => s.Owner == SubscriptionDialogue.Owner && s.IsSwitchboardEnabled, "SIPUsername", 0, MAX_SIPACCOUNTS_TO_RETRIEVE);
  59. }
  60. else
  61. {
  62. sipAccounts = m_sipAccountPersistor.Get(s => s.Owner == SubscriptionDialogue.Owner, "SIPUsername", 0, MAX_SIPACCOUNTS_TO_RETRIEVE);
  63. }
  64. }
  65. else
  66. {
  67. if (m_switchboardSIPAccountsOnly)
  68. {
  69. sipAccounts = m_sipAccountPersistor.Get(s => s.SIPUsername == CanonicalResourceURI.User && s.SIPDomain == CanonicalResourceURI.Host && s.IsSwitchboardEnabled, "SIPUsername", 0, MAX_SIPACCOUNTS_TO_RETRIEVE);
  70. }
  71. else
  72. {
  73. sipAccounts = m_sipAccountPersistor.Get(s => s.SIPUsername == CanonicalResourceURI.User && s.SIPDomain == CanonicalResourceURI.Host, "SIPUsername", 0, MAX_SIPACCOUNTS_TO_RETRIEVE);
  74. }
  75. }
  76. foreach (SIPAccount sipAccount in sipAccounts)
  77. {
  78. SIPURI aor = SIPURI.ParseSIPURIRelaxed(sipAccount.SIPUsername + "@" + sipAccount.SIPDomain);
  79. int bindingsCount = GetSIPRegistrarBindingsCount_External(b => b.SIPAccountId == sipAccount.Id);
  80. if (bindingsCount > 0)
  81. {
  82. string safeSIPAccountID = sipAccount.Id.ToString();
  83. Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.open, aor, Decimal.Zero));
  84. //logger.Debug(" full presence " + aor.ToString() + " open.");
  85. }
  86. else
  87. {
  88. string safeSIPAccountID = sipAccount.Id.ToString();
  89. Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.closed, null, Decimal.Zero));
  90. //logger.Debug(" full presence " + aor.ToString() + " closed.");
  91. }
  92. }
  93. MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.NotifySent, "Full state notification for presence and " + ResourceURI.ToString() + ".", SubscriptionDialogue.Owner));
  94. }
  95. catch (Exception excp)
  96. {
  97. logger.Error("Exception SIPPresenceEventSubscription GetFullState. " + excp.Message);
  98. }
  99. }
  100. public override string GetNotifyBody()
  101. {
  102. return Presence.ToXMLText();
  103. }
  104. /// <summary>
  105. /// Checks and where required adds a presence related monitor event to the list of pending notifications.
  106. /// </summary>
  107. /// <param name="machineEvent">The monitor event that has been received.</param>
  108. /// <returns>True if a notification needs to be sent as a result of this monitor event, false otherwise.</returns>
  109. public override bool AddMonitorEvent(SIPMonitorMachineEvent machineEvent)
  110. {
  111. try
  112. {
  113. MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Monitor, "Monitor event " + machineEvent.MachineEventType + " presence " + machineEvent.ResourceURI.ToString() + " for subscription to " + ResourceURI.ToString() + ".", SubscriptionDialogue.Owner));
  114. string safeSIPAccountID = machineEvent.ResourceID;
  115. SIPURI sipAccountURI = machineEvent.ResourceURI;
  116. bool sendNotificationForEvent = true;
  117. if (m_switchboardSIPAccountsOnly)
  118. {
  119. // Need to check whether the SIP account is switchboard enabled before forwarding the notification.
  120. Guid sipAccountID = new Guid(machineEvent.ResourceID);
  121. sendNotificationForEvent = Convert.ToBoolean(m_sipAccountPersistor.GetProperty(sipAccountID, "IsSwitchboardEnabled"));
  122. }
  123. if (sendNotificationForEvent)
  124. {
  125. if (machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingUpdate)
  126. {
  127. // A binding has been updated so there is at least one device online for the SIP account.
  128. Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.open, sipAccountURI, Decimal.Zero));
  129. //logger.Debug(" single presence open.");
  130. }
  131. else
  132. {
  133. // A binding has been removed but there could still be others.
  134. Guid sipAccountID = new Guid(machineEvent.ResourceID);
  135. int bindingsCount = GetSIPRegistrarBindingsCount_External(b => b.SIPAccountId == sipAccountID);
  136. if (bindingsCount > 0)
  137. {
  138. Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.open, sipAccountURI, Decimal.Zero));
  139. }
  140. else
  141. {
  142. Presence.Tuples.Add(new SIPEventPresenceTuple(safeSIPAccountID, SIPEventPresenceStateEnum.closed, sipAccountURI, Decimal.Zero));
  143. }
  144. }
  145. return true;
  146. }
  147. else
  148. {
  149. return false;
  150. }
  151. }
  152. catch (Exception excp)
  153. {
  154. logger.Error("Exception SIPresenceEventSubscription AddMonitorEvent. " + excp.Message);
  155. throw;
  156. }
  157. }
  158. public override void NotificationSent()
  159. {
  160. Presence.Tuples.Clear();
  161. }
  162. }
  163. }