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

org.mobicents.protocols.ss7.cap.CAPProviderImpl Maven / Gradle / Ivy

There is a newer version: 8.0.112
Show newest version
/*
 * TeleStax, Open Source Cloud Communications
 * Copyright 2012, Telestax Inc 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.cap;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import javolution.util.FastList;
import javolution.util.FastMap;

import org.apache.log4j.Logger;
import org.mobicents.protocols.asn.AsnException;
import org.mobicents.protocols.asn.AsnInputStream;
import org.mobicents.protocols.asn.AsnOutputStream;
import org.mobicents.protocols.asn.Tag;
import org.mobicents.protocols.ss7.cap.api.CAPApplicationContext;
import org.mobicents.protocols.ss7.cap.api.CAPDialog;
import org.mobicents.protocols.ss7.cap.api.CAPDialogListener;
import org.mobicents.protocols.ss7.cap.api.CAPException;
import org.mobicents.protocols.ss7.cap.api.CAPMessage;
import org.mobicents.protocols.ss7.cap.api.CAPParameterFactory;
import org.mobicents.protocols.ss7.cap.api.CAPParsingComponentException;
import org.mobicents.protocols.ss7.cap.api.CAPProvider;
import org.mobicents.protocols.ss7.cap.api.CAPServiceBase;
import org.mobicents.protocols.ss7.cap.api.dialog.CAPDialogState;
import org.mobicents.protocols.ss7.cap.api.dialog.CAPGeneralAbortReason;
import org.mobicents.protocols.ss7.cap.api.dialog.CAPGprsReferenceNumber;
import org.mobicents.protocols.ss7.cap.api.dialog.CAPNoticeProblemDiagnostic;
import org.mobicents.protocols.ss7.cap.api.dialog.CAPUserAbortReason;
import org.mobicents.protocols.ss7.cap.api.dialog.ServingCheckData;
import org.mobicents.protocols.ss7.cap.api.errors.CAPErrorCode;
import org.mobicents.protocols.ss7.cap.api.errors.CAPErrorMessage;
import org.mobicents.protocols.ss7.cap.api.errors.CAPErrorMessageFactory;
import org.mobicents.protocols.ss7.cap.api.service.circuitSwitchedCall.CAPServiceCircuitSwitchedCall;
import org.mobicents.protocols.ss7.cap.api.service.gprs.CAPServiceGprs;
import org.mobicents.protocols.ss7.cap.api.service.sms.CAPServiceSms;
import org.mobicents.protocols.ss7.cap.dialog.CAPGprsReferenceNumberImpl;
import org.mobicents.protocols.ss7.cap.dialog.CAPUserAbortPrimitiveImpl;
import org.mobicents.protocols.ss7.cap.errors.CAPErrorMessageFactoryImpl;
import org.mobicents.protocols.ss7.cap.errors.CAPErrorMessageImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.CAPServiceCircuitSwitchedCallImpl;
import org.mobicents.protocols.ss7.cap.service.gprs.CAPServiceGprsImpl;
import org.mobicents.protocols.ss7.cap.service.sms.CAPServiceSmsImpl;
import org.mobicents.protocols.ss7.inap.api.INAPParameterFactory;
import org.mobicents.protocols.ss7.inap.isup.INAPParameterFactoryImpl;
import org.mobicents.protocols.ss7.isup.ISUPParameterFactory;
import org.mobicents.protocols.ss7.isup.impl.message.parameter.ISUPParameterFactoryImpl;
import org.mobicents.protocols.ss7.map.MAPParameterFactoryImpl;
import org.mobicents.protocols.ss7.map.api.MAPParameterFactory;
import org.mobicents.protocols.ss7.sccp.parameter.SccpAddress;
import org.mobicents.protocols.ss7.tcap.DialogImpl;
import org.mobicents.protocols.ss7.tcap.api.MessageType;
import org.mobicents.protocols.ss7.tcap.api.TCAPProvider;
import org.mobicents.protocols.ss7.tcap.api.TCAPSendException;
import org.mobicents.protocols.ss7.tcap.api.TCListener;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.Dialog;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCBeginIndication;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCBeginRequest;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCContinueIndication;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCContinueRequest;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCEndIndication;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCEndRequest;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCNoticeIndication;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCPAbortIndication;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCUniIndication;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCUserAbortIndication;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCUserAbortRequest;
import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TerminationType;
import org.mobicents.protocols.ss7.tcap.asn.ApplicationContextName;
import org.mobicents.protocols.ss7.tcap.asn.DialogServiceProviderType;
import org.mobicents.protocols.ss7.tcap.asn.DialogServiceUserType;
import org.mobicents.protocols.ss7.tcap.asn.InvokeImpl;
import org.mobicents.protocols.ss7.tcap.asn.ResultSourceDiagnostic;
import org.mobicents.protocols.ss7.tcap.asn.TcapFactory;
import org.mobicents.protocols.ss7.tcap.asn.UserInformation;
import org.mobicents.protocols.ss7.tcap.asn.comp.Component;
import org.mobicents.protocols.ss7.tcap.asn.comp.ComponentType;
import org.mobicents.protocols.ss7.tcap.asn.comp.ErrorCodeType;
import org.mobicents.protocols.ss7.tcap.asn.comp.Invoke;
import org.mobicents.protocols.ss7.tcap.asn.comp.InvokeProblemType;
import org.mobicents.protocols.ss7.tcap.asn.comp.OperationCode;
import org.mobicents.protocols.ss7.tcap.asn.comp.PAbortCauseType;
import org.mobicents.protocols.ss7.tcap.asn.comp.Parameter;
import org.mobicents.protocols.ss7.tcap.asn.comp.Problem;
import org.mobicents.protocols.ss7.tcap.asn.comp.ProblemType;
import org.mobicents.protocols.ss7.tcap.asn.comp.Reject;
import org.mobicents.protocols.ss7.tcap.asn.comp.ReturnError;
import org.mobicents.protocols.ss7.tcap.asn.comp.ReturnErrorProblemType;
import org.mobicents.protocols.ss7.tcap.asn.comp.ReturnResultLast;
import org.mobicents.protocols.ss7.tcap.asn.comp.ReturnResultProblemType;

/**
 *
 * @author sergey vetyutnev
 * @author ProIDS sp. z o.o.
 *
 */
public class CAPProviderImpl implements CAPProvider, TCListener {

    protected final transient Logger loger;


    private transient Collection dialogListeners = new FastList().shared();

    protected transient FastMap dialogs = new FastMap().shared();

    private transient TCAPProvider tcapProvider = null;

    private final transient CAPParameterFactory capParameterFactory = new CAPParameterFactoryImpl();
    private final transient MAPParameterFactory mapParameterFactory = new MAPParameterFactoryImpl();
    private final transient ISUPParameterFactory isupParameterFactory = new ISUPParameterFactoryImpl();
    private final transient INAPParameterFactory inapParameterFactory = new INAPParameterFactoryImpl();
    private final transient CAPErrorMessageFactory capErrorMessageFactory = new CAPErrorMessageFactoryImpl();

    protected transient Set capServices = new HashSet();
    private final transient CAPServiceCircuitSwitchedCall capServiceCircuitSwitchedCall = new CAPServiceCircuitSwitchedCallImpl(
            this);
    private final transient CAPServiceGprs capServiceGprs = new CAPServiceGprsImpl(this);
    private final transient CAPServiceSms capServiceSms = new CAPServiceSmsImpl(this);

    public CAPProviderImpl(String name, TCAPProvider tcapProvider) {
        this.tcapProvider = tcapProvider;

        this.loger = Logger.getLogger(CAPStackImpl.class.getCanonicalName() + "-" + name);

        this.capServices.add(this.capServiceCircuitSwitchedCall);
        this.capServices.add(this.capServiceGprs);
        this.capServices.add(this.capServiceSms);
    }

    public TCAPProvider getTCAPProvider() {
        return this.tcapProvider;
    }

    @Override
    public CAPServiceCircuitSwitchedCall getCAPServiceCircuitSwitchedCall() {
        return this.capServiceCircuitSwitchedCall;
    }

    @Override
    public CAPServiceGprs getCAPServiceGprs() {
        return this.capServiceGprs;
    }

    @Override
    public CAPServiceSms getCAPServiceSms() {
        return this.capServiceSms;
    }

    @Override
    public void addCAPDialogListener(CAPDialogListener capDialogListener) {
        this.dialogListeners.add(capDialogListener);
    }

    @Override
    public CAPParameterFactory getCAPParameterFactory() {
        return capParameterFactory;
    }

    @Override
    public MAPParameterFactory getMAPParameterFactory() {
        return mapParameterFactory;
    }

    @Override
    public ISUPParameterFactory getISUPParameterFactory() {
        return isupParameterFactory;
    }

    @Override
    public INAPParameterFactory getINAPParameterFactory() {
        return inapParameterFactory;
    }

    @Override
    public CAPErrorMessageFactory getCAPErrorMessageFactory() {
        return this.capErrorMessageFactory;
    }

    @Override
    public void removeCAPDialogListener(CAPDialogListener capDialogListener) {
        this.dialogListeners.remove(capDialogListener);
    }

    @Override
    public CAPDialog getCAPDialog(Long dialogId) {
        //synchronized (this.dialogs) {
            return this.dialogs.get(dialogId);
        //}
    }

    public void start() {
        this.tcapProvider.addTCListener(this);
    }

    public void stop() {
        this.tcapProvider.removeTCListener(this);

    }

    protected void addDialog(CAPDialogImpl dialog) {
        //synchronized (this.dialogs) {
            this.dialogs.put(dialog.getLocalDialogId(), dialog);
        //}
    }

    protected CAPDialogImpl removeDialog(Long dialogId) {
        //synchronized (this.dialogs) {
            return this.dialogs.remove(dialogId);
        //}
    }

    private void SendUnsupportedAcn(ApplicationContextName acn, Dialog dialog, String cs) {
        StringBuffer s = new StringBuffer();
        s.append(cs + " ApplicationContextName is received: ");
        for (long l : acn.getOid()) {
            s.append(l).append(", ");
        }
        loger.warn(s.toString());

        try {
            this.fireTCAbort(dialog, CAPGeneralAbortReason.ACNNotSupported, null, false);
        } catch (CAPException e1) {
            loger.error("Error while firing TC-U-ABORT. ", e1);
        }
    }

    private CAPGprsReferenceNumberImpl ParseUserInfo(UserInformation userInfo, Dialog dialog) {

        // Parsing userInfo
        CAPGprsReferenceNumberImpl referenceNumber = null;

        // Checking UserData ObjectIdentifier
        if (!userInfo.isOid()) {
            loger.warn("onTCBegin: userInfo.isOid() is null");
            return null;
        }

        if (!Arrays.equals(CAPGprsReferenceNumberImpl.CAP_Dialogue_OId, userInfo.getOidValue())) {
            loger.warn("onTCBegin: userInfo.isOid() has bad value");
            return null;
        }

        if (!userInfo.isAsn()) {
            loger.warn("onTCBegin: userInfo.isAsn() is null");
            return null;
        }

        try {
            referenceNumber = new CAPGprsReferenceNumberImpl();
            byte[] asnData = userInfo.getEncodeType();

            AsnInputStream ais = new AsnInputStream(asnData);

            int tag = ais.readTag();
            // It should be SEQUENCE Tag
            if (tag != Tag.SEQUENCE || ais.getTagClass() != Tag.CLASS_UNIVERSAL || ais.isTagPrimitive()) {
                loger.warn("onTCBegin: Error parsing CAPGprsReferenceNumber: bad tag or tag class or is primitive");
                return null;
            }

            referenceNumber.decodeAll(ais);
        } catch (AsnException e) {
            loger.error("AsnException when parsing CAP-OPEN Pdu: " + e.getMessage(), e);
            return null;
        } catch (IOException e) {
            loger.error("IOException when parsing CAP-OPEN Pdu: " + e.getMessage(), e);
            return null;
        } catch (CAPParsingComponentException e) {
            loger.error("CAPParsingComponentException when parsing CAP-OPEN Pdu: " + e.getMessage(), e);
            return null;
        }

        return referenceNumber;
    }

    public void onTCBegin(TCBeginIndication tcBeginIndication) {

        ApplicationContextName acn = tcBeginIndication.getApplicationContextName();
        Component[] comps = tcBeginIndication.getComponents();

        // ACN must be present in CAMEL
        if (acn == null) {
            loger.warn("onTCBegin: Received TCBeginIndication without application context name");

            try {
                this.fireTCAbort(tcBeginIndication.getDialog(), CAPGeneralAbortReason.UserSpecific,
                        CAPUserAbortReason.abnormal_processing, false);
            } catch (CAPException e) {
                loger.error("Error while firing TC-U-ABORT. ", e);
            }
            return;
        }

        CAPApplicationContext capAppCtx = CAPApplicationContext.getInstance(acn.getOid());
        // Check if ApplicationContext is recognizable for CAP
        // If no - TC-U-ABORT - ACN-Not-Supported
        if (capAppCtx == null) {
            SendUnsupportedAcn(acn, tcBeginIndication.getDialog(), "onTCBegin: Unrecognizable");
            return;
        }

        // Parsing CAPGprsReferenceNumber if exists
        CAPGprsReferenceNumberImpl referenceNumber = null;
        UserInformation userInfo = tcBeginIndication.getUserInformation();
        if (userInfo != null) {
            referenceNumber = ParseUserInfo(userInfo, tcBeginIndication.getDialog());
            if (referenceNumber == null) {
                try {
                    this.fireTCAbort(tcBeginIndication.getDialog(), CAPGeneralAbortReason.UserSpecific,
                            CAPUserAbortReason.abnormal_processing, false);
                } catch (CAPException e) {
                    loger.error("Error while firing TC-U-ABORT. ", e);
                }

                return;
            }
        }

        // Selecting the CAP service that can perform the ApplicationContext
        CAPServiceBase perfSer = null;
        for (CAPServiceBase ser : this.capServices) {

            ServingCheckData chkRes = ser.isServingService(capAppCtx);
            switch (chkRes.getResult()) {
                case AC_Serving:
                    perfSer = ser;
                    break;

                case AC_VersionIncorrect:
                    SendUnsupportedAcn(acn, tcBeginIndication.getDialog(), "onTCBegin: Unsupported");
                    return;
            }

            if (perfSer != null)
                break;
        }

        // No CAPService can accept the received ApplicationContextName
        if (perfSer == null) {
            SendUnsupportedAcn(acn, tcBeginIndication.getDialog(), "onTCBegin: Unsupported");
            return;
        }

        // CAPService is not activated
        if (!perfSer.isActivated()) {
            SendUnsupportedAcn(acn, tcBeginIndication.getDialog(), "onTCBegin: Inactive CAPService");
            return;
        }

        CAPDialogImpl capDialogImpl = ((CAPServiceBaseImpl) perfSer).createNewDialogIncoming(capAppCtx,
                tcBeginIndication.getDialog());
        try {
            capDialogImpl.getTcapDialog().getDialogLock().lock();

            this.addDialog(capDialogImpl);
            capDialogImpl.tcapMessageType = MessageType.Begin;
            capDialogImpl.receivedGprsReferenceNumber = referenceNumber;

            capDialogImpl.setState(CAPDialogState.InitialReceived);

            capDialogImpl.delayedAreaState = CAPDialogImpl.DelayedAreaState.No;

            this.deliverDialogRequest(capDialogImpl, referenceNumber);
            if (capDialogImpl.getState() == CAPDialogState.Expunged) {
                // The Dialog was aborter or refused
                return;
            }

            // Now let us decode the Components
            if (comps != null) {
                processComponents(capDialogImpl, comps);
            }

            this.deliverDialogDelimiter(capDialogImpl);

            finishComponentProcessingState(capDialogImpl);

            if (this.getTCAPProvider().getPreviewMode()) {
                DialogImpl dimp = (DialogImpl) tcBeginIndication.getDialog();
                dimp.getPrevewDialogData().setUpperDialog(capDialogImpl);
            }
        } finally {
            capDialogImpl.getTcapDialog().getDialogLock().unlock();
        }
    }

    private void finishComponentProcessingState(CAPDialogImpl capDialogImpl) {

        if (capDialogImpl.getState() == CAPDialogState.Expunged)
            return;

        try {
            switch (capDialogImpl.delayedAreaState) {
                case Continue:
                    capDialogImpl.send();
                    break;
                case End:
                    capDialogImpl.close(false);
                    break;
                case PrearrangedEnd:
                    capDialogImpl.close(true);
                    break;
            }
        } catch (CAPException e) {
            loger.error("Error while finishComponentProcessingState, delayedAreaState=" + capDialogImpl.delayedAreaState, e);
        }

        capDialogImpl.delayedAreaState = null;
    }

    public void onTCContinue(TCContinueIndication tcContinueIndication) {

        Dialog tcapDialog = tcContinueIndication.getDialog();

        CAPDialogImpl capDialogImpl;
        if (this.getTCAPProvider().getPreviewMode()) {
            capDialogImpl = (CAPDialogImpl) (((DialogImpl) tcapDialog).getPrevewDialogData().getUpperDialog());
        } else {
            capDialogImpl = (CAPDialogImpl) this.getCAPDialog(tcapDialog.getLocalDialogId());
        }

        if (capDialogImpl == null) {
            loger.warn("CAP Dialog not found for Dialog Id " + tcapDialog.getLocalDialogId());
            try {
                this.fireTCAbort(tcContinueIndication.getDialog(), CAPGeneralAbortReason.UserSpecific,
                        CAPUserAbortReason.abnormal_processing, false);
            } catch (CAPException e) {
                loger.error("Error while firing TC-U-ABORT. ", e);
            }
            return;
        }
        capDialogImpl.tcapMessageType = MessageType.Continue;

        try {
            capDialogImpl.getTcapDialog().getDialogLock().lock();

            if (this.getTCAPProvider().getPreviewMode()) {
                CAPGprsReferenceNumberImpl referenceNumber = null;
                UserInformation userInfo = tcContinueIndication.getUserInformation();
                if (userInfo != null) {
                    referenceNumber = ParseUserInfo(userInfo, tcContinueIndication.getDialog());
                }
                capDialogImpl.receivedGprsReferenceNumber = referenceNumber;

                if (tcContinueIndication.getApplicationContextName() != null)
                    this.deliverDialogAccept(capDialogImpl, referenceNumber);

                Component[] comps = tcContinueIndication.getComponents();
                if (comps != null) {
                    processComponents(capDialogImpl, comps);
                }

                this.deliverDialogDelimiter(capDialogImpl);

            } else {
                if (capDialogImpl.getState() == CAPDialogState.InitialSent) {
                    ApplicationContextName acn = tcContinueIndication.getApplicationContextName();

                    if (acn == null) {
                        loger.warn("CAP Dialog is in InitialSent state but no application context name is received");
                        try {
                            this.fireTCAbort(tcContinueIndication.getDialog(), CAPGeneralAbortReason.UserSpecific,
                                    CAPUserAbortReason.abnormal_processing, capDialogImpl.getReturnMessageOnError());
                        } catch (CAPException e) {
                            loger.error("Error while firing TC-U-ABORT. ", e);
                        }

                        this.deliverDialogNotice(capDialogImpl, CAPNoticeProblemDiagnostic.AbnormalDialogAction);
                        capDialogImpl.setState(CAPDialogState.Expunged);

                        return;
                    }

                    CAPApplicationContext capAcn = CAPApplicationContext.getInstance(acn.getOid());
                    if (capAcn == null || !capAcn.equals(capDialogImpl.getApplicationContext())) {
                        loger.warn(String
                                .format("Received first TC-CONTINUE. But the received ACN is not the equal to the original ACN"));

                        try {
                            this.fireTCAbort(tcContinueIndication.getDialog(), CAPGeneralAbortReason.UserSpecific,
                                    CAPUserAbortReason.abnormal_processing, capDialogImpl.getReturnMessageOnError());
                        } catch (CAPException e) {
                            loger.error("Error while firing TC-U-ABORT. ", e);
                        }

                        this.deliverDialogNotice(capDialogImpl, CAPNoticeProblemDiagnostic.AbnormalDialogAction);
                        capDialogImpl.setState(CAPDialogState.Expunged);

                        return;
                    }

                    // Parsing CAPGprsReferenceNumber if exists
                    // we ignore all errors this
                    CAPGprsReferenceNumberImpl referenceNumber = null;
                    UserInformation userInfo = tcContinueIndication.getUserInformation();
                    if (userInfo != null) {
                        referenceNumber = ParseUserInfo(userInfo, tcContinueIndication.getDialog());
                    }
                    capDialogImpl.receivedGprsReferenceNumber = referenceNumber;

                    capDialogImpl.delayedAreaState = CAPDialogImpl.DelayedAreaState.No;

                    capDialogImpl.setState(CAPDialogState.Active);
                    this.deliverDialogAccept(capDialogImpl, referenceNumber);

                    if (capDialogImpl.getState() == CAPDialogState.Expunged) {
                        // The Dialog was aborter
                        finishComponentProcessingState(capDialogImpl);
                        return;
                    }
                } else {
                    capDialogImpl.delayedAreaState = CAPDialogImpl.DelayedAreaState.No;
                }

                // Now let us decode the Components
                if (capDialogImpl.getState() == CAPDialogState.Active) {
                    Component[] comps = tcContinueIndication.getComponents();
                    if (comps != null) {
                        processComponents(capDialogImpl, comps);
                    }
                } else {
                    // This should never happen
                    loger.error(String.format("Received TC-CONTINUE. CAPDialog=%s. But state is not Active", capDialogImpl));
                }

                this.deliverDialogDelimiter(capDialogImpl);

                finishComponentProcessingState(capDialogImpl);
            }
        } finally {
            capDialogImpl.getTcapDialog().getDialogLock().unlock();
        }
    }

    public void onTCEnd(TCEndIndication tcEndIndication) {

        Dialog tcapDialog = tcEndIndication.getDialog();

        CAPDialogImpl capDialogImpl;
        if (this.getTCAPProvider().getPreviewMode()) {
            capDialogImpl = (CAPDialogImpl) (((DialogImpl) tcapDialog).getPrevewDialogData().getUpperDialog());
        } else {
            capDialogImpl = (CAPDialogImpl) this.getCAPDialog(tcapDialog.getLocalDialogId());
        }

        if (capDialogImpl == null) {
            loger.warn("CAP Dialog not found for Dialog Id " + tcapDialog.getLocalDialogId());
            return;
        }
        capDialogImpl.tcapMessageType = MessageType.End;

        try {
            capDialogImpl.getTcapDialog().getDialogLock().lock();

            if (this.getTCAPProvider().getPreviewMode()) {

                capDialogImpl.setState(CAPDialogState.Active);

                // Parsing CAPGprsReferenceNumber if exists
                // we ignore all errors this
                CAPGprsReferenceNumberImpl referenceNumber = null;
                UserInformation userInfo = tcEndIndication.getUserInformation();
                if (userInfo != null) {
                    referenceNumber = ParseUserInfo(userInfo, tcEndIndication.getDialog());
                }
                capDialogImpl.receivedGprsReferenceNumber = referenceNumber;

                if (tcEndIndication.getApplicationContextName() != null)
                    this.deliverDialogAccept(capDialogImpl, referenceNumber);

                // Now let us decode the Components
                Component[] comps = tcEndIndication.getComponents();
                if (comps != null) {
                    processComponents(capDialogImpl, comps);
                }

                // capDialogImpl.setNormalDialogShutDown();
                this.deliverDialogClose(capDialogImpl);

            } else {
                if (capDialogImpl.getState() == CAPDialogState.InitialSent) {
                    ApplicationContextName acn = tcEndIndication.getApplicationContextName();

                    if (acn == null) {
                        loger.warn("CAP Dialog is in InitialSent state but no application context name is received");

                        this.deliverDialogNotice(capDialogImpl, CAPNoticeProblemDiagnostic.AbnormalDialogAction);
                        capDialogImpl.setState(CAPDialogState.Expunged);

                        return;
                    }

                    CAPApplicationContext capAcn = CAPApplicationContext.getInstance(acn.getOid());

                    if (capAcn == null || !capAcn.equals(capDialogImpl.getApplicationContext())) {
                        loger.error(String.format("Received first TC-END. CAPDialog=%s. But CAPApplicationContext=%s",
                                capDialogImpl, capAcn));

                        // capDialogImpl.setNormalDialogShutDown();

                        this.deliverDialogNotice(capDialogImpl, CAPNoticeProblemDiagnostic.AbnormalDialogAction);
                        capDialogImpl.setState(CAPDialogState.Expunged);

                        return;
                    }

                    capDialogImpl.setState(CAPDialogState.Active);

                    // Parsing CAPGprsReferenceNumber if exists
                    // we ignore all errors this
                    CAPGprsReferenceNumberImpl referenceNumber = null;
                    UserInformation userInfo = tcEndIndication.getUserInformation();
                    if (userInfo != null) {
                        referenceNumber = ParseUserInfo(userInfo, tcEndIndication.getDialog());
                    }
                    capDialogImpl.receivedGprsReferenceNumber = referenceNumber;

                    this.deliverDialogAccept(capDialogImpl, referenceNumber);
                    if (capDialogImpl.getState() == CAPDialogState.Expunged) {
                        // The Dialog was aborter
                        return;
                    }
                }

                // Now let us decode the Components
                Component[] comps = tcEndIndication.getComponents();
                if (comps != null) {
                    processComponents(capDialogImpl, comps);
                }

                // capDialogImpl.setNormalDialogShutDown();
                this.deliverDialogClose(capDialogImpl);

                capDialogImpl.setState(CAPDialogState.Expunged);
            }
        } finally {
            capDialogImpl.getTcapDialog().getDialogLock().unlock();
        }
    }

    public void onTCUni(TCUniIndication arg0) {
    }

    @Override
    public void onInvokeTimeout(Invoke invoke) {

        CAPDialogImpl capDialogImpl = (CAPDialogImpl) this.getCAPDialog(((InvokeImpl) invoke).getDialog().getLocalDialogId());

        if (capDialogImpl != null) {
            try {
                capDialogImpl.getTcapDialog().getDialogLock().lock();

                if (capDialogImpl.getState() != CAPDialogState.Expunged) {
                    // if (capDialogImpl.getState() != CAPDialogState.Expunged && !capDialogImpl.getNormalDialogShutDown()) {

                    // Getting the CAP Service that serves the CAP Dialog
                    CAPServiceBaseImpl perfSer = (CAPServiceBaseImpl) capDialogImpl.getService();

                    // Check if the InvokeTimeout in this situation is normal (may be for a class 2,3,4 components)
                    // TODO: ................................

                    perfSer.deliverInvokeTimeout(capDialogImpl, invoke);
                }
            } finally {
                capDialogImpl.getTcapDialog().getDialogLock().unlock();
            }
        }
    }

    @Override
    public void onDialogTimeout(Dialog tcapDialog) {

        CAPDialogImpl capDialogImpl = (CAPDialogImpl) this.getCAPDialog(tcapDialog.getLocalDialogId());

        if (capDialogImpl != null) {
            try {
                capDialogImpl.getTcapDialog().getDialogLock().lock();

                if (capDialogImpl.getState() != CAPDialogState.Expunged) {
                    // if (capDialogImpl.getState() != CAPDialogState.Expunged && !capDialogImpl.getNormalDialogShutDown()) {

                    this.deliverDialogTimeout(capDialogImpl);
                }
            } finally {
                capDialogImpl.getTcapDialog().getDialogLock().unlock();
            }
        }
    }

    @Override
    public void onDialogReleased(Dialog tcapDialog) {

        CAPDialogImpl capDialogImpl = (CAPDialogImpl) this.removeDialog(tcapDialog.getLocalDialogId());

        if (capDialogImpl != null) {
            try {
                capDialogImpl.getTcapDialog().getDialogLock().lock();

                this.deliverDialogRelease(capDialogImpl);
            } finally {
                capDialogImpl.getTcapDialog().getDialogLock().unlock();
            }
        }
    }

    public void onTCPAbort(TCPAbortIndication tcPAbortIndication) {
        Dialog tcapDialog = tcPAbortIndication.getDialog();

        CAPDialogImpl capDialogImpl;
        if (this.getTCAPProvider().getPreviewMode()) {
            capDialogImpl = (CAPDialogImpl) (((DialogImpl) tcapDialog).getPrevewDialogData().getUpperDialog());
        } else {
            capDialogImpl = (CAPDialogImpl) this.getCAPDialog(tcapDialog.getLocalDialogId());
        }

        if (capDialogImpl == null) {
            loger.warn("CAP Dialog not found for Dialog Id " + tcapDialog.getLocalDialogId());
            return;
        }
        capDialogImpl.tcapMessageType = MessageType.Abort;

        try {
            capDialogImpl.getTcapDialog().getDialogLock().lock();

            PAbortCauseType pAbortCause = tcPAbortIndication.getPAbortCause();

            this.deliverDialogProviderAbort(capDialogImpl, pAbortCause);

            capDialogImpl.setState(CAPDialogState.Expunged);
        } finally {
            capDialogImpl.getTcapDialog().getDialogLock().unlock();
        }
    }

    public void onTCUserAbort(TCUserAbortIndication tcUserAbortIndication) {
        Dialog tcapDialog = tcUserAbortIndication.getDialog();

        CAPDialogImpl capDialogImpl;
        if (this.getTCAPProvider().getPreviewMode()) {
            capDialogImpl = (CAPDialogImpl) (((DialogImpl) tcapDialog).getPrevewDialogData().getUpperDialog());
        } else {
            capDialogImpl = (CAPDialogImpl) this.getCAPDialog(tcapDialog.getLocalDialogId());
        }

        if (capDialogImpl == null) {
            loger.error("CAP Dialog not found for Dialog Id " + tcapDialog.getLocalDialogId());
            return;
        }
        capDialogImpl.tcapMessageType = MessageType.Abort;

        try {
            capDialogImpl.getTcapDialog().getDialogLock().lock();

            CAPGeneralAbortReason generalReason = null;
            // CAPGeneralAbortReason generalReason = CAPGeneralAbortReason.BadReceivedData;
            CAPUserAbortReason userReason = null;

            if (tcUserAbortIndication.IsAareApdu()) {
                if (capDialogImpl.getState() == CAPDialogState.InitialSent) {
                    generalReason = CAPGeneralAbortReason.DialogRefused;
                    ResultSourceDiagnostic resultSourceDiagnostic = tcUserAbortIndication.getResultSourceDiagnostic();
                    if (resultSourceDiagnostic != null) {
                        if (resultSourceDiagnostic.getDialogServiceUserType() == DialogServiceUserType.AcnNotSupported) {
                            generalReason = CAPGeneralAbortReason.ACNNotSupported;
                        } else if (resultSourceDiagnostic.getDialogServiceProviderType() == DialogServiceProviderType.NoCommonDialogPortion) {
                            generalReason = CAPGeneralAbortReason.NoCommonDialogPortionReceived;
                        }
                    }
                }
            } else {
                UserInformation userInfo = tcUserAbortIndication.getUserInformation();

                if (userInfo != null) {
                    // Checking userInfo.Oid==CAPUserAbortPrimitiveImpl.CAP_AbortReason_OId
                    if (!userInfo.isOid()) {
                        loger.warn("When parsing TCUserAbortIndication indication: userInfo.isOid() is null");
                    } else {
                        if (!Arrays.equals(userInfo.getOidValue(), CAPUserAbortPrimitiveImpl.CAP_AbortReason_OId)) {
                            loger.warn("When parsing TCUserAbortIndication indication: userInfo.getOidValue() must be CAPUserAbortPrimitiveImpl.CAP_AbortReason_OId");
                        } else if (!userInfo.isAsn()) {
                            loger.warn("When parsing TCUserAbortIndication indication: userInfo.isAsn() check failed");
                        } else {
                            try {
                                byte[] asnData = userInfo.getEncodeType();

                                AsnInputStream ais = new AsnInputStream(asnData);

                                int tag = ais.readTag();
                                if (tag != Tag.ENUMERATED || ais.getTagClass() != Tag.CLASS_UNIVERSAL || !ais.isTagPrimitive()) {
                                    loger.warn("When parsing TCUserAbortIndication indication: userInfo has bad tag or tagClass or is not primitive");
                                } else {
                                    CAPUserAbortPrimitiveImpl capUserAbortPrimitive = new CAPUserAbortPrimitiveImpl();
                                    capUserAbortPrimitive.decodeAll(ais);
                                    generalReason = CAPGeneralAbortReason.UserSpecific;
                                    userReason = capUserAbortPrimitive.getCAPUserAbortReason();
                                }
                            } catch (AsnException e) {
                                loger.warn("When parsing TCUserAbortIndication indication: AsnException" + e.getMessage(), e);
                            } catch (IOException e) {
                                loger.warn("When parsing TCUserAbortIndication indication: IOException" + e.getMessage(), e);
                            } catch (CAPParsingComponentException e) {
                                loger.warn(
                                        "When parsing TCUserAbortIndication indication: CAPParsingComponentException"
                                                + e.getMessage(), e);
                            }
                        }
                    }
                }
            }

            this.deliverDialogUserAbort(capDialogImpl, generalReason, userReason);

            capDialogImpl.setState(CAPDialogState.Expunged);
        } finally {
            capDialogImpl.getTcapDialog().getDialogLock().unlock();
        }
    }

    @Override
    public void onTCNotice(TCNoticeIndication ind) {

        if (this.getTCAPProvider().getPreviewMode()) {
            return;
        }

        Dialog tcapDialog = ind.getDialog();

        CAPDialogImpl capDialogImpl = (CAPDialogImpl) this.getCAPDialog(tcapDialog.getLocalDialogId());

        if (capDialogImpl == null) {
            loger.error("CAP Dialog not found for Dialog Id " + tcapDialog.getLocalDialogId());
            return;
        }

        try {
            capDialogImpl.getTcapDialog().getDialogLock().lock();

            this.deliverDialogNotice(capDialogImpl, CAPNoticeProblemDiagnostic.MessageCannotBeDeliveredToThePeer);

            if (capDialogImpl.getState() == CAPDialogState.InitialSent) {
                // capDialogImpl.setNormalDialogShutDown();
                capDialogImpl.setState(CAPDialogState.Expunged);
            }
        } finally {
            capDialogImpl.getTcapDialog().getDialogLock().unlock();
        }
    }

    private void processComponents(CAPDialogImpl capDialogImpl, Component[] components) {

        // Now let us decode the Components
        for (Component c : components) {

            doProcessComponent(capDialogImpl, c);
        }
    }

    private void doProcessComponent(CAPDialogImpl capDialogImpl, Component c) {

        // Getting the CAP Service that serves the CAP Dialog
        CAPServiceBaseImpl perfSer = (CAPServiceBaseImpl) capDialogImpl.getService();

        try {
            ComponentType compType = c.getType();

            Long invokeId = c.getInvokeId();

            Parameter parameter;
            OperationCode oc;
            Long linkedId = 0L;
            Invoke linkedInvoke = null;

            switch (compType) {
                case Invoke: {
                    Invoke comp = (Invoke) c;
                    oc = comp.getOperationCode();
                    parameter = comp.getParameter();
                    linkedId = comp.getLinkedId();

                    // Checking if the invokeId is not duplicated
                    if (linkedId != null) {
                        // linkedId exists Checking if the linkedId exists
                        linkedInvoke = comp.getLinkedInvoke();

                        long[] lstInv = perfSer.getLinkedOperationList(linkedInvoke.getOperationCode().getLocalOperationCode());
                        if (lstInv == null) {
                            Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                    .createProblem(ProblemType.Invoke);
                            problem.setInvokeProblemType(InvokeProblemType.LinkedResponseUnexpected);
                            capDialogImpl.sendRejectComponent(invokeId, problem);
                            perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);

                            return;
                        }

                        boolean found = false;
                        if (lstInv != null) {
                            for (long l : lstInv) {
                                if (l == comp.getOperationCode().getLocalOperationCode()) {
                                    found = true;
                                    break;
                                }
                            }
                        }
                        if (!found) {
                            Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                    .createProblem(ProblemType.Invoke);
                            problem.setInvokeProblemType(InvokeProblemType.UnexpectedLinkedOperation);
                            capDialogImpl.sendRejectComponent(invokeId, problem);
                            perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);

                            return;
                        }
                    }
                }
                    break;

                case ReturnResult: {
                    // ReturnResult is not supported by CAMEL
                    Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                            .createProblem(ProblemType.ReturnResult);
                    problem.setReturnResultProblemType(ReturnResultProblemType.ReturnResultUnexpected);
                    capDialogImpl.sendRejectComponent(null, problem);
                    perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);

                    return;
                }

                case ReturnResultLast: {
                    ReturnResultLast comp = (ReturnResultLast) c;
                    oc = comp.getOperationCode();
                    parameter = comp.getParameter();
                }
                    break;

                case ReturnError: {
                    ReturnError comp = (ReturnError) c;

                    long errorCode = 0;
                    if (comp.getErrorCode() != null && comp.getErrorCode().getErrorType() == ErrorCodeType.Local)
                        errorCode = comp.getErrorCode().getLocalErrorCode();
                    if (errorCode < CAPErrorCode.minimalCodeValue || errorCode > CAPErrorCode.maximumCodeValue) {
                        // Not Local error code and not CAP error code received
                        Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                .createProblem(ProblemType.ReturnError);
                        problem.setReturnErrorProblemType(ReturnErrorProblemType.UnrecognizedError);
                        capDialogImpl.sendRejectComponent(invokeId, problem);
                        perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);

                        return;
                    }

                    CAPErrorMessage msgErr = this.capErrorMessageFactory.createMessageFromErrorCode(errorCode);
                    try {
                        Parameter p = comp.getParameter();
                        if (p != null && p.getData() != null) {
                            byte[] data = p.getData();
                            AsnInputStream ais = new AsnInputStream(data, p.getTagClass(), p.isPrimitive(), p.getTag());
                            ((CAPErrorMessageImpl) msgErr).decodeData(ais, data.length);
                        }
                    } catch (CAPParsingComponentException e) {
                        // Failed when parsing the component - send TC-U-REJECT
                        Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                .createProblem(ProblemType.ReturnError);
                        problem.setReturnErrorProblemType(ReturnErrorProblemType.MistypedParameter);
                        capDialogImpl.sendRejectComponent(invokeId, problem);
                        perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);

                        return;
                    }
                    perfSer.deliverErrorComponent(capDialogImpl, comp.getInvokeId(), msgErr);

                    return;
                }

                case Reject: {
                    Reject comp = (Reject) c;
                    perfSer.deliverRejectComponent(capDialogImpl, comp.getInvokeId(), comp.getProblem(),
                            comp.isLocalOriginated());

                    return;
                }

                default:
                    return;
            }

            try {

                perfSer.processComponent(compType, oc, parameter, capDialogImpl, invokeId, linkedId, linkedInvoke);

            } catch (CAPParsingComponentException e) {

                loger.error(
                        "CAPParsingComponentException when parsing components: " + e.getReason().toString() + " - "
                                + e.getMessage(), e);

                switch (e.getReason()) {
                    case UnrecognizedOperation:
                        // Component does not supported - send TC-U-REJECT
                        if (compType == ComponentType.Invoke) {
                            Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                    .createProblem(ProblemType.Invoke);
                            problem.setInvokeProblemType(InvokeProblemType.UnrecognizedOperation);
                            capDialogImpl.sendRejectComponent(invokeId, problem);
                            perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);
                        } else {
                            Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                    .createProblem(ProblemType.ReturnResult);
                            problem.setReturnResultProblemType(ReturnResultProblemType.MistypedParameter);
                            capDialogImpl.sendRejectComponent(invokeId, problem);
                            perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);
                        }
                        break;

                    case MistypedParameter:
                        // Failed when parsing the component - send TC-U-REJECT
                        if (compType == ComponentType.Invoke) {
                            Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                    .createProblem(ProblemType.Invoke);
                            problem.setInvokeProblemType(InvokeProblemType.MistypedParameter);
                            capDialogImpl.sendRejectComponent(invokeId, problem);
                            perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);
                        } else {
                            Problem problem = this.getTCAPProvider().getComponentPrimitiveFactory()
                                    .createProblem(ProblemType.ReturnResult);
                            problem.setReturnResultProblemType(ReturnResultProblemType.MistypedParameter);
                            capDialogImpl.sendRejectComponent(invokeId, problem);
                            perfSer.deliverRejectComponent(capDialogImpl, invokeId, problem, true);
                        }
                        break;
                }

            }
        } catch (CAPException e) {
            loger.error("Error processing a Component: " + e.getMessage() + "\nComponent" + c, e);
        }
    }

    private void deliverDialogDelimiter(CAPDialog capDialog) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogDelimiter(capDialog);
        }
    }

    private void deliverDialogRequest(CAPDialog capDialog, CAPGprsReferenceNumber capGprsReferenceNumber) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogRequest(capDialog, capGprsReferenceNumber);
        }
    }

    private void deliverDialogAccept(CAPDialog capDialog, CAPGprsReferenceNumber capGprsReferenceNumber) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogAccept(capDialog, capGprsReferenceNumber);
        }
    }

    private void deliverDialogUserAbort(CAPDialog capDialog, CAPGeneralAbortReason generalReason, CAPUserAbortReason userReason) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogUserAbort(capDialog, generalReason, userReason);
        }
    }

    private void deliverDialogProviderAbort(CAPDialog capDialog, PAbortCauseType abortCause) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogProviderAbort(capDialog, abortCause);
        }
    }

    private void deliverDialogClose(CAPDialog capDialog) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogClose(capDialog);
        }
    }

    protected void deliverDialogRelease(CAPDialog capDialog) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogRelease(capDialog);
        }
    }

    protected void deliverDialogTimeout(CAPDialog capDialog) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogTimeout(capDialog);
        }
    }

    protected void deliverDialogNotice(CAPDialog capDialog, CAPNoticeProblemDiagnostic noticeProblemDiagnostic) {
        for (CAPDialogListener listener : this.dialogListeners) {
            listener.onDialogNotice(capDialog, noticeProblemDiagnostic);
        }
    }

    protected void fireTCBegin(Dialog tcapDialog, ApplicationContextName acn, CAPGprsReferenceNumber gprsReferenceNumber,
            boolean returnMessageOnError) throws CAPException {

        if (this.getTCAPProvider().getPreviewMode()) {
            return;
        }

        TCBeginRequest tcBeginReq = encodeTCBegin(tcapDialog, acn, gprsReferenceNumber);
        if (returnMessageOnError)
            tcBeginReq.setReturnMessageOnError(true);

        try {
            tcapDialog.send(tcBeginReq);
        } catch (TCAPSendException e) {
            throw new CAPException(e.getMessage(), e);
        }

    }

    protected TCBeginRequest encodeTCBegin(Dialog tcapDialog, ApplicationContextName acn,
            CAPGprsReferenceNumber gprsReferenceNumber) throws CAPException {

        TCBeginRequest tcBeginReq = this.getTCAPProvider().getDialogPrimitiveFactory().createBegin(tcapDialog);

        tcBeginReq.setApplicationContextName(acn);

        if (gprsReferenceNumber != null) {
            AsnOutputStream localasnOs = new AsnOutputStream();
            ((CAPGprsReferenceNumberImpl) gprsReferenceNumber).encodeAll(localasnOs);

            UserInformation userInformation = TcapFactory.createUserInformation();

            userInformation.setOid(true);
            userInformation.setOidValue(CAPGprsReferenceNumberImpl.CAP_Dialogue_OId);

            userInformation.setAsn(true);
            userInformation.setEncodeType(localasnOs.toByteArray());

            tcBeginReq.setUserInformation(userInformation);
        }
        return tcBeginReq;
    }

    protected void fireTCContinue(Dialog tcapDialog, ApplicationContextName acn, CAPGprsReferenceNumber gprsReferenceNumber,
            boolean returnMessageOnError) throws CAPException {

        if (this.getTCAPProvider().getPreviewMode()) {
            return;
        }

        TCContinueRequest tcContinueReq = encodeTCContinue(tcapDialog, acn, gprsReferenceNumber);
        if (returnMessageOnError)
            tcContinueReq.setReturnMessageOnError(true);

        try {
            tcapDialog.send(tcContinueReq);
        } catch (TCAPSendException e) {
            throw new CAPException(e.getMessage(), e);
        }
    }

    protected TCContinueRequest encodeTCContinue(Dialog tcapDialog, ApplicationContextName acn,
            CAPGprsReferenceNumber gprsReferenceNumber) throws CAPException {
        TCContinueRequest tcContinueReq = this.getTCAPProvider().getDialogPrimitiveFactory().createContinue(tcapDialog);

        if (acn != null)
            tcContinueReq.setApplicationContextName(acn);

        if (gprsReferenceNumber != null) {

            AsnOutputStream localasnOs = new AsnOutputStream();
            ((CAPGprsReferenceNumberImpl) gprsReferenceNumber).encodeAll(localasnOs);

            UserInformation userInformation = TcapFactory.createUserInformation();

            userInformation.setOid(true);
            userInformation.setOidValue(CAPGprsReferenceNumberImpl.CAP_Dialogue_OId);

            userInformation.setAsn(true);
            userInformation.setEncodeType(localasnOs.toByteArray());

            tcContinueReq.setUserInformation(userInformation);
        }
        return tcContinueReq;
    }

    protected void fireTCEnd(Dialog tcapDialog, boolean prearrangedEnd, ApplicationContextName acn,
            CAPGprsReferenceNumber gprsReferenceNumber, boolean returnMessageOnError) throws CAPException {

        if (this.getTCAPProvider().getPreviewMode()) {
            return;
        }

        TCEndRequest endRequest = encodeTCEnd(tcapDialog, prearrangedEnd, acn, gprsReferenceNumber);
        if (returnMessageOnError)
            endRequest.setReturnMessageOnError(true);

        try {
            tcapDialog.send(endRequest);
        } catch (TCAPSendException e) {
            throw new CAPException(e.getMessage(), e);
        }
    }

    protected TCEndRequest encodeTCEnd(Dialog tcapDialog, boolean prearrangedEnd, ApplicationContextName acn,
            CAPGprsReferenceNumber gprsReferenceNumber) throws CAPException {
        TCEndRequest endRequest = this.getTCAPProvider().getDialogPrimitiveFactory().createEnd(tcapDialog);

        if (!prearrangedEnd) {
            endRequest.setTermination(TerminationType.Basic);
        } else {
            endRequest.setTermination(TerminationType.PreArranged);
        }

        if (acn != null)
            endRequest.setApplicationContextName(acn);

        if (gprsReferenceNumber != null) {

            AsnOutputStream localasnOs = new AsnOutputStream();
            ((CAPGprsReferenceNumberImpl) gprsReferenceNumber).encodeAll(localasnOs);

            UserInformation userInformation = TcapFactory.createUserInformation();

            userInformation.setOid(true);
            userInformation.setOidValue(CAPGprsReferenceNumberImpl.CAP_Dialogue_OId);

            userInformation.setAsn(true);
            userInformation.setEncodeType(localasnOs.toByteArray());

            endRequest.setUserInformation(userInformation);
        }
        return endRequest;
    }

    protected void fireTCAbort(Dialog tcapDialog, CAPGeneralAbortReason generalAbortReason, CAPUserAbortReason userAbortReason,
            boolean returnMessageOnError) throws CAPException {

        if (this.getTCAPProvider().getPreviewMode()) {
            return;
        }

        TCUserAbortRequest tcUserAbort = this.getTCAPProvider().getDialogPrimitiveFactory().createUAbort(tcapDialog);

        switch (generalAbortReason) {
            case ACNNotSupported:
                tcUserAbort.setDialogServiceUserType(DialogServiceUserType.AcnNotSupported);
                tcUserAbort.setApplicationContextName(tcapDialog.getApplicationContextName());
                break;

            case UserSpecific:
                if (userAbortReason == null)
                    userAbortReason = CAPUserAbortReason.no_reason_given;
                CAPUserAbortPrimitiveImpl abortReasonPrimitive = new CAPUserAbortPrimitiveImpl(userAbortReason);
                AsnOutputStream localasnOs = new AsnOutputStream();
                abortReasonPrimitive.encodeAll(localasnOs);

                UserInformation userInformation = TcapFactory.createUserInformation();
                userInformation.setOid(true);
                userInformation.setOidValue(CAPUserAbortPrimitiveImpl.CAP_AbortReason_OId);
                userInformation.setAsn(true);
                userInformation.setEncodeType(localasnOs.toByteArray());

                tcUserAbort.setUserInformation(userInformation);
                break;

            // case DialogRefused:
            // if (tcapDialog.getApplicationContextName() != null) {
            // tcUserAbort.setDialogServiceUserType(DialogServiceUserType.NoReasonGive);
            // tcUserAbort.setApplicationContextName(tcapDialog.getApplicationContextName());
            // }
            // break;

            default:
                break;
        }
        if (returnMessageOnError)
            tcUserAbort.setReturnMessageOnError(true);

        try {
            tcapDialog.send(tcUserAbort);
        } catch (TCAPSendException e) {
            throw new CAPException(e.getMessage(), e);
        }
    }

    @Override
    public int getCurrentDialogsCount() {
        return this.tcapProvider.getCurrentDialogsCount();
    }

    public void relayCapMessage(int newServiceKey, CAPMessage capMessage) throws CAPException {
        throw new RuntimeException("NotImplemented");
    }

    public void relayCapMessage(int newServiceKey, SccpAddress origAddress, SccpAddress destAddress, CAPMessage capMessage) throws CAPException {
        throw new RuntimeException("NotImplemented");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy