Inheritance: ISIPClientUserAgent
Example #1
0
        /// <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();
            }
        }
Example #2
0
 /// <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);
 }
Example #3
0
        /// <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();
            }
        }
Example #4
0
        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));
        }
Example #5
0
        /// <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();
        }
Example #6
0
        /// <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();
        }
Example #7
0
        /// <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();
            }
        }
Example #8
0
        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);
            }
        }
        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);
     }
 }
Example #11
0
        /// <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);
            }
        }
Example #17
0
        /// <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);
            }
        }
Example #19
0
        /// <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();
        }
Example #20
0
        //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);
            }
        }
Example #22
0
        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);
            }
        }
Example #23
0
        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);
     }
 }