private void Answered(SDP sdp)
        {
            Console.WriteLine("XMPP client call answered.");

            IsUACAnswered = true;

            SIPResponse okResponse = new SIPResponse(SIPResponseStatusCodesEnum.Ok, "Ok", new SIPEndPoint(new IPEndPoint(IPAddress.Loopback, 0)));
            okResponse.Header.ContentType = SDP.SDP_MIME_CONTENTTYPE;
            okResponse.Body = sdp.ToString();

            SIPDialogue = new SIPDialogue(null, null, null, null, -1, null, null, null, Guid.NewGuid(), Owner, AdminMemberId, null, sdp.ToString());
            SIPDialogue.CallDurationLimit = CallDescriptor.CallDurationLimit;

            CallAnswered(this, okResponse);
        }
 public SIPEventSubscription(
     SIPMonitorLogDelegate log,
     string sessionID,
     SIPURI resourceURI,
     SIPURI canonicalResourceURI,
     string filter,
     SIPDialogue subscriptionDialogue,
     int expiry)
 {
     MonitorLogEvent_External = log;
     SessionID = sessionID;
     ResourceURI = resourceURI;
     CanonicalResourceURI = canonicalResourceURI;
     Filter = filter;
     SubscriptionDialogue = subscriptionDialogue;
     Expiry = expiry;
 }
 public SIPDialogEventSubscription(
     SIPMonitorLogDelegate log,
     string sessionID,
     SIPURI resourceURI,
     SIPURI canonincalResourceURI,
     string filter,
     SIPDialogue subscriptionDialogue,
     int expiry,
     SIPAssetGetListDelegate<SIPDialogueAsset> getDialogues,
     SIPAssetGetByIdDelegate<SIPDialogueAsset> getDialogue
     )
     : base(log, sessionID, resourceURI, canonincalResourceURI, filter, subscriptionDialogue, expiry)
 {
     GetDialogues_External = getDialogues;
     GetDialogue_External = getDialogue;
     DialogInfo = new SIPEventDialogInfo(0, SIPEventDialogInfoStateEnum.full, resourceURI);
 }
 public SIPPresenceEventSubscription(
     SIPMonitorLogDelegate log,
     string sessionID,
     SIPURI resourceURI,
     SIPURI canonincalResourceURI,
     string filter,
     SIPDialogue subscriptionDialogue,
     int expiry,
     SIPAssetPersistor<SIPAccount> sipAccountPersistor,
     SIPAssetCountDelegate<SIPRegistrarBinding> getBindingsCount,
     bool switchboardSIPAccountsOnly
     )
     : base(log, sessionID, resourceURI, canonincalResourceURI, filter, subscriptionDialogue, expiry)
 {
     m_sipAccountPersistor = sipAccountPersistor;
     GetSIPRegistrarBindingsCount_External = getBindingsCount;
     Presence = new SIPEventPresence(resourceURI);
     m_switchboardSIPAccountsOnly = switchboardSIPAccountsOnly;
 }
 public SIPTransferServerUserAgent(            
     SIPMonitorLogDelegate logDelegate,
     BlindTransferDelegate blindTransfer,
     SIPTransport sipTransport,
     SIPEndPoint outboundProxy,
     SIPDialogue dialogueToReplace,
     SIPDialogue oppositeDialogue,
     string callDestination,
     string owner,
     string adminID)
 {
     Log_External = logDelegate;
     BlindTransfer_External = blindTransfer;
     m_sipTransport = sipTransport;
     m_outboundProxy = outboundProxy;
     m_dialogueToReplace = dialogueToReplace;
     m_oppositeDialogue = oppositeDialogue;
     m_callDestination = callDestination;
     m_owner = owner;
     m_adminID = adminID;
     m_dummyRequest = CreateDummyRequest(m_dialogueToReplace, m_callDestination);
 }
Esempio n. 6
0
        public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogueTransferModesEnum transferMode, string[] customHeaders)
        {
            try
            {
                m_transferMode = transferMode;

                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);
                        }
                    }

                    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, m_owner, m_adminMemberId);
                        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;
            }
        }
        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;
            }
        }
Esempio n. 8
0
 public SIPDialogueAsset()
 {
     SIPDialogue = new SIPDialogue();
 }
Esempio n. 9
0
 /// <summary>
 /// Sends a request to the remote call party to initiate an attended transfer.
 /// </summary>
 /// <param name="transferee">The dialog that will be replaced on the initial call party.</param>
 /// <returns>True if the transfer was accepted or false if not.</returns>
 public Task <bool> AttendedTransfer(SIPDialogue transferee)
 {
     return(m_userAgent.AttendedTransfer(transferee, TimeSpan.FromSeconds(TRANSFER_RESPONSE_TIMEOUT_SECONDS), _cts.Token));
 }
Esempio n. 10
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);

                            if (answeredUAC.CallDescriptor.ImmediateReinvite == true)
                            {
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, $"Initiating re-INVITE request due to dial string options.", m_username));
                                FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, $"Re-sending SDP: {answeredUAC.SIPDialogue.SDP}", m_username));

                                SIPDialogue dummyDialogue = new SIPDialogue();
                                dummyDialogue.RemoteSDP = answeredUAC.SIPDialogue.SDP;
                                m_callManager.ReInvite(answeredUAC.SIPDialogue, dummyDialogue);
                            }
                        }

                        // 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;

                        CallAnswered?.Invoke(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);
            }
        }
Esempio n. 11
0
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue,
                           SIPDialogueTransferModesEnum transferMode)
 {
     TransactionComplete.Invoke(this);
     throw new NotImplementedException();
 }
Esempio n. 12
0
 public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue,
                           SIPDialogueTransferModesEnum transferMode)
 {
     NoRingTimeout.Invoke(this);
     throw new NotImplementedException();
 }
Esempio n. 13
0
 public SIPDialogueAsset(SIPDialogue sipDialogue)
 {
     SIPDialogue = sipDialogue;
 }
Esempio n. 14
0
 public SIPDialogueAsset()
 {
     SIPDialogue = new SIPDialogue();
 }
Esempio n. 15
0
 public void Load(DataRow row)
 {
     SIPDialogue = new SIPDialogue();
     SIPDialogue.Id = new Guid(row["id"] as string);
     SIPDialogue.Owner = row["owner"] as string;
     SIPDialogue.AdminMemberId = row["adminmemberid"] as string;
     SIPDialogue.LocalTag = row["localtag"] as string;
     SIPDialogue.RemoteTag = row["remotetag"] as string;
     SIPDialogue.LocalUserField = SIPUserField.ParseSIPUserField(row["localuserfield"] as string);
     SIPDialogue.RemoteUserField = SIPUserField.ParseSIPUserField(row["remoteuserfield"] as string);
     SIPDialogue.CallId = row["callid"] as string;
     SIPDialogue.CSeq = Convert.ToInt32(row["cseq"]);
     SIPDialogue.BridgeId = new Guid(row["bridgeid"] as string);
     SIPDialogue.RemoteTarget = SIPURI.ParseSIPURI(row["remotetarget"] as string);
     SIPDialogue.RouteSet = (row["routeset"] != null && row["routeset"] != DBNull.Value && !(row["routeset"] as string).IsNullOrBlank()) ? SIPRouteSet.ParseSIPRouteSet(row["routeset"] as string) : null;
     SIPDialogue.ProxySendFrom = (row["proxysipsocket"] != null && row["proxysipsocket"] != DBNull.Value) ? row["proxysipsocket"] as string : null;
     SIPDialogue.CDRId = new Guid(row["cdrid"] as string);
     SIPDialogue.CallDurationLimit = (row["calldurationlimit"] != null && row["calldurationlimit"] != DBNull.Value) ? Convert.ToInt32(row["calldurationlimit"]) : 0;
     SIPDialogue.Direction = (row["direction"] != null) ? (SIPCallDirection)Enum.Parse(typeof(SIPCallDirection), row["direction"] as string, true) : SIPCallDirection.None;
     Inserted = DateTimeOffset.Parse(row["inserted"] as string);
     TransferMode = row["transfermode"] as string;
     SDP = row["sdp"] as string;
     RemoteSDP = row["remotesdp"] as string;
     //SIPDialogue.SwitchboardCallerDescription = (row["switchboardcallerdescription"] != null && row["switchboardcallerdescription"] != DBNull.Value) ? row["switchboardcallerdescription"] as string : null;
     //SIPDialogue.SwitchboardDescription = (row["switchboarddescription"] != null && row["switchboarddescription"] != DBNull.Value) ? row["switchboarddescription"] as string : null;
     SIPDialogue.SwitchboardOwner = (row["switchboardowner"] != null && row["switchboardowner"] != DBNull.Value) ? row["switchboardowner"] as string : null;
     SIPDialogue.SwitchboardLineName = (row["switchboardlinename"] != null && row["switchboardlinename"] != DBNull.Value) ? row["switchboardlinename"] as string : null;
     SIPDialogue.CRMPersonName = (row["crmpersonname"] != null && row["crmpersonname"] != DBNull.Value) ? row["crmpersonname"] as string : null;
     SIPDialogue.CRMCompanyName = (row["crmcompanyname"] != null && row["crmcompanyname"] != DBNull.Value) ? row["crmcompanyname"] as string : null;
     SIPDialogue.CRMPictureURL = (row["crmpictureurl"] != null && row["crmpictureurl"] != DBNull.Value) ? row["crmpictureurl"] as string : null;
 }
Esempio n. 16
0
 public void Load(XElement dialogueElement)
 {
     SIPDialogue = new SIPDialogue();
     SIPDialogue.Id = new Guid(dialogueElement.Element("id").Value);
     SIPDialogue.Owner = dialogueElement.Element("owner").Value;
     SIPDialogue.AdminMemberId = dialogueElement.Element("adminmemberid").Value;
     SIPDialogue.LocalTag = dialogueElement.Element("localtag").Value;
     SIPDialogue.RemoteTag = dialogueElement.Element("remotetag").Value;
     SIPDialogue.LocalUserField = SIPUserField.ParseSIPUserField(dialogueElement.Element("localuserfield").Value);
     SIPDialogue.RemoteUserField = SIPUserField.ParseSIPUserField(dialogueElement.Element("remoteuserfield").Value);
     SIPDialogue.CallId = dialogueElement.Element("callid").Value;
     SIPDialogue.CSeq = Convert.ToInt32(dialogueElement.Element("cseq").Value);
     SIPDialogue.BridgeId = new Guid(dialogueElement.Element("bridgeid").Value);
     SIPDialogue.RemoteTarget = SIPURI.ParseSIPURI(dialogueElement.Element("remotetarget").Value);
     SIPDialogue.RouteSet = (dialogueElement.Element("routeset") != null && !dialogueElement.Element("routeset").Value.IsNullOrBlank()) ? SIPRouteSet.ParseSIPRouteSet(dialogueElement.Element("routeset").Value) : null;
     SIPDialogue.ProxySendFrom = (dialogueElement.Element("proxysipsocket") != null) ? dialogueElement.Element("proxysipsocket").Value : null;
     SIPDialogue.CDRId = new Guid(dialogueElement.Element("cdrid").Value);
     SIPDialogue.CallDurationLimit = (dialogueElement.Element("calldurationlimit") != null) ? Convert.ToInt32(dialogueElement.Element("calldurationlimit").Value) : 0;
     SIPDialogue.Direction = (dialogueElement.Element("direction") != null) ? (SIPCallDirection)Enum.Parse(typeof(SIPCallDirection), dialogueElement.Element("direction").Value, true) : SIPCallDirection.None;
     Inserted = DateTimeOffset.Parse(dialogueElement.Element("inserted").Value);
     TransferMode = dialogueElement.Element("transfermode").Value;
     SDP = dialogueElement.Element("sdp").Value;
     RemoteSDP = dialogueElement.Element("remotesdp").Value;
     //SIPDialogue.SwitchboardCallerDescription = (dialogueElement.Element("switchboardcallerdescription") != null) ? dialogueElement.Element("switchboardcallerdescription").Value : null;
     //SIPDialogue.SwitchboardDescription = (dialogueElement.Element("switchboarddescription") != null) ? dialogueElement.Element("switchboarddescription").Value : null;
     SIPDialogue.SwitchboardOwner = (dialogueElement.Element("switchboardowner") != null) ? dialogueElement.Element("switchboardowner").Value : null;
     SIPDialogue.SwitchboardLineName = (dialogueElement.Element("switchboardlinename") != null) ? dialogueElement.Element("switchboardlinename").Value : null;
     SIPDialogue.CRMPersonName = (dialogueElement.Element("crmpersonname") != null) ? dialogueElement.Element("crmpersonname").Value : null;
     SIPDialogue.CRMCompanyName = (dialogueElement.Element("crmcompanyname") != null) ? dialogueElement.Element("crmcompanyname").Value : null;
     SIPDialogue.CRMPictureURL = (dialogueElement.Element("crmpictureurl") != null) ? dialogueElement.Element("crmpictureurl").Value : null;
 }
Esempio n. 17
0
 /// <summary>
 /// Cleans up after a SIP call has completely finished.
 /// </summary>
 private void CallFinished(SIPDialogue dialogue)
 {
     m_pendingIncomingCall = null;
     CallEnded(this);
 }
Esempio n. 18
0
 public SIPDialogueAsset(SIPDialogue sipDialogue)
 {
     SIPDialogue = sipDialogue;
 }
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     throw new NotImplementedException();
 }
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     return Answer(contentType, body, answeredDialogue, transferMode);
 }
Esempio n. 21
0
 public SIPDialogue Answer(string contentType, string body, SIPDialogue answeredDialogue,
                           SIPDialogueTransferModesEnum transferMode)
 {
     return(Answer(contentType, body, null, answeredDialogue, transferMode));
 }
 public SIPDialogue Answer(string contentType, string body, string toTag, SIPDialogue answeredDialogue, SIPDialogueTransferModesEnum transferMode)
 {
     throw new NotImplementedException();
 }
Esempio n. 23
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;
            }
        }
Esempio n. 24
0
        private void ServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                //if (Thread.CurrentThread.Name.IsNullOrBlank())
                //{
                //    Thread.CurrentThread.Name = THREAD_NAME + DateTime.Now.ToString("HHmmss") + "-" + Crypto.GetRandomString(3);
                //}

                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + m_serverTransaction.TransactionRequest.URI.ToString() + ".", Owner));
                //m_sipTrace += "Received " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss") + " " + localEndPoint + "<-" + remoteEndPoint + "\r\n" + sipResponse.ToString();

                m_serverTransaction.UACInviteTransactionInformationResponseReceived -= ServerInformationResponseReceived;
                m_serverTransaction.UACInviteTransactionFinalResponseReceived -= ServerFinalResponseReceived;
                m_serverTransaction.TransactionTraceMessage -= TransactionTraceMessage;

                if (m_callCancelled && sipResponse.Status == SIPResponseStatusCodesEnum.RequestTerminated)
                {
                    // No action required. Correctly received request terminated on an INVITE we cancelled.
                }
                else if (m_callCancelled)
                {
                    #region Call has been cancelled, hangup.

                    if (m_hungupOnCancel)
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "A cancelled call to " + m_sipCallDescriptor.Uri + " has been answered AND has already been hungup, no further action being taken.", Owner));
                    }
                    else
                    {
                        m_hungupOnCancel = true;

                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "A cancelled call to " + m_sipCallDescriptor.Uri + " has been answered, hanging up.", Owner));

                        if (sipResponse.Header.Contact != null && sipResponse.Header.Contact.Count > 0)
                        {
                            SIPURI byeURI = sipResponse.Header.Contact[0].ContactURI;
                            SIPRequest byeRequest = GetByeRequest(sipResponse, byeURI, localSIPEndPoint);

                            //SIPEndPoint byeEndPoint = m_sipTransport.GetRequestEndPoint(byeRequest, m_outboundProxy, true);

                            // if (byeEndPoint != null)
                            // {
                            SIPNonInviteTransaction byeTransaction = m_sipTransport.CreateNonInviteTransaction(byeRequest, null, localSIPEndPoint, m_outboundProxy);
                            byeTransaction.SendReliableRequest();
                            // }
                            // else
                            // {
                            //     Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Could not end BYE on cancelled call as request end point could not be determined " + byeRequest.URI.ToString(), Owner));
                            //}
                        }
                        else
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "No contact header provided on response for cancelled call to " + m_sipCallDescriptor.Uri + " no further action.", Owner));
                        }
                    }

                    #endregion
                }
                else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    //logger.Debug("AuthReqd Final response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + m_serverTransaction.TransactionRequest.URI.ToString() + ".");

                    #region Authenticate client call to third party server.

                    if (!m_callCancelled)
                    {
                        if (m_sipCallDescriptor.Password.IsNullOrBlank())
                        {
                            // No point trying to authenticate if there is no password to use.
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Forward leg failed, authentication was requested but no credentials were available.", Owner));
                            FireCallFailed(this, "Authentication requested when no credentials available");
                        }
                        else if (m_serverAuthAttempts == 0)
                        {
                            m_serverAuthAttempts = 1;

                            // Resend INVITE with credentials.
                            string username = (m_sipCallDescriptor.AuthUsername != null && m_sipCallDescriptor.AuthUsername.Trim().Length > 0) ? m_sipCallDescriptor.AuthUsername : m_sipCallDescriptor.Username;
                            SIPAuthorisationDigest authRequest = sipResponse.Header.AuthenticationHeader.SIPDigest;
                            authRequest.SetCredentials(username, m_sipCallDescriptor.Password, m_sipCallDescriptor.Uri, SIPMethodsEnum.INVITE.ToString());

                            SIPRequest authInviteRequest = m_serverTransaction.TransactionRequest;

                            //if (SIPProviderMagicJack.IsMagicJackRequest(sipResponse))
                            //{
                            //    authInviteRequest.Header.AuthenticationHeader = SIPProviderMagicJack.GetAuthenticationHeader(sipResponse);
                            //}
                            //else
                            //{
                            authInviteRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authRequest);
                            authInviteRequest.Header.AuthenticationHeader.SIPDigest.Response = authRequest.Digest;
                            //}

                            authInviteRequest.Header.Vias.TopViaHeader.Branch = CallProperties.CreateBranchId();
                            authInviteRequest.Header.CSeq = authInviteRequest.Header.CSeq + 1;

                            // Create a new UAC transaction to establish the authenticated server call.
                            var originalCallTransaction = m_serverTransaction;
                            m_serverTransaction = m_sipTransport.CreateUACTransaction(authInviteRequest, m_serverEndPoint, localSIPEndPoint, m_outboundProxy);
                            if (m_serverTransaction.CDR != null)
                            {
                                m_serverTransaction.CDR.Owner = Owner;
                                m_serverTransaction.CDR.AdminMemberId = AdminMemberId;
                                m_serverTransaction.CDR.DialPlanContextID = m_sipCallDescriptor.DialPlanContextID;

                                m_serverTransaction.CDR.Updated();

                                if (AccountCode != null)
                                {
                                    //var rtccCDR = new SIPSorcery.Entities.CDR()
                                    //{
                                    //    ID = m_serverTransaction.CDR.CDRId.ToString(),
                                    //    Owner = m_serverTransaction.CDR.Owner,
                                    //    AdminMemberID = m_serverTransaction.CDR.AdminMemberId,
                                    //    Inserted = DateTimeOffset.UtcNow.ToString("o"),
                                    //    Created = DateTimeOffset.UtcNow.ToString("o"),
                                    //    DstHost = "",
                                    //    DstURI = m_sipCallDescriptor.Uri,
                                    //    CallID = "",
                                    //    FromHeader = m_sipCallDescriptor.From,
                                    //    LocalSocket = "udp:0.0.0.0:5060",
                                    //    RemoteSocket = "udp:0.0.0.0:5060",
                                    //    Direction = m_serverTransaction.CDR.CallDirection.ToString(),
                                    //    DialPlanContextID = m_sipCallDescriptor.DialPlanContextID.ToString()
                                    //};
            #if !SILVERLIGHT && !MIN_BUILD
                                    m_customerAccountDataLayer.UpdateRealTimeCallControlCDRID(originalCallTransaction.CDR.CDRId.ToString(), m_serverTransaction.CDR);
            #endif

                                    //m_serverTransaction.CDR.AccountCode = AccountCode;
                                    //m_serverTransaction.CDR.Rate = Rate;

                                    // Transfer any credit reservations from the original call to the new call.
                                    //m_serverTransaction.CDR.SecondsReserved = originalCallTransaction.CDR.SecondsReserved;
                                    //m_serverTransaction.CDR.Cost = originalCallTransaction.CDR.Cost;
                                    //m_serverTransaction.CDR.IncrementSeconds = originalCallTransaction.CDR.IncrementSeconds;
                                    //originalCallTransaction.CDR.SecondsReserved = 0;
                                    //originalCallTransaction.CDR.Cost = 0;
                                    //originalCallTransaction.CDR.ReconciliationResult = "reallocated";
                                    //originalCallTransaction.CDR.IsHangingUp = true;
                                }

                                logger.Debug("RTCC reservation was reallocated from CDR " + originalCallTransaction.CDR.CDRId + " to " + m_serverTransaction.CDR.CDRId + " for owner " + Owner + ".");
                            }
                            m_serverTransaction.UACInviteTransactionInformationResponseReceived += ServerInformationResponseReceived;
                            m_serverTransaction.UACInviteTransactionFinalResponseReceived += ServerFinalResponseReceived;
                            m_serverTransaction.UACInviteTransactionTimedOut += ServerTimedOut;
                            m_serverTransaction.TransactionTraceMessage += TransactionTraceMessage;

                            //logger.Debug("Sending authenticated switchcall INVITE to " + ForwardedCallStruct.Host + ".");
                            m_serverTransaction.SendInviteRequest(m_serverEndPoint, authInviteRequest);
                            //m_sipTrace += "Sending " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss") + " " + localEndPoint + "->" + ForwardedTransaction.TransactionRequest.GetRequestEndPoint() + "\r\n" + ForwardedTransaction.TransactionRequest.ToString();
                        }
                        else
                        {
                            //logger.Debug("Authentication of client call to switch server failed.");
                            FireCallFailed(this, "Authentication with provided credentials failed");
                        }
                    }

                    #endregion
                }
                else
                {
                    if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299)
                    {
                        if (sipResponse.Body.IsNullOrBlank())
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Body on UAC response was empty.", Owner));
                        }
                        else if (m_sipCallDescriptor.ContentType == m_sdpContentType)
                        {
                            if (!m_sipCallDescriptor.MangleResponseSDP)
                            {
                                IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body);
                                string sdpSocket = (sdpEndPoint != null) ? sdpEndPoint.ToString() : "could not determine";
                                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response was set to NOT mangle, RTP socket " + sdpEndPoint.ToString() + ".", Owner));
                            }
                            else
                            {
                                //m_callInProgress = false; // the call is now established
                                //logger.Debug("Final response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + ForwardedTransaction.TransactionRequest.URI.ToString() + ".");
                                // Determine of response SDP should be mangled.

                                IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body);
                                //Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAC response SDP was mangled from sdp=" + sdpEndPoint.Address.ToString() + ", proxyfrom=" + sipResponse.Header.ProxyReceivedFrom + ", mangle=" + m_sipCallDescriptor.MangleResponseSDP + ".", null));
                                if (sdpEndPoint != null)
                                {
                                    if (!IPSocket.IsPrivateAddress(sdpEndPoint.Address.ToString()))
                                    {
                                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response had public IP not mangled, RTP socket " + sdpEndPoint.ToString() + ".", Owner));
                                    }
                                    else
                                    {
                                        bool wasSDPMangled = false;
                                        string publicIPAddress = null;

                                        if (!sipResponse.Header.ProxyReceivedFrom.IsNullOrBlank())
                                        {
                                            IPAddress remoteUASAddress = SIPEndPoint.ParseSIPEndPoint(sipResponse.Header.ProxyReceivedFrom).Address;
                                            if (IPSocket.IsPrivateAddress(remoteUASAddress.ToString()) && m_sipCallDescriptor.MangleIPAddress != null)
                                            {
                                                // If the response has arrived here on a private IP address then it must be
                                                // for a local version install and an incoming call that needs it's response mangled.
                                                if(!IPSocket.IsPrivateAddress(m_sipCallDescriptor.MangleIPAddress.ToString()))
                                                {
                                                    publicIPAddress = m_sipCallDescriptor.MangleIPAddress.ToString();
                                                }
                                            }
                                            else
                                            {
                                                publicIPAddress = remoteUASAddress.ToString();
                                            }
                                        }
                                        else if (!IPSocket.IsPrivateAddress(remoteEndPoint.Address.ToString()) && remoteEndPoint.Address != IPAddress.Any)
                                        {
                                            publicIPAddress = remoteEndPoint.Address.ToString();
                                        }
                                        else if (m_sipCallDescriptor.MangleIPAddress != null)
                                        {
                                            publicIPAddress = m_sipCallDescriptor.MangleIPAddress.ToString();
                                        }

                                        if (publicIPAddress != null)
                                        {
                                            sipResponse.Body = SIPPacketMangler.MangleSDP(sipResponse.Body, publicIPAddress, out wasSDPMangled);
                                        }

                                        if (wasSDPMangled)
                                        {
                                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response had RTP socket mangled from " + sdpEndPoint.ToString() + " to " + publicIPAddress + ":" + sdpEndPoint.Port + ".", Owner));
                                        }
                                        else if (sdpEndPoint != null)
                                        {
                                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response could not be mangled, RTP socket " + sdpEndPoint.ToString() + ".", Owner));
                                        }
                                    }
                                }
                                else
                                {
                                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP RTP socket on UAC response could not be determined.", Owner));
                                }
                            }
                        }

                        m_sipDialogue = new SIPDialogue(m_serverTransaction, Owner, AdminMemberId);
                        m_sipDialogue.CallDurationLimit = m_sipCallDescriptor.CallDurationLimit;

                        // Set switchboard dialogue values from the answered response or from dialplan set values.
                        //m_sipDialogue.SwitchboardCallerDescription = sipResponse.Header.SwitchboardCallerDescription;
                        m_sipDialogue.SwitchboardLineName = sipResponse.Header.SwitchboardLineName;
                        m_sipDialogue.CRMPersonName = sipResponse.Header.CRMPersonName;
                        m_sipDialogue.CRMCompanyName = sipResponse.Header.CRMCompanyName;
                        m_sipDialogue.CRMPictureURL = sipResponse.Header.CRMPictureURL;

                        if (m_sipCallDescriptor.SwitchboardHeaders != null)
                        {
                            //if (!m_sipCallDescriptor.SwitchboardHeaders.SwitchboardDialogueDescription.IsNullOrBlank())
                            //{
                            //    m_sipDialogue.SwitchboardDescription = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardDialogueDescription;
                            //}

                            m_sipDialogue.SwitchboardLineName = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardLineName;
                            m_sipDialogue.SwitchboardOwner = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardOwner;
                        }
                    }

                    FireCallAnswered(this, sipResponse);
                }
            }
            catch (Exception excp)
            {
                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.Error, "Exception ServerFinalResponseReceived. " + excp.Message, Owner));
            }
        }
        /// <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;
            }
        }
        private SIPRequest CreateDummyRequest(SIPDialogue dialogueToReplace, string callDestination)
        {
            SIPRequest dummyInvite = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURIRelaxed(callDestination + "@sipsorcery.com"));
            SIPHeader dummyHeader = new SIPHeader("<sip:[email protected]>", "<sip:[email protected]>", 1, CallProperties.CreateNewCallId());
            dummyHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            dummyHeader.Vias.PushViaHeader(new SIPViaHeader(new IPEndPoint(SIPTransport.BlackholeAddress, 0), CallProperties.CreateBranchId()));
            dummyInvite.Header = dummyHeader;
            dummyInvite.Header.ContentType = "application/sdp";
            dummyInvite.Body = dialogueToReplace.SDP;

            return dummyInvite;
        }
        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();
            }
        }