public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     NoRingTimeout.Invoke(this);
     throw new NotImplementedException();
 }
        /// <summary>
        /// An answer on a blind transfer means the remote end of the dialogue being replaced should be re-invited and then the replaced dialogue
        /// should be hungup.
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="body"></param>
        /// <param name="toTag"></param>
        /// <param name="answeredDialogue"></param>
        /// <param name="transferMode"></param>
        /// <returns></returns>
        public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
        {
            try
            {
                if (m_answered)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A blind transfer received an answer on an already answered call, hanging up dialogue.", m_owner));
                    answeredDialogue.Hangup(m_sipTransport, m_outboundProxy);
                }
                else
                {
                    m_answered = true;
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A blind transfer received an answer.", m_owner));

                    if (UASStateChanged != null)
                    {
                        UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null);
                    }

                    BlindTransfer_External(m_dialogueToReplace, m_oppositeDialogue, answeredDialogue);
                }

                return(null);
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPTransferServerUserAgent Answer. " + excp.Message);
                throw;
            }
        }
Example #3
0
        public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
        {
            try
            {
                logger.Debug("SIPB2BUserAgent Answer.");
                m_sipDialogue = answeredDialogue;

                if (UASStateChanged != null)
                {
                    UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null);
                }

                SIPResponse uasOkResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null);
                m_uasTransaction.SendFinalResponse(uasOkResponse);
                m_uasTransaction.ACKReceived(m_blackhole, m_blackhole, null);

                SIPResponse uacOkResponse = SIPTransport.GetResponse(m_uacTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null);
                uacOkResponse.Header.Contact = new List <SIPContactHeader>()
                {
                    new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, m_blackhole))
                };
                m_uacTransaction.GotResponse(m_blackhole, m_blackhole, uacOkResponse);
                uacOkResponse.Header.ContentType = contentType;
                if (!body.IsNullOrBlank())
                {
                    uacOkResponse.Body = body;
                    uacOkResponse.Header.ContentLength = body.Length;
                }
                CallAnswered((ISIPClientUserAgent)this, uacOkResponse);
                return(null);
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPB2BUSerAgent Answer. " + excp.Message);
                throw;
            }
        }
 public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     return Answer(contentType, body, null, answeredDialogue, transferMode);
 }
Example #5
0
        public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode, string[] customHeaders)
        {
            try
            {
                if (m_uasTransaction.TransactionFinalResponse != null)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS Answer was called on an already answered call, ignoring.", m_owner));
                    return(null);
                }
                else
                {
                    UASStateChanged?.Invoke(this, SIPResponseStatusCodesEnum.Ok, null);

                    if (!toTag.IsNullOrBlank())
                    {
                        m_uasTransaction.LocalTag = toTag;
                    }

                    SIPResponse okResponse = m_uasTransaction.GetOkResponse(contentType, body);

                    if (body != null)
                    {
                        okResponse.Header.ContentType   = contentType;
                        okResponse.Header.ContentLength = body.Length;
                        okResponse.Body = body;
                    }
                    if (customHeaders != null && customHeaders.Length > 0)
                    {
                        foreach (string header in customHeaders)
                        {
                            okResponse.Header.UnknownHeaders.Add(header);
                        }
                    }

                    m_uasTransaction.SendFinalResponse(okResponse);

                    SIPDialogue = new SIPDialogue(m_uasTransaction, m_owner, m_adminMemberId);
                    SIPDialogue.TransferMode = transferMode;

                    return(SIPDialogue);
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPServerUserAgent Answer. " + excp.Message);
                throw;
            }
        }
Example #6
0
        public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
        {
            try
            {
                if (m_uasTransaction.TransactionFinalResponse != null)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS Answer was called on an already answered call, ignoring.", m_owner));
                    return(null);
                }
                else
                {
                    if (UASStateChanged != null)
                    {
                        UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null);
                    }

                    if (!toTag.IsNullOrBlank())
                    {
                        m_uasTransaction.SetLocalTag(toTag);
                    }

                    SIPResponse okResponse = m_uasTransaction.GetOkResponse(m_uasTransaction.TransactionRequest, m_uasTransaction.TransactionRequest.LocalSIPEndPoint, contentType, body);

                    if (body != null)
                    {
                        okResponse.Header.ContentType   = contentType;
                        okResponse.Header.ContentLength = body.Length;
                        okResponse.Body = body;
                    }

                    m_uasTransaction.SendFinalResponse(okResponse);

                    m_sipDialogue = new SIPDialogue(m_uasTransaction, m_owner, m_adminMemberId);
                    m_sipDialogue.TransferMode = transferMode;

                    return(m_sipDialogue);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPServerUserAgent Answer. " + excp.Message);
                throw;
            }
        }
 public SIPDialogue Answer(string contentType, string body, SIPDialogueTransferModesEnum transferMode,
                           string[] customHeaders)
 {
     return(Answer(contentType, body, null, transferMode, customHeaders));
 }
Example #8
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 SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
        {
            try
            {
                logger.Debug("SIPB2BUserAgent Answer.");
                m_sipDialogue = answeredDialogue;

                if (UASStateChanged != null)
                {
                    UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null);
                }

                SIPResponse uasOkResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null);
                m_uasTransaction.SendFinalResponse(uasOkResponse);
                m_uasTransaction.ACKReceived(m_blackhole, m_blackhole, null);

                SIPResponse uacOkResponse = SIPTransport.GetResponse(m_uacTransaction.TransactionRequest, SIPResponseStatusCodesEnum.Ok, null);
                uacOkResponse.Header.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, m_blackhole)) };
                m_uacTransaction.GotResponse(m_blackhole, m_blackhole, uacOkResponse);
                uacOkResponse.Header.ContentType = contentType;
                if (!body.IsNullOrBlank())
                {
                    uacOkResponse.Body = body;
                    uacOkResponse.Header.ContentLength = body.Length;
                }
                CallAnswered((ISIPClientUserAgent)this, uacOkResponse);
                return null;
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPB2BUSerAgent Answer. " + excp.Message);
                throw;
            }
        }
Example #10
0
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     throw new NotImplementedException();
 }
Example #11
0
        public void CallAnswered(SIPResponseStatusCodesEnum answeredStatus, string reasonPhrase, string toTag, string[] customHeaders, string answeredContentType, string answeredBody, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum uasTransferMode)
        {
            try
            {
                if (m_sipServerUserAgent != null && !m_isAnswered)
                {
                    if (!m_sipServerUserAgent.IsInvite)
                    {
                        m_isAnswered = true;
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Answering client call with a response status of " + (int)answeredStatus + ".", Owner));
                        m_sipServerUserAgent.AnswerNonInvite(answeredStatus, reasonPhrase, customHeaders, answeredContentType, answeredBody);
                    }
                    else
                    {
                        m_isAnswered = true;
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Answering client call with a response status of " + (int)answeredStatus + ".", Owner));

                        SIPDialogue uasDialogue = m_sipServerUserAgent.Answer(answeredContentType, answeredBody, toTag, answeredDialogue, uasTransferMode);

                        if (!m_sipServerUserAgent.IsB2B && answeredDialogue != null)
                        {
                            if (uasDialogue != null)
                            {
                                // Duplicate switchboard dialogue settings.
                                //uasDialogue.SwitchboardDescription = answeredDialogue.SwitchboardDescription;
                                //uasDialogue.SwitchboardCallerDescription = answeredDialogue.SwitchboardCallerDescription;
                                uasDialogue.SwitchboardLineName = answeredDialogue.SwitchboardLineName;
                                uasDialogue.CRMPersonName       = answeredDialogue.CRMPersonName;
                                uasDialogue.CRMCompanyName      = answeredDialogue.CRMCompanyName;
                                uasDialogue.CRMPictureURL       = answeredDialogue.CRMPictureURL;
                                uasDialogue.SwitchboardOwner    = answeredDialogue.SwitchboardOwner;

                                // Record the now established call with the call manager for in dialogue management and hangups.
                                CreateBridge_External(uasDialogue, answeredDialogue, m_dialPlan.Owner);
                            }
                            else
                            {
                                logger.Warn("Failed to get a SIPDialogue from UAS.Answer.");
                            }
                        }
                    }
                }
                else
                {
                    logger.Warn("DialPlanContext CallAnswered fired on already answered call.");
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception DialPlanContext CallAnswered. " + excp.Message);
            }
            finally
            {
                DialPlanExecutionFinished();
            }
        }
        public void ParseCallOptions(string options)
        {
            if (!options.IsNullOrBlank())
            {
                options = options.Trim('[', ']');

                // Parse delay time option.
                Match delayCallMatch = Regex.Match(options, DELAY_CALL_OPTION_KEY + @"=(?<delaytime>\d+)");
                if (delayCallMatch.Success)
                {
                    Int32.TryParse(delayCallMatch.Result("${delaytime}"), out DelaySeconds);
                }

                // Parse redirect mode option.
                Match redirectModeMatch = Regex.Match(options, REDIRECT_MODE_OPTION_KEY + @"=(?<redirectmode>\w)");
                if (redirectModeMatch.Success)
                {
                    string redirectMode = redirectModeMatch.Result("${redirectmode}");
                    if (redirectMode == "a" || redirectMode == "A")
                    {
                        RedirectMode = SIPCallRedirectModesEnum.Add;
                    }
                    else if (redirectMode == "r" || redirectMode == "R")
                    {
                        RedirectMode = SIPCallRedirectModesEnum.Replace;
                    }
                }

                // Parse call duration limit option.
                Match callDurationMatch = Regex.Match(options, CALL_DURATION_OPTION_KEY + @"=(?<callduration>\d+)");
                if (callDurationMatch.Success)
                {
                    Int32.TryParse(callDurationMatch.Result("${callduration}"), out CallDurationLimit);
                }

                // Parse the mangle option.
                Match mangleMatch = Regex.Match(options, MANGLE_MODE_OPTION_KEY + @"=(?<mangle>\w+)");
                if (mangleMatch.Success)
                {
                    Boolean.TryParse(mangleMatch.Result("${mangle}"), out MangleResponseSDP);
                }

                // Parse the From header display name option.
                Match fromDisplayNameMatch = Regex.Match(options, FROM_DISPLAY_NAME_KEY + @"=(?<displayname>.+?)(,|$)");
                if (fromDisplayNameMatch.Success)
                {
                    FromDisplayName = fromDisplayNameMatch.Result("${displayname}").Trim();
                }

                // Parse the From header URI username option.
                Match fromUsernameNameMatch = Regex.Match(options, FROM_USERNAME_KEY + @"=(?<username>.+?)(,|$)");
                if (fromUsernameNameMatch.Success)
                {
                    FromURIUsername = fromUsernameNameMatch.Result("${username}").Trim();
                }

                // Parse the From header URI host option.
                Match fromURIHostMatch = Regex.Match(options, FROM_HOST_KEY + @"=(?<host>.+?)(,|$)");
                if (fromURIHostMatch.Success)
                {
                    FromURIHost = fromURIHostMatch.Result("${host}").Trim();
                }

                // Parse the Transfer behaviour option.
                Match transferMatch = Regex.Match(options, TRANSFER_MODE_OPTION_KEY + @"=(?<transfermode>.+?)(,|$)");
                if (transferMatch.Success)
                {
                    string transferMode = transferMatch.Result("${transfermode}");
                    if (transferMode == "n" || transferMode == "N")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.NotAllowed;
                    }
                    else if (transferMode == "p" || transferMode == "P")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.PassThru;
                    }
                    else if (transferMode == "c" || transferMode == "C")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.BlindPlaceCall;
                    }
                    /*else if (transferMode == "o" || transferMode == "O")
                    {
                        TransferMode = SIPCallTransferModesEnum.Caller;
                    }
                    else if (transferMode == "d" || transferMode == "D")
                    {
                        TransferMode = SIPCallTransferModesEnum.Callee;
                    }
                    else if (transferMode == "b" || transferMode == "B")
                    {
                        TransferMode = SIPCallTransferModesEnum.Both;
                    }*/
                }

                // Parse the switchboard description value.
                Match switchboardDescriptionMatch = Regex.Match(options, SWITCHBOARD_CALL_DESCRIPTION_KEY + @"=(?<description>.+?)(,|$)");
                if (switchboardDescriptionMatch.Success)
                {
                    SwitchboardHeaders.SwitchboardDescription = switchboardDescriptionMatch.Result("${description}").Trim();
                }

                // Parse the switchboard dialogue description value.
                Match switchboardDialogueDescriptionMatch = Regex.Match(options, SWITCHBOARD_DIALOGUE_DESCRIPTION_KEY + @"=(?<description>.+?)(,|$)");
                if (switchboardDialogueDescriptionMatch.Success)
                {
                    SwitchboardHeaders.SwitchboardDialogueDescription = switchboardDialogueDescriptionMatch.Result("${description}").Trim();
                }

                // Parse the switchboard CallID value.
                Match switchboardCallIDMatch = Regex.Match(options, SWITCHBOARD_CALLID_KEY + @"=(?<callid>.+?)(,|$)");
                if (switchboardCallIDMatch.Success)
                {
                    SwitchboardHeaders.SwitchboardCallID = switchboardCallIDMatch.Result("${callid}").Trim();
                }

                // Parse the switchboard owner value.
                Match switchboardOwnerMatch = Regex.Match(options, SWITCHBOARD_OWNER_KEY + @"=(?<owner>.+?)(,|$)");
                if (switchboardOwnerMatch.Success)
                {
                    SwitchboardHeaders.SwitchboardOwner = switchboardOwnerMatch.Result("${owner}").Trim();
                }

                // Parse the request caller details option.
                Match callerDetailsMatch = Regex.Match(options,REQUEST_CALLER_DETAILS + @"=(?<callerdetails>\w+)");
                if (callerDetailsMatch.Success)
                {
                    Boolean.TryParse(callerDetailsMatch.Result("${callerdetails}"), out RequestCallerDetails);
                }
            }
        }
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogueTransferModesEnum transferMode, string[] customHeaders)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// An answer on a blind transfer means the remote end of the dialogue being replaced should be re-invited and then the replaced dialogue 
        /// should be hungup.
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="body"></param>
        /// <param name="toTag"></param>
        /// <param name="answeredDialogue"></param>
        /// <param name="transferMode"></param>
        /// <returns></returns>
        public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
        {
            try
            {
                if (m_answered)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A blind transfer received an answer on an already answered call, hanging up dialogue.", m_owner));
                    answeredDialogue.Hangup(m_sipTransport, m_outboundProxy);
                }
                else
                {
                    m_answered = true;
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "A blind transfer received an answer.", m_owner));

                    if (UASStateChanged != null)
                    {
                        UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null);
                    }

                    BlindTransfer_External(m_dialogueToReplace, m_oppositeDialogue, answeredDialogue);
                }

                return null;
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPTransferServerUserAgent Answer. " + excp.Message);
                throw;
            }
        }
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     TransactionComplete.Invoke(this);
     throw new NotImplementedException();
 }
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     throw new NotImplementedException();
 }
Example #17
0
 public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     return(Answer(contentType, body, null, answeredDialogue, transferMode));
 }
Example #18
0
        public void ParseCallOptions(string options)
        {
            if (!options.IsNullOrBlank())
            {
                options = options.Trim('[', ']');

                // Parse delay time option.
                Match delayCallMatch = Regex.Match(options, DELAY_CALL_OPTION_KEY + @"=(?<delaytime>\d+)");
                if (delayCallMatch.Success)
                {
                    Int32.TryParse(delayCallMatch.Result("${delaytime}"), out DelaySeconds);
                }

                // Parse redirect mode option.
                Match redirectModeMatch = Regex.Match(options, REDIRECT_MODE_OPTION_KEY + @"=(?<redirectmode>\w)");
                if (redirectModeMatch.Success)
                {
                    string redirectMode = redirectModeMatch.Result("${redirectmode}");
                    //if (redirectMode == "a" || redirectMode == "A")
                    //{
                    //    RedirectMode = SIPCallRedirectModesEnum.Add;
                    //}
                    //else if (redirectMode == "r" || redirectMode == "R")
                    //{
                    //    RedirectMode = SIPCallRedirectModesEnum.Replace;
                    //}
                    if (redirectMode == "n" || redirectMode == "N")
                    {
                        RedirectMode = SIPCallRedirectModesEnum.NewDialPlan;
                    }
                    else if (redirectMode == "m" || redirectMode == "M")
                    {
                        RedirectMode = SIPCallRedirectModesEnum.Manual;
                    }
                }

                // Parse call duration limit option.
                Match callDurationMatch = Regex.Match(options, CALL_DURATION_OPTION_KEY + @"=(?<callduration>\d+)");
                if (callDurationMatch.Success)
                {
                    Int32.TryParse(callDurationMatch.Result("${callduration}"), out CallDurationLimit);
                }

                // Parse the mangle option.
                Match mangleMatch = Regex.Match(options, MANGLE_MODE_OPTION_KEY + @"=(?<mangle>\w+)");
                if (mangleMatch.Success)
                {
                    Boolean.TryParse(mangleMatch.Result("${mangle}"), out MangleResponseSDP);
                }

                // Parse the From header display name option.
                Match fromDisplayNameMatch = Regex.Match(options, FROM_DISPLAY_NAME_KEY + @"=(?<displayname>.+?)(,|$)");
                if (fromDisplayNameMatch.Success)
                {
                    FromDisplayName = fromDisplayNameMatch.Result("${displayname}").Trim();
                }

                // Parse the From header URI username option.
                Match fromUsernameNameMatch = Regex.Match(options, FROM_USERNAME_KEY + @"=(?<username>.+?)(,|$)");
                if (fromUsernameNameMatch.Success)
                {
                    FromURIUsername = fromUsernameNameMatch.Result("${username}").Trim();
                }

                // Parse the From header URI host option.
                Match fromURIHostMatch = Regex.Match(options, FROM_HOST_KEY + @"=(?<host>.+?)(,|$)");
                if (fromURIHostMatch.Success)
                {
                    FromURIHost = fromURIHostMatch.Result("${host}").Trim();
                }

                // Parse the Transfer behaviour option.
                Match transferMatch = Regex.Match(options, TRANSFER_MODE_OPTION_KEY + @"=(?<transfermode>.+?)(,|$)");
                if (transferMatch.Success)
                {
                    string transferMode = transferMatch.Result("${transfermode}");
                    if (transferMode == "n" || transferMode == "N")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.NotAllowed;
                    }
                    else if (transferMode == "p" || transferMode == "P")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.PassThru;
                    }
                    else if (transferMode == "c" || transferMode == "C")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.BlindPlaceCall;
                    }

                    /*else if (transferMode == "o" || transferMode == "O")
                     * {
                     *  TransferMode = SIPCallTransferModesEnum.Caller;
                     * }
                     * else if (transferMode == "d" || transferMode == "D")
                     * {
                     *  TransferMode = SIPCallTransferModesEnum.Callee;
                     * }
                     * else if (transferMode == "b" || transferMode == "B")
                     * {
                     *  TransferMode = SIPCallTransferModesEnum.Both;
                     * }*/
                }

                // Parse the switchboard description value.
                Match switchboardDescriptionMatch = Regex.Match(options, SWITCHBOARD_LINE_NAME_KEY + @"=(?<lineName>.+?)(,|$)");
                if (switchboardDescriptionMatch.Success)
                {
                    SwitchboardHeaders.SwitchboardLineName = switchboardDescriptionMatch.Result("${lineName}").Trim();
                }

                // Parse the switchboard dialogue description value.
                //Match switchboardDialogueDescriptionMatch = Regex.Match(options, SWITCHBOARD_DIALOGUE_DESCRIPTION_KEY + @"=(?<description>.+?)(,|$)");
                //if (switchboardDialogueDescriptionMatch.Success)
                //{
                //    SwitchboardHeaders.SwitchboardDialogueDescription = switchboardDialogueDescriptionMatch.Result("${description}").Trim();
                //}

                // Parse the switchboard CallID value.
                Match switchboardCallIDMatch = Regex.Match(options, SWITCHBOARD_CALLID_KEY + @"=(?<callid>.+?)(,|$)");
                if (switchboardCallIDMatch.Success)
                {
                    SwitchboardHeaders.SwitchboardOriginalCallID = switchboardCallIDMatch.Result("${callid}").Trim();
                }

                // Parse the switchboard owner value.
                Match switchboardOwnerMatch = Regex.Match(options, SWITCHBOARD_OWNER_KEY + @"=(?<owner>.+?)(,|$)");
                if (switchboardOwnerMatch.Success)
                {
                    SwitchboardHeaders.SwitchboardOwner = switchboardOwnerMatch.Result("${owner}").Trim();
                }

                // Parse the request caller details option.
                Match callerDetailsMatch = Regex.Match(options, REQUEST_CALLER_DETAILS + @"=(?<callerdetails>\w+)");
                if (callerDetailsMatch.Success)
                {
                    Boolean.TryParse(callerDetailsMatch.Result("${callerdetails}"), out RequestCallerDetails);
                }

                // Parse the accountcode.
                Match accountCodeMatch = Regex.Match(options, ACCOUNT_CODE_KEY + @"=(?<accountCode>\w+)");
                if (accountCodeMatch.Success)
                {
                    AccountCode = accountCodeMatch.Result("${accountCode}");
                }

                // Parse the rate code.
                Match rateCodeMatch = Regex.Match(options, RATE_CODE_KEY + @"=(?<rateCode>\w+)");
                if (rateCodeMatch.Success)
                {
                    RateCode = rateCodeMatch.Result("${rateCode}");
                }
            }
        }
        public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogueTransferModesEnum transferMode, string[] customHeaders)
        {
            try
            {
                m_transferMode = transferMode;

                if (m_uasTransaction.TransactionFinalResponse != null)
                {
                    logger.LogDebug("UAS Answer was called on an already answered call, ignoring.");
                    return(null);
                }
                else
                {
                    //UASStateChanged?.Invoke(this, SIPResponseStatusCodesEnum.Ok, null);

                    if (!toTag.IsNullOrBlank())
                    {
                        m_uasTransaction.LocalTag = toTag;
                    }

                    SIPResponse okResponse = m_uasTransaction.GetOkResponse(contentType, body);

                    if (body != null)
                    {
                        okResponse.Header.ContentType   = contentType;
                        okResponse.Header.ContentLength = body.Length;
                        okResponse.Body = body;
                    }
                    if (customHeaders != null && customHeaders.Length > 0)
                    {
                        foreach (string header in customHeaders)
                        {
                            okResponse.Header.UnknownHeaders.Add(header);
                        }
                    }

                    if (OfferSDP == null)
                    {
                        // The INVITE request did not contain an SDP offer. We need to send the offer in the response and
                        // then get the answer from the ACK.
                        m_uasTransaction.OnAckReceived += OnAckAnswerReceived;
                    }

                    m_uasTransaction.SendFinalResponse(okResponse);

                    if (OfferSDP != null)
                    {
                        SIPDialogue = new SIPDialogue(m_uasTransaction);
                        SIPDialogue.TransferMode = transferMode;

                        OnDialogueCreated?.Invoke(SIPDialogue);

                        return(SIPDialogue);
                    }
                    else
                    {
                        // The dialogue cannot be created until the ACK is received.
                        return(null);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPServerUserAgent Answer. " + excp.Message);
                throw;
            }
        }
Example #20
0
        public void ParseCallOptions(string options)
        {
            if (!options.IsNullOrBlank())
            {
                options = options.Trim('[', ']');

                // Parse delay time option.
                Match delayCallMatch = Regex.Match(options, DELAY_CALL_OPTION_KEY + @"=(?<delaytime>\d+)");
                if (delayCallMatch.Success)
                {
                    Int32.TryParse(delayCallMatch.Result("${delaytime}"), out DelaySeconds);
                }

                // Parse redirect mode option.
                Match redirectModeMatch = Regex.Match(options, REDIRECT_MODE_OPTION_KEY + @"=(?<redirectmode>\w)");
                if (redirectModeMatch.Success)
                {
                    string redirectMode = redirectModeMatch.Result("${redirectmode}");
                    //if (redirectMode == "a" || redirectMode == "A")
                    //{
                    //    RedirectMode = SIPCallRedirectModesEnum.Add;
                    //}
                    //else if (redirectMode == "r" || redirectMode == "R")
                    //{
                    //    RedirectMode = SIPCallRedirectModesEnum.Replace;
                    //}
                    if (redirectMode == "n" || redirectMode == "N")
                    {
                        RedirectMode = SIPCallRedirectModesEnum.NewDialPlan;
                    }
                    else if (redirectMode == "m" || redirectMode == "M")
                    {
                        RedirectMode = SIPCallRedirectModesEnum.Manual;
                    }
                }

                // Parse call duration limit option.
                Match callDurationMatch = Regex.Match(options, CALL_DURATION_OPTION_KEY + @"=(?<callduration>\d+)");
                if (callDurationMatch.Success)
                {
                    Int32.TryParse(callDurationMatch.Result("${callduration}"), out CallDurationLimit);
                }

                // Parse the mangle option.
                Match mangleMatch = Regex.Match(options, MANGLE_MODE_OPTION_KEY + @"=(?<mangle>\w+)");
                if (mangleMatch.Success)
                {
                    Boolean.TryParse(mangleMatch.Result("${mangle}"), out MangleResponseSDP);
                }

                // Parse the From header display name option.
                Match fromDisplayNameMatch = Regex.Match(options, FROM_DISPLAY_NAME_KEY + @"=(?<displayname>.+?)(,|$)");
                if (fromDisplayNameMatch.Success)
                {
                    FromDisplayName = fromDisplayNameMatch.Result("${displayname}").Trim();
                }

                // Parse the From header URI username option.
                Match fromUsernameNameMatch = Regex.Match(options, FROM_USERNAME_KEY + @"=(?<username>.+?)(,|$)");
                if (fromUsernameNameMatch.Success)
                {
                    FromURIUsername = fromUsernameNameMatch.Result("${username}").Trim();
                }

                // Parse the From header URI host option.
                Match fromURIHostMatch = Regex.Match(options, FROM_HOST_KEY + @"=(?<host>.+?)(,|$)");
                if (fromURIHostMatch.Success)
                {
                    FromURIHost = fromURIHostMatch.Result("${host}").Trim();
                }

                // Parse the Transfer behaviour option.
                Match transferMatch = Regex.Match(options, TRANSFER_MODE_OPTION_KEY + @"=(?<transfermode>.+?)(,|$)");
                if (transferMatch.Success)
                {
                    string transferMode = transferMatch.Result("${transfermode}");
                    if (transferMode == "n" || transferMode == "N")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.NotAllowed;
                    }
                    else if (transferMode == "p" || transferMode == "P")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.PassThru;
                    }
                    else if (transferMode == "c" || transferMode == "C")
                    {
                        TransferMode = SIPDialogueTransferModesEnum.BlindPlaceCall;
                    }

                    /*else if (transferMode == "o" || transferMode == "O")
                     * {
                     *  TransferMode = SIPCallTransferModesEnum.Caller;
                     * }
                     * else if (transferMode == "d" || transferMode == "D")
                     * {
                     *  TransferMode = SIPCallTransferModesEnum.Callee;
                     * }
                     * else if (transferMode == "b" || transferMode == "B")
                     * {
                     *  TransferMode = SIPCallTransferModesEnum.Both;
                     * }*/
                }

                // Parse the request caller details option.
                Match callerDetailsMatch = Regex.Match(options, REQUEST_CALLER_DETAILS + @"=(?<callerdetails>\w+)");
                if (callerDetailsMatch.Success)
                {
                    Boolean.TryParse(callerDetailsMatch.Result("${callerdetails}"), out RequestCallerDetails);
                }

                // Parse the accountcode.
                Match accountCodeMatch = Regex.Match(options, ACCOUNT_CODE_KEY + @"=(?<accountCode>\w+)");
                if (accountCodeMatch.Success)
                {
                    AccountCode = accountCodeMatch.Result("${accountCode}");
                }

                // Parse the rate code.
                Match rateCodeMatch = Regex.Match(options, RATE_CODE_KEY + @"=(?<rateCode>\w+)");
                if (rateCodeMatch.Success)
                {
                    RateCode = rateCodeMatch.Result("${rateCode}");
                }

                // Parse the delayed reinvite option.
                Match delayedReinviteMatch = Regex.Match(options, DELAYED_REINVITE_KEY + @"=(?<delayedReinvite>\d+)");
                if (delayedReinviteMatch.Success)
                {
                    Int32.TryParse(delayedReinviteMatch.Result("${delayedReinvite}"), out ReinviteDelay);

                    if (ReinviteDelay > MAX_REINVITE_DELAY)
                    {
                        ReinviteDelay = DEFAULT_REINVITE_DELAY;
                    }
                }

                // Parse the immediate reinvite option (TODO: remove after user switches to delayed reinvite option).
                Match immediateReinviteMatch = Regex.Match(options, @"ir=\w+");
                if (immediateReinviteMatch.Success)
                {
                    ReinviteDelay = DEFAULT_REINVITE_DELAY;
                }
            }
        }
 public SIPDialogue Answer(string contentType, string body, string toTag,
                           SIPDialogueTransferModesEnum transferMode)
 {
     return(Answer(contentType, body, toTag, transferMode, null));
 }
        public void CallAnswered(SIPResponseStatusCodesEnum answeredStatus, string reasonPhrase, string toTag, string[] customHeaders, string answeredContentType, string answeredBody, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum uasTransferMode)
        {
            try
            {
                if (!m_isAnswered)
                {
                    m_isAnswered = true;
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Answering client call with a response status of " + (int)answeredStatus + ".", Owner));

                    SIPDialogue uasDialogue = m_sipServerUserAgent.Answer(answeredContentType, answeredBody, toTag, answeredDialogue, uasTransferMode);

                    if (!m_sipServerUserAgent.IsB2B && answeredDialogue != null)
                    {
                        if (uasDialogue != null)
                        {
                            // Duplicate switchboard dialogue settings.
                            uasDialogue.SwitchboardDescription = answeredDialogue.SwitchboardDescription;
                            uasDialogue.SwitchboardCallerDescription = answeredDialogue.SwitchboardCallerDescription;
                            uasDialogue.SwitchboardOwner = answeredDialogue.SwitchboardOwner;

                            // Record the now established call with the call manager for in dialogue management and hangups.
                            CreateBridge_External(uasDialogue, answeredDialogue, m_dialPlan.Owner);
                        }
                        else
                        {
                            logger.Warn("Failed to get a SIPDialogue from UAS.Answer.");
                        }
                    }
                }
                else
                {
                    logger.Warn("DialPlanContext CallAnswered fired on already answered call.");
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception DialPlanContext CallAnswered. " + excp.Message);
            }
            finally
            {
                DialPlanExecutionFinished();
            }
        }
        public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
        {
            try
            {
                if (m_uasTransaction.TransactionFinalResponse != null)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAS Answer was called on an already answered call, ignoring.", m_owner));
                    return null;
                }
                else
                {
                    if (UASStateChanged != null)
                    {
                        UASStateChanged(this, SIPResponseStatusCodesEnum.Ok, null);
                    }

                    if (!toTag.IsNullOrBlank())
                    {
                        m_uasTransaction.SetLocalTag(toTag);
                    }

                    SIPResponse okResponse = m_uasTransaction.GetOkResponse(m_uasTransaction.TransactionRequest, m_uasTransaction.TransactionRequest.LocalSIPEndPoint, contentType, body);

                    //added for gruu compatibility
                    if (!m_gruu.IsNullOrBlank())
                    {
                        okResponse.Header.Contact[0].ContactURI.Parameters.Set(SIPCallDescriptor.GRUU_KEY,m_gruu);
                    }

                    if (body != null)
                    {
                        okResponse.Header.ContentType = contentType;
                        okResponse.Header.ContentLength = body.Length;
                        okResponse.Body = body;
                    }

                    m_uasTransaction.SendFinalResponse(okResponse);

                    m_sipDialogue = new SIPDialogue(m_uasTransaction, m_owner, m_adminMemberId);
                    m_sipDialogue.TransferMode = transferMode;

                    return m_sipDialogue;
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPServerUserAgent Answer. " + excp.Message);
                throw;
            }
        }
        public void Transfer(SIPTransport sipTransport, SIPURI referTo, Boolean unattended, SIPEndPoint outboundProxy)
        {
            if (!unattended)
            {
                throw new NotImplementedException();
            }
            else
            {
                TransferMode = SIPDialogueTransferModesEnum.PassThru;
                try
                {
                    SIPEndPoint referOutboundProxy = null;
                    if (outboundProxy != null && IPAddress.IsLoopback(outboundProxy.Address))
                    {
                        referOutboundProxy = outboundProxy;
                    }
                    else if (!ProxySendFrom.IsNullOrBlank())
                    {
                        referOutboundProxy = new SIPEndPoint(new IPEndPoint(SIPEndPoint.ParseSIPEndPoint(ProxySendFrom).Address, m_defaultSIPPort));
                    }
                    else if (outboundProxy != null)
                    {
                        referOutboundProxy = outboundProxy;
                    }

                    SIPEndPoint localEndPoint = (referOutboundProxy != null) ? sipTransport.GetDefaultSIPEndPoint(referOutboundProxy.Protocol) : sipTransport.GetDefaultSIPEndPoint(GetRemoteTargetProtocol());
                    SIPRequest referRequest = GetReferRequest(localEndPoint, referTo);
                    SIPNonInviteTransaction referTransaction = sipTransport.CreateNonInviteTransaction(referRequest, null, localEndPoint, referOutboundProxy);
                    referTransaction.NonInviteTransactionFinalResponseReceived += referTransaction_NonInviteTransactionFinalResponseReceived;
                    referTransaction.SendReliableRequest();
                }
                catch (Exception excp)
                {
                    logger.Error("Exception SIPDialogue Transfer. " + excp.Message);
                    throw;
                }
            }
        }