private void SendInitialRegister() { try { if (m_attempts >= MAX_REGISTER_ATTEMPTS) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.", m_owner)); m_isRegistered = false; if (RegistrationTemporaryFailure != null) { RegistrationTemporaryFailure(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts."); } m_waitForRegistrationMRE.Set(); } else { m_attempts++; SIPEndPoint registrarSIPEndPoint = m_outboundProxy; if (registrarSIPEndPoint == null) { SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false); if (lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Could not resolve " + m_registrarHost + ", " + lookupResult.LookupError, m_owner)); } else { registrarSIPEndPoint = lookupResult.GetSIPEndPoint(); } } if (registrarSIPEndPoint == null && RegistrationFailed != null) { RegistrationFailed(m_sipAccountAOR, "Could not resolve " + m_registrarHost + "."); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Initiating registration to " + m_registrarHost + " at " + registrarSIPEndPoint.ToString() + " for " + m_sipAccountAOR.ToString() + ".", m_owner)); SIPRequest regRequest = GetRegistrationRequest(m_localEndPoint); SIPNonInviteTransaction regTransaction = m_sipTransport.CreateNonInviteTransaction(regRequest, registrarSIPEndPoint, m_localEndPoint, m_outboundProxy); // These handlers need to be on their own threads to take the processing off the SIP transport layer. regTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { ServerResponseReceived(lep, rep, tn, rsp); }); }; regTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendSIPReliable(regTransaction); } } } catch (Exception excp) { logger.Error("Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); if (RegistrationFailed != null) { RegistrationFailed(m_sipAccountAOR, "Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); } } }
/// <summary> /// The event handler for responses to the initial register request. /// </summary> private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Server response " + sipResponse.Status + " received for " + m_sipAccountAOR.ToString() + ".", null)); if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if (m_attempts >= MAX_REGISTER_ATTEMPTS) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.", null)); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts."); m_waitForRegistrationMRE.Set(); } else { m_attempts++; SIPRequest authenticatedRequest = GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse); SIPEndPoint registrarSIPEndPoint = m_outboundProxy; if (registrarSIPEndPoint == null) { SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false); if (lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Could not resolve " + m_registrarHost + ", " + lookupResult.LookupError, null)); } else { registrarSIPEndPoint = lookupResult.GetSIPEndPoint(); } } if (registrarSIPEndPoint == null) { logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + "."); RegistrationFailed?.Invoke(m_sipAccountAOR, "Could not resolve " + m_registrarHost + "."); } else { SIPNonInviteTransaction regAuthTransaction = new SIPNonInviteTransaction(m_sipTransport, authenticatedRequest, registrarSIPEndPoint); regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); }); return(Task.FromResult(SocketError.Success)); }; regAuthTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendTransaction(regAuthTransaction); } } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied for " + m_sipAccountAOR.ToString() + ".", null)); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied."); m_waitForRegistrationMRE.Set(); } } else { if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { if (m_expiry > 0) { m_isRegistered = true; m_expiry = GetUpdatedExpiry(sipResponse); RegistrationSuccessful?.Invoke(m_sipAccountAOR); } else { m_isRegistered = false; RegistrationRemoved?.Invoke(m_sipAccountAOR); } m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound) { // SIP account does not appear to exist. Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ", no further registration attempts will be made.", null)); string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); m_exit = true; m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0) { m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse); Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" + m_expiry + " and trying again.", null)); SendInitialRegister(); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ".", null)); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + "."); m_waitForRegistrationMRE.Set(); } } } catch (Exception excp) { logger.LogError("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message); } }
/// <summary> /// Initiates a SUBSCRIBE request to a notification server. /// </summary> /// <param name="subscribeToURI">The SIP user that dialog notifications are being subscribed to.</param> public void Subscribe(SIPURI subscribeURI, int expiry, SIPEventPackage sipEventPackage, string subscribeCallID, SIPURI contactURI) { try { if (m_attempts >= MAX_SUBSCRIBE_ATTEMPTS) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NotifierClient, SIPMonitorEventTypesEnum.SubscribeFailed, "Susbcription to " + subscribeURI.ToString() + " reached the maximum number of allowed attempts without a failure condition.", null)); m_subscribed = false; SubscriptionFailed(subscribeURI, SIPResponseStatusCodesEnum.InternalServerError, "Subscription reached the maximum number of allowed attempts."); m_waitForSubscribeResponse.Set(); } else { m_attempts++; m_localCSeq++; SIPRequest subscribeRequest = m_sipTransport.GetRequest( SIPMethodsEnum.SUBSCRIBE, m_resourceURI, new SIPToHeader(null, subscribeURI, m_subscriptionToTag), null); if (contactURI != null) { subscribeRequest.Header.Contact = new List <SIPContactHeader>() { new SIPContactHeader(null, contactURI) }; } subscribeRequest.Header.From = new SIPFromHeader(null, new SIPURI(m_authUsername, m_authDomain, null, SIPSchemesEnum.sip, SIPProtocolsEnum.udp), m_subscriptionFromTag); subscribeRequest.Header.CSeq = m_localCSeq; subscribeRequest.Header.Expires = expiry; subscribeRequest.Header.Event = sipEventPackage.ToString(); subscribeRequest.Header.CallId = subscribeCallID; if (!m_filter.IsNullOrBlank()) { subscribeRequest.Body = m_filter; subscribeRequest.Header.ContentLength = m_filter.Length; subscribeRequest.Header.ContentType = m_filterTextType; } SIPEndPoint dstEndPoint = m_outboundProxy; if (dstEndPoint == null) { SIPDNSLookupResult lookupResult = m_sipTransport.GetURIEndPoint(m_resourceURI, false); if (lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NotifierClient, SIPMonitorEventTypesEnum.SubscribeFailed, "Could not resolve " + m_resourceURI.Host + ", " + lookupResult.LookupError, null)); } else { dstEndPoint = lookupResult.GetSIPEndPoint(); } } SIPNonInviteTransaction subscribeTransaction = m_sipTransport.CreateNonInviteTransaction(subscribeRequest, dstEndPoint, null, m_outboundProxy); subscribeTransaction.NonInviteTransactionFinalResponseReceived += SubscribeTransactionFinalResponseReceived; subscribeTransaction.NonInviteTransactionTimedOut += SubsribeTransactionTimedOut; m_sipTransport.SendSIPReliable(subscribeTransaction); LastSubscribeAttempt = DateTime.Now; } } catch (Exception excp) { logger.Error("Exception SIPNotifierClient Subscribe. " + excp.Message); SubscriptionFailed(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Exception Subscribing. " + excp.Message); m_waitForSubscribeResponse.Set(); } }