All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mobicents.protocols.ss7.isup.impl.Circuit Maven / Gradle / Ivy

/*
 * TeleStax, Open Source Cloud Communications  Copyright 2012.
 * and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.mobicents.protocols.ss7.isup.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javolution.util.ReentrantLock;

import org.mobicents.protocols.ss7.isup.ISUPEvent;
import org.mobicents.protocols.ss7.isup.ISUPTimeoutEvent;
import org.mobicents.protocols.ss7.isup.ParameterException;
import org.mobicents.protocols.ss7.isup.impl.message.AbstractISUPMessage;
import org.mobicents.protocols.ss7.isup.message.AddressCompleteMessage;
import org.mobicents.protocols.ss7.isup.message.BlockingAckMessage;
import org.mobicents.protocols.ss7.isup.message.BlockingMessage;
import org.mobicents.protocols.ss7.isup.message.CircuitGroupBlockingMessage;
import org.mobicents.protocols.ss7.isup.message.CircuitGroupQueryMessage;
import org.mobicents.protocols.ss7.isup.message.CircuitGroupQueryResponseMessage;
import org.mobicents.protocols.ss7.isup.message.CircuitGroupResetAckMessage;
import org.mobicents.protocols.ss7.isup.message.CircuitGroupResetMessage;
import org.mobicents.protocols.ss7.isup.message.CircuitGroupUnblockingAckMessage;
import org.mobicents.protocols.ss7.isup.message.CircuitGroupUnblockingMessage;
import org.mobicents.protocols.ss7.isup.message.ConnectMessage;
import org.mobicents.protocols.ss7.isup.message.ISUPMessage;
import org.mobicents.protocols.ss7.isup.message.InformationMessage;
import org.mobicents.protocols.ss7.isup.message.InformationRequestMessage;
import org.mobicents.protocols.ss7.isup.message.InitialAddressMessage;
import org.mobicents.protocols.ss7.isup.message.ReleaseCompleteMessage;
import org.mobicents.protocols.ss7.isup.message.ReleaseMessage;
import org.mobicents.protocols.ss7.isup.message.ResetCircuitMessage;
import org.mobicents.protocols.ss7.isup.message.SubsequentAddressMessage;
import org.mobicents.protocols.ss7.isup.message.UnblockingAckMessage;
import org.mobicents.protocols.ss7.isup.message.UnblockingMessage;
import org.mobicents.protocols.ss7.isup.message.parameter.CauseIndicators;
import org.mobicents.protocols.ss7.mtp.Mtp3;
import org.mobicents.protocols.ss7.mtp.Mtp3TransferPrimitive;
import org.mobicents.protocols.ss7.mtp.Mtp3TransferPrimitiveFactory;
import org.mobicents.protocols.ss7.scheduler.ConcurrentLinkedList;
import org.mobicents.protocols.ss7.scheduler.Scheduler;
import org.mobicents.protocols.ss7.scheduler.Task;

/**
 *
 * @author baranowb
 * @author amit bhayani
 *
 */
@SuppressWarnings("rawtypes")
class Circuit {
    private final int cic;
    private final int dpc;
    private final ISUPProviderImpl provider;

    private ReentrantLock lock = new ReentrantLock();

    private ConcurrentLinkedList incoming = new ConcurrentLinkedList();
    private ConcurrentLinkedList outgoing = new ConcurrentLinkedList();

    private Sender sender;
    private Receiver receiver;

    private ByteArrayOutputStream bos = new ByteArrayOutputStream(300);

    /**
     * @param cic
     */
    public Circuit(int cic, int dpc, ISUPProviderImpl provider, Scheduler scheduler) {
        sender = new Sender(scheduler);
        receiver = new Receiver(scheduler);
        this.cic = cic;
        this.dpc = dpc;
        this.provider = provider;

        // create all timers and deactivate them
        t1 = new TimerT1(scheduler);
        t5 = new TimerT5(scheduler);
        t7 = new TimerT7(scheduler);
        t12 = new TimerT12(scheduler);
        t13 = new TimerT13(scheduler);
        t14 = new TimerT14(scheduler);
        t15 = new TimerT15(scheduler);
        t16 = new TimerT16(scheduler);
        t17 = new TimerT17(scheduler);
        t18 = new TimerT18(scheduler);
        t19 = new TimerT19(scheduler);
        t20 = new TimerT20(scheduler);
        t21 = new TimerT21(scheduler);
        t22 = new TimerT22(scheduler);
        t23 = new TimerT23(scheduler);
        t28 = new TimerT28(scheduler);
        t33 = new TimerT33(scheduler);
        onStop();
    }

    /**
     * @return the cic
     */
    public int getCic() {
        return cic;
    }

    /**
     * @return the dpc
     */
    public int getDpc() {
        return dpc;
    }

    /**
     * @param timerId
     * @return
     */
    public boolean cancelTimer(int timerId) {
        try {

            lock.lock();
            switch (timerId) {
                case ISUPTimeoutEvent.T1:
                    return cancelT1();
                case ISUPTimeoutEvent.T5:
                    return cancelT5();
                case ISUPTimeoutEvent.T7:
                    return cancelT7();
                case ISUPTimeoutEvent.T12:
                    return cancelT12();
                case ISUPTimeoutEvent.T13:
                    return cancelT13();
                case ISUPTimeoutEvent.T14:
                    return cancelT14();
                case ISUPTimeoutEvent.T15:
                    return cancelT15();
                case ISUPTimeoutEvent.T16:
                    return cancelT16();
                case ISUPTimeoutEvent.T17:
                    return cancelT17();
                case ISUPTimeoutEvent.T18:
                    return cancelT18();
                case ISUPTimeoutEvent.T19:
                    return cancelT19();
                case ISUPTimeoutEvent.T20:
                    return cancelT20();
                case ISUPTimeoutEvent.T21:
                    return cancelT21();
                case ISUPTimeoutEvent.T22:
                    return cancelT22();
                case ISUPTimeoutEvent.T23:
                    return cancelT23();
                case ISUPTimeoutEvent.T28:
                    return cancelT28();
                case ISUPTimeoutEvent.T33:
                    return cancelT33();
                default:
                    return false;
            }
        } finally {
            lock.unlock();
        }
    }

    /**
     * @param message
     */
    public void receive(ISUPMessage message) {
        incoming.offer(message);
        receiver.submit();
    }

    /**
     * @param message
     * @throws ParameterException
     * @throws IOException
     */
    public void send(ISUPMessage message) throws ParameterException, IOException {
        outgoing.offer(message);
        sender.submit();
    }

    /**
     * @param message
     * @return
     * @throws ParameterException
     * @throws IOException
     */
    private Mtp3TransferPrimitive decorate(ISUPMessage message) throws ParameterException, IOException {
        ((AbstractISUPMessage) message).encode(bos);
        byte[] encoded = bos.toByteArray();
        int opc = this.provider.getLocalSpc();
        int dpc = this.dpc;
        int si = Mtp3._SI_SERVICE_ISUP;
        int ni = this.provider.getNi();
        int sls = message.getSls() & 0x0F; // promote

        Mtp3TransferPrimitiveFactory factory = this.provider.stack.getMtp3UserPart().getMtp3TransferPrimitiveFactory();
        Mtp3TransferPrimitive msg = factory.createMtp3TransferPrimitive(si, ni, 0, opc, dpc, sls, encoded);
        return msg;
    }

    // --------------- data handlers ---------------------------
    private class Receiver extends Task {
        public Receiver(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.L4READ_QUEUE;
        }

        public void submit() {
            scheduler.submit(this, getQueueNumber());
        }

        public long perform() {
            lock.lock();
            ISUPMessage message;
            while (!incoming.isEmpty()) {
                message = incoming.poll();
                try {
                    // process timers
                    switch (message.getMessageType().getCode()) {
                    // FIXME: add check for SEG
                        case ReleaseCompleteMessage.MESSAGE_CODE:
                            // this is tricy BS.... its REL and RSC are answered with RLC
                            if (!stopRELTimers()) {
                                stopRSCTimers();
                            }
                            break;
                        case AddressCompleteMessage.MESSAGE_CODE:
                        case ConnectMessage.MESSAGE_CODE:
                            stoptXAMTimers();
                            break;
                        case BlockingAckMessage.MESSAGE_CODE:
                            stoptBLOTimers();
                            break;
                        case UnblockingAckMessage.MESSAGE_CODE:
                            stoptUBLTimers();
                            break;
                        case CircuitGroupBlockingMessage.MESSAGE_CODE:
                            stoptCGBTimers();
                            break;

                        case CircuitGroupUnblockingAckMessage.MESSAGE_CODE:
                            stoptCGUTimers();
                            break;
                        case CircuitGroupResetAckMessage.MESSAGE_CODE:
                            stoptGRSTimers();
                            break;
                        case CircuitGroupQueryResponseMessage.MESSAGE_CODE:
                            stoptCQMTimers();
                            break;
                        case InformationMessage.MESSAGE_CODE:
                            stoptINRTimers();
                            break;
                    }

                    // deliver
                    ISUPEvent event = new ISUPEvent(provider, message, dpc);
                    provider.deliver(event);
                } catch (Exception e) {
                    // catch exception, so thread dont die.
                    e.printStackTrace();
                }
            }

            lock.unlock();
            return 0;
        }
    }

    private class Sender extends Task {
        public Sender(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.L4WRITE_QUEUE;
        }

        public void submit() {
            scheduler.submit(this, getQueueNumber());
        }

        public long perform() {
            ISUPMessage message;
            while (!outgoing.isEmpty()) {
                try {
                    message = outgoing.poll();
                    lock.lock();
                    bos.reset();

                    // FIXME: add SEG creation?
                    Mtp3TransferPrimitive msg = decorate(message);
                    // process timers
                    switch (message.getMessageType().getCode()) {
                        case ReleaseMessage.MESSAGE_CODE:
                            startRELTimers(msg, (ReleaseMessage) message);
                            break;
                        case SubsequentAddressMessage.MESSAGE_CODE:
                        case InitialAddressMessage.MESSAGE_CODE:
                            startXAMTimers(message);
                            break;
                        case BlockingMessage.MESSAGE_CODE:
                            startBLOTimers(msg, (BlockingMessage) message);
                            break;
                        case UnblockingMessage.MESSAGE_CODE:
                            startUBLTimers(msg, (UnblockingMessage) message);
                            break;
                        case ResetCircuitMessage.MESSAGE_CODE:
                            startRSCTimers(msg, (ResetCircuitMessage) message);
                            break;
                        case CircuitGroupBlockingMessage.MESSAGE_CODE:
                            startCGBTimers(msg, (CircuitGroupBlockingMessage) message);
                            break;
                        case CircuitGroupUnblockingMessage.MESSAGE_CODE:
                            startCGUTimers(msg, (CircuitGroupUnblockingMessage) message);
                            break;
                        case CircuitGroupResetMessage.MESSAGE_CODE:
                            startGRSTimers(msg, (CircuitGroupResetMessage) message);
                            break;
                        case CircuitGroupQueryMessage.MESSAGE_CODE:
                            startCQMTimers((CircuitGroupQueryMessage) message);
                            break;
                        case InformationRequestMessage.MESSAGE_CODE:
                            startINRTimers((InformationRequestMessage) message);
                            break;
                    }
                    // send
                    provider.send(msg);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }

            return 0;
        }
    }

    // ----------------- timer handlers ----------------------

    // FIXME: check how t3 works....

    private TimerT1 t1;
    private TimerT5 t5;
    private Mtp3TransferPrimitive t1t5encodedREL; // keep encoded value, so we can simply send,
    // without spending CPU on encoding.
    private ReleaseMessage t1t5REL; // keep for timers.
    private TimerT7 t7;
    private ISUPMessage t7AddressMessage; // IAM/SAM

    // FIXME: t8 - receive IAM with contuuity check ind.
    // FIXME: t11

    private TimerT12 t12;
    private TimerT13 t13;
    private Mtp3TransferPrimitive t12t13encodedBLO; // keep encoded value, so we can simply
    // send, without spending CPU on
    // encoding.
    private BlockingMessage t12t13BLO; // keep for timers.

    private TimerT14 t14;
    private TimerT15 t15;
    private Mtp3TransferPrimitive t14t15encodedUBL; // keep encoded value, so we can simply
    // send, without spending CPU on
    // encoding.
    private UnblockingMessage t14t15UBL; // keep for timers.

    private TimerT16 t16;
    private TimerT17 t17;
    private Mtp3TransferPrimitive t16t17encodedRSC; // keep encoded value, so we can simply
    // send, without spending CPU on
    // encoding.
    private ResetCircuitMessage t16t17RSC; // keep for timers.

    private TimerT18 t18;
    private TimerT19 t19;
    private Mtp3TransferPrimitive t18t19encodedCGB; // keep encoded value, so we can simply
    // send, without spending CPU on
    // encoding.
    private CircuitGroupBlockingMessage t18t19CGB; // keep for timers.

    private TimerT20 t20;
    private TimerT21 t21;
    private Mtp3TransferPrimitive t20t21encodedCGU; // keep encoded value, so we can simply
    // send, without spending CPU on
    // encoding.
    private CircuitGroupUnblockingMessage t20t21CGU; // keep for timers.

    private TimerT22 t22;
    private TimerT23 t23;
    private Mtp3TransferPrimitive t22t23encodedGRS; // keep encoded value, so we can simply
    // send, without spending CPU on
    // encoding.
    private CircuitGroupResetMessage t22t23GRS; // keep for timers.

    private TimerT28 t28;
    private CircuitGroupQueryMessage t28CQM;

    private TimerT33 t33;
    private InformationRequestMessage t33INR;

    // FIXME: t34 - check how SEG works

    private void startRELTimers(Mtp3TransferPrimitive encoded, ReleaseMessage rel) {
        // FIXME: add lock ?
        this.t1t5encodedREL = encoded;
        this.t1t5REL = rel;

        // it is started always.
        startT1();

        if (!this.t5.isActive()) {
            startT5();
        }
    }

    /**
     * @return
     */
    private boolean stopRELTimers() {
        if (this.t1.isActive() || this.t5.isActive()) {
            cancelT1();
            cancelT5();
            return true;
        } else {
            return false;
        }
    }

    /**
     * @param encoded
     * @param message
     */
    private void startXAMTimers(ISUPMessage message) {
        this.cancelT7();
        this.t7AddressMessage = message;
        this.startT7();
    }

    /**
     * @return
     */
    private void stoptXAMTimers() {
        cancelT7();
    }

    /**
     * @param encoded
     * @param message
     */
    private void startBLOTimers(Mtp3TransferPrimitive encoded, BlockingMessage message) {
        this.t12t13BLO = message;
        this.t12t13encodedBLO = encoded;
        // it is started always.
        startT12();

        if (!this.t13.isActive())
            startT13();
    }

    /**
     * @return
     */
    private void stoptBLOTimers() {
        cancelT12();
        cancelT13();
    }

    /**
     * @param encoded
     * @param message
     */
    private void startUBLTimers(Mtp3TransferPrimitive encoded, UnblockingMessage message) {
        this.t14t15UBL = message;
        this.t14t15encodedUBL = encoded;
        // it is started always.
        startT14();

        if (!this.t15.isActive())
            startT15();
    }

    /**
     * @return
     */
    private void stoptUBLTimers() {
        cancelT14();
        cancelT15();

    }

    /**
     * @param encoded
     * @param message
     */
    private void startRSCTimers(Mtp3TransferPrimitive encoded, ResetCircuitMessage message) {
        this.t16t17RSC = message;
        this.t16t17encodedRSC = encoded;
        // it is started always.
        startT16();

        if (!this.t17.isActive())
            startT17();
    }

    /**
     * @return
     */
    private void stopRSCTimers() {
        cancelT16();
        cancelT17();
    }

    /**
     * @param encoded
     * @param message
     */
    private void startINRTimers(InformationRequestMessage message) {
        this.t33INR = message;
        startT33();
    }

    /**
     * @return
     */
    private void stoptINRTimers() {
        cancelT33();
    }

    /**
     * @param encoded
     * @param message
     */
    private void startCQMTimers(CircuitGroupQueryMessage message) {
        this.t28CQM = message;

        // it is started always.
        startT28();
        // FIXME: can we send more than one?
    }

    /**
     * @return
     */
    private void stoptCQMTimers() {
        cancelT28();
    }

    /**
     * @param encoded
     * @param message
     */
    private void startGRSTimers(Mtp3TransferPrimitive encoded, CircuitGroupResetMessage message) {
        this.t22t23GRS = message;
        this.t22t23encodedGRS = encoded;
        // it is started always.
        startT22();

        if (!this.t23.isActive())
            startT23();
    }

    /**
     * @return
     */
    private void stoptGRSTimers() {
        cancelT22();
        cancelT23();
    }

    /**
     * @param encoded
     * @param message
     */
    private void startCGUTimers(Mtp3TransferPrimitive encoded, CircuitGroupUnblockingMessage message) {
        this.t20t21CGU = message;
        this.t20t21encodedCGU = encoded;
        // it is started always.
        startT20();

        if (!this.t21.isActive())
            startT21();
    }

    /**
     * @return
     */
    private void stoptCGUTimers() {
        cancelT20();
        cancelT21();
    }

    /**
     * @param encoded
     * @param message
     */
    private void startCGBTimers(Mtp3TransferPrimitive encoded, CircuitGroupBlockingMessage message) {
        this.t18t19CGB = message;
        this.t18t19encodedCGB = encoded;
        // it is started always.
        startT18();

        if (!this.t19.isActive())
            startT19();
    }

    /**
     * @return
     */
    private void stoptCGBTimers() {
        cancelT18();
        cancelT19();
    }

    private void startT1() {
        cancelT1();
        this.t1.start();
    }

    private boolean cancelT1() {
        if (this.t1.isActive()) {
            this.t1.cancel();
            return true;
        }

        return false;
    }

    private void startT5() {
        cancelT5();
        this.t5.start();
    }

    private boolean cancelT5() {
        if (this.t5.isActive()) {
            this.t5.cancel();
            return true;
        }

        return false;
    }

    private void startT7() {
        cancelT7();
        this.t7.start();
    }

    private boolean cancelT7() {
        if (this.t7.isActive()) {
            this.t7.cancel();
            return true;
        }

        return false;
    }

    private void startT12() {
        cancelT12();
        this.t12.start();
    }

    private boolean cancelT12() {
        if (this.t12.isActive()) {
            this.t12.cancel();
            return true;
        }

        return false;
    }

    private void startT13() {
        cancelT13();
        this.t13.start();
    }

    private boolean cancelT13() {
        if (this.t13.isActive()) {
            this.t13.cancel();
            return true;
        }

        return false;
    }

    private void startT14() {
        cancelT14();
        this.t14.start();
    }

    private boolean cancelT14() {
        if (this.t14.isActive()) {
            this.t14.cancel();
            return true;
        }

        return false;
    }

    private void startT15() {
        cancelT15();
        this.t15.start();
    }

    private boolean cancelT15() {
        if (this.t15.isActive()) {
            this.t15.cancel();
            return true;
        }

        return false;
    }

    private void startT16() {
        cancelT16();
        this.t16.start();
    }

    private boolean cancelT16() {
        if (this.t16.isActive()) {
            this.t16.cancel();
            return true;
        }

        return false;
    }

    private void startT17() {
        cancelT17();
        this.t17.start();
    }

    private boolean cancelT17() {
        if (this.t17.isActive()) {
            this.t17.cancel();
            return true;
        }

        return false;
    }

    private void startT18() {
        cancelT18();
        this.t18.start();
    }

    private boolean cancelT18() {
        if (this.t18.isActive()) {
            this.t18.cancel();
            return true;
        }

        return false;
    }

    private void startT19() {
        cancelT19();
        this.t19.start();
    }

    private boolean cancelT19() {
        if (this.t19.isActive()) {
            this.t19.cancel();
            return true;
        }

        return false;
    }

    private void startT20() {
        cancelT20();
        this.t20.start();
    }

    private boolean cancelT20() {
        if (this.t20.isActive()) {
            this.t20.cancel();
            return true;
        }

        return false;
    }

    private void startT21() {
        cancelT21();
        this.t21.start();
    }

    private boolean cancelT21() {
        if (this.t21.isActive()) {
            this.t21.cancel();
            return true;
        }

        return false;
    }

    private void startT22() {
        cancelT22();
        this.t22.start();
    }

    private boolean cancelT22() {
        if (this.t22.isActive()) {
            this.t22.cancel();
            return true;
        }

        return false;
    }

    private void startT23() {
        cancelT23();
        this.t23.start();
    }

    private boolean cancelT23() {
        if (this.t23.isActive()) {
            this.t23.cancel();
            return true;
        }

        return false;
    }

    private void startT28() {
        cancelT28();
        this.t28.start();
    }

    private boolean cancelT28() {
        if (this.t28.isActive()) {
            this.t28.cancel();
            return true;
        }

        return false;
    }

    private void startT33() {
        cancelT33();
        this.t33.start();
    }

    private boolean cancelT33() {
        if (this.t33.isActive()) {
            this.t33.cancel();
            return true;
        }

        return false;
    }

    private class TimerT1 extends Task {
        private int ttl;

        public TimerT1(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT1Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // cancel it
                this.cancel();
                // start T1
                startT1();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        // TODO: CI required ?
                        provider.send(t1t5encodedREL);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t1t5REL, ISUPTimeoutEvent.T1, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT5 extends Task {
        private int ttl;

        public TimerT5(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT5Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove t5, its current runnable.
                cancelT1();
                // cancel it
                this.cancel();
                // restart T5
                startT5();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        final ResetCircuitMessage rcm = provider.getMessageFactory().createRSC(cic);
                        // avoid provider method, since we dont want other timer to be
                        // setup.
                        provider.sendMessage(rcm, dpc);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t1t5REL, ISUPTimeoutEvent.T5, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT7 extends Task {
        private int ttl;

        public TimerT7(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT7Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // cancel it
                this.cancel();
                // send REL
                if (provider.isAutomaticTimerMessages())
                    try {
                        final ReleaseMessage rel = provider.getMessageFactory().createREL(cic);
                        final CauseIndicators ci = provider.getParameterFactory().createCauseIndicators();
                        ci.setCauseValue(CauseIndicators._CV_NORMAL_UNSPECIFIED);
                        rel.setCauseIndicators(ci);
                        provider.sendMessage(rel, dpc);
                    } catch (ParameterException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t7AddressMessage, ISUPTimeoutEvent.T7, dpc);
                t7AddressMessage = null;
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT12 extends Task {
        private int ttl;

        public TimerT12(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT12Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // cancel it
                this.cancel();
                // start T12
                startT12();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t12t13encodedBLO);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t12t13BLO, ISUPTimeoutEvent.T12, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT13 extends Task {
        private int ttl;

        public TimerT13(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT13Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // cancel it
                this.cancel();
                // cancel T12
                cancelT12();
                // restart T13
                startT13();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t12t13encodedBLO);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t12t13BLO, ISUPTimeoutEvent.T13, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT14 extends Task {
        private int ttl;

        public TimerT14(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT14Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // cancel it
                this.cancel();
                // start T14
                startT14();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t14t15encodedUBL);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t14t15UBL, ISUPTimeoutEvent.T14, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT15 extends Task {
        private int ttl;

        public TimerT15(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT15Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove t15, its current runnable.
                this.cancel();
                // cancel T14
                cancelT14();
                // start
                startT15();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t14t15encodedUBL);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t14t15UBL, ISUPTimeoutEvent.T15, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT16 extends Task {
        private int ttl;

        public TimerT16(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT16Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove us
                this.cancel();
                // start T14
                startT16();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t16t17encodedRSC);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t16t17RSC, ISUPTimeoutEvent.T16, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT17 extends Task {
        private int ttl;

        public TimerT17(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT17Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove t17, its current runnable.
                this.cancel();
                // cancel T16
                cancelT16();
                // restart T17
                startT17();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t16t17encodedRSC);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t16t17RSC, ISUPTimeoutEvent.T17, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT18 extends Task {
        private int ttl;

        public TimerT18(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT18Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove us
                this.cancel();
                // start T18
                startT18();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t18t19encodedCGB);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t18t19CGB, ISUPTimeoutEvent.T18, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT19 extends Task {
        private int ttl;

        public TimerT19(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT19Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove t19, its current runnable.
                this.cancel();
                // cancel T18
                cancelT18();
                // restart T19
                startT19();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t18t19encodedCGB);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t18t19CGB, ISUPTimeoutEvent.T19, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT20 extends Task {
        private int ttl;

        public TimerT20(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT20Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove us
                this.cancel();
                // start T20
                startT20();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t20t21encodedCGU);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t20t21CGU, ISUPTimeoutEvent.T20, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT21 extends Task {
        private int ttl;

        public TimerT21(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT21Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove t21, its current runnable.
                this.cancel();
                // cancel T20
                cancelT20();
                // restart T21
                startT21();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t20t21encodedCGU);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t20t21CGU, ISUPTimeoutEvent.T21, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT22 extends Task {
        private int ttl;

        public TimerT22(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT22Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove us
                this.cancel();
                // start T22
                startT22();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t22t23encodedGRS);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t22t23GRS, ISUPTimeoutEvent.T22, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT23 extends Task {
        private int ttl;

        public TimerT23(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT23Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove t23, its current runnable.
                this.cancel();
                // cancel T22
                cancelT22();
                // restart T23
                startT23();
                // send
                if (provider.isAutomaticTimerMessages())
                    try {
                        provider.send(t22t23encodedGRS);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, t22t23GRS, ISUPTimeoutEvent.T23, dpc);
                provider.deliver(timeoutEvent);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT28 extends Task {
        private int ttl;

        public TimerT28(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT28Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove us
                this.cancel();
                // notify user
                final CircuitGroupQueryMessage msg = t28CQM;
                t28CQM = null;
                ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, msg, ISUPTimeoutEvent.T28, dpc);
                provider.deliver(timeoutEvent);

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    private class TimerT33 extends Task {
        private int ttl;

        public TimerT33(Scheduler scheduler) {
            super(scheduler);
        }

        public int getQueueNumber() {
            return scheduler.HEARTBEAT_QUEUE;
        }

        public void start() {
            this.activate(true);
            ttl = (int) (provider.getT33Timeout() / 100);
            scheduler.submitHeatbeat(this);
        }

        public long perform() {
            if (ttl > 0) {
                ttl--;
                scheduler.submitHeatbeat(this);
                return 0;
            }

            try {
                lock.lock();
                // remove us
                this.cancel();
                // send REL
                if (provider.isAutomaticTimerMessages())
                    try {
                        final ReleaseMessage rel = provider.getMessageFactory().createREL(cic);
                        final CauseIndicators ci = provider.getParameterFactory().createCauseIndicators();
                        ci.setCauseValue(CauseIndicators._CV_NORMAL_UNSPECIFIED);
                        rel.setCauseIndicators(ci);
                        provider.sendMessage(rel, dpc);
                    } catch (ParameterException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                final InformationRequestMessage msg = t33INR;
                t33INR = null;
                // notify user
                final ISUPTimeoutEvent timeoutEvent = new ISUPTimeoutEvent(provider, msg, ISUPTimeoutEvent.T33, dpc);
                provider.deliver(timeoutEvent);
                // FIXME: do this after call, to prevent send of another msg

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

            return 0;
        }
    }

    /**
     *
     */
    public void onStop() {
        try {
            lock.lock();
            cancelT1();
            cancelT5();
            cancelT12();
            cancelT13();
            cancelT14();
            cancelT15();
            cancelT16();
            cancelT17();
            cancelT18();
            cancelT19();
            cancelT20();
            cancelT21();
            cancelT22();
            cancelT23();
            cancelT28();
            cancelT33();

        } finally {
            lock.unlock();
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy