public void SendFullStateNotify(string sessionID) { try { if (m_subscriptions.ContainsKey(sessionID)) { SIPEventSubscription subscription = m_subscriptions[sessionID]; lock (subscription) { subscription.GetFullState(); SendNotifyRequestForSubscription(subscription); } } else { logger.Warn("No subscription could be found for " + sessionID + " when attempting to send a full state notification."); } } catch (Exception excp) { logger.Error("Exception NotifierSubscriptionsManager SendFullStateNotify. " + excp.Message); throw; } }
private void SendNotifyRequestForSubscription(SIPEventSubscription subscription) { try { subscription.SubscriptionDialogue.CSeq++; //logger.Debug(DateTime.Now.ToString("HH:mm:ss:fff") + " Sending NOTIFY request for " + subscription.SubscriptionDialogue.Owner + " event " + subscription.SubscriptionEventPackage.ToString() // + " and " + subscription.ResourceURI.ToString() + " to " + subscription.SubscriptionDialogue.RemoteTarget.ToString() + ", cseq=" + (subscription.SubscriptionDialogue.CSeq) + "."); int secondsRemaining = Convert.ToInt32(subscription.LastSubscribe.AddSeconds(subscription.Expiry).Subtract(DateTime.Now).TotalSeconds % Int32.MaxValue); SIPRequest notifyRequest = m_sipTransport.GetRequest(SIPMethodsEnum.NOTIFY, subscription.SubscriptionDialogue.RemoteTarget); notifyRequest.Header.From = SIPFromHeader.ParseFromHeader(subscription.SubscriptionDialogue.LocalUserField.ToString()); notifyRequest.Header.To = SIPToHeader.ParseToHeader(subscription.SubscriptionDialogue.RemoteUserField.ToString()); notifyRequest.Header.Event = subscription.SubscriptionEventPackage.ToString(); notifyRequest.Header.CSeq = subscription.SubscriptionDialogue.CSeq; notifyRequest.Header.CallId = subscription.SubscriptionDialogue.CallId; notifyRequest.Body = subscription.GetNotifyBody(); notifyRequest.Header.ContentLength = notifyRequest.Body.Length; notifyRequest.Header.SubscriptionState = "active;expires=" + secondsRemaining.ToString(); notifyRequest.Header.ContentType = subscription.NotifyContentType; notifyRequest.Header.ProxySendFrom = subscription.SubscriptionDialogue.ProxySendFrom; // If the outbound proxy is a loopback address, as it will normally be for local deployments, then it cannot be overriden. SIPEndPoint dstEndPoint = m_outboundProxy; if (m_outboundProxy != null && IPAddress.IsLoopback(m_outboundProxy.Address)) { dstEndPoint = m_outboundProxy; } else if (subscription.SubscriptionDialogue.ProxySendFrom != null) { // The proxy will always be listening on UDP port 5060 for requests from internal servers. dstEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(SIPEndPoint.ParseSIPEndPoint(subscription.SubscriptionDialogue.ProxySendFrom).Address, m_defaultSIPPort)); } SIPNonInviteTransaction notifyTransaction = m_sipTransport.CreateNonInviteTransaction(notifyRequest, dstEndPoint, m_sipTransport.GetDefaultSIPEndPoint(dstEndPoint), m_outboundProxy); notifyTransaction.NonInviteTransactionFinalResponseReceived += (local, remote, transaction, response) => { NotifyTransactionFinalResponseReceived(local, remote, transaction, response, subscription); }; m_sipTransport.SendSIPReliable(notifyTransaction); //logger.Debug(notifyRequest.ToString()); MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.NotifySent, "Notification sent for " + subscription.SubscriptionEventPackage.ToString() + " and " + subscription.ResourceURI.ToString() + " to " + subscription.SubscriptionDialogue.RemoteTarget.ToString() + " (cseq=" + notifyRequest.Header.CSeq + ").", subscription.SubscriptionDialogue.Owner)); subscription.NotificationSent(); } catch (Exception excp) { logger.Error("Exception SendNotifyRequestForSubscription. " + excp.Message); throw; } }
private void StopSubscription(SIPEventSubscription subscription) { try { m_publisher.CloseSession(m_notificationsAddress, subscription.SessionID); lock (m_subscriptions) { m_subscriptions.Remove(subscription.SessionID); } MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Stopping subscription for " + subscription.SubscriptionEventPackage.ToString() + " " + subscription.ResourceURI.ToString() + ".", subscription.SubscriptionDialogue.Owner)); } catch (Exception excp) { logger.Error("Exception StopSubscription. " + excp.Message); } }
private bool MonitorEventAvailable(SIPMonitorEvent sipMonitorEvent) { try { SIPMonitorMachineEvent machineEvent = sipMonitorEvent as SIPMonitorMachineEvent; if (machineEvent != null && !machineEvent.SessionID.IsNullOrBlank() && m_subscriptions.ContainsKey(machineEvent.SessionID)) { SIPEventSubscription subscription = m_subscriptions[machineEvent.SessionID]; lock (subscription) { string resourceURI = (machineEvent.ResourceURI != null) ? machineEvent.ResourceURI.ToString() : null; //logger.Debug("NotifierSubscriptionsManager received new " + machineEvent.MachineEventType + ", resource ID=" + machineEvent.ResourceID + ", resource URI=" + resourceURI + "."); //MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Monitor, "NotifierSubscriptionsManager received new " + machineEvent.MachineEventType + ", resource ID=" + machineEvent.ResourceID + ", resource URI=" + resourceURI + ".", subscription.SubscriptionDialogue.Owner)); if (subscription.AddMonitorEvent(machineEvent)) { SendNotifyRequestForSubscription(subscription); } //logger.Debug("NotifierSubscriptionsManager completed " + machineEvent.MachineEventType + ", resource ID=" + machineEvent.ResourceID + ", resource URI=" + resourceURI + "."); } return(true); } return(false); } catch (Exception excp) { logger.Error("Exception NotifierSubscriptionsManager MonitorEventAvailable. " + excp.Message); return(false); } }
private void NotifyTransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse, SIPEventSubscription subscription) { try { if (sipResponse.StatusCode >= 300) { // The NOTIFY request was met with an error response. MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "A notify request received an error response of " + sipResponse.Status + " " + sipResponse.ReasonPhrase + ".", subscription.SubscriptionDialogue.Owner)); StopSubscription(subscription); } } catch (Exception excp) { logger.Error("Exception NotifyTransactionFinalResponseReceived. " + excp.Message); } }
/// <summary> /// Attempts to renew an existing subscription. /// </summary> /// <returns>The session ID if the renewal was successful or null if it wasn't.</returns> public string RenewSubscription(SIPRequest subscribeRequest, out SIPResponseStatusCodesEnum errorResponse, out string errorReason) { errorResponse = SIPResponseStatusCodesEnum.None; errorReason = null; try { int expiry = subscribeRequest.Header.Expires; string toTag = subscribeRequest.Header.To.ToTag; string fromTag = subscribeRequest.Header.From.FromTag; string callID = subscribeRequest.Header.CallId; int cseq = subscribeRequest.Header.CSeq; // Check for an existing subscription. SIPEventSubscription existingSubscription = (from sub in m_subscriptions.Values where sub.SubscriptionDialogue.CallId == callID select sub).FirstOrDefault(); if (existingSubscription != null) { if (expiry == 0) { // Subsciption is being cancelled. StopSubscription(existingSubscription); return(null); } else if (cseq > existingSubscription.SubscriptionDialogue.RemoteCSeq) { logger.Debug("Renewing subscription for " + existingSubscription.SessionID + " and " + existingSubscription.SubscriptionDialogue.Owner + "."); existingSubscription.SubscriptionDialogue.RemoteCSeq = cseq; //existingSubscription.ProxySendFrom = (!subscribeRequest.Header.ProxyReceivedOn.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(subscribeRequest.Header.ProxyReceivedOn) : null; string extensionResult = m_publisher.ExtendSession(m_notificationsAddress, existingSubscription.SessionID, expiry); if (extensionResult != null) { // One or more of the monitor servers could not extend the session. Close all the existing sessions and re-create. MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Monitor session extension for " + existingSubscription.SubscriptionEventPackage.ToString() + " " + existingSubscription.ResourceURI.ToString() + " failed. " + extensionResult, existingSubscription.SubscriptionDialogue.Owner)); m_publisher.CloseSession(m_notificationsAddress, existingSubscription.SessionID); // Need to re-establish the sessions with the notification servers. string subscribeError = null; string sessionID = Guid.NewGuid().ToString(); m_publisher.Subscribe(existingSubscription.SubscriptionDialogue.Owner, existingSubscription.SubscriptionDialogue.AdminMemberId, m_notificationsAddress, sessionID, SIPMonitorClientTypesEnum.Machine.ToString(), existingSubscription.MonitorFilter, expiry, null, out subscribeError); if (subscribeError != null) { throw new ApplicationException(subscribeError); } else { lock (m_subscriptions) { m_subscriptions.Remove(existingSubscription.SessionID); existingSubscription.SessionID = sessionID; m_subscriptions.Add(sessionID, existingSubscription); } MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Monitor session recreated for " + existingSubscription.SubscriptionEventPackage.ToString() + " " + existingSubscription.ResourceURI.ToString() + ".", existingSubscription.SubscriptionDialogue.Owner)); } } MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeRenew, "Monitor session successfully renewed for " + existingSubscription.SubscriptionEventPackage.ToString() + " " + existingSubscription.ResourceURI.ToString() + ".", existingSubscription.SubscriptionDialogue.Owner)); return(existingSubscription.SessionID); } else { throw new ApplicationException("A duplicate SUBSCRIBE request was received by NotifierSubscriptionsManager."); } } else { //throw new ApplicationException("No existing subscription could be found for a subscribe renewal request."); errorResponse = SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist; errorReason = "Subscription dialog not found"; return(null); } } catch (Exception excp) { logger.Error("Exception RenewSubscription. " + excp.Message); throw; } }