Package com.ericsson.ssa.sip.transaction

Source Code of com.ericsson.ssa.sip.transaction.NonInviteClientTransaction

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.ericsson.ssa.sip.transaction;

import static com.ericsson.ssa.sip.transaction.TransactionState.COMPLETED;
import static com.ericsson.ssa.sip.transaction.TransactionState.PROCEEDING;
import static com.ericsson.ssa.sip.transaction.TransactionState.TERMINATED;
import static com.ericsson.ssa.sip.transaction.TransactionState.TRYING;
import static com.ericsson.ssa.sip.transaction.TransactionTimer.TimerE;
import static com.ericsson.ssa.sip.transaction.TransactionTimer.TimerF;
import static com.ericsson.ssa.sip.transaction.TransactionTimer.TimerK;

import java.util.concurrent.Callable;
import java.util.logging.Level;

import com.ericsson.ssa.container.SipContainerThreadPool;
import com.ericsson.ssa.container.startup.SipMonitoring;
import com.ericsson.ssa.sip.Dispatcher;
import com.ericsson.ssa.sip.SipServletRequestImpl;
import com.ericsson.ssa.sip.SipServletResponseImpl;
import com.ericsson.ssa.sip.persistence.ReplicationUnitOfWork;
import com.ericsson.ssa.sip.timer.GeneralTimer;
import com.ericsson.ssa.sip.timer.GeneralTimerImpl;


/**
* @author ekrigro TODO To change the template for this generated type comment
*         go to Window - Preferences - Java - Code Style - Code Templates
*/
public class NonInviteClientTransaction extends ClientTransaction {
    private GeneralTimer _timerE; // T1 -> T1*2 ->
    private GeneralTimer _timerF; // 64*T1
    private GeneralTimer _timerK; // T4 for UDP 0s TCP

    /**
     * @param state
     * @param req
     */
    public NonInviteClientTransaction(String id, SipServletRequestImpl req) {
        super(id, TRYING, req);
        getRequest().saveRetransmissionApplicationStack();
        // start timer F
        _timerF = _timerService.createTimer(this, 64 * T1, TimerF);

        if (!_reliableTransport) {
            // Start timer E
            _timerE = _timerService.createTimer(this, T1, TimerE);
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.sip.Dispatcher#dispatch(com.ericsson.ssa.sip.SipServletResponseImpl)
     */
    public synchronized boolean handle(SipServletResponseImpl resp) {
        boolean isStop = false;
        // For every response got from the stack have to associate it to the req
        resp.setRequest(getRequest());

        int status = resp.getStatus() / 100;

        switch (_state) {
        case TRYING:

            if (status == 1) {
                if (_timerE != null) {
                    _timerE.cancel();
                    _timerE = _timerService.createTimer(this, T2, TimerE);
                }

                _state = PROCEEDING;
            } else {
                toCompleted(resp); // 2xx to 6xx
            }

            break;

        case PROCEEDING:

            if (status == 1) {
                break;
            } else {
                toCompleted(resp); // 2xx to 6xx
            }

            break;

        case COMPLETED:
            isStop = true;

            break; // Should not get any response from TU in this state

        case TERMINATED:
            isStop = true;

            break; // Should not get any response from TU in this state

        default:
            _log.log(Level.FINE, "IllegalState in ICT = " + _state);
            isStop = true;
        }

        return isStop; // Continue up the chain?
    }

    public void timeout(GeneralTimer timer) {
        TransactionTimer tt = (TransactionTimer) timer.getInfo();
        SipServletRequestImpl req = null;
        Dispatcher d = null;

        switch (tt) {
        case TimerE:

            synchronized (this) {
                if ((_state == TRYING) || (_state == PROCEEDING)) {
                    long delay = T2; // default to PROCEEDING delay

                    if (_state == TRYING) {
                        // Have to dirty cast in order not to reimplement hole
                        // structure
                        delay = ((GeneralTimerImpl) timer).getDelay();
                        // calculate next timer*2 but less then T2 (4sec)
                        delay = ((delay * 2) <= T2) ? (delay * 2) : T2;
                    }

                    if (_timerE != null) {
                        _timerE.cancel();
                    }

                    // schedule new timer
                    _timerE = _timerService.createTimer(this, delay,
                            TimerE);

                    // resend the request
                    getRequest().restoreRetransmissionApplicationStack();
                    req = (SipServletRequestImpl) getRequest().clone();
                }
            }

            // dispatch after synch block...
            if (req != null) {
                d = req.popDispatcher();

                if (d != null) {
                    d.dispatch(req);
                }

                if (SipMonitoring.isEnabled(SipMonitoring.TRANSACTION_MANAGER)) {
                    updateLastAccessTimestamp();
                }
            }

            break;

        case TimerF:

            SipServletResponseImpl resp = null;

            synchronized (this) {
                if ((_state == TRYING) || (_state == PROCEEDING)) {
                    resp = getRequest().createTerminatingResponse(408);
                    resp.setInternalTransportFailure(true);
                }

                // lets remove this transaction before sending the 408 response
                terminate(false);
            }

            // dispatch after synch block...
            if (resp != null) {
                popVia(resp);
                if (_log.isLoggable(Level.FINE)) {
                    _log.log(Level.FINE,
                        "Timer F fired - send 408 Request Timeout " + _state +
                        " , response = " + resp.toDebugString());
                }
                final SipServletResponseImpl respToSend = resp;
                SipContainerThreadPool.getInstance().execute(new Callable() {
                    public Object call() throws Exception {
                        try {
                          // UOW is set by the replication manager
                          TransactionManager.getInstance().invokeNextLayer(respToSend);
                        } finally {
                            ReplicationUnitOfWork.clearThreadLocal();
                        }
                        return null;
                    }
                });

                cleanup();
            }

            break; // Time to do some GC

        case TimerK:
            terminate();

            break;

        default:
            _log.log(Level.FINE, "IllegalTimer in ICT = " + tt);
        }
    }

    protected synchronized void terminate() {
        terminate(true);
    }
   
    /* TODO check synchronization */
    protected synchronized void terminate(boolean cleanup) {
        super.terminate(cleanup);

        if (_timerE != null) {
            _timerE.cancel();
            _timerE = null;
        }

        if (_timerF != null) {
            _timerF.cancel();
            _timerF = null;
        }

        if (_timerK != null) {
            _timerK.cancel();
            _timerK = null;
        }

        _state = TERMINATED;
    }

    private void toCompleted(SipServletResponseImpl resp) {
        if (_timerF != null) {
            _timerF.cancel();
            _timerF = null;
        }

        if (!_reliableTransport) { // Start timer K

            if (SipMonitoring.isEnabled(SipMonitoring.TRANSACTION_MANAGER)) {
                updateLastAccessTimestamp();
            }

            if (_timerE != null) {
                _timerE.cancel();
                _timerE = null;
            }

            _state = COMPLETED;
            _timerK = _timerService.createTimer(this, T4,TimerK);
           
            // Make sure dialog UOW is finished ASAP
            if (getDialog()  != null) {
                getDialog().getDialogLifeCycle().onTransactionRemoved(getTransactionId(), true);
            }
            clearRequest();
        } else {
            _state = TERMINATED; // TimerK = 0
            super.terminate();
        }
    }
}
TOP

Related Classes of com.ericsson.ssa.sip.transaction.NonInviteClientTransaction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.