public SIPNonInviteServerUserAgent( SIPTransport sipTransport, SIPEndPoint outboundProxy, string sipUsername, string sipDomain, SIPCallDirection callDirection, SIPAssetGetDelegate<SIPAccount> getSIPAccount, SIPAuthenticateRequestDelegate sipAuthenticateRequest, SIPMonitorLogDelegate logDelegate, SIPNonInviteTransaction transaction) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_sipUsername = sipUsername; m_sipDomain = sipDomain; m_sipCallDirection = callDirection; GetSIPAccount_External = getSIPAccount; SIPAuthenticateRequest_External = sipAuthenticateRequest; Log_External = logDelegate ?? Log_External; m_transaction = transaction; m_transaction.TransactionTraceMessage += TransactionTraceMessage; //m_uasTransaction.UASInviteTransactionTimedOut += ClientTimedOut; //m_uasTransaction.UASInviteTransactionCancelled += UASTransactionCancelled; //m_uasTransaction.TransactionRemoved += new SIPTransactionRemovedDelegate(UASTransaction_TransactionRemoved); //m_uasTransaction.TransactionStateChanged += (t) => { logger.Debug("Transaction state change to " + t.TransactionState + ", uri=" + t.TransactionRequestURI.ToString() + "."); }; }
private void ByeServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentServer, SIPMonitorEventTypesEnum.DialPlan, "Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + sipTransaction.TransactionRequest.URI.ToString() + ".", Owner)); SIPNonInviteTransaction byeTransaction = sipTransaction as SIPNonInviteTransaction; byeTransaction.NonInviteTransactionFinalResponseReceived -= ByeServerFinalResponseReceived; if ((sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) && SIPAccount != null) { // Resend BYE with credentials. SIPAuthorisationDigest authRequest = sipResponse.Header.AuthenticationHeader.SIPDigest; SIPURI contactUri = sipResponse.Header.Contact.Any() ? sipResponse.Header.Contact[0].ContactURI : sipResponse.Header.From.FromURI; authRequest.SetCredentials(SIPAccount.SIPUsername, SIPAccount.SIPPassword, contactUri.ToString(), SIPMethodsEnum.BYE.ToString()); SIPRequest authByeRequest = byeTransaction.TransactionRequest; authByeRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authRequest); authByeRequest.Header.AuthenticationHeader.SIPDigest.Response = authRequest.Digest; authByeRequest.Header.Vias.TopViaHeader.Branch = CallProperties.CreateBranchId(); authByeRequest.Header.CSeq = authByeRequest.Header.CSeq + 1; SIPNonInviteTransaction bTransaction = m_sipTransport.CreateNonInviteTransaction(authByeRequest, null); bTransaction.SendReliableRequest(); } } catch (Exception excp) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.Error, "Exception ByServerFinalResponseReceived. " + excp.Message, Owner)); } }
public SIPReferServerUserAgent(SIPTransport sipTransport, SIPMonitorLogDelegate logDelegate, SIPNonInviteTransaction sipTransaction) { m_sipTransport = sipTransport; Log_External = logDelegate; m_sipTransaction = sipTransaction; m_sipTransaction.TransactionTraceMessage += TransactionTraceMessage; m_sipTransaction.NonInviteTransactionTimedOut += ClientTimedOut; // If external logging is not required assign an empty handler to stop null reference exceptions. if (Log_External == null) { Log_External = (e) => { }; } var referTo = SIPURI.ParseSIPURI(m_sipTransaction.TransactionRequest.Header.ReferTo); var replacesParameter = SIPReplacesParameter.Parse(referTo.Headers.Get("Replaces")); ReplacedCall = new ReplacesCallDescriptor(); ReplacedCall.CallId = replacesParameter.CallID; ReplacedCall.FromTag = replacesParameter.FromTag; ReplacedCall.ToTag = replacesParameter.ToTag; ReferToUri = referTo.CopyOf(); ReferToUri.Headers.RemoveAll(); }
/// <summary> /// Used to hangup the call or indicate that the client hungup. /// </summary> /// <param name="clientHungup">True if the BYE request was received from the client. False if the hangup /// needs to originate from this agent.</param> public void Hangup(bool clientHungup) { m_isHungup = true; if (SIPDialogue == null) { return; } // Only need to send a BYE request if the client didn't already do so. if (clientHungup == false) { try { // Cases found where the Contact in the INVITE was to a different protocol than the oringinal request. var inviteContact = m_uasTransaction.TransactionRequest.Header.Contact.FirstOrDefault(); if (inviteContact == null) { logger.LogWarning("The Contact header on the INVITE request was missing, BYE request cannot be generated."); } else { SIPRequest byeRequest = GetByeRequest(); SIPNonInviteTransaction byeTransaction = m_sipTransport.CreateNonInviteTransaction(byeRequest, m_outboundProxy); byeTransaction.NonInviteTransactionFinalResponseReceived += ByeServerFinalResponseReceived; byeTransaction.SendReliableRequest(); } } catch (Exception excp) { logger.LogError("Exception SIPServerUserAgent Hangup. " + excp.Message); throw; } } }
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> /// Cancels an in progress call. This method should be called prior to the remote user agent server answering the call. /// </summary> public void Cancel() { try { m_callCancelled = true; // Cancel server call. if (m_serverTransaction == null) { logger.LogDebug("Cancelling forwarded call leg " + m_sipCallDescriptor.Uri + ", server transaction has not been created yet no CANCEL request required."); } else if (m_cancelTransaction != null) { if (m_cancelTransaction.TransactionState != SIPTransactionStatesEnum.Completed) { logger.LogDebug("Call " + m_serverTransaction.TransactionRequest.URI.ToString() + " has already been cancelled once, trying again."); m_cancelTransaction.SendRequest(); } else { logger.LogDebug("Call " + m_serverTransaction.TransactionRequest.URI.ToString() + " has already responded to CANCEL, probably overlap in messages not re-sending."); } } else //if (m_serverTransaction.TransactionState == SIPTransactionStatesEnum.Proceeding || m_serverTransaction.TransactionState == SIPTransactionStatesEnum.Trying) { logger.LogDebug("Cancelling forwarded call leg, sending CANCEL to " + m_serverTransaction.TransactionRequest.URI.ToString() + "."); // No response has been received from the server so no CANCEL request necessary, stop any retransmits of the INVITE. m_serverTransaction.CancelCall(); SIPRequest cancelRequest = GetCancelRequest(m_serverTransaction.TransactionRequest); // If auth header is included inside INVITE request, we re-include them inside CANCEL request if (m_serverTransaction.TransactionRequest.Header.HasAuthenticationHeader) { string username = (m_sipCallDescriptor.AuthUsername == null || m_sipCallDescriptor.AuthUsername.Trim().Length <= 0 ? m_sipCallDescriptor.Username : m_sipCallDescriptor.AuthUsername); SIPAuthorisationDigest authDigest = m_serverTransaction.TransactionRequest.Header.AuthenticationHeaders.First().SIPDigest; authDigest.SetCredentials(username, m_sipCallDescriptor.Password, m_sipCallDescriptor.Uri, SIPMethodsEnum.CANCEL.ToString()); var authHeader = new SIPAuthenticationHeader(authDigest); authHeader.SIPDigest.IncrementNonceCount(); authHeader.SIPDigest.Response = authDigest.GetDigest(); cancelRequest.Header.AuthenticationHeaders.Clear(); cancelRequest.Header.AuthenticationHeaders.Add(authHeader); } m_cancelTransaction = new SIPNonInviteTransaction(m_sipTransport, cancelRequest, m_outboundProxy); m_cancelTransaction.SendRequest(); } CallFailed?.Invoke(this, "Call cancelled by user.", null); } catch (Exception excp) { logger.LogError("Exception CancelServerCall. " + excp.Message); } }
public void ProcessInDialogueRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { SIPDialogue dialogue = GetDialogue(sipRequest); if (dialogue == null) { SIPNonInviteTransaction nonInvTx = new SIPNonInviteTransaction(m_sipTransport, sipRequest, m_outboundProxy); var noLegResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); nonInvTx.SendResponse(noLegResp); } else if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPNonInviteTransaction byeTransaction = new SIPNonInviteTransaction(m_sipTransport, sipRequest, m_outboundProxy); //logger.Debug("Matching dialogue found for BYE request to " + sipRequest.URI.ToString() + "."); SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendResponse(byeResponse); // Normal BYE request. CallHungup(dialogue, sipRequest.Header.Reason, false); } //else if (sipRequest.Method == SIPMethodsEnum.INVITE) //{ // UASInviteTransaction reInviteTransaction = new UASInviteTransaction(m_sipTransport, sipRequest, m_outboundProxy); // SIPResponse tryingResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null); // reInviteTransaction.SendProvisionalResponse(tryingResponse); // reInviteTransaction.CDR = null; // Don't want CDR's on re-INVITEs. // ForwardInDialogueRequest(dialogue, reInviteTransaction, localSIPEndPoint, remoteEndPoint); //} else if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { // Send back the remote SDP. logger.LogDebug("OPTIONS request for established dialogue " + dialogue.DialogueName + "."); SIPNonInviteTransaction optionsTransaction = new SIPNonInviteTransaction(m_sipTransport, sipRequest, m_outboundProxy); SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Body = dialogue.RemoteSDP; okResponse.Header.ContentLength = okResponse.Body.Length; okResponse.Header.ContentType = m_sdpContentType; optionsTransaction.SendResponse(okResponse); } else if (sipRequest.Method == SIPMethodsEnum.MESSAGE) { logger.LogDebug("MESSAGE for call " + sipRequest.URI.ToString() + ": " + sipRequest.Body + "."); SIPNonInviteTransaction messageTransaction = new SIPNonInviteTransaction(m_sipTransport, sipRequest, m_outboundProxy); SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); messageTransaction.SendResponse(okResponse); } else { //// This is a request on an established call forward through to the opposite dialogue. //SIPNonInviteTransaction passThruTransaction = new SIPNonInviteTransaction(m_sipTransport, sipRequest, m_outboundProxy); //ForwardInDialogueRequest(dialogue, passThruTransaction, localSIPEndPoint, remoteEndPoint); logger.LogDebug($"{sipRequest.Method} received for dialogue {sipRequest.URI}, processing not yet implemented TODO!."); SIPNonInviteTransaction nonInvTx = new SIPNonInviteTransaction(m_sipTransport, sipRequest, m_outboundProxy); var noLegResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); nonInvTx.SendResponse(noLegResp); } }
private void SendInitialRegister() { try { if (m_attempts >= m_maxRegisterAttempts) { logger.LogWarning("Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition."); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(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); SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_registrarHost); var lookupResult = m_sipTransport.ResolveSIPUriAsync(uri).ConfigureAwait(false).GetAwaiter().GetResult(); if (lookupResult == null) { logger.LogWarning("Could not resolve " + m_registrarHost + "."); } else { registrarSIPEndPoint = lookupResult; } } if (registrarSIPEndPoint == null) { logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + "."); RegistrationFailed?.Invoke(m_sipAccountAOR, "Could not resolve " + m_registrarHost + "."); } else { logger.LogDebug("Initiating registration to " + m_registrarHost + " at " + registrarSIPEndPoint.ToString() + " for " + m_sipAccountAOR.ToString() + "."); SIPRequest regRequest = GetRegistrationRequest(); SIPNonInviteTransaction regTransaction = new SIPNonInviteTransaction(m_sipTransport, regRequest, registrarSIPEndPoint); // 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); }); return(Task.FromResult(SocketError.Success)); }; regTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendTransaction(regTransaction); } } } catch (Exception excp) { logger.LogError("Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); RegistrationFailed?.Invoke(m_sipAccountAOR, "Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); } }
private void DoSubscribe(SIPNonInviteTransaction subTx) { SIPRequest req = subTx.TransactionRequest; string user = req.Header.From.FromURI.User; string domain = req.Header.From.FromURI.HostAddress; string canonicalDomain = m_sipDomainManager.GetCanonicalDomain(domain); if (canonicalDomain == null) { Logger.LogWarning($"Subscribe Register request for {req.Header.From.FromURI.Host} rejected as no matching domain found."); SIPResponse noDomainResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); subTx.SendResponse(noDomainResponse); } else { SIPAccount sipAccount = m_sipAccountsDataLayer.GetSIPAccount(user, canonicalDomain).Result; if (sipAccount == null) { Logger.LogWarning($"SubscriberCore SIP account {user}@{canonicalDomain} does not exist."); SIPResponse forbiddenResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Forbidden, null); subTx.SendResponse(forbiddenResponse); } else { SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator.AuthenticateSIPRequest(req.LocalSIPEndPoint, req.RemoteSIPEndPoint, req, sipAccount); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPResponse.GetResponse(req, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; subTx.SendResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { Logger.LogWarning($"Forbidden {sipAccount.AOR} does not exist, received from {req.RemoteSIPEndPoint}, user agent {req.Header.UserAgent}."); } } else { SIPResponse okResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Ok, null); subTx.SendResponse(okResponse); Logger.LogDebug($"Subscription request for {user}@{domain} was successful."); // Give the subscribe response time to be sent. Thread.Sleep(500); if (req.Header.Expires > 0) { SendInitialNotification(req, sipAccount); } } } } }
private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if ((m_callDescriptor.Username != null || m_callDescriptor.AuthUsername != null) && m_callDescriptor.Password != null) { SIPRequest authenticatedRequest = GetAuthenticatedRequest(sipTransaction.TransactionRequest, sipResponse); SIPNonInviteTransaction authTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, sipTransaction.RemoteEndPoint, localSIPEndPoint, m_outboundProxy); authTransaction.NonInviteTransactionFinalResponseReceived += AuthResponseReceived; authTransaction.NonInviteTransactionTimedOut += RequestTimedOut; m_sipTransport.SendSIPReliable(authTransaction); } else { if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } else { if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } else { if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } catch (Exception excp) { Logger.Logger.Error("Exception SIPNonInviteClientUserAgent ServerResponseReceived (" + remoteEndPoint + "). ->" + excp.Message); } }
private void SendInitialRegister() { try { if (m_attempts >= m_maxRegisterAttempts) { logger.LogWarning($"Registration to {m_sipAccountAOR} reached the maximum number of allowed attempts without a failure condition."); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts."); m_waitForRegistrationMRE.Set(); } else { m_attempts++; SIPEndPoint registrarSIPEndPoint = m_outboundProxy; if (registrarSIPEndPoint == null) { SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_registrarHost); var lookupResult = m_sipTransport.ResolveSIPUriAsync(uri).Result; if (lookupResult == null || lookupResult == SIPEndPoint.Empty) { logger.LogWarning("Could not resolve " + m_registrarHost + " when sending initial registration request."); } else { registrarSIPEndPoint = lookupResult; } } if (registrarSIPEndPoint == null) { logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + "."); RegistrationFailed?.Invoke(m_sipAccountAOR, "Could not resolve " + m_registrarHost + "."); } else { logger.LogDebug("Initiating registration to " + m_registrarHost + " at " + registrarSIPEndPoint.ToString() + " for " + m_sipAccountAOR.ToString() + "."); SIPRequest regRequest = GetRegistrationRequest(); SIPNonInviteTransaction regTransaction = new SIPNonInviteTransaction(m_sipTransport, regRequest, registrarSIPEndPoint); regTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ServerResponseReceived(lep, rep, tn, rsp); return(Task.FromResult(SocketError.Success)); }; regTransaction.NonInviteTransactionTimedOut += RegistrationTimedOut; m_sipTransport.SendTransaction(regTransaction); } } } catch (Exception excp) { logger.LogError("Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); RegistrationFailed?.Invoke(m_sipAccountAOR, "Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); } }
public void ProcessRegisterRequest() { logger.Debug("SIPRegistrarCore is running at " + _localSipAccount.MsgProtocol + ":" + _localSipAccount.LocalIP + ":" + _localSipAccount.LocalPort); try { while (!Stop) { if (m_registerQueue.Count > 0) { try { SIPNonInviteTransaction registrarTransaction = null; lock (m_registerQueue) { registrarTransaction = m_registerQueue.Dequeue(); } if (registrarTransaction != null) { DateTime startTime = DateTime.Now; var result = Register(registrarTransaction); var duration = DateTime.Now.Subtract(startTime); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegistrarTiming, "register result=" + result.ToString() + ", time=" + duration.TotalMilliseconds + "ms, user="******".", null)); RegisterComplete?.Invoke(duration.TotalMilliseconds, registrarTransaction.TransactionRequest.Header.AuthenticationHeader != null); logger.Debug("Camera[" + registrarTransaction.RemoteEndPoint + "] have completed registering GB service."); //CacheDeviceItem(registrarTransaction.TransactionRequest); //device alarm subscribe DeviceAlarmSubscribe?.Invoke(registrarTransaction); } } catch (InvalidOperationException invalidOpExcp) { // This occurs when the queue is empty. logger.Warn("InvalidOperationException ProcessRegisterRequest Register Job. " + invalidOpExcp.Message); } catch (Exception regExcp) { logger.Error("Exception ProcessRegisterRequest Register Job. " + regExcp.Message); } } else { m_registerARE.WaitOne(MAX_PROCESS_REGISTER_SLEEP); } } logger.Warn("ProcessRegisterRequest thread " + Thread.CurrentThread.Name + " stopping."); } catch (Exception excp) { logger.Error("Exception ProcessRegisterRequest (" + Thread.CurrentThread.Name + "). " + excp.Message); } }
private Task <SocketError> ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; logger.LogDebug("Server response " + sipResponse.StatusCode + " " + reasonPhrase + " received for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + "."); if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if ((m_callDescriptor.Username != null || m_callDescriptor.AuthUsername != null) && m_callDescriptor.Password != null) { SIPRequest authenticatedRequest = GetAuthenticatedRequest(sipTransaction.TransactionRequest, sipResponse); SIPNonInviteTransaction authTransaction = new SIPNonInviteTransaction(m_sipTransport, authenticatedRequest, m_outboundProxy); authTransaction.NonInviteTransactionFinalResponseReceived += AuthResponseReceived; authTransaction.NonInviteTransactionTimedOut += RequestTimedOut; m_sipTransport.SendTransaction(authTransaction); } else { logger.LogDebug("Send request received an authentication required response but no credentials were available."); if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } else { logger.LogDebug("Send request failed with " + sipResponse.StatusCode + " but no authentication header was supplied for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + "."); if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } else { if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message); } return(Task.FromResult(SocketError.Success)); }
private void ProcessRegisterRequest(string threadName) { try { Thread.CurrentThread.Name = threadName; while (!Stop) { if (m_registerQueue.Count > 0) { try { SIPNonInviteTransaction registrarTransaction = null; lock (m_registerQueue) { registrarTransaction = m_registerQueue.Dequeue(); } if (registrarTransaction != null) { DateTime startTime = DateTime.Now; RegisterResultEnum result = Register(registrarTransaction); TimeSpan duration = DateTime.Now.Subtract(startTime); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegistrarTiming, "register result=" + result.ToString() + ", time=" + duration.TotalMilliseconds + "ms, user="******".", null)); if (RegisterComplete != null) { RegisterComplete(duration.TotalMilliseconds, registrarTransaction.TransactionRequest.Header.AuthenticationHeader != null); } } } catch (InvalidOperationException invalidOpExcp) { // This occurs when the queue is empty. logger.Warn("InvalidOperationException ProcessRegisterRequest Register Job. " + invalidOpExcp.Message); } catch (Exception regExcp) { logger.Error("Exception ProcessRegisterRequest Register Job. " + regExcp.Message); } } else { m_registerARE.WaitOne(MAX_PROCESS_REGISTER_SLEEP); } } logger.Warn("ProcessRegisterRequest thread " + Thread.CurrentThread.Name + " stopping."); } catch (Exception excp) { logger.Error("Exception ProcessRegisterRequest (" + Thread.CurrentThread.Name + "). " + excp.Message); } }
private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Server response " + sipResponse.StatusCode + " " + reasonPhrase + " received for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".", m_owner)); if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if ((m_callDescriptor.Username != null || m_callDescriptor.AuthUsername != null) && m_callDescriptor.Password != null) { SIPRequest authenticatedRequest = GetAuthenticatedRequest(sipTransaction.TransactionRequest, sipResponse); SIPNonInviteTransaction authTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, sipTransaction.RemoteEndPoint, localSIPEndPoint, m_outboundProxy); authTransaction.NonInviteTransactionFinalResponseReceived += AuthResponseReceived; authTransaction.NonInviteTransactionTimedOut += RequestTimedOut; m_sipTransport.SendSIPReliable(authTransaction); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Send request received an authentication required response but no credentials were available.", m_owner)); if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Send request failed with " + sipResponse.StatusCode + " but no authentication header was supplied for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".", m_owner)); if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } else { if (ResponseReceived != null) { ResponseReceived(sipResponse); } } } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message); } }
/// <summary> /// 处理注册请求消息 /// </summary> /// <param name="localSIPEndPoint">本地终结点</param> /// <param name="remoteEndPoint">远程终结点</param> /// <param name="registerRequest">注册请求</param> private void ProcessRegisterReqMessage(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest registerRequest) { SIPSorceryPerformanceMonitor.IncrementCounter(SIPSorceryPerformanceMonitor.REGISTRAR_REGISTRATION_REQUESTS_PER_SECOND); int requestedExpiry = GetRequestedExpiry(registerRequest); if (registerRequest.Header.To == null) { logger.Debug("Bad register request, no To header from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing To header"); m_sipTransport.SendResponse(badReqResponse); } else if (registerRequest.Header.To.ToURI.User.IsNullOrBlank()) { logger.Debug("Bad register request, no To user from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing username on To header"); m_sipTransport.SendResponse(badReqResponse); } else if (registerRequest.Header.Contact == null || registerRequest.Header.Contact.Count == 0) { logger.Debug("Bad register request, no Contact header from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing Contact header"); m_sipTransport.SendResponse(badReqResponse); } else if (requestedExpiry > 0 && requestedExpiry < MINIMUM_EXPIRY_SECONDS) { logger.Debug("Bad register request, no expiry of " + requestedExpiry + " to small from " + remoteEndPoint + "."); SIPResponse tooFrequentResponse = GetErrorResponse(registerRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null); tooFrequentResponse.Header.MinExpires = MINIMUM_EXPIRY_SECONDS; m_sipTransport.SendResponse(tooFrequentResponse); } else { if (m_registerQueue.Count < MAX_REGISTER_QUEUE_SIZE) { SIPNonInviteTransaction registrarTransaction = m_sipTransport.CreateNonInviteTransaction(registerRequest, remoteEndPoint, localSIPEndPoint, null); lock (m_registerQueue) { m_registerQueue.Enqueue(registrarTransaction); } FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.BindingInProgress, "Register queued for " + registerRequest.Header.To.ToURI.ToString() + ".", null)); } else { logger.Error("Register queue exceeded max queue size " + MAX_REGISTER_QUEUE_SIZE + ", overloaded response sent."); SIPResponse overloadedResponse = SIPTransport.GetResponse(registerRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Registrar overloaded, please try again shortly"); m_sipTransport.SendResponse(overloadedResponse); } m_registerARE.Set(); } }
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; } }
/// <summary> /// Processes a transfer once the REFER request has been determined. /// </summary> /// <param name="referRequest">The REFER request for the transfer.</param> /// <param name="timeout">Timeout for the transfer request to get accepted.</param> /// <param name="ct">Cancellation token. Can be set to cancel the transfer prior to it being /// accepted or timing out.</param> /// <returns>True if the transfer was accepted by the Transferee or false if not.</returns> private async Task <bool> Transfer(SIPRequest referRequest, TimeSpan timeout, CancellationToken ct) { if (Dialogue == null) { logger.LogWarning("Transfer was called on the SIPUserAgent when no dialogue was available."); return(false); } else { TaskCompletionSource <bool> transferAccepted = new TaskCompletionSource <bool>(); SIPNonInviteTransaction referTx = new SIPNonInviteTransaction(m_transport, referRequest, null); SIPTransactionResponseReceivedDelegate referTxStatusHandler = (localSIPEndPoint, remoteEndPoint, sipTransaction, sipResponse) => { // This handler has to go on a separate thread or the SIPTransport "ProcessInMessage" thread will be blocked. Task.Run(() => { if (sipResponse.Header.CSeqMethod == SIPMethodsEnum.REFER && sipResponse.Status == SIPResponseStatusCodesEnum.Accepted) { logger.LogInformation("Call transfer was accepted by remote server."); transferAccepted.SetResult(true); } else { transferAccepted.SetResult(false); } }, ct); return(Task.FromResult(SocketError.Success)); }; referTx.NonInviteTransactionFinalResponseReceived += referTxStatusHandler; referTx.SendRequest(); await Task.WhenAny(transferAccepted.Task, Task.Delay((int)timeout.TotalMilliseconds, ct)).ConfigureAwait(false); referTx.NonInviteTransactionFinalResponseReceived -= referTxStatusHandler; if (transferAccepted.Task.IsCompleted) { return(transferAccepted.Task.Result); } else { logger.LogWarning($"Call transfer request timed out after {timeout.TotalMilliseconds}ms."); return(false); } } }
public void SendRequest(SIPMethodsEnum method) { try { SIPRequest req = GetRequest(method); SIPNonInviteTransaction tran = new SIPNonInviteTransaction(m_sipTransport, req, m_outboundProxy); ManualResetEvent waitForResponse = new ManualResetEvent(false); tran.NonInviteTransactionFailed += TransactionFailed; tran.NonInviteTransactionFinalResponseReceived += ServerResponseReceived; tran.SendRequest(); } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent SendRequest to " + m_callDescriptor.Uri + ". " + excp.Message); throw; } }
public void SendRequest(SIPMethodsEnum method) { try { SIPRequest req = GetRequest(method); SIPNonInviteTransaction tran = m_sipTransport.CreateNonInviteTransaction(req, null, m_sipTransport.GetDefaultSIPEndPoint(), m_outboundProxy); ManualResetEvent waitForResponse = new ManualResetEvent(false); tran.NonInviteTransactionTimedOut += RequestTimedOut; tran.NonInviteTransactionFinalResponseReceived += ServerResponseReceived; tran.SendReliableRequest(); } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent SendRequest to " + m_callDescriptor.Uri + ". " + excp.Message); throw; } }
private void ProcessSubscribeRequest(string threadName) { try { Thread.CurrentThread.Name = threadName; while (!m_exit) { if (m_notifierQueue.Count > 0) { try { SIPNonInviteTransaction subscribeTransaction = null; lock (m_notifierQueue) { subscribeTransaction = m_notifierQueue.Dequeue(); } if (subscribeTransaction != null) { DateTime startTime = DateTime.Now; Subscribe(subscribeTransaction); TimeSpan duration = DateTime.Now.Subtract(startTime); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Timing, "Subscribe time=" + duration.TotalMilliseconds + "ms, user="******".", null)); } } catch (Exception regExcp) { logger.Error("Exception ProcessSubscribeRequest Subscribe Job. " + regExcp.Message); } } else { m_notifierARE.WaitOne(MAX_NOTIFIER_SLEEP_TIME); } } logger.Warn("ProcessSubscribeRequest thread " + Thread.CurrentThread.Name + " stopping."); } catch (Exception excp) { logger.Error("Exception ProcessSubscribeRequest (" + Thread.CurrentThread.Name + "). " + excp.Message); } }
public void SendSIPRequest(SIPRequest sipRequest, string dstSocket) { //ResetSIPResponse(); if (sipRequest.Method == SIPMethodsEnum.INVITE) { //m_inviteRequest = sipRequest; UACInviteTransaction inviteTransaction = m_sipTransport.CreateUACTransaction(sipRequest, IPSocket.GetIPEndPoint(dstSocket), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP); inviteTransaction.UACInviteTransactionInformationResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionInformationResponseReceived); inviteTransaction.UACInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionFinalResponseReceived); m_sipTransport.SendSIPReliable(inviteTransaction); } else { SIPNonInviteTransaction sipTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, IPSocket.GetIPEndPoint(dstSocket), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP); sipTransaction.NonInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionFinalResponseReceived); m_sipTransport.SendSIPReliable(sipTransaction); } }
private Task <SocketError> ByeServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { logger.LogDebug("Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + sipTransaction.TransactionRequest.URI.ToString() + "."); SIPNonInviteTransaction byeTransaction = sipTransaction as SIPNonInviteTransaction; if ((sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) && SIPAccount != null) { // Resend BYE with credentials. SIPAuthorisationDigest authRequest = sipResponse.Header.AuthenticationHeader.SIPDigest; SIPURI contactUri = sipResponse.Header.Contact.Any() ? sipResponse.Header.Contact[0].ContactURI : sipResponse.Header.From.FromURI; authRequest.SetCredentials(SIPAccount.SIPUsername, SIPAccount.SIPPassword, contactUri.ToString(), SIPMethodsEnum.BYE.ToString()); SIPRequest authByeRequest = byeTransaction.TransactionRequest; authByeRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authRequest); authByeRequest.Header.AuthenticationHeader.SIPDigest.Response = authRequest.Digest; authByeRequest.Header.Vias.TopViaHeader.Branch = CallProperties.CreateBranchId(); authByeRequest.Header.CSeq = authByeRequest.Header.CSeq + 1; SIPNonInviteTransaction authByeTransaction = new SIPNonInviteTransaction(m_sipTransport, authByeRequest, null); authByeTransaction.SendRequest(); } return(Task.FromResult(SocketError.Success)); } catch (Exception excp) { logger.LogError("Exception ByServerFinalResponseReceived. " + excp.Message); return(Task.FromResult(SocketError.Fault)); } }
public void Hangup() { if (m_sipDialogue == null) { return; } try { //SIPRequest byeRequest = GetByeRequest(m_serverTransaction.TransactionFinalResponse, m_sipDialogue.RemoteTarget); SIPRequest byeRequest = m_sipDialogue.GetInDialogRequest(SIPMethodsEnum.BYE); byeRequest.SetSendFromHints(m_serverTransaction.TransactionRequest.LocalSIPEndPoint); m_byeTransaction = new SIPNonInviteTransaction(m_sipTransport, byeRequest, m_outboundProxy); m_byeTransaction.NonInviteTransactionFinalResponseReceived += ByeServerFinalResponseReceived; m_byeTransaction.NonInviteTransactionFailed += (tx, reason) => logger.LogWarning($"Bye request for {m_sipCallDescriptor.Uri} failed with {reason}."); m_byeTransaction.SendRequest(); } catch (Exception excp) { logger.LogError("Exception SIPClientUserAgent Hangup. " + excp.Message); } }
#pragma warning restore public SIPNonInviteServerUserAgent( SIPTransport sipTransport, SIPEndPoint outboundProxy, string sipUsername, string sipDomain, SIPCallDirection callDirection, ISIPAccount sipAccount, SIPNonInviteTransaction transaction) { m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_sipUsername = sipUsername; m_sipDomain = sipDomain; m_sipCallDirection = callDirection; m_sipAccount = sipAccount; m_transaction = transaction; //m_transaction.TransactionTraceMessage += TransactionTraceMessage; //m_uasTransaction.UASInviteTransactionTimedOut += ClientTimedOut; //m_uasTransaction.UASInviteTransactionCancelled += UASTransactionCancelled; //m_uasTransaction.TransactionRemoved += new SIPTransactionRemovedDelegate(UASTransaction_TransactionRemoved); //m_uasTransaction.TransactionStateChanged += (t) => { logger.Debug("Transaction state change to " + t.TransactionState + ", uri=" + t.TransactionRequestURI.ToString() + "."); }; }
public void AddRegisterRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest registerRequest) { if (registerRequest.Method != SIPMethodsEnum.REGISTER) { SIPResponse notSupportedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Registration requests only"); m_sipTransport.SendResponseAsync(notSupportedResponse).Wait(); } else { int requestedExpiry = GetRequestedExpiry(registerRequest); if (requestedExpiry > 0 && requestedExpiry < m_minimumBindingExpiry) { Logger.LogDebug("Bad register request, no expiry of " + requestedExpiry + " to small from " + remoteEndPoint + "."); SIPResponse tooFrequentResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null); tooFrequentResponse.Header.MinExpires = m_minimumBindingExpiry; m_sipTransport.SendResponseAsync(tooFrequentResponse).Wait(); } else { if (m_registerQueue.Count < MAX_REGISTER_QUEUE_SIZE) { SIPNonInviteTransaction regTx = new SIPNonInviteTransaction(m_sipTransport, registerRequest, null); m_registerQueue.Enqueue(regTx); } else { Logger.LogError("Register queue exceeded maximum queue size " + MAX_REGISTER_QUEUE_SIZE + ", overloaded response sent."); SIPResponse overloadedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Registrar overloaded, please try again shortly"); m_sipTransport.SendResponseAsync(overloadedResponse).Wait(); } m_registerARE.Set(); } } }
public void AddSubscribeRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest subscribeRequest) { if (subscribeRequest.Method != SIPMethodsEnum.SUBSCRIBE) { SIPResponse notSupportedResponse = SIPResponse.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Subscribe requests only"); m_sipTransport.SendResponseAsync(notSupportedResponse).Wait(); } else { if (m_subscribeQueue.Count < MAX_SUBSCRIBE_QUEUE_SIZE) { SIPNonInviteTransaction subTx = new SIPNonInviteTransaction(m_sipTransport, subscribeRequest, null); m_subscribeQueue.Enqueue(subTx); } else { Logger.LogError($"Subscribe queue exceeded maximum queue size {MAX_SUBSCRIBE_QUEUE_SIZE}, overloaded response sent."); SIPResponse overloadedResponse = SIPResponse.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Subscriber core overloaded, please try again shortly"); m_sipTransport.SendResponseAsync(overloadedResponse).Wait(); } m_subscribeARE.Set(); } }
private Task <SocketError> ByeServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { logger.LogDebug("Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + sipTransaction.TransactionRequest.URI.ToString() + "."); SIPNonInviteTransaction byeTransaction = sipTransaction as SIPNonInviteTransaction; if ((sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) && SIPAccount != null) { var authRequest = sipTransaction.TransactionRequest.DuplicateAndAuthenticate(sipResponse.Header.AuthenticationHeaders, SIPAccount.SIPUsername, SIPAccount.SIPPassword); SIPNonInviteTransaction authByeTransaction = new SIPNonInviteTransaction(m_sipTransport, authRequest, null); authByeTransaction.SendRequest(); } return(Task.FromResult(SocketError.Success)); } catch (Exception excp) { logger.LogError("Exception ByServerFinalResponseReceived. " + excp.Message); return(Task.FromResult(SocketError.Fault)); } }
private void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { switch (sipRequest.Method) { case SIPMethodsEnum.OPTIONS: SIPNonInviteTransaction optionsTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse optionsResponse = SipHelper.WG67ResponseNormalize( SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null)); optionsTransaction.SendFinalResponse(optionsResponse); OptionsReceived?.Invoke(remoteEndPoint.ToString()); break; case SIPMethodsEnum.SUBSCRIBE: m_sip_notifier.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest); break; case SIPMethodsEnum.PUBLISH: default: throw new NotImplementedException(); } } catch (NotImplementedException) { _logger.From().Debug(sipRequest.Method + " request processing not implemented for " + sipRequest.URI.ToParameterlessString() + " from " + remoteEndPoint + "."); SIPNonInviteTransaction notImplTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse notImplResponse = SipHelper.WG67ResponseNormalize(SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotImplemented, null)); notImplTransaction.SendFinalResponse(notImplResponse); } catch (Exception x) { _logger.From().Debug($"SIPTransportRequestReceived Exception {x.Message}", x); } }
/// <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() + ".", m_owner)); 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.", m_owner)); 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); SIPNonInviteTransaction regAuthTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, sipTransaction.RemoteEndPoint, localSIPEndPoint, m_outboundProxy); regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); }); }; regAuthTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendSIPReliable(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() + ".", m_owner)); 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.", m_owner)); 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.", m_owner)); SendInitialRegister(); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ".", m_owner)); 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> /// Handler for processing incomign SIP requests. /// </summary> /// <param name="localSIPEndPoint">The end point the request was received on.</param> /// <param name="remoteEndPoint">The end point the request came from.</param> /// <param name="sipRequest">The SIP request received.</param> private void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (sipRequest.Method == SIPMethodsEnum.BYE) { if (m_uac != null && m_uac.SIPDialogue != null && sipRequest.Header.CallId == m_uac.SIPDialogue.CallId) { // Call has been hungup by remote end. StatusMessage("Call hungup by remote end."); SIPNonInviteTransaction byeTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); CallFinished(); } else if (m_uas != null && m_uas.SIPDialogue != null && sipRequest.Header.CallId == m_uas.SIPDialogue.CallId) { // Call has been hungup by remote end. StatusMessage("Call hungup."); m_uas.SIPDialogue.Hangup(m_sipTransport, null); CallFinished(); } else { logger.Debug("Unmatched BYE request received for " + sipRequest.URI.ToString() + "."); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { StatusMessage("Incoming call request: " + localSIPEndPoint + "<-" + remoteEndPoint + " " + sipRequest.URI.ToString() + "."); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); m_uas = new SIPServerUserAgent(m_sipTransport, null, null, null, SIPCallDirection.In, null, null, null, uasTransaction); m_uas.CallCancelled += UASCallCancelled; IncomingCall(); } else if (sipRequest.Method == SIPMethodsEnum.CANCEL) { UASInviteTransaction inviteTransaction = (UASInviteTransaction)m_sipTransport.GetTransaction(SIPTransaction.GetRequestTransactionId(sipRequest.Header.Vias.TopViaHeader.Branch, SIPMethodsEnum.INVITE)); if (inviteTransaction != null) { StatusMessage("Call was cancelled by remote end."); SIPCancelTransaction cancelTransaction = m_sipTransport.CreateCancelTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, inviteTransaction); cancelTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { logger.Debug("No matching transaction was found for CANCEL to " + sipRequest.URI.ToString() + "."); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } CallFinished(); } else { logger.Debug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting."); SIPResponse notAllowedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); m_sipTransport.SendResponse(notAllowedResponse); } }
private RegisterResultEnum Register(SIPNonInviteTransaction registerTransaction) { try { SIPRequest sipRequest = registerTransaction.TransactionRequest; SIPURI registerURI = sipRequest.URI; SIPToHeader toHeader = sipRequest.Header.To; string toUser = toHeader.ToURI.User; string canonicalDomain = m_sipDomainManager.GetCanonicalDomain(toHeader.ToURI.HostAddress); int requestedExpiry = GetRequestedExpiry(sipRequest); if (canonicalDomain == null) { Logger.LogWarning($"Register request for {toHeader.ToURI.HostAddress} rejected as no matching domain found."); SIPResponse noDomainResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); registerTransaction.SendResponse(noDomainResponse); return(RegisterResultEnum.DomainNotServiced); } else { SIPAccount sipAccount = m_sipAccountsDataLayer.GetSIPAccount(toUser, canonicalDomain).Result; if (sipAccount == null) { Logger.LogWarning($"RegistrarCore SIP account {toUser}@{canonicalDomain} does not exist."); SIPResponse forbiddenResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, null); registerTransaction.SendResponse(forbiddenResponse); return(RegisterResultEnum.Forbidden); } else { SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator.AuthenticateSIPRequest( registerTransaction.TransactionRequest.LocalSIPEndPoint, registerTransaction.TransactionRequest.RemoteSIPEndPoint, sipRequest, sipAccount.ToSIPAccountModel()); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPResponse.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; registerTransaction.SendResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { Logger.LogWarning($"Forbidden {sipAccount.AOR} does not exist, {sipRequest.Header.ProxyReceivedFrom}, {sipRequest.Header.UserAgent}."); return(RegisterResultEnum.Forbidden); } else { return(RegisterResultEnum.AuthenticationRequired); } } else { if (sipRequest.Header.Contact == null || sipRequest.Header.Contact.Count == 0) { // No contacts header to update bindings with, return a list of the current bindings. //List<SIPRegistrarBinding> bindings = m_registrarBindingsManager.GetBindings(sipAccount.ID); List <SIPRegistrarBinding> bindings = m_sipRegistrarBindingDataLayer.GetForSIPAccount(new Guid(sipAccount.ID)).ToList(); //List<SIPContactHeader> contactsList = m_registrarBindingsManager.GetContactHeader(); // registration.GetContactHeader(true, null); if (bindings != null) { sipRequest.Header.Contact = GetContactHeader(bindings); } SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendResponse(okResponse); Logger.LogDebug($"Empty registration request successful for {sipAccount.AOR} from {sipRequest.Header.ProxyReceivedFrom}."); } else { SIPEndPoint uacRemoteEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? registerTransaction.TransactionRequest.RemoteSIPEndPoint; SIPEndPoint proxySIPEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn); SIPEndPoint registrarEndPoint = registerTransaction.TransactionRequest.LocalSIPEndPoint; SIPResponseStatusCodesEnum updateResult = SIPResponseStatusCodesEnum.Ok; string updateMessage = null; DateTime startTime = DateTime.Now; List <SIPRegistrarBinding> bindingsList = m_registrarBindingsManager.UpdateBindings( sipAccount, proxySIPEndPoint, uacRemoteEndPoint, registrarEndPoint, sipRequest.Header.Contact, sipRequest.Header.CallId, sipRequest.Header.CSeq, sipRequest.Header.Expires, sipRequest.Header.UserAgent, out updateResult, out updateMessage); TimeSpan duration = DateTime.Now.Subtract(startTime); Logger.LogDebug($"Binding update time for {sipAccount.AOR} took {duration.TotalMilliseconds}ms."); if (updateResult == SIPResponseStatusCodesEnum.Ok) { string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null; Logger.LogDebug($"Bindings for {sipAccount.AOR}:"); for (int i = 0; i < bindingsList.Count(); i++) { var binding = bindingsList[i]; Logger.LogDebug($" {i}: {binding.ContactURI}, expiry {binding.Expiry}s."); } sipRequest.Header.Contact = GetContactHeader(bindingsList); SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendResponse(okResponse); } else { // The binding update failed even though the REGISTER request was authorised. This is probably due to a // temporary problem connecting to the bindings data store. Send Ok but set the binding expiry to the minimum so // that the UA will try again as soon as possible. Logger.LogError($"Registration request successful but binding update failed for {sipAccount.AOR} from {registerTransaction.TransactionRequest.RemoteSIPEndPoint}."); sipRequest.Header.Contact[0].Expires = m_minimumBindingExpiry; SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendResponse(okResponse); } } return(RegisterResultEnum.Authenticated); } } } } catch (Exception excp) { string regErrorMessage = "Exception registrarcore registering. " + excp.Message + "\r\n" + registerTransaction.TransactionRequest.ToString(); Logger.LogError(regErrorMessage); SIPResponse errorResponse = SIPResponse.GetResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); registerTransaction.SendResponse(errorResponse); return(RegisterResultEnum.Error); } }
public void ReferOutOfDialog(SIPURI fromUri, SIPURI toUri, SIPURI referToUri, ReplacesCallDescriptor sipReplacesCallDescriptor) { try { m_sipCallDescriptor = new SIPCallDescriptor(null,toUri.ToString(),fromUri.ToString(),null,null); m_sipCallDescriptor.Gruu = toUri.Parameters.Get(SIPCallDescriptor.GRUU_KEY); m_sipCallDescriptor.ReplacesCall = sipReplacesCallDescriptor; SIPURI callURI = SIPURI.ParseSIPURI(m_sipCallDescriptor.Uri); // If the outbound proxy is a loopback address, as it will normally be for local deployments, then it cannot be overriden. if (m_outboundProxy != null && IPAddress.IsLoopback(m_outboundProxy.Address)) { m_serverEndPoint = m_outboundProxy; } else if (!m_sipCallDescriptor.ProxySendFrom.IsNullOrBlank()) { // If the binding has a specific proxy end point sent then the request needs to be forwarded to the proxy's default end point for it to take care of. SIPEndPoint outboundProxyEndPoint = SIPEndPoint.ParseSIPEndPoint(m_sipCallDescriptor.ProxySendFrom); m_outboundProxy = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(outboundProxyEndPoint.Address, m_defaultSIPPort)); m_serverEndPoint = m_outboundProxy; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "SIPReferClientUserAgent refer request using alternate outbound proxy of " + m_outboundProxy + ".", Owner)); } else if (m_outboundProxy != null) { // Using the system outbound proxy only, no additional user routing requirements. m_serverEndPoint = m_outboundProxy; } // A custom route set may have been specified for the call. if (m_sipCallDescriptor.RouteSet != null && m_sipCallDescriptor.RouteSet.IndexOf(OUTBOUNDPROXY_AS_ROUTESET_CHAR) != -1) { try { RouteSet = new SIPRouteSet(); RouteSet.PushRoute(new SIPRoute(m_sipCallDescriptor.RouteSet, true)); } catch { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Error an outbound proxy value was not recognised in SIPReferClientUserAgent refer request. " + m_sipCallDescriptor.RouteSet + ".", Owner)); } } // No outbound proxy, determine the forward destination based on the SIP request. if (m_serverEndPoint == null) { SIPDNSLookupResult lookupResult = null; if (RouteSet == null || RouteSet.Length == 0) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Attempting to resolve " + callURI.Host + ".", Owner)); lookupResult = m_sipTransport.GetURIEndPoint(callURI, false); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Route set for refer request " + RouteSet.ToString() + ".", Owner)); lookupResult = m_sipTransport.GetURIEndPoint(RouteSet.TopRoute.URI, false); } if (lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "DNS error resolving " + callURI.Host + ", " + lookupResult.LookupError + ". Refer request cannot proceed.", Owner)); } else { m_serverEndPoint = lookupResult.GetSIPEndPoint(); } } if (m_serverEndPoint != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Switching to " + SIPURI.ParseSIPURI(m_sipCallDescriptor.Uri).CanonicalAddress + " via " + m_serverEndPoint + ".", Owner)); m_localSIPEndPoint = m_sipTransport.GetDefaultSIPEndPoint(m_serverEndPoint); if (m_localSIPEndPoint == null) { throw new ApplicationException("The refer request could not locate an appropriate SIP transport channel for protocol " + callURI.Protocol + "."); } SIPRequest referRequest = GetReferRequest(m_localSIPEndPoint,referToUri, sipReplacesCallDescriptor); // Now that we have a destination socket create a new UAC transaction for forwarded leg of the call. m_serverTransaction = m_sipTransport.CreateNonInviteTransaction(referRequest, m_serverEndPoint, m_localSIPEndPoint, m_outboundProxy); m_serverTransaction.NonInviteTransactionFinalResponseReceived += m_serverTransaction_NonInviteTransactionFinalResponseReceived; m_serverTransaction.NonInviteTransactionTimedOut += m_serverTransaction_NonInviteTransactionTimedOut; m_serverTransaction.TransactionTraceMessage += TransactionTraceMessage; m_serverTransaction.SendReliableRequest(); } else { if (RouteSet == null || RouteSet.Length == 0) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Forward leg failed, could not resolve URI host " + callURI.Host, Owner)); FireReferFailed(this, "unresolvable destination " + callURI.Host); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Forward leg failed, could not resolve top Route host " + RouteSet.TopRoute.Host, Owner)); FireReferFailed(this, "unresolvable destination " + RouteSet.TopRoute.Host); } } } catch (ApplicationException appExcp) { FireReferFailed(this, appExcp.Message); } catch (Exception excp) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.Refer, "Exception UserAgentClient Call. " + excp.Message, Owner)); FireReferFailed(this, excp.Message); } }
public void Cancel() { try { m_callCancelled = true; // Cancel server call. if (m_serverTransaction == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Cancelling forwarded call leg " + m_sipCallDescriptor.Uri + ", server transaction has not been created yet no CANCEL request required.", Owner)); } else if (m_cancelTransaction != null) { if (m_cancelTransaction.TransactionState != SIPTransactionStatesEnum.Completed) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Call " + m_serverTransaction.TransactionRequest.URI.ToString() + " has already been cancelled once, trying again.", Owner)); m_cancelTransaction.SendRequest(m_cancelTransaction.TransactionRequest); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Call " + m_serverTransaction.TransactionRequest.URI.ToString() + " has already responded to CANCEL, probably overlap in messages not re-sending.", Owner)); } } else //if (m_serverTransaction.TransactionState == SIPTransactionStatesEnum.Proceeding || m_serverTransaction.TransactionState == SIPTransactionStatesEnum.Trying) { //logger.Debug("Cancelling forwarded call leg, sending CANCEL to " + ForwardedTransaction.TransactionRequest.URI.ToString() + " (transid: " + ForwardedTransaction.TransactionId + ")."); Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Cancelling forwarded call leg, sending CANCEL to " + m_serverTransaction.TransactionRequest.URI.ToString() + ".", Owner)); // No reponse has been received from the server so no CANCEL request neccessary, stop any retransmits of the INVITE. m_serverTransaction.CancelCall(); SIPRequest cancelRequest = GetCancelRequest(m_serverTransaction.TransactionRequest); m_cancelTransaction = m_sipTransport.CreateNonInviteTransaction(cancelRequest, m_serverEndPoint, m_serverTransaction.LocalSIPEndPoint, m_outboundProxy); m_cancelTransaction.TransactionTraceMessage += TransactionTraceMessage; //m_cancelTransaction.SendRequest(m_serverEndPoint, cancelRequest); m_cancelTransaction.SendReliableRequest(); } //else //{ // No reponse has been received from the server so no CANCEL request neccessary, stop any retransmits of the INVITE. // m_serverTransaction.CancelCall(); // Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Cancelling forwarded call leg " + m_sipCallDescriptor.Uri.ToString() + ", no response from server has been received so no CANCEL request required.", Owner)); //} FireCallFailed(this, "Call cancelled by user."); } catch (Exception excp) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Exception CancelServerCall. " + excp.Message, Owner)); } }