
org.restcomm.protocols.ss7.m3ua.impl.AspImpl 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.restcomm.protocols.ss7.m3ua.impl;
import javolution.xml.XMLFormat;
import javolution.xml.XMLSerializable;
import javolution.xml.stream.XMLStreamException;
import org.apache.log4j.Logger;
import org.restcomm.protocols.ss7.m3ua.As;
import org.restcomm.protocols.ss7.m3ua.Asp;
import org.restcomm.protocols.ss7.m3ua.ExchangeType;
import org.restcomm.protocols.ss7.m3ua.IPSPType;
import org.restcomm.protocols.ss7.m3ua.State;
import org.restcomm.protocols.ss7.m3ua.impl.fsm.FSM;
import org.restcomm.protocols.ss7.m3ua.impl.message.MessageFactoryImpl;
import org.restcomm.protocols.ss7.m3ua.message.MessageFactory;
import org.restcomm.protocols.ss7.m3ua.parameter.ASPIdentifier;
/**
*
* @author amit bhayani
*
*/
public class AspImpl implements XMLSerializable, Asp {
private static final Logger logger = Logger.getLogger(AspImpl.class);
protected static final String NAME = "name";
protected String name;
/**
* Local FSM is such that it sends ASP_UP to other side
**/
protected FSM localFSM;
/**
* Peer FSM is such that it receives ASP_UP from other side
**/
protected FSM peerFSM;
protected AspFactoryImpl aspFactoryImpl;
protected AsImpl asImpl;
protected ASPIdentifier aSPIdentifier;
private MessageFactory messageFactory = new MessageFactoryImpl();
protected State state = AspState.DOWN;
public AspImpl() {
}
public AspImpl(String name, AspFactoryImpl aspFactroy) {
this.name = name;
this.aspFactoryImpl = aspFactroy;
this.init();
}
private void init() {
switch (this.aspFactoryImpl.functionality) {
case IPSP:
if (this.aspFactoryImpl.exchangeType == ExchangeType.SE) {
if (this.aspFactoryImpl.ipspType == IPSPType.CLIENT) {
// If this ASP is IPSP and client side, it should send the
// ASP_UP to other side
this.initLocalFSM();
} else {
// else this will receive ASP_UP from other side
this.initPeerFSM();
}
} else {
// If this is IPSP and DE, it should maintain two states. One
// for sending ASP_UP to other side and other for receiving
// ASP_UP form
// other side
this.initPeerFSM();
this.initLocalFSM();
}
break;
case AS:
if (this.aspFactoryImpl.exchangeType == ExchangeType.SE) {
// If this is AS side, it should always send the ASP_UP to other
// side
this.initLocalFSM();
} else {
// If DE it should maintain two states
this.initPeerFSM();
this.initLocalFSM();
}
break;
case SGW:
if (this.aspFactoryImpl.exchangeType == ExchangeType.SE) {
// If this is SGW, it should always receive ASP_UP from other
// side
this.initPeerFSM();
} else {
// If DE it should maintain two states
this.initPeerFSM();
this.initLocalFSM();
}
break;
}
}
private void initLocalFSM() {
this.localFSM = new FSM(this.name + "_LOCAL");
// Define states
this.localFSM.createState(AspState.DOWN_SENT.toString()).setOnEnter(new AspStateEnterDown(this));
this.localFSM.createState(AspState.DOWN.toString()).setOnEnter(new AspStateEnterDown(this));
this.localFSM.createState(AspState.UP_SENT.toString()).setOnEnter(new AspStateEnterDown(this));
this.localFSM.createState(AspState.INACTIVE.toString()).setOnEnter(new AspStateEnterInactive(this));
this.localFSM.createState(AspState.ACTIVE_SENT.toString()).setOnEnter(new AspStateEnterInactive(this));
this.localFSM.createState(AspState.ACTIVE.toString()).setOnEnter(new AspStateEnterActive(this));
this.localFSM.createState(AspState.INACTIVE_SENT.toString()).setOnEnter(new AspStateEnterInactive(this));
this.localFSM.setStart(AspState.DOWN.toString());
this.localFSM.setEnd(AspState.DOWN.toString());
// Define Transitions
// ******************************************************************/
// DOWN /
// ******************************************************************/
this.localFSM.createTransition(TransitionState.COMM_UP, AspState.DOWN.toString(), AspState.UP_SENT.toString());
// .setHandler(new AspTransDwnToAspUpSnt(this, this.fsm));
this.localFSM.createTransition(TransitionState.COMM_DOWN, AspState.DOWN.toString(), AspState.DOWN.toString());
// ******************************************************************/
// UP_SENT/
// ******************************************************************/
// Keep sending ASP_UP if timeout occurs.
this.localFSM.createTimeoutTransition(AspState.UP_SENT.toString(), AspState.UP_SENT.toString(), 2000).setHandler(
new THLocalAspDwnToAspUpSnt(this, this.localFSM));
this.localFSM.createTransition(TransitionState.ASP_INACTIVE, AspState.UP_SENT.toString(), AspState.INACTIVE.toString());
this.localFSM.createTransition(TransitionState.ASP_ACTIVE_SENT, AspState.UP_SENT.toString(),
AspState.ACTIVE_SENT.toString());
this.localFSM.createTransition(TransitionState.ASP_DOWN_SENT, AspState.UP_SENT.toString(),
AspState.DOWN_SENT.toString());
this.localFSM.createTransition(TransitionState.COMM_DOWN, AspState.UP_SENT.toString(), AspState.DOWN.toString());
// ******************************************************************/
// ACTIVE_SENT/
// ******************************************************************/
// TODO Keep sending ASP_ACTIVE ?
this.localFSM.createTimeoutTransition(AspState.ACTIVE_SENT.toString(), AspState.ACTIVE_SENT.toString(), 2000);
this.localFSM.createTransition(TransitionState.ASP_ACTIVE_ACK, AspState.ACTIVE_SENT.toString(),
AspState.ACTIVE.toString());
// .setHandler(new AspTransActSntToAct(this, this.fsm));
this.localFSM.createTransition(TransitionState.ASP_DOWN_SENT, AspState.ACTIVE_SENT.toString(),
AspState.DOWN_SENT.toString());
this.localFSM.createTransition(TransitionState.COMM_DOWN, AspState.ACTIVE_SENT.toString(), AspState.DOWN.toString());
// ******************************************************************/
// ACTIVE/
// ******************************************************************/
this.localFSM.createTransition(TransitionState.ASP_INACTIVE_SENT, AspState.ACTIVE.toString(),
AspState.INACTIVE_SENT.toString());
// .setHandler(new AspTransActToInactSnt(this, this.fsm));
this.localFSM.createTransition(TransitionState.OTHER_ALTERNATE_ASP_ACTIVE, AspState.ACTIVE.toString(),
AspState.INACTIVE.toString());
this.localFSM
.createTransition(TransitionState.ASP_DOWN_SENT, AspState.ACTIVE.toString(), AspState.DOWN_SENT.toString());
this.localFSM.createTransition(TransitionState.COMM_DOWN, AspState.ACTIVE.toString(), AspState.DOWN.toString());
// .setHandler(new AspTransActToDwn(this, this.fsm));
// ******************************************************************/
// INACTIVE/
// ******************************************************************/
this.localFSM.createTransition(TransitionState.COMM_DOWN, AspState.INACTIVE.toString(), AspState.DOWN.toString());
// .setHandler(new AspTransInactToDwn(this, this.fsm));
this.localFSM.createTransition(TransitionState.ASP_ACTIVE_SENT, AspState.INACTIVE.toString(),
AspState.ACTIVE_SENT.toString());
this.localFSM.createTransition(TransitionState.ASP_DOWN_SENT, AspState.INACTIVE.toString(),
AspState.DOWN_SENT.toString());
// ******************************************************************/
// INACTIVE_SENT/
// ******************************************************************/
// TODO keep sending INACTIVE ASP ?
this.localFSM.createTimeoutTransition(AspState.INACTIVE_SENT.toString(), AspState.INACTIVE_SENT.toString(), 2000);
// TODO Take care of this .setHandler(new
// AspTransActToInactSnt(this,
// this.fsm));
this.localFSM.createTransition(TransitionState.ASP_INACTIVE_ACK, AspState.INACTIVE_SENT.toString(),
AspState.INACTIVE.toString());
this.localFSM.createTransition(TransitionState.ASP_DOWN_SENT, AspState.INACTIVE_SENT.toString(),
AspState.DOWN_SENT.toString());
this.localFSM.createTransition(TransitionState.COMM_DOWN, AspState.INACTIVE_SENT.toString(), AspState.DOWN.toString());
// ******************************************************************/
// DOWN_SENT/
// ******************************************************************/
this.localFSM.createTransition(TransitionState.ASP_DOWN_ACK, AspState.DOWN_SENT.toString(), AspState.DOWN.toString());
this.localFSM.createTransition(TransitionState.COMM_DOWN, AspState.DOWN_SENT.toString(), AspState.DOWN.toString());
}
private void initPeerFSM() {
this.peerFSM = new FSM(this.name + "_PEER");
// Define states
this.peerFSM.createState(AspState.DOWN.toString()).setOnEnter(new AspStateEnterDown(this));
this.peerFSM.createState(AspState.ACTIVE.toString()).setOnEnter(new AspStateEnterActive(this));
this.peerFSM.createState(AspState.INACTIVE.toString()).setOnEnter(new AspStateEnterInactive(this));
this.peerFSM.setStart(AspState.DOWN.toString());
this.peerFSM.setEnd(AspState.DOWN.toString());
// Define Transitions
// ******************************************************************/
// STATE DOWN /
// ******************************************************************/
this.peerFSM.createTransition(TransitionState.COMM_UP, AspState.DOWN.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.COMM_DOWN, AspState.DOWN.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.ASP_UP, AspState.DOWN.toString(), AspState.INACTIVE.toString());
// If the SGP receives any other M3UA messages before an ASP Up message
// is received (other than ASP Down; see Section 4.3.4.2), the SGP MAY
// discard them.
this.peerFSM.createTransition(TransitionState.DAUD, AspState.DOWN.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.ASP_ACTIVE, AspState.DOWN.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.ASP_INACTIVE, AspState.DOWN.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.PAYLOAD, AspState.DOWN.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.ASP_DOWN, AspState.DOWN.toString(), AspState.DOWN.toString());
// TODO : For REG_REQ/DREG_REQ we don't support dynamic adding of
// key.
// Handle this
// ******************************************************************/
// STATE INACTIVE /
// ******************************************************************/
this.peerFSM.createTransition(TransitionState.COMM_DOWN, AspState.INACTIVE.toString(), AspState.DOWN.toString());
// Mo transition needed? .setHandler(new RemAspTransInactToDwn(this,
// this.fsm));
this.peerFSM.createTransition(TransitionState.ASP_UP, AspState.INACTIVE.toString(), AspState.INACTIVE.toString());
this.peerFSM.createTransition(TransitionState.ASP_DOWN, AspState.INACTIVE.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.ASP_ACTIVE, AspState.INACTIVE.toString(), AspState.ACTIVE.toString());
// TODO: Ignore payload if Remote ASP is still INACTIVE. may be log
// it?
this.peerFSM.createTransition(TransitionState.PAYLOAD, AspState.INACTIVE.toString(), AspState.INACTIVE.toString());
// ******************************************************************/
// STATE ACTIVE /
// ******************************************************************/
this.peerFSM.createTransition(TransitionState.COMM_DOWN, AspState.ACTIVE.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.ASP_UP, AspState.ACTIVE.toString(), AspState.INACTIVE.toString());
this.peerFSM.createTransition(TransitionState.ASP_DOWN, AspState.ACTIVE.toString(), AspState.DOWN.toString());
this.peerFSM.createTransition(TransitionState.ASP_INACTIVE, AspState.ACTIVE.toString(), AspState.INACTIVE.toString());
// No transition handler .setHandler(new RemAspTransActToInact(this,
// this.fsm));
this.peerFSM.createTransition(TransitionState.PAYLOAD, AspState.ACTIVE.toString(), AspState.ACTIVE.toString());
// This transition will be signaled from SGW
this.peerFSM.createTransition(TransitionState.OTHER_ALTERNATE_ASP_ACTIVE, AspState.ACTIVE.toString(),
AspState.INACTIVE.toString());
}
public String getName() {
return this.name;
}
public boolean isStarted() {
return this.aspFactoryImpl.started;
}
public boolean isConnected() {
return this.isStarted() && this.isUp();
}
public boolean isUp() {
return this.state.getName().equals(State.STATE_ACTIVE);
}
public State getState() {
return this.state;
}
public FSM getLocalFSM() {
return localFSM;
}
public FSM getPeerFSM() {
return peerFSM;
}
public As getAs() {
return asImpl;
}
public void setAs(AsImpl asImpl) {
this.asImpl = asImpl;
}
public AspFactoryImpl getAspFactory() {
return this.aspFactoryImpl;
}
public ASPIdentifier getASPIdentifier() {
return aSPIdentifier;
}
public void setASPIdentifier(ASPIdentifier identifier) {
aSPIdentifier = identifier;
}
public MessageFactory getMessageFactory() {
return messageFactory;
}
/**
* XML Serialization/Deserialization
*/
protected static final XMLFormat ASP_XML = new XMLFormat(AspImpl.class) {
@Override
public void read(javolution.xml.XMLFormat.InputElement xml, AspImpl aspImpl) throws XMLStreamException {
aspImpl.name = xml.getAttribute(NAME, "");
}
@Override
public void write(AspImpl aspImpl, javolution.xml.XMLFormat.OutputElement xml) throws XMLStreamException {
xml.setAttribute(NAME, aspImpl.name);
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy