ToString() public method

public ToString ( ) : string
return string
        /// <summary>
        /// In transaction ACK requests are for non-2xx responses, i.e. INVITE rejected and no dialogue being created.
        /// </summary>
        private SIPRequest GetInTransactionACKRequest(SIPResponse sipResponse, SIPURI ackURI, SIPEndPoint localSIPEndPoint)
        {
            SIPRequest ackRequest = new SIPRequest(SIPMethodsEnum.ACK, ackURI.ToString());
            ackRequest.LocalSIPEndPoint = localSIPEndPoint;

            SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To, sipResponse.Header.CSeq, sipResponse.Header.CallId);
            header.CSeqMethod = SIPMethodsEnum.ACK;
            header.AuthenticationHeader = TransactionRequest.Header.AuthenticationHeader;
            header.Routes = base.TransactionRequest.Header.Routes;
            header.ProxySendFrom = base.TransactionRequest.Header.ProxySendFrom;

            ackRequest.Header = header;

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, sipResponse.Header.Vias.TopViaHeader.Branch);
            ackRequest.Header.Vias.PushViaHeader(viaHeader);

            return ackRequest;
        }
        /// <summary>
        /// New transaction ACK requests are for 2xx responses, i.e. INVITE accepted and dialogue being created.
        /// </summary>
        /// <remarks>
        /// From RFC 3261 Chapter 17.1.1.3 - ACK for non-2xx final responses
        /// 
        /// IMPORTANT:
        /// an ACK for a non-2xx response will also have the same branch ID as the INVITE whose response it acknowledges.
        /// 
        /// The ACK request constructed by the client transaction MUST contain
        /// values for the Call-ID, From, and Request-URI that are equal to the
        /// values of those header fields in the request passed to the transport
        /// by the client transaction (call this the "original request").  The To
        /// header field in the ACK MUST equal the To header field in the
        /// response being acknowledged, and therefore will usually differ from
        /// the To header field in the original request by the addition of the
        /// tag parameter.  The ACK MUST contain a single Via header field, and
        /// this MUST be equal to the top Via header field of the original
        /// request.  The CSeq header field in the ACK MUST contain the same
        /// value for the sequence number as was present in the original request,
        /// but the method parameter MUST be equal to "ACK".
        ///
        /// If the INVITE request whose response is being acknowledged had Route
        /// header fields, those header fields MUST appear in the ACK.  This is
        /// to ensure that the ACK can be routed properly through any downstream
        /// stateless proxies.
        /// 
        /// From RFC 3261 Chapter 13.2.2.4 - ACK for 2xx final responses
        /// 
        /// IMPORTANT:
        /// an ACK for a 2xx final response is a new transaction and has a new branch ID.
        /// 
        /// The UAC core MUST generate an ACK request for each 2xx received from
        /// the transaction layer.  The header fields of the ACK are constructed
        /// in the same way as for any request sent within a dialog (see Section
        /// 12) with the exception of the CSeq and the header fields related to
        /// authentication.  The sequence number of the CSeq header field MUST be
        /// the same as the INVITE being acknowledged, but the CSeq method MUST
        /// be ACK.  The ACK MUST contain the same credentials as the INVITE.  If
        /// the 2xx contains an offer (based on the rules above), the ACK MUST
        /// carry an answer in its body.  If the offer in the 2xx response is not
        /// acceptable, the UAC core MUST generate a valid answer in the ACK and
        /// then send a BYE immediately.
        /// </remarks>
        private SIPRequest GetNewTransactionACKRequest(SIPResponse sipResponse, SIPURI ackURI, SIPEndPoint localSIPEndPoint)
        {
            SIPRequest ackRequest = new SIPRequest(SIPMethodsEnum.ACK, ackURI.ToString());
            ackRequest.LocalSIPEndPoint = localSIPEndPoint;

            SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To, sipResponse.Header.CSeq, sipResponse.Header.CallId);
            header.CSeqMethod = SIPMethodsEnum.ACK;
            header.AuthenticationHeader = TransactionRequest.Header.AuthenticationHeader;
            header.ProxySendFrom = base.TransactionRequest.Header.ProxySendFrom;

            if (sipResponse.Header.RecordRoutes != null)
            {
                header.Routes = sipResponse.Header.RecordRoutes.Reversed();
            }

            ackRequest.Header = header;

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId());
            ackRequest.Header.Vias.PushViaHeader(viaHeader);

            return ackRequest;
        }
Example #3
0
        /// <summary>
        /// Processes an in dialogue REFER request that specifies a new destination for an existing call leg.
        /// </summary>
        /// <param name="username">The username of the user the transfer is being processed for.</param>
        /// <param name="referTo">The Refer-To header URI from the REFER request.</param>
        /// <param name="dialplanName">The dialplan to use to process the transfer.</param>
        /// <param name="replacesCallID">The call ID that is being replaced by the new dialogue if one is created.</param>
        /// <returns>A SIP server user agent.</returns>
        public ISIPServerUserAgent BlindTransfer(string username, SIPURI referTo, string dialplanName, SIPDialogue replacesDialogue)
        {
            if (dialplanName.IsNullOrBlank())
            {
                throw new ApplicationException("A dial plan name must be provided when processing a blind transfer.");
            }
            else if (referTo == null)
            {
                throw new ApplicationException("The refer to URI cannot be empty when processing a blind transfer.");
            }
            else if (replacesDialogue == null)
            {
                throw new ApplicationException("The blind transfer could not be initiated, the dialogue to transfer could not be found.");
            }

            //bool wasExecutionCountIncremented = false;
            Customer customer = null;
            SIPDialPlan dialPlan = null;

            try
            {
                customer = m_customerPersistor.Get(c => c.CustomerUsername == username);

                if (customer == null)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer using dialplan " + dialplanName + " rejected for " + username + " and " + referTo.ToString() + ", as no matching user.", username));
                    throw new ApplicationException("No matching user was found, the blind transfer was not initiated.");
                }
                else if (customer.Suspended)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer using dialplan " + dialplanName + " rejected for " + username + " and " + referTo.ToString() + ", user account is suspended.", username));
                    throw new ApplicationException("The user's account is suspended, the blind transfer was not initiated.");
                }

                else
                {
                    dialPlan = GetDialPlan_External(d => d.Owner == username && d.DialPlanName == dialplanName);
                    if (dialPlan == null)
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer rejected as no " + dialplanName + " dialplan exists.", username));
                        throw new ApplicationException("The blind transfer could not be initiated, no dialplan with name " + dialplanName + " could be found.");
                    }
                    else
                    {
                        if (!IsDialPlanExecutionAllowed(dialPlan, customer))
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Execution of blind transfer for dialplan " + dialplanName + " was not processed as maximum execution count has been reached.", username));
                            throw new ApplicationException("The blind transfer was not initiated, dial plan execution exceeded maximum allowed");
                        }
                        else
                        {
                            //IncrementCustomerExecutionCount(customer);

                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Blind transfer for dialplan " + dialplanName + " starting for " + referTo.ToString() + ".", username));

                            SIPDialogue oppositeDialogue = m_sipDialogueManager.GetOppositeDialogue(replacesDialogue);
                            ISIPServerUserAgent uas = new SIPTransferServerUserAgent(Log_External, m_sipDialogueManager.DialogueTransfer, m_sipTransport, m_outboundProxy, replacesDialogue, oppositeDialogue, referTo.ToString(), customer.CustomerUsername, customer.AdminId);

                            DialPlanScriptContext scriptContext = new DialPlanScriptContext(
                                    Log_External,
                                    m_sipTransport,
                                    CreateDialogueBridge,
                                    m_outboundProxy,
                                    uas,
                                    dialPlan,
                                    GetSIPProviders_External(p => p.Owner == username, null, 0, Int32.MaxValue),
                                    m_traceDirectory,
                                    null,
                                    customer,
                                    null,
                                    GetCanonicalDomain_External);
                            //scriptContext.DialPlanComplete += () => { DecrementCustomerExecutionCount(customer); };
                            m_dialPlanEngine.Execute(scriptContext, uas, SIPCallDirection.Out, CreateDialogueBridge, this);

                            return uas;
                        }
                    }
                }
            }
            catch (ApplicationException)
            {
                throw;
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPCallManager BlindTransfer. " + excp.Message);

                //if (wasExecutionCountIncremented)
                //{
                //DecrementDialPlanExecutionCount(dialPlan, customer.Id, originalExecutionCount);
                //DecrementCustomerExecutionCount(customer);
                //}

                throw;
            }
        }
        /// <summary>
        /// Can't be used for local destinations!
        /// </summary>
        /// <param name="sipRequest"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        private SIPCallDescriptor GetForwardsForExternalLeg(
            SIPRequest sipRequest,
            SIPURI callLegURI,
            string customContentType,
            string customContent,
            string fromDisplayName,
            string fromUsername,
            string fromHost,
            CRMHeaders contact)
        {
            try
            {
                SIPCallDescriptor sipCallDescriptor = null;

                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Attempting to locate a provider for call leg: " + callLegURI.ToString() + ".", m_username));
                bool providerFound = false;

                string contentType = (sipRequest != null) ? sipRequest.Header.ContentType : null;
                string content = (sipRequest != null) ? sipRequest.Body : null;

                if (!customContentType.IsNullOrBlank())
                {
                    contentType = customContentType;
                }

                if (!customContent.IsNullOrBlank())
                {
                    content = customContent;
                }

                IPAddress publicSDPAddress = PublicIPAddress;
                if (publicSDPAddress == null && sipRequest != null)
                {
                    publicSDPAddress = SIPPacketMangler.GetRequestIPAddress(sipRequest);
                }

                if (m_sipProviders != null)
                {
                    foreach (SIPProvider provider in m_sipProviders)
                    {
                        if (callLegURI.Host.ToUpper() == provider.ProviderName.ToUpper())
                        {
                            if (provider.ProviderType == ProviderTypes.GoogleVoice)
                            {
                                sipCallDescriptor = new SIPCallDescriptor(
                                        provider.ProviderUsername,
                                        provider.ProviderPassword,
                                        callLegURI.User + "@" + provider.ProviderName,
                                        provider.GVCallbackNumber,
                                        provider.GVCallbackPattern,
                                        (provider.GVCallbackType != null) ? (int)provider.GVCallbackType.Value : DEFAULT_GVCALLBACK_TYPE,
                                        content,
                                        contentType);

                                sipCallDescriptor.CRMHeaders = contact;
                                providerFound = true;
                                break;
                            }
                            else
                            {
                                SIPURI providerURI = SIPURI.ParseSIPURI(provider.ProviderServer);
                                if (providerURI != null)
                                {
                                    providerURI.User = callLegURI.User;

                                    if (callLegURI.Parameters.Count > 0)
                                    {
                                        foreach (string parameterName in callLegURI.Parameters.GetKeys())
                                        {
                                            if (!providerURI.Parameters.Has(parameterName))
                                            {
                                                providerURI.Parameters.Set(parameterName, callLegURI.Parameters.Get(parameterName));
                                            }
                                        }
                                    }

                                    if (callLegURI.Headers.Count > 0)
                                    {
                                        foreach (string headerName in callLegURI.Headers.GetKeys())
                                        {
                                            if (!providerURI.Headers.Has(headerName))
                                            {
                                                providerURI.Headers.Set(headerName, callLegURI.Headers.Get(headerName));
                                            }
                                        }
                                    }

                                    SIPFromHeader fromHeader = ParseFromHeaderOption(provider.ProviderFrom, sipRequest, provider.ProviderUsername, providerURI.Host);

                                    sipCallDescriptor = new SIPCallDescriptor(
                                        provider.ProviderUsername,
                                        provider.ProviderPassword,
                                        providerURI.ToString(),
                                        fromHeader.ToString(),
                                        providerURI.ToString(),
                                        null,
                                        SIPCallDescriptor.ParseCustomHeaders(SubstituteRequestVars(sipRequest, provider.CustomHeaders)),
                                        provider.ProviderAuthUsername,
                                        SIPCallDirection.Out,
                                        contentType,
                                        content,
                                        publicSDPAddress);
                                    sipCallDescriptor.CRMHeaders = contact;

                                    if (!provider.ProviderOutboundProxy.IsNullOrBlank())
                                    {
                                        sipCallDescriptor.ProxySendFrom = provider.ProviderOutboundProxy.Trim();
                                    }

                                    providerFound = true;

                                    if (provider.ProviderFrom.IsNullOrBlank())
                                    {
                                        // If there is already a custom From header set on the provider that overrides the general settings.
                                        sipCallDescriptor.SetGeneralFromHeaderFields(fromDisplayName, fromUsername, fromHost);
                                    }

                                    break;
                                }
                                else
                                {
                                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Could not parse SIP URI from Provider Server " + provider.ProviderServer + " in GetForwardsForExternalLeg.", m_username));
                                }
                            }
                        }
                    }
                }

                if (!providerFound)
                {
                    // Treat as an anonymous SIP URI.

                    // Copy the From header so the tag can be removed before adding to the forwarded request.
                    string fromHeaderStr = (sipRequest != null) ? sipRequest.Header.From.ToString() : m_anonymousFromURI;
                    SIPFromHeader forwardedFromHeader = SIPFromHeader.ParseFromHeader(fromHeaderStr);
                    forwardedFromHeader.FromTag = null;

                    sipCallDescriptor = new SIPCallDescriptor(
                        m_anonymousUsername,
                        null,
                        callLegURI.ToString(),
                        forwardedFromHeader.ToString(),
                        callLegURI.ToString(),
                        null,
                        null,
                        null,
                        SIPCallDirection.Out,
                        contentType,
                        content,
                        publicSDPAddress);
                    sipCallDescriptor.CRMHeaders = contact;

                    sipCallDescriptor.SetGeneralFromHeaderFields(fromDisplayName, fromUsername, fromHost);
                }

                return sipCallDescriptor;
            }
            catch (Exception excp)
            {
                logger.Error("Exception GetForwardsForExternalLeg. " + excp.Message);
                return null;
            }
        }
        public List<SIPCallDescriptor> GetForwardsForRedirect(SIPURI redirectURI, SIPCallDescriptor callDescriptor)
        {
            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Getting forwards for redirect to " + redirectURI.ToString() + ".", m_username));

            List<SIPCallDescriptor> redirectCalls = new List<SIPCallDescriptor>();

            string localDomain = GetCanonicalDomain_External(redirectURI.Host, false);
            if (localDomain != null)
            {
                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect is for local SIP account " + redirectURI.User + " and canonical domain " + localDomain + ", looking up bindings.", m_username));

                SIPAccount sipAccount = GetSIPAccount_External(s => s.SIPUsername == redirectURI.User && s.SIPDomain == localDomain);

                List<SIPRegistrarBinding> bindings = GetRegistrarBindings_External(b => b.SIPAccountId == sipAccount.Id, null, 0, Int32.MaxValue);

                if (bindings != null)
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, bindings.Count + " bindings found for local SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " when processing redirect.", m_username));

                    // Build list of registered contacts.
                    for (int index = 0; index < bindings.Count; index++)
                    {
                        SIPRegistrarBinding binding = bindings[index];
                        SIPURI contactURI = binding.MangledContactSIPURI;
                        SIPCallDescriptor redirectCallDescriptor = callDescriptor.CopyOf();
                        redirectCallDescriptor.Uri = contactURI.ToString();
                        redirectCalls.Add(redirectCallDescriptor);
                    }
                }
                else
                {
                    Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "No bindings were found for local SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " when processing redirect.", m_username));
                }
            }
            else
            {
                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Redirect destination " + redirectURI.ToString() + " was determined as an external URI.", m_username));

                SIPCallDescriptor redirectCallDescriptor = callDescriptor.CopyOf();
                redirectCallDescriptor.Uri = redirectURI.ToString();
                redirectCalls.Add(redirectCallDescriptor);
            }

            return redirectCalls;
        }
        private SIPRequest GetInviteRequest(SIPDialogue dialogue, SIPEndPoint localSIPEndPoint, string body)
        {
            SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, dialogue.RemoteTarget);

            SIPHeader inviteHeader = new SIPHeader(SIPFromHeader.ParseFromHeader(dialogue.LocalUserField.ToString()), SIPToHeader.ParseToHeader(dialogue.RemoteUserField.ToString()), dialogue.CSeq, dialogue.CallId);
            SIPURI contactURI = new SIPURI(dialogue.RemoteTarget.Scheme, localSIPEndPoint);
            inviteHeader.Contact = SIPContactHeader.ParseContactHeader("<" + contactURI.ToString() + ">");
            inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE;
            inviteRequest.Header = inviteHeader;
            inviteRequest.Header.Routes = dialogue.RouteSet;

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId());
            inviteRequest.Header.Vias.PushViaHeader(viaHeader);

            inviteRequest.Body = body;
            inviteRequest.Header.ContentLength = body.Length;
            inviteRequest.Header.ContentType = "application/sdp";

            return inviteRequest;
        }
        public string SubscribeClient(
            string owner,
            string adminID,
            SIPRequest subscribeRequest,
            string toTag,
            SIPURI canonicalResourceURI,
            out SIPResponseStatusCodesEnum errorResponse,
            out string errorReason)
        {
            try
            {
                errorResponse = SIPResponseStatusCodesEnum.None;
                errorReason = null;

                SIPURI resourceURI = subscribeRequest.URI.CopyOf();
                SIPEventPackage eventPackage = SIPEventPackage.Parse(subscribeRequest.Header.Event);
                int expiry = subscribeRequest.Header.Expires;

                if (!(eventPackage == SIPEventPackage.Dialog || eventPackage == SIPEventPackage.Presence))
                {
                    throw new ApplicationException("Event package " + eventPackage.ToString() + " is not supported by the subscriptions manager.");
                }
                else
                {
                    if (expiry > 0)
                    {
                        string subscribeError = null;
                        string sessionID = Guid.NewGuid().ToString();
                        SIPDialogue subscribeDialogue = new SIPDialogue(subscribeRequest, owner, adminID, toTag);

                        if (eventPackage == SIPEventPackage.Dialog)
                        {
                            string monitorFilter = "dialog " + canonicalResourceURI.ToString();
                            if (!subscribeRequest.Body.IsNullOrBlank())
                            {
                                monitorFilter += " and " + subscribeRequest.Body;
                            }

                            m_publisher.Subscribe(owner, adminID, m_notificationsAddress, sessionID, SIPMonitorClientTypesEnum.Machine.ToString(), monitorFilter, expiry, null, out subscribeError);

                            if (subscribeError != null)
                            {
                                throw new ApplicationException(subscribeError);
                            }
                            else
                            {
                                SIPDialogEventSubscription subscription = new SIPDialogEventSubscription(MonitorLogEvent_External, sessionID, resourceURI, canonicalResourceURI, monitorFilter, subscribeDialogue, expiry, GetDialogues_External, GetDialogue_External);
                                m_subscriptions.Add(sessionID, subscription);
                                MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "New dialog subscription created for " + resourceURI.ToString() + ", expiry " + expiry + "s.", owner));
                            }
                        }
                        else if (eventPackage == SIPEventPackage.Presence)
                        {
                            string monitorFilter = "presence " + canonicalResourceURI.ToString();
                            m_publisher.Subscribe(owner, adminID, m_notificationsAddress, sessionID, SIPMonitorClientTypesEnum.Machine.ToString(), monitorFilter, expiry, null, out subscribeError);

                            if (subscribeError != null)
                            {
                                throw new ApplicationException(subscribeError);
                            }
                            else
                            {
                                bool switchboardAccountsOnly = subscribeRequest.Body == SIPPresenceEventSubscription.SWITCHBOARD_FILTER;
                                SIPPresenceEventSubscription subscription = new SIPPresenceEventSubscription(MonitorLogEvent_External, sessionID, resourceURI, canonicalResourceURI, monitorFilter, subscribeDialogue, expiry, m_sipAssetPersistor, GetSIPRegistrarBindingsCount_External, switchboardAccountsOnly);
                                m_subscriptions.Add(sessionID, subscription);
                                MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "New presence subscription created for " + resourceURI.ToString() + ", expiry " + expiry + "s.", owner));
                            }
                        }

                        return sessionID;
                    }

                    return null;
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception NotifierSubscriptionsManager SubscribeClient. " + excp.Message);
                throw;
            }
        }
        public string ToXMLText()
        {
            XNamespace ns             = m_dialogXMLNS;
            XDocument  dialogEventDoc = new XDocument(new XElement(ns + "dialog-info",
                                                                   new XAttribute("version", Version),
                                                                   new XAttribute("state", State),
                                                                   new XAttribute("entity", Entity.ToString())
                                                                   ));

            DialogItems.ForEach((item) =>
            {
                XElement dialogItemElement = item.ToXML();
                dialogEventDoc.Root.Add(dialogItemElement);
                item.HasBeenSent = true;
            });

            StringBuilder     sb  = new StringBuilder();
            XmlWriterSettings xws = new XmlWriterSettings();

            xws.NewLineHandling = NewLineHandling.None;
            xws.Indent          = true;

            using (XmlWriter xw = XmlWriter.Create(sb, xws))
            {
                dialogEventDoc.WriteTo(xw);
            }

            return(sb.ToString());
        }
        public override string ToXMLText()
        {
            XNamespace ns = m_pidfXMLNS;

            XDocument presenceDoc = new XDocument(new XElement(ns + "presence",
                                                               new XAttribute("entity", Entity.ToString())));

            Tuples.ForEach((item) =>
            {
                XElement tupleElement = item.ToXML();
                presenceDoc.Root.Add(tupleElement);
            });

            StringBuilder     sb  = new StringBuilder();
            XmlWriterSettings xws = new XmlWriterSettings();

            xws.NewLineHandling = NewLineHandling.None;
            xws.Indent          = true;

            using (XmlWriter xw = XmlWriter.Create(sb, xws))
            {
                presenceDoc.WriteTo(xw);
            }

            return(sb.ToString());
        }
        /// <summary>
        /// Puts the dialog participant information to an XML element.
        /// </summary>
        /// <param name="nodeName">A participant can represent a local or remote party, the node name needs to be set to either "local" or "remote".</param>
        /// <returns>An XML element representing the dialog participant.</returns>
        public XElement ToXML(string nodeName)
        {
            XNamespace ns = m_dialogXMLNS;
            XNamespace ss = m_sipsorceryXMLNS;
            XElement   participantElement = new XElement(ns + nodeName);

            if (URI != null)
            {
                XElement identityElement = new XElement(ns + "identity", URI.ToString());
                if (!DisplayName.IsNullOrBlank())
                {
                    identityElement.Add(new XAttribute("display-name", DisplayName));
                }
                participantElement.Add(identityElement);
            }

            if (TargetURI != null)
            {
                XElement targetElement = new XElement(ns + "target", new XAttribute("uri", TargetURI.ToString()));
                participantElement.Add(targetElement);
            }

            if (CSeq > 0)
            {
                XElement cseqElement = new XElement(ns + "cseq", CSeq);
                participantElement.Add(cseqElement);
            }

            if (!SwitchboardLineName.IsNullOrBlank())
            {
                XElement switchLineNameElement = new XElement(ss + "switchboardlinename", SwitchboardLineName);
                participantElement.Add(switchLineNameElement);
            }

            if (!CRMPersonName.IsNullOrBlank())
            {
                XElement crmPersonNameElement = new XElement(ss + "crmpersonname", CRMPersonName);
                participantElement.Add(crmPersonNameElement);
            }

            if (!CRMCompanyName.IsNullOrBlank())
            {
                XElement crmCompanyNameElement = new XElement(ss + "crmcompanyname", CRMCompanyName);
                participantElement.Add(crmCompanyNameElement);
            }

            if (!CRMPictureURL.IsNullOrBlank())
            {
                XElement crmPictureURLElement = new XElement(ss + "crmpictureurl", CRMPictureURL);
                participantElement.Add(crmPictureURLElement);
            }

            return(participantElement);
        }
        private SIPRequest GetReferRequest(SIPEndPoint localSIPEndPoint, SIPURI referTo)
        {
            SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, RemoteTarget);
            SIPFromHeader referFromHeader = SIPFromHeader.ParseFromHeader(LocalUserField.ToString());
            SIPToHeader referToHeader = SIPToHeader.ParseToHeader(RemoteUserField.ToString());
            int cseq = ++CSeq;

            SIPHeader referHeader = new SIPHeader(referFromHeader, referToHeader, cseq, CallId);
            referHeader.CSeqMethod = SIPMethodsEnum.REFER;
            referRequest.Header = referHeader;
            referRequest.Header.ReferTo = referTo.ToString();
            referRequest.Header.Routes = RouteSet;
            referRequest.Header.ProxySendFrom = ProxySendFrom;

            SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId());
            referRequest.Header.Vias.PushViaHeader(viaHeader);

            return referRequest;
        }