Call() public method

public Call ( SIPCallDescriptor sipCallDescriptor ) : void
sipCallDescriptor SIPCallDescriptor
return void
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>
        /// 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 #6
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);
            }
        }
        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 #8
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);
        }
Example #9
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);
        }
        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);
            }
        }
        /// <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>
        /// 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);
            }
        }
        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);
            //}
        }
        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);
            }
        }