예제 #1
0
        /// <summary>
        /// Terminates dialog.
        /// </summary>
        /// <param name="reason">Termination reason. This value may be null.</param>
        /// <param name="sendBye">If true BYE is sent to remote party.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        public virtual void Terminate(string reason, bool sendBye)
        {
            lock (m_pLock){
                if (this.State == SIP_DialogState.Disposed)
                {
                    throw new ObjectDisposedException(this.GetType().Name);
                }
                if (this.State == SIP_DialogState.Terminating || this.State == SIP_DialogState.Terminated)
                {
                    return;
                }

                /* RFC 3261 15.
                 *  The caller's UA MAY send a BYE for either confirmed or early dialogs, and the callee's UA MAY send a BYE on
                 *  confirmed dialogs, but MUST NOT send a BYE on early dialogs.
                 *
                 * RFC 3261 15.1.
                 *  Once the BYE is constructed, the UAC core creates a new non-INVITE client transaction, and passes it the BYE request.
                 *  The UAC MUST consider the session terminated (and therefore stop sending or listening for media) as soon as the BYE
                 *  request is passed to the client transaction. If the response for the BYE is a 481 (Call/Transaction Does Not Exist)
                 *  or a 408 (Request Timeout) or no response at all is received for the BYE (that is, a timeout is returned by the
                 *  client transaction), the UAC MUST consider the session and the dialog terminated.
                 */

                this.SetState(SIP_DialogState.Terminating, true);

                if (sendBye)
                {
                    // TODO: UAS early

                    if (this.State == SIP_DialogState.Confirmed)
                    {
                        SIP_Request bye = CreateRequest(SIP_Methods.BYE);
                        if (!string.IsNullOrEmpty(reason))
                        {
                            SIP_t_ReasonValue r = new SIP_t_ReasonValue();
                            r.Protocol = "SIP";
                            r.Text     = reason;
                            bye.Reason.Add(r.ToStringValue());
                        }

                        // Send BYE, just wait BYE to complete, we don't care about response code.
                        SIP_RequestSender sender = CreateRequestSender(bye);
                        sender.Completed += delegate(object s, EventArgs a){
                            this.SetState(SIP_DialogState.Terminated, true);
                        };
                        sender.Start();
                    }
                }
                else
                {
                    this.SetState(SIP_DialogState.Terminated, true);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Starts terminating dialog.
        /// </summary>
        /// <param name="reason">Termination reason. This value may be null.</param>
        /// <param name="sendBye">If true BYE is sent to remote party.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        public override void Terminate(string reason, bool sendBye)
        {
            lock (SyncRoot)
            {
                if (State == SIP_DialogState.Disposed)
                {
                    throw new ObjectDisposedException(GetType().Name);
                }
                if (State == SIP_DialogState.Terminating || State == SIP_DialogState.Terminated)
                {
                    return;
                }

                /* RFC 3261 15.
                    The caller's UA MAY send a BYE for either confirmed or early dialogs, and the callee's UA MAY send a BYE on
                    confirmed dialogs, but MUST NOT send a BYE on early dialogs.
                 
                   RFC 3261 15.1.
                    Once the BYE is constructed, the UAC core creates a new non-INVITE client transaction, and passes it the BYE request.
                    The UAC MUST consider the session terminated (and therefore stop sending or listening for media) as soon as the BYE 
                    request is passed to the client transaction. If the response for the BYE is a 481 (Call/Transaction Does Not Exist) 
                    or a 408 (Request Timeout) or no response at all is received for the BYE (that is, a timeout is returned by the 
                    client transaction), the UAC MUST consider the session and the dialog terminated.
                */

                if (sendBye)
                {
                    if ((State == SIP_DialogState.Early && m_pActiveInvite is SIP_ClientTransaction) ||
                        State == SIP_DialogState.Confirmed)
                    {
                        SetState(SIP_DialogState.Terminating, true);

                        SIP_Request bye = CreateRequest(SIP_Methods.BYE);
                        if (!string.IsNullOrEmpty(reason))
                        {
                            SIP_t_ReasonValue r = new SIP_t_ReasonValue();
                            r.Protocol = "SIP";
                            r.Text = reason;
                            bye.Reason.Add(r.ToStringValue());
                        }

                        // Send BYE, just wait BYE to complete, we don't care about response code.
                        SIP_RequestSender sender = CreateRequestSender(bye);
                        sender.Completed += delegate { SetState(SIP_DialogState.Terminated, true); };
                        sender.Start();
                    }
                    else
                    {
                        /* We are "early" UAS dialog, we need todo follwoing:
                            *) If we havent sent final response, send '408 Request terminated' and we are done.
                            *) We have sen't final response, we need to wait ACK to arrive or timeout.
                                If will ACK arrives or timeout, send BYE.                                
                        */

                        if (m_pActiveInvite != null && m_pActiveInvite.FinalResponse == null)
                        {
                            Stack.CreateResponse(SIP_ResponseCodes.x408_Request_Timeout,
                                                 m_pActiveInvite.Request);

                            SetState(SIP_DialogState.Terminated, true);
                        }
                        else
                        {
                            // Wait ACK to arrive or timeout. 

                            SetState(SIP_DialogState.Terminating, true);
                        }
                    }
                }
                else
                {
                    SetState(SIP_DialogState.Terminated, true);
                }
            }
        }
        /// <summary>
        /// Starts terminating dialog.
        /// </summary>
        /// <param name="reason">Termination reason. This value may be null.</param>
        /// <param name="sendBye">If true BYE is sent to remote party.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        public override void Terminate(string reason, bool sendBye)
        {
            lock (SyncRoot)
            {
                if (State == SIP_DialogState.Disposed)
                {
                    throw new ObjectDisposedException(GetType().Name);
                }
                if (State == SIP_DialogState.Terminating || State == SIP_DialogState.Terminated)
                {
                    return;
                }

                /* RFC 3261 15.
                 *  The caller's UA MAY send a BYE for either confirmed or early dialogs, and the callee's UA MAY send a BYE on
                 *  confirmed dialogs, but MUST NOT send a BYE on early dialogs.
                 *
                 * RFC 3261 15.1.
                 *  Once the BYE is constructed, the UAC core creates a new non-INVITE client transaction, and passes it the BYE request.
                 *  The UAC MUST consider the session terminated (and therefore stop sending or listening for media) as soon as the BYE
                 *  request is passed to the client transaction. If the response for the BYE is a 481 (Call/Transaction Does Not Exist)
                 *  or a 408 (Request Timeout) or no response at all is received for the BYE (that is, a timeout is returned by the
                 *  client transaction), the UAC MUST consider the session and the dialog terminated.
                 */

                if (sendBye)
                {
                    if ((State == SIP_DialogState.Early && m_pActiveInvite is SIP_ClientTransaction) ||
                        State == SIP_DialogState.Confirmed)
                    {
                        SetState(SIP_DialogState.Terminating, true);

                        SIP_Request bye = CreateRequest(SIP_Methods.BYE);
                        if (!string.IsNullOrEmpty(reason))
                        {
                            SIP_t_ReasonValue r = new SIP_t_ReasonValue();
                            r.Protocol = "SIP";
                            r.Text     = reason;
                            bye.Reason.Add(r.ToStringValue());
                        }

                        // Send BYE, just wait BYE to complete, we don't care about response code.
                        SIP_RequestSender sender = CreateRequestSender(bye);
                        sender.Completed += delegate { SetState(SIP_DialogState.Terminated, true); };
                        sender.Start();
                    }
                    else
                    {
                        /* We are "early" UAS dialog, we need todo follwoing:
                         *) If we havent sent final response, send '408 Request terminated' and we are done.
                         *) We have sen't final response, we need to wait ACK to arrive or timeout.
                         *      If will ACK arrives or timeout, send BYE.
                         */

                        if (m_pActiveInvite != null && m_pActiveInvite.FinalResponse == null)
                        {
                            Stack.CreateResponse(SIP_ResponseCodes.x408_Request_Timeout,
                                                 m_pActiveInvite.Request);

                            SetState(SIP_DialogState.Terminated, true);
                        }
                        else
                        {
                            // Wait ACK to arrive or timeout.

                            SetState(SIP_DialogState.Terminating, true);
                        }
                    }
                }
                else
                {
                    SetState(SIP_DialogState.Terminated, true);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Terminates dialog.
        /// </summary>
        /// <param name="reason">Termination reason. This value may be null.</param>
        /// <param name="sendBye">If true BYE is sent to remote party.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        public virtual void Terminate(string reason, bool sendBye)
        {
            lock (m_pLock)
            {
                if (State == SIP_DialogState.Disposed)
                {
                    throw new ObjectDisposedException(GetType().Name);
                }
                if (State == SIP_DialogState.Terminating || State == SIP_DialogState.Terminated)
                {
                    return;
                }

                /* RFC 3261 15.
                    The caller's UA MAY send a BYE for either confirmed or early dialogs, and the callee's UA MAY send a BYE on
                    confirmed dialogs, but MUST NOT send a BYE on early dialogs.
                 
                   RFC 3261 15.1.
                    Once the BYE is constructed, the UAC core creates a new non-INVITE client transaction, and passes it the BYE request.
                    The UAC MUST consider the session terminated (and therefore stop sending or listening for media) as soon as the BYE 
                    request is passed to the client transaction. If the response for the BYE is a 481 (Call/Transaction Does Not Exist) 
                    or a 408 (Request Timeout) or no response at all is received for the BYE (that is, a timeout is returned by the 
                    client transaction), the UAC MUST consider the session and the dialog terminated.
                */

                SetState(SIP_DialogState.Terminating, true);

                if (sendBye)
                {
                    // TODO: UAS early

                    if (State == SIP_DialogState.Confirmed)
                    {
                        SIP_Request bye = CreateRequest(SIP_Methods.BYE);
                        if (!string.IsNullOrEmpty(reason))
                        {
                            SIP_t_ReasonValue r = new SIP_t_ReasonValue();
                            r.Protocol = "SIP";
                            r.Text = reason;
                            bye.Reason.Add(r.ToStringValue());
                        }

                        // Send BYE, just wait BYE to complete, we don't care about response code.
                        SIP_RequestSender sender = CreateRequestSender(bye);
                        sender.Completed += delegate { SetState(SIP_DialogState.Terminated, true); };
                        sender.Start();
                    }
                }
                else
                {
                    SetState(SIP_DialogState.Terminated, true);
                }
            }
        }