/// <summary> /// Initiates the call to the remote user agent server. /// </summary> /// <param name="sipCallDescriptor">The descriptor for the call that describes how to reach the user agent server and other properties.</param> /// <param name="serverEndPoint">Optional. If the server end point for the call is known or has been resolved in advance. If /// not set the SIP transport layer will attempt to resolve the destination at sending time.</param> public SIPRequest Call(SIPCallDescriptor sipCallDescriptor, SIPEndPoint serverEndPoint) { try { m_sipCallDescriptor = sipCallDescriptor; SIPURI callURI = SIPURI.ParseSIPURI(sipCallDescriptor.Uri); SIPRouteSet routeSet = null; logger.LogDebug($"UAC commencing call to {SIPURI.ParseSIPURI(m_sipCallDescriptor.Uri).CanonicalAddress}."); // 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 { logger.LogDebug("Error an outbound proxy value was not recognised in SIPClientUserAgent Call. " + m_sipCallDescriptor.RouteSet + "."); } } string content = sipCallDescriptor.Content; if (content.IsNullOrBlank()) { logger.LogDebug("Body on UAC call was empty."); } if (this.m_sipCallDescriptor.BranchId.IsNullOrBlank()) { this.m_sipCallDescriptor.BranchId = CallProperties.CreateBranchId(); } if (this.m_sipCallDescriptor.CallId.IsNullOrBlank()) { this.m_sipCallDescriptor.CallId = CallProperties.CreateNewCallId(); } SIPRequest inviteRequest = GetInviteRequest(m_sipCallDescriptor, m_sipCallDescriptor.BranchId, m_sipCallDescriptor.CallId, routeSet, content, sipCallDescriptor.ContentType); // Now that we have a destination socket create a new UAC transaction for forwarded leg of the call. m_serverTransaction = new UACInviteTransaction(m_sipTransport, inviteRequest, m_outboundProxy); m_serverTransaction.UACInviteTransactionInformationResponseReceived += ServerInformationResponseReceived; m_serverTransaction.UACInviteTransactionFinalResponseReceived += ServerFinalResponseReceived; m_serverTransaction.UACInviteTransactionFailed += ServerTransactionFailed; m_serverTransaction.SendInviteRequest(); return(inviteRequest); } catch (ApplicationException appExcp) { m_serverTransaction?.CancelCall(appExcp.Message); CallFailed?.Invoke(this, appExcp.Message, null); return(null); } catch (Exception excp) { logger.LogError("Exception UserAgentClient Call. " + excp); m_serverTransaction?.CancelCall("Unknown exception"); CallFailed?.Invoke(this, excp.Message, null); return(null); } }
public void Call(SIPCallDescriptor sipCallDescriptor) { try { m_sipCallDescriptor = sipCallDescriptor; SIPURI callURI = SIPURI.ParseSIPURI(sipCallDescriptor.Uri); SIPRouteSet routeSet = null; if (!m_callCancelled) { // 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 (!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(sipCallDescriptor.ProxySendFrom); m_outboundProxy = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(outboundProxyEndPoint.Address, m_defaultSIPPort)); m_serverEndPoint = m_outboundProxy; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "SIPClientUserAgent Call 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.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Error an outbound proxy value was not recognised in SIPClientUserAgent Call. " + 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.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Attempting to resolve " + callURI.Host + ".", Owner)); lookupResult = m_sipTransport.GetURIEndPoint(callURI, false); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Route set for call " + routeSet.ToString() + ".", Owner)); lookupResult = m_sipTransport.GetURIEndPoint(routeSet.TopRoute.URI, false); } if (lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "DNS error resolving " + callURI.Host + ", " + lookupResult.LookupError + ". Call cannot proceed.", Owner)); } else { m_serverEndPoint = lookupResult.GetSIPEndPoint(); } } if (m_callCancelled) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Call was cancelled during DNS resolution of " + callURI.Host, Owner)); FireCallFailed(this, "Cancelled by caller"); } else if (m_serverEndPoint != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "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 call could not locate an appropriate SIP transport channel for protocol " + callURI.Protocol + "."); } string content = sipCallDescriptor.Content; if (content.IsNullOrBlank()) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Body on UAC call was empty.", Owner)); } else if (m_sipCallDescriptor.ContentType == m_sdpContentType) { if (!m_sipCallDescriptor.MangleResponseSDP) { IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(content); if (sdpEndPoint != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC call was set to NOT mangle, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC call was set to NOT mangle, RTP socket could not be determined.", Owner)); } } else { IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(content); if (sdpEndPoint != null) { if (!IPSocket.IsPrivateAddress(sdpEndPoint.Address.ToString())) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC call had public IP not mangled, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } else { bool wasSDPMangled = false; if (sipCallDescriptor.MangleIPAddress != null) { if (sdpEndPoint != null) { content = SIPPacketMangler.MangleSDP(content, sipCallDescriptor.MangleIPAddress.ToString(), out wasSDPMangled); } } if (wasSDPMangled) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC call had RTP socket mangled from " + sdpEndPoint.ToString() + " to " + sipCallDescriptor.MangleIPAddress.ToString() + ":" + sdpEndPoint.Port + ".", Owner)); } else if (sdpEndPoint != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC could not be mangled, using original RTP socket of " + sdpEndPoint.ToString() + ".", Owner)); } } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP RTP socket on UAC call could not be determined.", Owner)); } } } SIPRequest switchServerInvite = GetInviteRequest(m_sipCallDescriptor, CallProperties.CreateBranchId(), CallProperties.CreateNewCallId(), m_localSIPEndPoint, routeSet, content, sipCallDescriptor.ContentType); // Now that we have a destination socket create a new UAC transaction for forwarded leg of the call. m_serverTransaction = m_sipTransport.CreateUACTransaction(switchServerInvite, m_serverEndPoint, m_localSIPEndPoint, m_outboundProxy); m_serverTransaction.CDR.DialPlanContextID = m_sipCallDescriptor.DialPlanContextID; #region Real-time call control processing. string rtccError = null; if (m_serverTransaction.CDR != null) { m_serverTransaction.CDR.Owner = Owner; m_serverTransaction.CDR.AdminMemberId = AdminMemberId; m_serverTransaction.CDR.Updated(); #if !SILVERLIGHT if (m_sipCallDescriptor.AccountCode != null && RtccGetCustomer_External != null) { //var customerAccount = m_customerAccountDataLayer.CheckAccountCode(Owner, m_sipCallDescriptor.AccountCode); var customerAccount = RtccGetCustomer_External(Owner, m_sipCallDescriptor.AccountCode); if (customerAccount == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A billable call could not proceed as no account exists for account code or number " + m_sipCallDescriptor.AccountCode + ".", Owner)); rtccLogger.Debug("A billable call could not proceed as no account exists for account code or number " + m_sipCallDescriptor.AccountCode + " and owner " + Owner + "."); rtccError = "Real-time call control invalid account code"; } else { AccountCode = customerAccount.AccountCode; string rateDestination = m_sipCallDescriptor.Uri; if (SIPURI.TryParse(m_sipCallDescriptor.Uri)) { rateDestination = SIPURI.ParseSIPURIRelaxed(m_sipCallDescriptor.Uri).User; } //var rate = m_customerAccountDataLayer.GetRate(Owner, m_sipCallDescriptor.RateCode, rateDestination, customerAccount.RatePlan); var rate = RtccGetRate_External(Owner, m_sipCallDescriptor.RateCode, rateDestination, customerAccount.RatePlan); if (rate == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A billable call could not proceed as no rate could be determined for destination " + rateDestination + ".", Owner)); rtccLogger.Debug("A billable call could not proceed as no rate could be determined for destination " + rateDestination + " and owner " + Owner + "."); rtccError = "Real-time call control no rate"; } else { Rate = rate.RatePerIncrement; if (rate.RatePerIncrement == 0 && rate.SetupCost == 0) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "The rate and setup cost for the " + rateDestination + "were both zero. The call will be allowed to proceed with no RTCC reservation.", Owner)); } else { //decimal balance = m_customerAccountDataLayer.GetBalance(AccountCode); decimal balance = RtccGetBalance_External(AccountCode); if (balance < Rate) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A billable call could not proceed as the available credit for " + AccountCode + " was not sufficient for 60 seconds to destination " + rateDestination + ".", Owner)); rtccLogger.Debug("A billable call could not proceed as the available credit for " + AccountCode + " was not sufficient for 60 seconds to destination " + rateDestination + " and owner " + Owner + "."); rtccError = "Real-time call control insufficient credit"; } else { int intialSeconds = 0; //var reservationCost = m_customerAccountDataLayer.ReserveInitialCredit(AccountCode, rate, m_serverTransaction.CDR, out intialSeconds); var reservationCost = RtccReserveInitialCredit_External(AccountCode, rate.ID, m_serverTransaction.CDR, out intialSeconds); if (reservationCost == Decimal.MinusOne) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call will not proceed as the intial real-time call control credit reservation failed.", Owner)); rtccLogger.Debug("Call will not proceed as the intial real-time call control credit reservation failed for owner " + Owner + "."); rtccError = "Real-time call control initial reservation failed"; } else { ReservedCredit = reservationCost; ReservedSeconds = intialSeconds; } } } } } } #endif } #endregion if (rtccError == null) { m_serverTransaction.UACInviteTransactionInformationResponseReceived += ServerInformationResponseReceived; m_serverTransaction.UACInviteTransactionFinalResponseReceived += ServerFinalResponseReceived; m_serverTransaction.UACInviteTransactionTimedOut += ServerTimedOut; m_serverTransaction.TransactionTraceMessage += TransactionTraceMessage; m_serverTransaction.SendInviteRequest(m_serverEndPoint, m_serverTransaction.TransactionRequest); } else { m_serverTransaction.CancelCall(rtccError); FireCallFailed(this, rtccError); } } else { if (routeSet == null || routeSet.Length == 0) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Forward leg failed, could not resolve URI host " + callURI.Host, Owner)); m_serverTransaction?.CancelCall("Unresolvable destination " + callURI.Host); FireCallFailed(this, "unresolvable destination " + callURI.Host); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Forward leg failed, could not resolve top Route host " + routeSet.TopRoute.Host, Owner)); m_serverTransaction?.CancelCall("Unresolvable destination " + routeSet.TopRoute.Host); FireCallFailed(this, "unresolvable destination " + routeSet.TopRoute.Host); } } } } catch (ApplicationException appExcp) { m_serverTransaction?.CancelCall(appExcp.Message); FireCallFailed(this, appExcp.Message); } catch (Exception excp) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Exception UserAgentClient Call. " + excp.Message, Owner)); m_serverTransaction?.CancelCall("Unknown exception"); FireCallFailed(this, excp.Message); } }
/// <summary> /// Gets the destination of the remote SIP end point for this call. /// </summary> /// <param name="sipCallDescriptor">The call descriptor containing the settings to use to place the call.</param> /// <returns>The server end point for the call.</returns> public async Task <SIPEndPoint> GetCallDestination(SIPCallDescriptor sipCallDescriptor) { SIPURI callURI = SIPURI.ParseSIPURI(sipCallDescriptor.Uri); SIPEndPoint serverEndPoint = null; // 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)) { serverEndPoint = m_outboundProxy; } else if (!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(sipCallDescriptor.ProxySendFrom); //m_outboundProxy = new SIPEndPoint(SIPProtocolsEnum.udp, outboundProxyEndPoint.Address, SIPConstants.DEFAULT_SIP_PORT); //m_serverEndPoint = m_outboundProxy; m_outboundProxy = SIPEndPoint.ParseSIPEndPoint(sipCallDescriptor.ProxySendFrom); serverEndPoint = m_outboundProxy; logger.LogDebug($"SIPClientUserAgent Call using alternate outbound proxy of {serverEndPoint}."); } else if (m_outboundProxy != null) { // Using the system outbound proxy only, no additional user routing requirements. serverEndPoint = m_outboundProxy; } // No outbound proxy, determine the forward destination based on the SIP request. if (serverEndPoint == null) { //SIPDNSLookupResult lookupResult = null; SIPEndPoint lookupResult = null; double lookupDurationMilliseconds = 0; if (sipCallDescriptor.RouteSet != null && sipCallDescriptor.RouteSet.IndexOf(OUTBOUNDPROXY_AS_ROUTESET_CHAR) != -1) { var routeSet = new SIPRouteSet(); routeSet.PushRoute(new SIPRoute(sipCallDescriptor.RouteSet, true)); logger.LogDebug("Route set for call " + routeSet.ToString() + "."); //lookupResult = m_sipTransport.GetURIEndPoint(routeSet.TopRoute.URI, false); lookupResult = await m_sipTransport.ResolveSIPUriAsync(routeSet.TopRoute.URI).ConfigureAwait(false); } else { logger.LogDebug("SIPClientUserAgent attempting to resolve " + callURI.Host + "."); //lookupResult = m_sipTransport.GetURIEndPoint(callURI, false); DateTime lookupStartedAt = DateTime.Now; lookupResult = await m_sipTransport.ResolveSIPUriAsync(callURI).ConfigureAwait(false); lookupDurationMilliseconds = DateTime.Now.Subtract(lookupStartedAt).TotalMilliseconds; } if (lookupResult == null) { logger.LogDebug($"SIPClientUserAgent DNS failure resolving {callURI.Host} in {lookupDurationMilliseconds:0.##}ms. Call cannot proceed."); } else { logger.LogDebug($"SIPClientUserAgent resolved {callURI.Host} to {lookupResult} in {lookupDurationMilliseconds:0.##}ms."); serverEndPoint = lookupResult; } } return(serverEndPoint); }
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); } }