/// <summary> /// Attempts to place a new outgoing call. /// </summary> /// <param name="sipCallDescriptor">A call descriptor containing the information about how /// and where to place the call.</param> /// <param name="mediaSession">The media session used for this call</param> public async Task InitiateCall(SIPCallDescriptor sipCallDescriptor, IMediaSession mediaSession) { m_uac = new SIPClientUserAgent(m_transport); m_uac.CallTrying += ClientCallTryingHandler; m_uac.CallRinging += ClientCallRingingHandler; m_uac.CallAnswered += ClientCallAnsweredHandler; m_uac.CallFailed += ClientCallFailedHandler; SIPEndPoint serverEndPoint = m_uac.GetCallDestination(sipCallDescriptor); if (serverEndPoint != null) { MediaSession = mediaSession; MediaSession.SessionMediaChanged += MediaSessionOnSessionMediaChanged; var sdp = await MediaSession.CreateOffer(serverEndPoint.Address).ConfigureAwait(false); sipCallDescriptor.Content = sdp; m_uac.Call(sipCallDescriptor); } else { ClientCallFailed?.Invoke(m_uac, $"Could not resolve destination when placing call to {sipCallDescriptor.Uri}."); CallEnded(); } }
/// <summary> /// Attempts to place a new outgoing call. /// </summary> /// <param name="sipCallDescriptor">A call descriptor containing the information about how and where to place the call.</param> public void Call(SIPCallDescriptor sipCallDescriptor) { m_uac = new SIPClientUserAgent(m_transport); m_uac.CallTrying += ClientCallTryingHandler; m_uac.CallRinging += ClientCallRingingHandler; m_uac.CallAnswered += ClientCallAnsweredHandler; m_uac.CallFailed += ClientCallFailedHandler; m_uac.Call(sipCallDescriptor); }
/// <summary> /// Attempts to place a new outgoing call. /// </summary> /// <param name="sipCallDescriptor">A call descriptor containing the information about how /// and where to place the call.</param> /// <param name="mediaSession">The media session used for this call</param> public async Task InitiateCallAsync(SIPCallDescriptor sipCallDescriptor, IMediaSession mediaSession) { m_cts = new CancellationTokenSource(); m_uac = new SIPClientUserAgent(m_transport); m_uac.CallTrying += ClientCallTryingHandler; m_uac.CallRinging += ClientCallRingingHandler; m_uac.CallAnswered += ClientCallAnsweredHandler; m_uac.CallFailed += ClientCallFailedHandler; // Can be DNS lookups involved in getting the call destination. SIPEndPoint serverEndPoint = await Task.Run <SIPEndPoint>(() => { return(m_uac.GetCallDestination(sipCallDescriptor)); }).ConfigureAwait(false); if (serverEndPoint != null) { MediaSession = mediaSession; MediaSession.OnRtpEvent += OnRemoteRtpEvent; //MediaSession.OnRtpClosed += (reason) => Hangup(); MediaSession.OnRtpClosed += (reason) => { if (!MediaSession.IsClosed) { logger.LogWarning($"RTP channel was closed with reason {reason}."); } }; RTCOfferOptions offerOptions = new RTCOfferOptions { RemoteSignallingAddress = serverEndPoint.Address }; var sdp = await mediaSession.createOffer(offerOptions).ConfigureAwait(false); mediaSession.setLocalDescription(new RTCSessionDescription { sdp = sdp, type = RTCSdpType.offer }); if (mediaSession.localDescription == null) { ClientCallFailed?.Invoke(m_uac, $"Could not create a local SDP offer."); CallEnded(); } else { sipCallDescriptor.Content = mediaSession.localDescription.sdp.ToString(); // This initiates the call but does not wait for an answer. m_uac.Call(sipCallDescriptor); } } else { ClientCallFailed?.Invoke(m_uac, $"Could not resolve destination when placing call to {sipCallDescriptor.Uri}."); CallEnded(); } }
public SIPRequest Call(SIPCallDescriptor sipCallDescriptor, SIPEndPoint serverEndPoint) { m_uacCallDescriptor = sipCallDescriptor; m_uac = new SIPClientUserAgent(m_sipTransport, m_outboundProxy); m_uac.CallFailed += ClientCallFailed; m_uac.CallTrying += (uac, resp) => CallTrying?.Invoke(uac, resp); m_uac.CallRinging += (uac, resp) => CallRinging?.Invoke(uac, resp); m_uac.CallAnswered += ClientCallAnswered; return(m_uac.Call(m_uacCallDescriptor)); }
/// <summary> /// The current call has ended. Reset the state of the user agent. /// </summary> private void CallEnded() { m_uac = null; m_uas = null; if (MediaSession != null && !MediaSession.IsClosed) { MediaSession.Close("normal"); MediaSession = null; } OnCallHungup?.Invoke(); }
/// <summary> /// The current call has ended. Reset the state of the user agent. /// </summary> private void CallEnded() { m_uac = null; m_uas = null; if (MediaSession != null) { MediaSession.SessionMediaChanged -= MediaSessionOnSessionMediaChanged; MediaSession.Close(); MediaSession = null; } OnCallHungup?.Invoke(); }
/// <summary> /// Attempts to place a new outgoing call. /// </summary> /// <param name="sipCallDescriptor">A call descriptor containing the information about how /// and where to place the call.</param> /// <param name="mediaSession">The media session used for this call</param> public async Task InitiateCallAsync(SIPCallDescriptor sipCallDescriptor, IMediaSession mediaSession) { m_cts = new CancellationTokenSource(); m_uac = new SIPClientUserAgent(m_transport); m_uac.CallTrying += ClientCallTryingHandler; m_uac.CallRinging += ClientCallRingingHandler; m_uac.CallAnswered += ClientCallAnsweredHandler; m_uac.CallFailed += ClientCallFailedHandler; // Can be DNS lookups involved in getting the call destination. SIPEndPoint serverEndPoint = await Task.Run <SIPEndPoint>(() => { return(m_uac.GetCallDestination(sipCallDescriptor)); }).ConfigureAwait(false); if (serverEndPoint != null) { MediaSession = mediaSession; MediaSession.OnRtpEvent += OnRemoteRtpEvent; //MediaSession.OnRtpClosed += (reason) => Hangup(); MediaSession.OnRtpClosed += (reason) => { if (!MediaSession.IsClosed) { logger.LogWarning($"RTP channel was closed with reason {reason}."); } }; var sdpAnnounceAddress = NetServices.GetLocalAddressForRemote(serverEndPoint.Address); var sdp = mediaSession.CreateOffer(sdpAnnounceAddress); if (sdp == null) { ClientCallFailed?.Invoke(m_uac, $"Could not generate an offer.", null); CallEnded(); } else { sipCallDescriptor.Content = sdp.ToString(); // This initiates the call but does not wait for an answer. m_uac.Call(sipCallDescriptor); } } else { ClientCallFailed?.Invoke(m_uac, $"Could not resolve destination when placing call to {sipCallDescriptor.Uri}.", null); CallEnded(); } }
public override void Start() { try { base.Start(); m_activeAppServerEntry = GetActiveAppServer(); if (m_activeAppServerEntry != null) { while (!m_stop) { Thread.Sleep(Convert.ToInt32(m_interval.TotalMilliseconds % Int32.MaxValue)); logger.Debug("AppServerDispatcher executing."); m_startCheckTime.Reset(); m_startCheckTime.Start(); SIPClientUserAgent uac = new SIPClientUserAgent(m_sipTransport, null, null, null, LogMonitorEvent); SIPCallDescriptor callDescriptor = new SIPCallDescriptor(null, null, m_activeAppServerEntry.AppServerURI.ToString(), null, null, null, null, null, SIPCallDirection.Out, null, null, null); callDescriptor.MangleResponseSDP = false; uac.CallFailed += CallFailed; uac.CallAnswered += CallAnswered; uac.Call(callDescriptor); uac.ServerTransaction.CDR = null; } } else { logger.Warn("No active app server could be set in AppServerDispatcher.Start, job stopping."); } } catch (Exception excp) { logger.Error("Exception AppServerDispatcher StartJob. " + excp.Message); } }
private void FireCallTrying(SIPClientUserAgent uac, SIPResponse tryingResponse) { if (CallTrying != null) { CallTrying(uac, tryingResponse); } }
/// <summary> /// Handler for when an in dialog request is received on an established call. /// Typical types of request will be re-INVITES for things like putting a call on or /// off hold and REFER requests for transfers. Some in dialog request types, such /// as re-INVITES have specific events so they can be bubbled up to the /// application to deal with. /// </summary> /// <param name="request">The in dialog request received.</param> public async Task InDialogRequestReceivedAsync(SIPRequest sipRequest) { // Make sure the request matches our dialog and is not a stray. // A dialog request should match on to tag, from tag and call ID. We'll be more // accepting just in case the sender got the tags wrong. if (Dialogue == null || sipRequest.Header.CallId != Dialogue.CallId) { var noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); var sendResult = await SendResponse(noCallLegResponse); if (sendResult != SocketError.Success) { logger.LogWarning($"SIPUserAgent send response failed in InCallRequestReceivedAsync with {sendResult}."); } } else { if (sipRequest.Method == SIPMethodsEnum.BYE) { logger.LogDebug($"Matching dialogue found for {sipRequest.StatusLine}."); SIPNonInviteTransaction byeTransaction = m_transport.CreateNonInviteTransaction(sipRequest, m_outboundProxy); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); CallHungup?.Invoke(); m_uac = null; m_uas = null; } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { logger.LogDebug($"Re-INVITE request received {sipRequest.StatusLine}."); UASInviteTransaction reInviteTransaction = m_transport.CreateUASTransaction(sipRequest, m_outboundProxy); if (OnReinviteRequest == null) { // The application isn't prepared to accept re-INVITE requests. We'll reject as gently as we can to try and not lose the call. SIPResponse notAcceptableResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotAcceptable, null); reInviteTransaction.SendFinalResponse(notAcceptableResponse); } else { SIPResponse tryingResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null); reInviteTransaction.SendProvisionalResponse(tryingResponse); OnReinviteRequest(reInviteTransaction); } } else if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { //Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "OPTIONS request for established dialogue " + dialogue.DialogueName + ".", dialogue.Owner)); SIPNonInviteTransaction optionsTransaction = m_transport.CreateNonInviteTransaction(sipRequest, m_outboundProxy); SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Body = Dialogue.RemoteSDP; okResponse.Header.ContentLength = okResponse.Body.Length; okResponse.Header.ContentType = m_sdpContentType; optionsTransaction.SendFinalResponse(okResponse); } else if (sipRequest.Method == SIPMethodsEnum.MESSAGE) { //Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "MESSAGE for call " + sipRequest.URI.ToString() + ": " + sipRequest.Body + ".", dialogue.Owner)); SIPNonInviteTransaction messageTransaction = m_transport.CreateNonInviteTransaction(sipRequest, m_outboundProxy); SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); messageTransaction.SendFinalResponse(okResponse); } else if (sipRequest.Method == SIPMethodsEnum.REFER) { //Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "REFER received on dialogue " + dialogue.DialogueName + ", transfer mode is " + dialogue.TransferMode + ".", dialogue.Owner)); SIPNonInviteTransaction referTransaction = m_transport.CreateNonInviteTransaction(sipRequest, m_outboundProxy); if (sipRequest.Header.ReferTo.IsNullOrBlank()) { // A REFER request must have a Refer-To header. //Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Bad REFER request, no Refer-To header.", dialogue.Owner)); SIPResponse invalidResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing mandatory Refer-To header"); referTransaction.SendFinalResponse(invalidResponse); } else { //TODO: Add handling logic for indialog REFER requests. } } } }
private void FireCallFailed(SIPClientUserAgent uac, string errorMessage) { if (CallFailed != null) { CallFailed(uac, errorMessage); } }
private void FireCallRinging(SIPClientUserAgent uac, SIPResponse ringingResponse) { if (CallRinging != null) { CallRinging(uac, ringingResponse); } }
private void ProbeWorkers() { try { while (!m_exit) { Thread.Sleep(PROBE_WORKER_CALL_PERIOD); try { SIPEndPoint activeWorkerEndPoint = GetFirstHealthyEndPoint(); if (activeWorkerEndPoint != null) { SIPCallDescriptor callDescriptor = new SIPCallDescriptor(m_dispatcherUsername, null, "sip:" + m_dispatcherUsername + "@" + activeWorkerEndPoint.GetIPEndPoint().ToString(), "sip:" + m_dispatcherUsername + "@sipcalldispatcher", "sip:" + activeWorkerEndPoint.GetIPEndPoint().ToString(), null, null, null, SIPCallDirection.Out, null, null, null); SIPClientUserAgent uac = new SIPClientUserAgent(m_sipTransport, null, null, null, null); uac.CallFailed += new SIPCallFailedDelegate(AppServerCallFailed); uac.CallAnswered += (call, sipResponse) => { if (sipResponse.Status != SIPResponseStatusCodesEnum.BadExtension) { logger.Warn("Probe call answered with unexpected response code of " + sipResponse.StatusCode + "."); AppServerCallFailed(call, "Unexpected response of " + ((int)sipResponse.StatusCode) + " on probe call."); } }; uac.Call(callDescriptor); } else { logger.Warn("SIPAppServerManager was not able to find a healthy app server endpoint."); } } catch (Exception probeExcp) { logger.Error("Exception SIPAppServerManager Sending Probe. " + probeExcp.Message); } } } catch (Exception excp) { logger.Error("Exception SIPAppServerManager ProberWorkers. " + excp.Message); } }
private void PlaceCall(object state) { string callURI = (string)state; /*m_dnsLookupComplete.Reset(); ThreadPool.QueueUserWorkItem(new WaitCallback(DNSLookup), callURI); if (!m_dnsLookupComplete.WaitOne(DNS_LOOKUP_TIMEOUT)) { AppendTraceMessage("DNS lookup for " + callURI + " timed out.\n"); ResetToCallStartState(); } else {*/ AppendTraceMessage("Starting call to " + callURI + ".\n"); m_uac = new SIPClientUserAgent(m_sipTransport, null, null, null, LogTraceMessage); m_uac.CallTrying += CallTrying; m_uac.CallRinging += CallRinging; m_uac.CallAnswered += CallAnswered; m_uac.CallFailed += CallFailed; SIPCallDescriptor callDescriptor = new SIPCallDescriptor("anonymous", null, callURI, null, null, null, null, null, SIPCallDirection.Out, null, null, null); m_uac.Call(callDescriptor); //} }
/// <summary> /// Sends the SIP INVITE probe request. /// </summary> public void SendProbe() { try { if (WorkerProcess == null) { logger.Debug("When attempting to send probe the worker process was null. Marking for immediate restart."); NeedsImmediateRestart = true; } else if (WorkerProcess.HasExited) { logger.Debug("When attempting to send probe the worker had exited. Marking for immediate restart."); NeedsImmediateRestart = true; } else if (m_probeUAC != null && !m_probeUAC.IsUACAnswered) { // A probe call has timed out. m_probeUAC.Cancel(); m_missedProbes++; if (m_missedProbes >= m_missedProbesLimit) { logger.Warn(m_missedProbes + " probes missed for " + AppServerEndpoint.ToString() + ". Marking for immediate restart."); NeedsImmediateRestart = true; } } if(!NeedsImmediateRestart && !NeedsToRestart) { m_probeCount++; //logger.Debug("Sending probe " + m_probeCount + " to " + AppServerEndpoint.GetIPEndPoint().ToString() + "."); DateTime probeSentAt = DateTime.Now; SIPCallDescriptor callDescriptor = new SIPCallDescriptor(m_dispatcherUsername, null, "sip:" + m_dispatcherUsername + "@" + AppServerEndpoint.GetIPEndPoint().ToString(), "sip:" + m_dispatcherUsername + "@sipcalldispatcher", "sip:" + AppServerEndpoint.GetIPEndPoint().ToString(), null, null, null, SIPCallDirection.Out, null, null, null); m_probeUAC = new SIPClientUserAgent(m_sipTransport, null, null, null, null); m_probeUAC.CallAnswered += (call, sipResponse) => { //logger.Debug("Probe response received for " + AppServerEndpoint.ToString() + "."); if (sipResponse.Status != SIPResponseStatusCodesEnum.BadExtension) //if (sipResponse.Status != SIPResponseStatusCodesEnum.InternalServerError) { logger.Warn("Probe to " + AppServerEndpoint.ToString() + " answered incorrectly on probe number " + m_probeCount + " after " + DateTime.Now.Subtract(probeSentAt).TotalSeconds.ToString("0.##") + "s, unexpected response of " + ((int)sipResponse.StatusCode) + "."); NeedsImmediateRestart = true; } else { m_gotInitialProbeResponse = true; } if (m_initialResponseMRE != null) { m_initialResponseMRE.Set(); } }; m_probeUAC.Call(callDescriptor); } } catch (Exception excp) { logger.Error("Exception SendProbe. " + excp.Message); } }
/// <summary> /// Places an outgoing SIP call. /// </summary> /// <param name="destination">The SIP URI to place a call to. The destination can be a full SIP URI in which case the all will /// be placed anonymously directly to that URI. Alternatively it can be just the user portion of a URI in which case it will /// be sent to the configured SIP server.</param> public void Call(MediaManager mediaManager, string destination) { _mediaManager = mediaManager; _mediaManager.NewCall(); // Determine if this is a direct anonymous call or whether it should be placed using the pre-configured SIP server account. SIPURI callURI = null; string sipUsername = null; string sipPassword = null; string fromHeader = null; if (destination.Contains("@") || m_sipServer == null) { // Anonymous call direct to SIP server specified in the URI. callURI = SIPURI.ParseSIPURIRelaxed(destination); } else { // This call will use the pre-configured SIP account. callURI = SIPURI.ParseSIPURIRelaxed(destination + "@" + m_sipServer); sipUsername = m_sipUsername; sipPassword = m_sipPassword; fromHeader = (new SIPFromHeader(m_sipFromName, new SIPURI(m_sipUsername, m_sipServer, null), null)).ToString(); } StatusMessage("Starting call to " + callURI.ToString() + "."); m_uac = new SIPClientUserAgent(m_sipTransport, null, null, null, null); m_uac.CallTrying += CallTrying; m_uac.CallRinging += CallRinging; m_uac.CallAnswered += CallAnswered; m_uac.CallFailed += CallFailed; // Get the SDP requesting that the public IP address be used if the host on the call destination is not a private IP address. SDP sdp = _mediaManager.GetSDP(!(IPSocket.IsIPAddress(callURI.Host) && IPSocket.IsPrivateAddress(callURI.Host))); System.Diagnostics.Debug.WriteLine(sdp.ToString()); SIPCallDescriptor callDescriptor = new SIPCallDescriptor(sipUsername, sipPassword, callURI.ToString(), fromHeader, null, null, null, null, SIPCallDirection.Out, _sdpMimeContentType, sdp.ToString(), null); m_uac.Call(callDescriptor); }
/// <summary> /// Sends the SIP INVITE probe request. /// </summary> private void ProbeWorker(SIPAppServerWorker worker, bool isInitialProbe) { try { if (isInitialProbe) { worker.InitialProbeCount++; } int workerProcessID = worker.WorkerProcess.Id; SIPEndPoint workerEndPoint = worker.AppServerEndpoint; DateTime probeSentAt = DateTime.Now; SIPCallDescriptor callDescriptor = new SIPCallDescriptor(m_dispatcherUsername, null, "sip:" + m_dispatcherUsername + "@" + workerEndPoint.GetIPEndPoint().ToString(), "sip:" + m_dispatcherUsername + "@sipcalldispatcher", "sip:" + workerEndPoint.GetIPEndPoint().ToString(), null, null, null, SIPCallDirection.Out, null, null, null); SIPClientUserAgent uac = new SIPClientUserAgent(m_sipTransport, null, null, null, null); uac.CallFailed += (failedUAC, errorMessage) => { AppServerCallFailed(failedUAC, errorMessage, workerProcessID, probeSentAt, isInitialProbe); }; uac.CallAnswered += (call, sipResponse) => { if (sipResponse.Status != SIPResponseStatusCodesEnum.BadExtension) { //logger.Warn("Probe call answered with unexpected response code of " + sipResponse.StatusCode + "."); AppServerCallFailed(call, "Unexpected response of " + ((int)sipResponse.StatusCode) + " on probe call.", workerProcessID, probeSentAt, isInitialProbe); } else { AppServerCallSucceeded(call); } }; uac.Call(callDescriptor); } catch (Exception excp) { logger.Error("Exception SIPAppServerManager ProberWorker. " + excp.Message); } }
/// <summary> /// Cleans up after a SIP call has completely finished. /// </summary> private void CallFinished() { if (_mediaManager != null) { _mediaManager.EndCall(); _mediaManager = null; } m_uac = null; m_uas = null; CallEnded(); }
//private SIPDNSLookupResult ResolveSIPEndPoint(SIPURI uri, bool async) //{ // logger.Debug("Resolving SIP URI " + uri.ToParameterlessString() + "."); // return null; //} /// <summary> /// Places an outgoing SIP call. /// </summary> /// <param name="destination">The SIP URI to place a call to. The destination can be a full SIP URI in which case the all will /// be placed anonymously directly to that URI. Alternatively it can be just the user portion of a URI in which case it will /// be sent to the configured SIP server.</param> public void Call(string destination, IPEndPoint rtpEndPoint, string sipUsername, string sipPassword, string realm) { // Determine if this is a direct anonymous call or whether it should be placed using the pre-configured SIP server account. SIPURI callURI = null; //string sipUsername = null; //string sipPassword = null; string fromHeader = null; //if (destination.Contains("@") || m_sipServer == null) //{ // Anonymous call direct to SIP server specified in the URI. callURI = SIPURI.ParseSIPURIRelaxed(destination); //} //else //{ // // This call will use the pre-configured SIP account. // callURI = SIPURI.ParseSIPURIRelaxed(destination + "@" + m_sipServer); // sipUsername = m_sipUsername; // sipPassword = m_sipPassword; fromHeader = (new SIPFromHeader(sipUsername, new SIPURI(sipUsername, realm, null), null)).ToString(); //} StatusMessage("Starting call to " + callURI.ToString() + "."); m_uac = new SIPClientUserAgent(m_sipTransport, null, null, null, null); m_uac.CallTrying += CallTrying; m_uac.CallRinging += CallRinging; m_uac.CallAnswered += CallAnswered; m_uac.CallFailed += CallFailed; _audioChannel = new AudioChannel(rtpEndPoint); // Get the SDP requesting that the public IP address be used if the host on the call destination is not a private IP address. SDP sdp = _audioChannel.GetSDP(); SIPCallDescriptor callDescriptor = new SIPCallDescriptor(sipUsername, sipPassword, callURI.ToString(), fromHeader, null, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null); m_uac.Call(callDescriptor); }
private void ProbeWorkers() { try { while (!m_exit) { try { SIPEndPoint activeWorkerEndPoint = GetFirstHealthyEndPoint(); SIPCallDescriptor callDescriptor = new SIPCallDescriptor(m_dispatcherUsername, null, "sip:" + m_dispatcherUsername + "@" + activeWorkerEndPoint.SocketEndPoint.ToString(), "sip:" + m_dispatcherUsername + "@sipcalldispatcher", "sip:" + activeWorkerEndPoint.SocketEndPoint.ToString(), null, null, null, SIPCallDirection.Out, null, null, null); SIPClientUserAgent uac = new SIPClientUserAgent(m_sipTransport, null, null, null, null); uac.CallAnswered += DispatcherCallAnswered; uac.CallFailed += new SIPCallFailedDelegate(DispatcherCallFailed); uac.Call(callDescriptor); } catch (Exception probeExcp) { dispatcherLogger.Error("Exception SIPCallDispatcher Sending Probe. " + probeExcp.Message); } Thread.Sleep(PROBE_WORKER_CALL_PERIOD); } } catch (Exception excp) { logger.Error("Exception SIPCallDispatcher ProberWorkers. " + excp.Message); } }
private void StartNewCallSync(SIPCallDescriptor callDescriptor) { try { // A call will not be delayed if there are no other calls being attempted. if (callDescriptor.DelaySeconds != 0 && m_switchCalls.Count > 0) { callDescriptor.DelayMRE = new ManualResetEvent(false); lock (m_delayedCalls) { m_delayedCalls.Add(callDescriptor); } int delaySeconds = (callDescriptor.DelaySeconds > MAX_DELAY_SECONDS) ? MAX_DELAY_SECONDS : callDescriptor.DelaySeconds; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Delaying call leg to " + callDescriptor.Uri + " by " + delaySeconds + "s.", m_username)); callDescriptor.DelayMRE.WaitOne(delaySeconds * 1000); } lock (m_delayedCalls) { m_delayedCalls.Remove(callDescriptor); } if (!m_callAnswered && !m_commandCancelled) { ISIPClientUserAgent uacCall = null; if (callDescriptor.ToSIPAccount == null) { if (callDescriptor.IsGoogleVoiceCall) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Creating Google Voice user agent for " + callDescriptor.Uri + ".", m_username)); uacCall = new GoogleVoiceUserAgent(m_sipTransport, m_callManager, m_statefulProxyLogEvent, m_username, m_adminMemberId, m_outboundProxySocket); } else { uacCall = new SIPClientUserAgent(m_sipTransport, m_outboundProxySocket, m_username, m_adminMemberId, m_statefulProxyLogEvent); } } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Creating B2B call for " + callDescriptor.Uri + ".", m_username)); uacCall = new SIPB2BUserAgent(m_statefulProxyLogEvent, QueueNewCall_External, m_sipTransport, m_username, m_adminMemberId); } //ISIPClientUserAgent uacCall = new JingleUserAgent(m_username, m_adminMemberId, m_statefulProxyLogEvent); lock (m_switchCalls) { m_switchCalls.Add(uacCall); } uacCall.CallAnswered += UACCallAnswered; uacCall.CallFailed += UACCallFailed; uacCall.CallRinging += UACCallProgress; //uacCall.CallTrying += UACCallTrying; uacCall.Call(callDescriptor); } } catch (Exception excp) { logger.Error("Exception ForkCall StartNewCall. " + excp.Message); } }
private void StartNewCallSync(SIPCallDescriptor callDescriptor) { try { callDescriptor.DialPlanContextID = (m_dialPlanContext != null) ? m_dialPlanContext.DialPlanContextID : Guid.Empty; if (callDescriptor.DelaySeconds != 0) { callDescriptor.DelayMRE = new ManualResetEvent(false); lock (m_delayedCalls) { m_delayedCalls.Add(callDescriptor); } int delaySeconds = (callDescriptor.DelaySeconds > MAX_DELAY_SECONDS) ? MAX_DELAY_SECONDS : callDescriptor.DelaySeconds; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Delaying call leg to " + callDescriptor.Uri + " by " + delaySeconds + "s.", m_username)); callDescriptor.DelayMRE.WaitOne(delaySeconds * 1000); } lock (m_delayedCalls) { m_delayedCalls.Remove(callDescriptor); } if (!m_callAnswered && !m_commandCancelled) { ISIPClientUserAgent uacCall = null; if (callDescriptor.ToSIPAccount == null) { if (callDescriptor.IsGoogleVoiceCall) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Creating Google Voice user agent for " + callDescriptor.Uri + ".", m_username)); uacCall = new GoogleVoiceUserAgent(m_sipTransport, m_callManager, m_statefulProxyLogEvent, m_username, m_adminMemberId, m_outboundProxySocket); } else { uacCall = new SIPClientUserAgent(m_sipTransport, m_outboundProxySocket, m_username, m_adminMemberId, m_statefulProxyLogEvent, m_customerAccountDataLayer.GetRtccCustomer, m_customerAccountDataLayer.GetRtccRate, m_customerAccountDataLayer.GetBalance, m_customerAccountDataLayer.ReserveInitialCredit, m_customerAccountDataLayer.UpdateRealTimeCallControlCDRID); } } else { if (QueueNewCall_External == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "B2B calls are not supported in this dialplan manifestation.", m_username)); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Creating B2B call for " + callDescriptor.Uri + ".", m_username)); uacCall = new SIPB2BUserAgent(m_statefulProxyLogEvent, QueueNewCall_External, m_sipTransport, m_username, m_adminMemberId); } } //ISIPClientUserAgent uacCall = new JingleUserAgent(m_username, m_adminMemberId, m_statefulProxyLogEvent); if (uacCall != null) { lock (m_switchCalls) { m_switchCalls.Add(uacCall); } uacCall.CallAnswered += UACCallAnswered; uacCall.CallFailed += UACCallFailed; uacCall.CallRinging += UACCallProgress; //uacCall.CallTrying += UACCallTrying; uacCall.Call(callDescriptor); } } } catch (Exception excp) { logger.Error("Exception ForkCall StartNewCall. " + excp.Message); } }
private void FireCallAnswered(SIPClientUserAgent uac, SIPResponse answeredResponse) { if (CallAnswered != null) { CallAnswered(uac, answeredResponse); } }