Example #1
0
        /// <summary>
        /// An outgoing call was successfully answered.
        /// </summary>
        /// <param name="uac">The local SIP user agent client that initiated the call.</param>
        /// <param name="sipResponse">The SIP answer response received from the remote party.</param>
        private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            StatusMessage(this, "Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");

            if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
            {
                if (sipResponse.Header.ContentType != _sdpMimeContentType)
                {
                    // Payload not SDP, I don't understand :(.
                    StatusMessage(this, "Call was hungup as the answer response content type was not recognized: " + sipResponse.Header.ContentType + ". :(");
                    Hangup();
                }
                else if (sipResponse.Body.IsNullOrBlank())
                {
                    // They said SDP but didn't give us any :(.
                    StatusMessage(this, "Call was hungup as the answer response had an empty SDP payload. :(");
                    Hangup();
                }
                else
                {
                    CallAnswer?.Invoke(this);
                }
            }
            else
            {
                CallFinished();
            }
        }
Example #2
0
        private void DispatcherCallFailed(ISIPClientUserAgent uac, string errorMessage)
        {
            try {
                string workerSocket = SIPURI.ParseSIPURI(uac.CallDescriptor.Uri).Host;
                dispatcherLogger.Debug("Dispatcher call to " + workerSocket + " failed " + errorMessage + ".");

                // Find the worker for the failed end point.
                SIPCallDispatcherWorker failedWorker = null;
                lock (m_callDispatcherWorkers) {
                    foreach (SIPCallDispatcherWorker worker in m_callDispatcherWorkers)
                    {
                        if (worker.AppServerEndpoint.SocketEndPoint.ToString() == workerSocket)
                        {
                            failedWorker = worker;
                            break;
                        }
                    }
                }

                if (failedWorker != null)
                {
                    dispatcherLogger.Debug("Scheduling immediate restart on worker process pid=" + failedWorker.WorkerProcess.Id + " due to failed probe.");
                    failedWorker.RestartTime = DateTime.Now;
                }
            }
            catch (Exception excp) {
                dispatcherLogger.Error("Exception DispatcherCallFailed. " + excp.Message);
            }
        }
 private void ForwardCallAnswered(ISIPClientUserAgent uac, SIPB2BUserAgent b2bua)
 {
     if (uac.SIPDialogue != null)
     {
         _sipCallManager.BridgeDialogues(uac.SIPDialogue, b2bua.SIPDialogue);
     }
 }
        /// <summary>
        /// Event handler for a failed probe response.
        /// </summary>
        private void AppServerCallFailed(ISIPClientUserAgent uac, string errorMessage, int workerProcessID, DateTime probeSentAt, bool isInitialProbe)
        {
            try
            {
                string workerSocket = SIPURI.ParseSIPURI(uac.CallDescriptor.Uri).Host;
                logger.Warn("SIPAppServerManager call to " + workerSocket + " for PID " + workerProcessID + " failed, initial probe " + isInitialProbe + " , sent at " + probeSentAt.ToString("dd MMM yyyy HH:mm:ss") + ", " + errorMessage);

                // Find the worker for the failed end point.
                SIPAppServerWorker failedWorker = GetWorkerForEndPoint(workerSocket);

                // Make sure the worker process hasn't changed in the meantime and don't restart for initial probes.
                if (failedWorker != null && failedWorker.WorkerProcess != null && failedWorker.WorkerProcess.Id == workerProcessID)
                {
                    if (!isInitialProbe)
                    {
                        failedWorker.InitialProbeResponseReceived = true;
                        logger.Debug("Scheduling immediate restart on app server worker process pid=" + failedWorker.WorkerProcess.Id + ", " + workerSocket + " due to failed probe.");
                        failedWorker.ScheduleRestart(DateTime.Now);
                    }
                    else if (failedWorker.InitialProbeCount >= INITIAL_PROBE_RETRANSMIT_LIMIT)
                    {
                        failedWorker.InitialProbeResponseReceived = true;
                        logger.Debug("Initial probe retransmit limit reached, scheduling immediate restart on app server worker process pid=" + failedWorker.WorkerProcess.Id + ", " + workerSocket + " due to failed probe.");
                        failedWorker.ScheduleRestart(DateTime.Now);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception AppServerCallFailed. " + excp.Message);
            }
        }
Example #5
0
        /// <summary>
        /// An outgoing call was successfully answered.
        /// </summary>
        /// <param name="uac">The local SIP user agent client that initiated the call.</param>
        /// <param name="sipResponse">The SIP answer response received from the remote party.</param>
        private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            StatusMessage("Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");

            if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
            {
                if (sipResponse.Header.ContentType != _sdpMimeContentType)
                {
                    // Payload not SDP, I don't understand :(.
                    StatusMessage("Call was hungup as the answer response content type was not recognised: " + sipResponse.Header.ContentType + ". :(");
                    Hangup();
                }
                else if (sipResponse.Body.IsNullOrBlank())
                {
                    // They said SDP but didn't give me any :(.
                    StatusMessage("Call was hungup as the answer response had an empty SDP payload. :(");
                    Hangup();
                }

                SDP sdpAnswer = SDP.ParseSDPDescription(sipResponse.Body);
                System.Diagnostics.Debug.WriteLine(sipResponse.Body);
                _mediaManager.SetRemoteSDP(sdpAnswer);
                CallAnswer();
            }
            else
            {
                CallFinished();
            }
        }
Example #6
0
        public void CancelNotRequiredCallLegs(CallCancelCause cancelCause)
        {
            try
            {
                m_commandCancelled = true;
                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Cancelling all call legs for ForkCall app.", m_username));

                // Cancel all forwarded call legs.
                if (m_switchCalls.Count > 0)
                {
                    ISIPClientUserAgent[] inProgressCalls = (from ua in m_switchCalls where !ua.IsUACAnswered select ua).ToArray();
                    for (int index = 0; index < inProgressCalls.Length; index++)
                    {
                        ISIPClientUserAgent uac = inProgressCalls[index];
                        uac.Cancel();
                    }
                }

                // Signal any delayed calls that they are no longer required.
                foreach (SIPCallDescriptor callDescriptor in m_delayedCalls)
                {
                    callDescriptor.DelayMRE.Set();
                }

                CallLegCompleted();
            }
            catch (Exception excp)
            {
                logger.Error("Exception ForkCall CancelAllCallLegs. " + excp);
            }
        }
Example #7
0
        /// <summary>
        /// An outgoing call was successfully answered.
        /// </summary>
        /// <param name="uac">The local SIP user agent client that initiated the call.</param>
        /// <param name="sipResponse">The SIP answer response received from the remote party.</param>
        private async void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            StatusMessage(this, "Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");

            // This call will allow the session source to be adjusted depending on whether the underlying
            // session has support for audio or video.
            await MediaSession.SetSources(null, null).ConfigureAwait(false);

            CallAnswer?.Invoke(this);
        }
Example #8
0
 /// <summary>
 /// Event handler for a client call (one initiated by us) failing.
 /// </summary>
 /// <param name="uac">The client user agent used to initiate the call.</param>
 /// <param name="errorMessage">An error message indicating the reason for the failure.</param>
 private void ClientCallFailedHandler(ISIPClientUserAgent uac, string errorMessage)
 {
     if (ClientCallFailed != null)
     {
         ClientCallFailed(uac, errorMessage);
     }
     else
     {
         logger.LogWarning($"Call attempt to {m_uac.CallDescriptor.Uri} failed with {errorMessage}.");
     }
 }
Example #9
0
 /// <summary>
 /// Event handler for a client call (one initiated by us) receiving an in progress response.
 /// </summary>
 /// <param name="uac">The client user agent used to initiate the call.</param>
 /// <param name="sipResponse">The INVITE ringing response.</param>
 private void ClientCallRingingHandler(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     if (ClientCallRinging != null)
     {
         ClientCallRinging(uac, sipResponse);
     }
     else
     {
         logger.LogInformation($"Call attempt to {m_uac.CallDescriptor.Uri} received a ringing response {sipResponse.ShortDescription}.");
     }
 }
Example #10
0
 /// <summary>
 /// Event handler for a client call (one initiated by us) being answered.
 /// </summary>
 /// <param name="uac">The client user agent used to initiate the call.</param>
 /// <param name="sipResponse">The INVITE success response.</param>
 private void ClientCallAnsweredHandler(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     if (ClientCallAnswered != null)
     {
         ClientCallAnswered(uac, sipResponse);
     }
     else
     {
         logger.LogDebug($"Call attempt to {m_uac.CallDescriptor.Uri} was answered.");
     }
 }
Example #11
0
        private void ClientCallFailed(ISIPClientUserAgent uac, string error, SIPResponse errResponse)
        {
            if (!base.IsCancelled)
            {
                logger.LogDebug($"B2BUserAgent client call failed {error}.");

                var status  = (errResponse != null) ? errResponse.Status : SIPResponseStatusCodesEnum.Decline;
                var errResp = SIPResponse.GetResponse(m_uasTransaction.TransactionRequest, status, errResponse?.ReasonPhrase);
                m_uasTransaction.SendFinalResponse(errResp);

                CallFailed?.Invoke(uac, error, errResponse);
            }
        }
Example #12
0
        /// <summary>
        /// An outgoing call was successfully answered.
        /// </summary>
        /// <param name="uac">The local SIP user agent client that initiated the call.</param>
        /// <param name="sipResponse">The SIP answer response received from the remote party.</param>
        private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            StatusMessage("Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");

            if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
            {
                IPEndPoint remoteSDPEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body);
                _audioChannel.SetRemoteRTPEndPoint(remoteSDPEndPoint);
                CallAnswer();
            }
            else
            {
                CallFinished();
            }
        }
 /// <summary>
 /// Event handler for a successful probe response.
 /// </summary>
 private void AppServerCallSucceeded(ISIPClientUserAgent uac)
 {
     try
     {
         string             workerSocket = SIPURI.ParseSIPURI(uac.CallDescriptor.Uri).Host;
         SIPAppServerWorker worker       = GetWorkerForEndPoint(workerSocket);
         if (!worker.InitialProbeResponseReceived)
         {
             logger.Debug("Initial probe received for " + workerSocket + ".");
             worker.InitialCallSuccessful();
         }
     }
     catch (Exception excp)
     {
         logger.Error("Exception AppServerCallSucceeded. " + excp.Message);
     }
 }
Example #14
0
        private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            logger.Debug("AppServerDispatcher CallAnswered with " + (int)sipResponse.Status + " " + sipResponse.ReasonPhrase + ".");
            SIPHeader okHeader       = uac.ServerTransaction.TransactionFinalResponse.Header;
            int       executionCount = 0;

            foreach (string unknownHeader in okHeader.UnknownHeaders)
            {
                if (unknownHeader.StartsWith("DialPlanEngine-ExecutionCount"))
                {
                    executionCount = Convert.ToInt32(Regex.Match(unknownHeader, @"\S: (?<count>\d+)").Result("${count}"));
                    break;
                }
            }
            m_startCheckTime.Stop();
            logger.Debug("AppServerDispatcher execution count for " + m_activeAppServerEntry.AppServerURI.ToString() + " is " + executionCount + ".");
            logger.Debug("AppServerDispatcher response took " + m_startCheckTime.ElapsedMilliseconds + "ms.");
        }
Example #15
0
        private void ClientCallAnswered(ISIPClientUserAgent uac, SIPResponse resp)
        {
            logger.LogDebug($"B2BUserAgent client call answered {resp.ShortDescription}.");

            if (resp.Status == SIPResponseStatusCodesEnum.Ok)
            {
                base.Answer(resp.Header.ContentType, resp.Body, SIPDialogueTransferModesEnum.NotAllowed);

                CallAnswered?.Invoke(uac, resp);
            }
            else
            {
                var failureResponse = SIPResponse.GetResponse(m_uasTransaction.TransactionRequest, resp.Status, resp.ReasonPhrase);
                m_uasTransaction.SendFinalResponse(failureResponse);

                CallFailed?.Invoke(uac, failureResponse.ReasonPhrase, failureResponse);
            }
        }
Example #16
0
 private void UACCallProgress(ISIPClientUserAgent uac, SIPResponse progressResponse)
 {
     try
     {
         if (m_commandCancelled)
         {
             //logger.Debug("Call " + uac.CallDescriptor.Uri + " should not be in a progress state after a cancel. Cancel again.");
             uac.Cancel();
         }
         else
         {
             CallProgress(progressResponse.Status, progressResponse.ReasonPhrase, null, progressResponse.Header.ContentType, progressResponse.Body, uac);
         }
     }
     catch (Exception excp)
     {
         logger.Error("Exception ForkCall UACCallProgress. " + excp);
     }
 }
Example #17
0
        /// <summary>
        /// Event handler for a client call (one initiated by us) being answered.
        /// </summary>
        /// <param name="uac">The client user agent used to initiate the call.</param>
        /// <param name="sipResponse">The INVITE success response.</param>
        private async Task ClientCallAnsweredHandlerAsync(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
            {
                // Only set the remote RTP end point if there hasn't already been a packet received on it.
                await MediaSession.OfferAnswered(sipResponse.Body).ConfigureAwait(false);

                Dialogue.DialogueState = SIPDialogueStateEnum.Confirmed;

                logger.LogInformation($"Call attempt to {m_uac.CallDescriptor.Uri} was answered.");

                ClientCallAnswered?.Invoke(uac, sipResponse);
            }
            else
            {
                logger.LogDebug($"Call attempt was answered with failure response {sipResponse.ShortDescription}.");
                ClientCallFailed?.Invoke(uac, sipResponse.ReasonPhrase);
                CallEnded();
            }
        }
Example #18
0
        /*private void UACCallTrying(ISIPClientUserAgent uac, SIPResponse sipResponse)
         * {
         *  try
         *  {
         *      // Test for the custom multiple redirect response.
         *      if (sipResponse.Status == SIPResponseStatusCodesEnum.MultipleRedirect)
         *      {
         *          ProcessRedirect(uac, sipResponse);
         *      }
         *  }
         *  catch (Exception excp)
         *  {
         *      logger.Error("Exception ForkCall UACCallTrying. " + excp.Message);
         *  }
         * }*/

        /// <summary>
        /// This event occurs if it was not possible to initiate a call to the destination specified in the forwarded call. An example
        /// would be an unresolvable hostname in the destination URI.
        /// </summary>
        /// <param name="sipSwitchCall"></param>
        /// <param name="errorMessage"></param>
        private void UACCallFailed(ISIPClientUserAgent uac, string errorMessage)
        {
            lock (m_switchCalls)
            {
                m_switchCalls.Remove(uac);
            }

            m_lastFailureStatus = SIPResponseStatusCodesEnum.TemporarilyUnavailable;
            m_lastFailureReason = errorMessage;

            if (m_switchCallTransactions != null && uac.ServerTransaction != null)
            {
                m_switchCallTransactions.Add(uac.ServerTransaction);
            }

            uac.CallAnswered -= UACCallAnswered;
            uac.CallFailed   -= UACCallFailed;
            uac.CallRinging  -= UACCallProgress;

            CallLegCompleted();
        }
Example #19
0
        private void Uac_CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            logger.Debug($"{ prefix } Call answered; { sipResponse.StatusCode } { sipResponse.Status }");

            switch (sipResponse.StatusCode)
            {
            case 404:
                logger.Error($"{ prefix } Received 404 Not Found from remote endpoint");
                break;

            case 486:
                // Busy
                logger.Error($"{ prefix } Received 486 Remote endpoint is busy; try again later");
                break;

            case 488:
                // Possible audio format issue
                logger.Error($"{ prefix } Received 488 Not Acceptable from remote endpoint; check audio format");
                break;

            case 503:
                // Check Twilio service and geo-permissions
                logger.Error($"{ prefix } Received 503 Service Unavailable from remote endpoint; check service permissions");
                break;

            case 200:
                if (sipResponse.Header.ContentType != SDP.SDP_MIME_CONTENTTYPE)
                {
                    logger.Error($"{ prefix } Received incorrect content type");

                    Stop();
                    return;
                }

                if (sipResponse.Body.IsNullOrBlank())
                {
                    logger.Error($"{ prefix } Received an empty SDP payload");

                    Stop();
                    return;
                }

                var sdp          = SDP.ParseSDPDescription(sipResponse.Body);
                var ip           = IPAddress.Parse(sdp.Connection.ConnectionAddress);
                var announcement = sdp.Media.Where(x => x.Media == SDPMediaTypesEnum.audio).FirstOrDefault();

                if (announcement != null)
                {
                    if (announcement.Port != 0)
                    {
                        rtpChannel.OnControlDataReceived       += (b) => { logger.Debug($"{prefix} Control Data Received; {b.Length} bytes"); };
                        rtpChannel.OnControlSocketDisconnected += () => { logger.Debug($"{prefix} Control Socket Disconnected"); };

                        rtpChannel.RemoteEndPoint = new IPEndPoint(ip, announcement.Port);
                        rtpChannel.Start();

                        // Send some setup parameters to punch a hole in the firewall/router
                        rtpChannel.SendRTPRaw(new byte[] { 80, 95, 198, 88, 55, 96, 225, 141, 215, 205, 185, 242, 00 });
                    }
                    else
                    {
                        logger.Error($"{ prefix } Remote endpoint did not specify a port number");
                        return;
                    }
                }
                else
                {
                    logger.Error($"{ prefix } Remote endpoint has not valid audio announcement");
                    return;
                }
                break;
            }
        }
Example #20
0
 /// <summary>
 /// An outgoing call was rejected by the remote SIP UAS on an outgoing call.
 /// </summary>
 private void CallFailed(ISIPClientUserAgent uac, string errorMessage)
 {
     StatusMessage(this, "Call failed: " + errorMessage + ".");
     CallFinished();
 }
 private void CallFailed(ISIPClientUserAgent uac, string errorMessage)
 {
     AppendTraceMessage("Call failed: " + errorMessage + "\n");
     ResetToCallStartState();
 }
        private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            AppendTraceMessage("Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".\n");

            if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
            {
                SetVisibility(m_callButton, Visibility.Collapsed);
                SetVisibility(m_cancelButton, Visibility.Collapsed);
                SetVisibility(m_byeButton, Visibility.Visible);
            }
            else
            {
                ResetToCallStartState();
            }
        }
Example #23
0
        /// <summary>
        /// An outgoing call was successfully answered.
        /// </summary>
        /// <param name="uac">The local SIP user agent client that initiated the call.</param>
        /// <param name="sipResponse">The SIP answer response received from the remote party.</param>
        private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            StatusMessage("Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");

            if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
            {
                IPEndPoint remoteSDPEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body);
                _audioChannel.SetRemoteRTPEndPoint(remoteSDPEndPoint);
                CallAnswer();
            }
            else
            {
                CallFinished();
            }
        }
 private void CallProgress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody, ISIPClientUserAgent uac)
 {
     SIPResponse progressResponse = new SIPResponse(progressStatus, reasonPhrase, null);
     CallRinging(this, progressResponse);
 }
Example #25
0
 /// <summary>
 /// An outgoing call was rejected by the remote SIP UAS on an outgoing call.
 /// </summary>
 private void CallFailed(ISIPClientUserAgent uac, string errorMessage, SIPResponse failureResponse)
 {
     StatusMessage(this, "Call failed: " + errorMessage + ".");
     CallFinished(null);
 }
 private void CallFailed(ISIPClientUserAgent uac, string errorMessage)
 {
     logger.Debug("AppServerDispatcher CallFailed with " + errorMessage + ".");
     m_activeAppServerEntry.HasFailed = true;
     m_activeAppServerEntry = GetActiveAppServer();
 }
Example #27
0
        /*private void UACCallTrying(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            try
            {
                // Test for the custom multiple redirect response.
                if (sipResponse.Status == SIPResponseStatusCodesEnum.MultipleRedirect)
                {
                    ProcessRedirect(uac, sipResponse);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception ForkCall UACCallTrying. " + excp.Message);
            }
        }*/
        /// <summary>
        /// This event occurs if it was not possible to initiate a call to the destination specified in the forwarded call. An example
        /// would be an unresolvable hostname in the destination URI.
        /// </summary>
        /// <param name="sipSwitchCall"></param>
        /// <param name="errorMessage"></param>
        private void UACCallFailed(ISIPClientUserAgent uac, string errorMessage)
        {
            lock (m_switchCalls)
            {
                m_switchCalls.Remove(uac);
            }

            m_lastFailureStatus = SIPResponseStatusCodesEnum.TemporarilyUnavailable;
            m_lastFailureReason = errorMessage;

            if (m_switchCallTransactions != null && uac.ServerTransaction != null)
            {
                m_switchCallTransactions.Add(uac.ServerTransaction);
            }

            uac.CallAnswered -= UACCallAnswered;
            uac.CallFailed -= UACCallFailed;
            uac.CallRinging -= UACCallProgress;

            CallLegCompleted();
        }
Example #28
0
        private void ProcessRedirect(ISIPClientUserAgent answeredUAC, SIPResponse answeredResponse)
        {
            try
            {
                SIPURI redirectURI = answeredResponse.Header.Contact[0].ContactURI;

                if (redirectURI == null)
                {
                    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect target could not be determined from redirect response, ignoring.", m_username));
                }
                else
                {
                    //string canincalDomain = m_dialPlanContext.GetCanonicalDomain_External(redirectURI.Host, false);

                    if (answeredUAC.CallDescriptor.RedirectMode == SIPCallRedirectModesEnum.NewDialPlan)
                    {
                        m_dialPlanContext.ExecuteDialPlanForRedirect(answeredResponse);
                    }
                    else if (answeredUAC.CallDescriptor.RedirectMode == SIPCallRedirectModesEnum.Manual)
                    {
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect response with URI " + redirectURI.ToString() + " was not acted on as redirect mode set to manual in dial string.", m_username));
                        CallLegCompleted();
                    }
                    else
                    {
                        // The redirect was not explicitly allowed so will be processed as an anonymous call.
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect response to " + redirectURI.ToString() + " accepted.", m_username));
                        var redirectCalls = m_dialStringParser.GetForwardsForRedirect(redirectURI, answeredUAC.CallDescriptor);
                        //SIPCallDescriptor redirectCallDescriptor = answeredUAC.CallDescriptor.CopyOf();
                        //redirectCallDescriptor.Uri = redirectURI.ToString();
                        //StartNewCallAsync(redirectCallDescriptor);
                        if (redirectCalls != null && redirectCalls.Count > 0)
                        {
                            foreach (var redirectCall in redirectCalls)
                            {
                                StartNewCallAsync(redirectCall);
                            }
                        }
                    }
                    //else if (answeredUAC.CallDescriptor.RedirectMode == SIPCallRedirectModesEnum.Replace)
                    //{
                    //    // In the Replace redirect mode the existing dialplan execution needs to be cancelled and the single redirect call be used to replace it.
                    //    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect response rejected as Replace mode not yet implemented.", m_username));
                    //    CallLegCompleted();
                    //}
                    //else
                    //{
                    //    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect response with URI " + redirectURI.ToString() + " was not acted on as not enabled in dial string.", m_username));
                    //    CallLegCompleted();
                    //}

                    // A redirect response was received. Create a new call leg(s) using the SIP URIs in the contact header of the response.
                    //if (m_dialStringParser != null)
                    //{
                    //    // If there is a dial string parser available it will be used to generate a list of call destination from the redirect URI.
                    //    SIPCallDescriptor redirectCallDescriptor = answeredUAC.CallDescriptor.CopyOf();
                    //    Queue<List<SIPCallDescriptor>> redirectQueue = m_dialStringParser.ParseDialString(DialPlanContextsEnum.Script, null, redirectURI.ToString(), redirectCallDescriptor.CustomHeaders,
                    //        redirectCallDescriptor.ContentType, redirectCallDescriptor.Content, null, redirectCallDescriptor.FromDisplayName, redirectCallDescriptor.FromURIUsername, redirectCallDescriptor.FromURIHost, null, CustomerServiceLevels.None);

                    //    if (redirectQueue != null && redirectQueue.Count > 0)
                    //    {
                    //        // Only the first list in the queue is used (and there should only be a single list since it's generated from a redirect SIP URI and not
                    //        // a full dial string).
                    //        List<SIPCallDescriptor> callDescriptors = redirectQueue.Dequeue();
                    //        for (int index = 0; index < callDescriptors.Count; index++)
                    //        {
                    //            callDescriptors[index].MangleIPAddress = redirectCallDescriptor.MangleIPAddress;
                    //            callDescriptors[index].MangleResponseSDP = redirectCallDescriptor.MangleResponseSDP;
                    //            callDescriptors[index].TransferMode = redirectCallDescriptor.TransferMode;
                    //        }
                    //        Start(callDescriptors);
                    //    }
                    //    else
                    //    {
                    //        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A redirect response to " + redirectURI.ToString() + " did not generate any new call leg destinations.", m_username));
                    //    }
                    //}
                    //else
                    //{
                    //    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect response to " + redirectURI.ToString() + " accepted.", m_username));
                    //    SIPCallDescriptor redirectCallDescriptor = answeredUAC.CallDescriptor.CopyOf();
                    //    redirectCallDescriptor.Uri = redirectURI.ToString();
                    //    StartNewCallAsync(redirectCallDescriptor);
                    //}
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception ForkCall ProcessRedirect. " + excp.Message);
            }
        }
Example #29
0
 /// <summary>
 /// Event handler for a client call (one initiated by us) being answered.
 /// </summary>
 /// <param name="uac">The client user agent used to initiate the call.</param>
 /// <param name="sipResponse">The INVITE success response.</param>
 private void ClientCallAnsweredHandler(ISIPClientUserAgent uac, SIPResponse sipResponse) =>
 _ = ClientCallAnsweredHandlerAsync(uac, sipResponse);
Example #30
0
        private void ProcessRedirect(ISIPClientUserAgent answeredUAC, SIPResponse answeredResponse)
        {
            try
            {
                SIPURI redirectURI = answeredResponse.Header.Contact[0].ContactURI;

                if (redirectURI == null)
                {
                    FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect target could not be determined from redirect response, ignoring.", m_username));
                }
                else
                {
                    // A redirect response was received. Create a new call leg(s) using the SIP URIs in the contact header of the response.
                    if (m_dialStringParser != null)
                    {
                        // If there is a dial string parser available it will be used to generate a list of call destination from the redirect URI.
                        SIPCallDescriptor redirectCallDescriptor = answeredUAC.CallDescriptor.CopyOf();
                        Queue<List<SIPCallDescriptor>> redirectQueue = m_dialStringParser.ParseDialString(DialPlanContextsEnum.Script, null, redirectURI.ToString(), redirectCallDescriptor.CustomHeaders,
                            redirectCallDescriptor.ContentType, redirectCallDescriptor.Content, null, redirectCallDescriptor.FromDisplayName, redirectCallDescriptor.FromURIUsername, redirectCallDescriptor.FromURIHost, null);

                        if (redirectQueue != null && redirectQueue.Count > 0)
                        {
                            // Only the first list in the queue is used (and there should only be a single list since it's generated from a redirect SIP URI and not 
                            // a full dial string).
                            List<SIPCallDescriptor> callDescriptors = redirectQueue.Dequeue();
                            for (int index = 0; index < callDescriptors.Count; index++)
                            {
                                callDescriptors[index].MangleIPAddress = redirectCallDescriptor.MangleIPAddress;
                                callDescriptors[index].MangleResponseSDP = redirectCallDescriptor.MangleResponseSDP;
                                callDescriptors[index].TransferMode = redirectCallDescriptor.TransferMode;
                            }
                            Start(callDescriptors);
                        }
                        else
                        {
                            FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A redirect response to " + redirectURI.ToString() + " did not generate any new call leg destinations.", m_username));
                        }
                    }
                    else
                    {
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect response to " + redirectURI.ToString() + " accepted.", m_username));
                        SIPCallDescriptor redirectCallDescriptor = answeredUAC.CallDescriptor.CopyOf();
                        redirectCallDescriptor.Uri = redirectURI.ToString();
                        StartNewCallAsync(redirectCallDescriptor);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception ForkCall ProcessRedirect. " + excp.Message);
            }
        }
        private void CallProgress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody, ISIPClientUserAgent uac)
        {
            try
            {
                Log("Progress response of " + progressStatus + " received on CallBack Dial" + ".");

                if (m_firstLegDialogue != null && !progressBody.IsNullOrBlank() && !m_firstLegEarlyMediaSet)
                {
                    m_firstLegEarlyMediaSet = true;
                    // The first leg is up and a call on the second leg has some early media that can be passed on.
                    //m_callManager.ReInvite(m_firstLegDialogue, progressBody);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception CallbackApp. " + excp.Message);
            }
        }
Example #32
0
        private void Uac_CallFailed(ISIPClientUserAgent uac, string errorMessage)
        {
            logger.Debug($"{ prefix } Call to { endpoint } failed");

            uac.Cancel();
        }
 private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     logger.Debug("AppServerDispatcher CallAnswered with " + (int)sipResponse.Status + " " + sipResponse.ReasonPhrase + ".");
     SIPHeader okHeader = uac.ServerTransaction.TransactionFinalResponse.Header;
     int executionCount = 0;
     foreach (string unknownHeader in okHeader.UnknownHeaders)
     {
         if (unknownHeader.StartsWith("DialPlanEngine-ExecutionCount"))
         {
             executionCount = Convert.ToInt32(Regex.Match(unknownHeader, @"\S: (?<count>\d+)").Result("${count}"));
             break;
         }
     }
     m_startCheckTime.Stop();
     logger.Debug("AppServerDispatcher execution count for " + m_activeAppServerEntry.AppServerURI.ToString() + " is " + executionCount + ".");
     logger.Debug("AppServerDispatcher response took " + m_startCheckTime.ElapsedMilliseconds + "ms.");
 }
 /// <summary>
 /// Event handler for a successful probe response.
 /// </summary>
 private void AppServerCallSucceeded(ISIPClientUserAgent uac)
 {
     try
     {
         string workerSocket = SIPURI.ParseSIPURI(uac.CallDescriptor.Uri).Host;
         SIPAppServerWorker worker = GetWorkerForEndPoint(workerSocket);
         if (!worker.InitialProbeResponseReceived)
         {
             logger.Debug("Initial probe received for " + workerSocket + ".");
             worker.InitialCallSuccessful();
         }
     }
     catch (Exception excp)
     {
         logger.Error("Exception AppServerCallSucceeded. " + excp.Message);
     }
 }
Example #35
0
 /// <summary>
 /// An outgoing call was rejected by the remote SIP UAS on an outgoing call.
 /// </summary>
 private void CallFailed(ISIPClientUserAgent uac, string errorMessage)
 {
     StatusMessage("Call failed: " + errorMessage + ".");
     CallFinished();
 }
Example #36
0
 /// <summary>
 /// An outgoing call was successfully answered.
 /// </summary>
 /// <param name="uac">The local SIP user agent client that initiated the call.</param>
 /// <param name="sipResponse">The SIP answer response received from the remote party.</param>
 private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     StatusMessage(this, "Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");
     CallAnswer?.Invoke(this);
 }
Example #37
0
 /// <summary>
 /// A trying response has been received from the remote SIP UAS on an outgoing call.
 /// </summary>
 private void CallTrying(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     StatusMessage("Call trying: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");
 }
        /// <summary>
        /// Event handler for a failed probe response.
        /// </summary>
        private void AppServerCallFailed(ISIPClientUserAgent uac, string errorMessage, int workerProcessID, DateTime probeSentAt, bool isInitialProbe)
        {
            try
            {
                string workerSocket = SIPURI.ParseSIPURI(uac.CallDescriptor.Uri).Host;
                logger.Warn("SIPAppServerManager call to " + workerSocket + " for PID " + workerProcessID + " failed, initial probe " + isInitialProbe  + " , sent at " + probeSentAt.ToString("dd MMM yyyy HH:mm:ss") + ", " + errorMessage);

                // Find the worker for the failed end point.
                SIPAppServerWorker failedWorker = GetWorkerForEndPoint(workerSocket);

                // Make sure the worker process hasn't changed in the meantime and don't restart for initial probes.
                if (failedWorker != null && failedWorker.WorkerProcess != null && failedWorker.WorkerProcess.Id == workerProcessID)
                {
                    if (!isInitialProbe)
                    {
                        failedWorker.InitialProbeResponseReceived = true;
                        logger.Debug("Scheduling immediate restart on app server worker process pid=" + failedWorker.WorkerProcess.Id + ", " + workerSocket + " due to failed probe.");
                        failedWorker.ScheduleRestart(DateTime.Now);
                    }
                    else if (failedWorker.InitialProbeCount >= INITIAL_PROBE_RETRANSMIT_LIMIT)
                    {
                        failedWorker.InitialProbeResponseReceived = true;
                        logger.Debug("Initial probe retransmit limit reached, scheduling immediate restart on app server worker process pid=" + failedWorker.WorkerProcess.Id + ", " + workerSocket + " due to failed probe.");
                        failedWorker.ScheduleRestart(DateTime.Now);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception AppServerCallFailed. " + excp.Message);
            }
        }
        private void DispatcherCallFailed(ISIPClientUserAgent uac, string errorMessage) {
            try {
                string workerSocket = SIPURI.ParseSIPURI(uac.CallDescriptor.Uri).Host;
                dispatcherLogger.Debug("Dispatcher call to " + workerSocket + " failed " + errorMessage + ".");

                // Find the worker for the failed end point.
                SIPCallDispatcherWorker failedWorker = null;
                lock (m_callDispatcherWorkers) {
                    foreach (SIPCallDispatcherWorker worker in m_callDispatcherWorkers) {
                        if (worker.AppServerEndpoint.SocketEndPoint.ToString() == workerSocket) {
                            failedWorker = worker;
                            break;
                        }
                    }
                }

                if (failedWorker != null) {
                    dispatcherLogger.Debug("Scheduling immediate restart on worker process pid=" + failedWorker.WorkerProcess.Id + " due to failed probe.");
                    failedWorker.RestartTime = DateTime.Now;
                }
            }
            catch (Exception excp) {
                dispatcherLogger.Error("Exception DispatcherCallFailed. " + excp.Message);
            }
        }
 private void CallRinging(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     AppendTraceMessage("Call ringing: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".\n");
 }
 private void DispatcherCallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse) {
     //logger.Debug("Dispatcher call answered, execution count = " + sipResponse.Header.UnknownHeaders[0] + ".");
 }
Example #42
0
        /// <summary>
        /// Event handler for a client call (one initiated by us) failing.
        /// </summary>
        /// <param name="uac">The client user agent used to initiate the call.</param>
        /// <param name="errorMessage">An error message indicating the reason for the failure.</param>
        private void ClientCallFailedHandler(ISIPClientUserAgent uac, string errorMessage)
        {
            logger.LogWarning($"Call attempt to {m_uac.CallDescriptor.Uri} failed with {errorMessage}.");

            ClientCallFailed?.Invoke(uac, errorMessage);
        }
        public void CallProgress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody, ISIPClientUserAgent uac)
        {
            if (m_sipServerUserAgent != null && !m_isAnswered)
            {
                m_sipServerUserAgent.Progress(progressStatus, reasonPhrase, customHeaders, progressContentType, progressBody);

                if (uac != null && uac.CallDescriptor.RequestCallerDetails && CallerCRMDetails != null)
                {
                    if (CallerCRMDetails.Pending && !m_uacWaitingForCallDetails.Contains(uac) && !m_uacCallDetailsSent.Contains(uac))
                    {
                        m_uacWaitingForCallDetails.Add(uac);
                    }
                    else if (!CallerCRMDetails.Pending && !m_uacCallDetailsSent.Contains(uac))
                    {
                        // Send the call details to the client user agent.
                        uac.Update(CallerCRMDetails);
                    }
                }
            }
        }
Example #44
0
 /// <summary>
 /// A ringing response has been received from the remote SIP UAS on an outgoing call.
 /// </summary>
 private void CallRinging(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     StatusMessage(this, "Call ringing: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");
 }
Example #45
0
        private void CallProgress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody, ISIPClientUserAgent uac)
        {
            SIPResponse progressResponse = new SIPResponse(progressStatus, reasonPhrase, null);

            CallRinging(this, progressResponse);
        }
Example #46
0
        private void CallProgress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody, ISIPClientUserAgent uac)
        {
            try
            {
                Log("Progress response of " + progressStatus + " received on CallBack Dial" + ".");

                if (m_firstLegDialogue != null && !progressBody.IsNullOrBlank() && !m_firstLegEarlyMediaSet)
                {
                    m_firstLegEarlyMediaSet = true;
                    // The first leg is up and a call on the second leg has some early media that can be passed on.
                    //m_callManager.ReInvite(m_firstLegDialogue, progressBody);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception CallbackApp. " + excp.Message);
            }
        }
Example #47
0
 private void Uac_CallRinging(ISIPClientUserAgent uac, SIPResponse sipResponse)
 {
     logger.Debug($"{ prefix } Ringing ...");
 }
Example #48
0
        private void UACCallAnswered(ISIPClientUserAgent answeredUAC, SIPResponse answeredResponse)
        {
            try
            {
                // Remove the current call from the pending list.
                lock (m_switchCalls)
                {
                    m_switchCalls.Remove(answeredUAC);
                }

                if (m_switchCallTransactions != null && answeredUAC.ServerTransaction != null)
                {
                    m_switchCallTransactions.Add(answeredUAC.ServerTransaction);
                }

                if (answeredResponse != null && answeredResponse.StatusCode >= 200 && answeredResponse.StatusCode <= 299)
                {
                    #region 2xx final response.

                    if (!m_callAnswered && !m_commandCancelled)
                    {
                        // This is the first call we've got an answer on.
                        m_callAnswered = true;
                        m_answeredUAC = answeredUAC;
                        AnsweredSIPResponse = answeredResponse;

                        SIPDialogueTransferModesEnum uasTransferMode = SIPDialogueTransferModesEnum.Default;
                        if (m_answeredUAC.CallDescriptor.TransferMode == SIPDialogueTransferModesEnum.NotAllowed)
                        {
                            answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.NotAllowed;
                            uasTransferMode = SIPDialogueTransferModesEnum.NotAllowed;
                        }
                        else if (m_answeredUAC.CallDescriptor.TransferMode == SIPDialogueTransferModesEnum.BlindPlaceCall)
                        {
                            answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.BlindPlaceCall;
                            uasTransferMode = SIPDialogueTransferModesEnum.BlindPlaceCall;
                        }
                        else if (m_answeredUAC.CallDescriptor.TransferMode == SIPDialogueTransferModesEnum.PassThru)
                        {
                            answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.PassThru;
                            uasTransferMode = SIPDialogueTransferModesEnum.PassThru;
                        }
                        /*else if (m_answeredUAC.CallDescriptor.TransferMode == SIPCallTransferModesEnum.Caller)
                        {
                            answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.NotAllowed;
                            uasTransferMode = SIPDialogueTransferModesEnum.Allowed;
                        }
                        else if (m_answeredUAC.CallDescriptor.TransferMode == SIPCallTransferModesEnum.Callee)
                        {
                            answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.Allowed;
                            uasTransferMode = SIPDialogueTransferModesEnum.NotAllowed;
                        }
                        else if (m_answeredUAC.CallDescriptor.TransferMode == SIPCallTransferModesEnum.Both)
                        {
                            answeredUAC.SIPDialogue.TransferMode = SIPDialogueTransferModesEnum.Allowed;
                            uasTransferMode = SIPDialogueTransferModesEnum.Allowed;
                        }*/

                        if (CallAnswered != null)
                        {
                            logger.Debug("Transfer mode=" + m_answeredUAC.CallDescriptor.TransferMode + ".");
                            CallAnswered(answeredResponse.Status, answeredResponse.ReasonPhrase, null, null, answeredResponse.Header.ContentType, answeredResponse.Body, answeredUAC.SIPDialogue, uasTransferMode);
                        }

                        // Cancel/hangup and other calls on this leg that are still around.
                        CancelNotRequiredCallLegs(CallCancelCause.NormalClearing);
                    }
                    else
                    {
                        // Call already answered or cancelled, hangup (send BYE).
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call leg " + answeredUAC.CallDescriptor.Uri + " answered but call was already answered or cancelled, hanging up.", m_username));
                        SIPDialogue sipDialogue = new SIPDialogue(answeredUAC.ServerTransaction, m_username, m_adminMemberId);
                        sipDialogue.Hangup(m_sipTransport, m_outboundProxySocket);
                    }

                    #endregion

                    CallLegCompleted();
                }
                else if (answeredUAC.SIPDialogue != null)
                {
                    // Google Voice calls create the dialogue without using a SIP response.
                    if (!m_callAnswered && !m_commandCancelled)
                    {
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call leg for Google Voice call to " + answeredUAC.CallDescriptor.Uri + " answered.", m_username));

                        // This is the first call we've got an answer on.
                        m_callAnswered = true;
                        m_answeredUAC = answeredUAC;

                        if (CallAnswered != null)
                        {
                            CallAnswered(SIPResponseStatusCodesEnum.Ok, null, null, null, answeredUAC.SIPDialogue.ContentType, answeredUAC.SIPDialogue.RemoteSDP, answeredUAC.SIPDialogue, SIPDialogueTransferModesEnum.NotAllowed);
                        }

                        // Cancel/hangup and other calls on this leg that are still around.
                        CancelNotRequiredCallLegs(CallCancelCause.NormalClearing);
                    }
                    else
                    {
                        // Call already answered or cancelled, hangup (send BYE).
                        FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call leg for Google Voice call to " + answeredUAC.CallDescriptor.Uri + " answered but call was already answered or cancelled, hanging up.", m_username));
                        answeredUAC.SIPDialogue.Hangup(m_sipTransport, m_outboundProxySocket);
                    }
                }
                else if (answeredResponse != null && answeredResponse.StatusCode >= 300 && answeredResponse.StatusCode <= 399)
                {
                    ProcessRedirect(answeredUAC, answeredResponse);
                }
                else if (answeredResponse != null)
                {
                    // This call leg failed, record the failure status and reason.
                    m_lastFailureStatus = answeredResponse.Status;
                    m_lastFailureReason = answeredResponse.ReasonPhrase;

                    if (m_switchCallTransactions != null && answeredUAC.ServerTransaction != null)
                    {
                        m_switchCallTransactions.Add(answeredUAC.ServerTransaction);
                    }

                    CallLegCompleted();
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception ForkCall UACCallAnswered. " + excp);
            }
        }
        public void CallProgress(SIPResponseStatusCodesEnum progressStatus, string reasonPhrase, string[] customHeaders, string progressContentType, string progressBody, ISIPClientUserAgent uac)
        {
            if (!m_isAnswered)
            {
                m_sipServerUserAgent.Progress(progressStatus, reasonPhrase, customHeaders, progressContentType, progressBody);

                if (uac != null && uac.CallDescriptor.RequestCallerDetails && CallerCRMDetails != null)
                {
                    if (CallerCRMDetails.Pending && !m_uacWaitingForCallDetails.Contains(uac) && !m_uacCallDetailsSent.Contains(uac))
                    {
                        m_uacWaitingForCallDetails.Add(uac);
                    }
                    else if (!CallerCRMDetails.Pending && !m_uacCallDetailsSent.Contains(uac))
                    {
                        // Send the call details to the client user agent.
                        uac.Update(CallerCRMDetails);
                    }
                }
            }
        }
Example #50
0
 private void UACCallProgress(ISIPClientUserAgent uac, SIPResponse progressResponse)
 {
     try
     {
         if (m_commandCancelled)
         {
             //logger.Debug("Call " + uac.CallDescriptor.Uri + " should not be in a progress state after a cancel. Cancel again.");
             uac.Cancel();
         }
         else
         {
             CallProgress(progressResponse.Status, progressResponse.ReasonPhrase, null, progressResponse.Header.ContentType, progressResponse.Body, uac);
         }
     }
     catch (Exception excp)
     {
         logger.Error("Exception ForkCall UACCallProgress. " + excp);
     }
 }
Example #51
0
        /// <summary>
        /// An outgoing call was successfully answered.
        /// </summary>
        /// <param name="uac">The local SIP user agent client that initiated the call.</param>
        /// <param name="sipResponse">The SIP answer response received from the remote party.</param>
        private void CallAnswered(ISIPClientUserAgent uac, SIPResponse sipResponse)
        {
            StatusMessage("Call answered: " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".");

            if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
            {
                if(sipResponse.Header.ContentType != _sdpMimeContentType)
                {
                    // Payload not SDP, I don't understand :(.
                    StatusMessage("Call was hungup as the answer response content type was not recognised: " + sipResponse.Header.ContentType + ". :(");
                    Hangup();
                }
                else if(sipResponse.Body.IsNullOrBlank())
                {
                    // They said SDP but didn't give me any :(.
                    StatusMessage("Call was hungup as the answer response had an empty SDP payload. :(");
                    Hangup();
                }

                SDP sdpAnswer = SDP.ParseSDPDescription(sipResponse.Body);
                System.Diagnostics.Debug.WriteLine(sipResponse.Body);
                _mediaManager.SetRemoteSDP(sdpAnswer);
                CallAnswer();
            }
            else
            {
                CallFinished();
            }
        }