Example #1
0
        internal const Int64 SHUTDOWN_TIMEOUT = 2000; /* miliseconds. */

        internal TSIP_Dialog(tsip_dialog_type_t type, String callId, TSip_Session session)
        {
            mId           = sUniqueId++;
            mRecordRoutes = new List <TSIP_HeaderRecordRoute>();
            mChallenges   = new List <TSIP_Challenge>();

            mPaths          = new List <TSIP_Uri>();
            mServiceRoutes  = new List <TSIP_Uri>();
            mAssociatedUris = new List <TSIP_Uri>();

            mState = tsip_dialog_state_t.Initial;
            mType  = type;

            mCallId     = String.IsNullOrEmpty(callId) ? TSIP_HeaderCallId.RandomCallId() : callId;
            mSipSession = session;

            /* Sets some default values */
            mExpires   = TSip_Session.DEFAULT_EXPIRES;
            mTagLocal  = TSK_String.Random();
            mCSeqValue = (UInt32) new Random().Next();

            /*=== SIP Session ===*/
            if (mSipSession != null)
            {
                mExpires  = mSipSession.Expires;
                mUriLocal = !String.IsNullOrEmpty(callId) /* Server Side */ ? mSipSession.UriTo : mSipSession.UriFrom;
                if (mSipSession.UriTo != null)
                {
                    mUriRemote       = mSipSession.UriTo;
                    mUriRemoteTarget = mSipSession.UriTo;
                }
                else
                {
                    mUriRemote       = mSipSession.UriFrom;
                    mUriRemoteTarget = mSipSession.Stack.Realm;
                }
            }
            else
            {
                TSK_Debug.Error("Invalid Sip Session");
            }
        }
Example #2
0
        /// <summary>
        /// Updates the dialog state:
        /// - Authorizations (using challenges from the @a response message)
        /// - State (early, established, disconnected, ...)
        /// - Routes (and Service-Route)
        /// - Target (remote)
        /// - ...
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        protected Boolean UpdateWithResponse(TSIP_Response response)
        {
            if (response == null || response.To == null || response.CSeq == null)
            {
                return(false);
            }
            String tag = response.To.Tag;

            /*
             *	1xx (!100) or 2xx
             */
            /*
             *	401 or 407 or 421 or 494
             */
            if (response.StatusCode == 401 || response.StatusCode == 407 || response.StatusCode == 421 || response.StatusCode == 494)
            {
                Boolean acceptNewVector;

                /* 3GPP IMS - Each authentication vector is used only once.
                 *	==> Re-registration/De-registration ==> Allow 401/407 challenge.
                 */
                acceptNewVector = (response.CSeq.RequestType == TSIP_Message.tsip_request_type_t.REGISTER && this.State == tsip_dialog_state_t.Established);
                return(this.UpdateChallenges(response, acceptNewVector));
            }
            else if (100 < response.StatusCode && response.StatusCode < 300)
            {
                tsip_dialog_state_t state = this.State;

                /* 1xx */
                if (response.StatusCode <= 199)
                {
                    if (String.IsNullOrEmpty(response.To.Tag))
                    {
                        TSK_Debug.Error("Invalid tag  parameter");
                        return(false);
                    }
                    state = tsip_dialog_state_t.Early;
                }
                /* 2xx */
                else
                {
                    state = tsip_dialog_state_t.Established;
                }

                /* Remote target */
                {
                    /*	RFC 3261 12.2.1.2 Processing the Responses
                     *  When a UAC receives a 2xx response to a target refresh request, it
                     *  MUST replace the dialog's remote target URI with the URI from the
                     *  Contact header field in that response, if present.
                     *
                     *  FIXME: Because PRACK/UPDATE sent before the session is established MUST have
                     *  the rigth target URI to be delivered to the UAS ==> Do not not check that we are connected
                     */
                    if (response.CSeq.RequestType != TSIP_Message.tsip_request_type_t.REGISTER && response.Contact != null && response.Contact.Uri != null)
                    {
                        mUriRemoteTarget = response.Contact.Uri.Clone(true, false);
                    }
                }

                /* Route sets */
                {
                    int index;
                    TSIP_HeaderRecordRoute recordRoute;

                    mRecordRoutes.Clear();

                    for (index = 0; (recordRoute = response.GetHeaderAtIndex(TSIP_Header.tsip_header_type_t.Record_Route, index) as TSIP_HeaderRecordRoute) != null; index++)
                    {
                        mRecordRoutes.Insert(0, recordRoute); /* Copy reversed. */
                    }
                }

                /* cseq + tags + ... */
                if (this.State == tsip_dialog_state_t.Established && String.Equals(mTagRemote, tag, StringComparison.InvariantCultureIgnoreCase))
                {
                    return(true);
                }
                else
                {
                    if (response.CSeq.RequestType != TSIP_Message.tsip_request_type_t.REGISTER && response.CSeq.RequestType != TSIP_Message.tsip_request_type_t.PUBLISH)
                    { /* REGISTER and PUBLISH don't establish dialog */
                        mTagRemote = tag;
                    }
#if NEVER_EXECUTE_00    // PRACK and BYE will have same CSeq value ==> Let CSeq value to be incremented by "tsip_dialog_request_new()"
                    self->cseq_value = response->CSeq ? response->CSeq->seq : self->cseq_value;
#endif
                }

                this.State = state;
                return(true);
            }

            return(true);
        }