/*
* 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.tcapAnsi.asn;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.mobicents.protocols.asn.AsnException;
import org.mobicents.protocols.asn.AsnInputStream;
import org.mobicents.protocols.asn.Tag;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.ApplicationContext;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.DialogPortion;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.ParseException;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.ProtocolVersion;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.UserInformation;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.UserInformationElement;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.Component;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.ErrorCode;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.Invoke;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.OperationCode;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.PAbortCause;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.Parameter;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.Reject;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.RejectProblem;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.ReturnError;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.ReturnResultNotLast;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.ReturnResultLast;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.TCAbortMessage;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.TCQueryMessage;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.TCConversationMessage;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.TCResponseMessage;
import org.mobicents.protocols.ss7.tcapAnsi.api.asn.comp.TCUniMessage;
import org.mobicents.protocols.ss7.tcapAnsi.api.tc.component.InvokeClass;
/**
* @author baranowb
* @author amit bhayani
* @author sergey vetyutnev
*
*/
public final class TcapFactory {
private static final Logger logger = Logger.getLogger(TcapFactory.class); // listenres
public static DialogPortion createDialogPortion(AsnInputStream ais) throws ParseException {
DialogPortionImpl dpi = new DialogPortionImpl();
dpi.decode(ais);
return dpi;
}
public static DialogPortion createDialogPortion() {
return new DialogPortionImpl();
}
public static ProtocolVersion createProtocolVersionFull() {
return new ProtocolVersionImpl();
}
public static ProtocolVersion createProtocolVersionEmpty() {
ProtocolVersionImpl pv = new ProtocolVersionImpl();
pv.setT1_114_1996Supported(false);
pv.setT1_114_2000Supported(false);
return pv;
}
public static ProtocolVersion createProtocolVersion(AsnInputStream ais) throws ParseException {
ProtocolVersionImpl pv = new ProtocolVersionImpl();
pv.decode(ais);
return pv;
}
public static ApplicationContext createApplicationContext(long[] oid) {
ApplicationContextImpl acn = new ApplicationContextImpl();
acn.setOid(oid);
return acn;
}
public static ApplicationContext createApplicationContext(long val) {
ApplicationContextImpl acn = new ApplicationContextImpl();
acn.setInteger(val);
return acn;
}
public static ApplicationContext createApplicationContext(AsnInputStream ais) throws ParseException {
ApplicationContextImpl acn = new ApplicationContextImpl();
acn.decode(ais);
return acn;
}
public static UserInformation createUserInformation() {
return new UserInformationImpl();
}
public static UserInformation createUserInformation(AsnInputStream localAis) throws ParseException {
UserInformationImpl ui = new UserInformationImpl();
ui.decode(localAis);
return ui;
}
public static UserInformationElement createUserInformationElement() {
return new UserInformationElementImpl();
}
public static UserInformationElement createUserInformationElement(AsnInputStream localAis) throws ParseException {
UserInformationElementImpl ui = new UserInformationElementImpl();
ui.decode(localAis);
return ui;
}
public static TCUniMessage createTCUniMessage(AsnInputStream localAis) throws ParseException {
TCUniMessageImpl tc = new TCUniMessageImpl();
tc.decode(localAis);
return tc;
}
public static TCUniMessage createTCUniMessage() {
TCUniMessageImpl tc = new TCUniMessageImpl();
return tc;
}
public static TCConversationMessage createTCConversationMessage(AsnInputStream localAis) throws ParseException {
TCConversationMessageImpl tc = new TCConversationMessageImpl();
tc.decode(localAis);
return tc;
}
public static TCConversationMessage createTCConversationMessage() {
TCConversationMessageImpl tc = new TCConversationMessageImpl();
return tc;
}
public static TCResponseMessage createTCResponseMessage(AsnInputStream localAis) throws ParseException {
TCResponseMessageImpl tc = new TCResponseMessageImpl();
tc.decode(localAis);
return tc;
}
public static TCResponseMessage createTCResponseMessage() {
TCResponseMessageImpl tc = new TCResponseMessageImpl();
return tc;
}
public static TCAbortMessage createTCAbortMessage(AsnInputStream localAis) throws ParseException {
TCAbortMessageImpl tc = new TCAbortMessageImpl();
tc.decode(localAis);
return tc;
}
public static TCAbortMessage createTCAbortMessage() {
TCAbortMessageImpl tc = new TCAbortMessageImpl();
return tc;
}
public static TCQueryMessage createTCQueryMessage(AsnInputStream localAis) throws ParseException {
TCQueryMessageImpl tc = new TCQueryMessageImpl();
tc.decode(localAis);
return tc;
}
public static TCQueryMessage createTCQueryMessage() {
TCQueryMessageImpl tc = new TCQueryMessageImpl();
return tc;
}
public static OperationCode createOperationCode() {
OperationCodeImpl oc = new OperationCodeImpl();
return oc;
}
public static OperationCode createOperationCode(AsnInputStream localAis) throws ParseException {
OperationCodeImpl oc = new OperationCodeImpl();
oc.decode(localAis);
return oc;
}
public static Parameter createParameter() {
ParameterImpl p = new ParameterImpl();
return p;
}
public static Parameter createParameterSet() {
ParameterImpl p = new ParameterImpl();
p.setTagClass(Tag.CLASS_PRIVATE);
p.setTag(Parameter._TAG_SET);
p.setPrimitive(false);
return p;
}
public static Parameter createParameterSequence() {
ParameterImpl p = new ParameterImpl();
p.setTagClass(Tag.CLASS_PRIVATE);
p.setTag(Parameter._TAG_SEQUENCE);
p.setPrimitive(false);
return p;
}
public static Parameter createParameter(AsnInputStream localAis)
throws ParseException {
ParameterImpl p = new ParameterImpl();
p.decode(localAis);
return p;
}
public static Parameter createParameter(int tag, AsnInputStream localAis, boolean singleParameterInAsn)
throws ParseException {
ParameterImpl p = new ParameterImpl();
p.setTag(tag);
if (singleParameterInAsn)
p.setSingleParameterInAsn();
p.decode(localAis);
return p;
}
public static Reject createComponentReject() {
return new RejectImpl();
}
public static ReturnResultLast createComponentReturnResultLast() {
return new ReturnResultLastImpl();
}
public static ReturnResultNotLast createComponentReturnResultNotLast() {
return new ReturnResultNotLastImpl();
}
public static Invoke createComponentInvoke() {
return new InvokeImpl();
}
public static Invoke createComponentInvoke(InvokeClass invokeClass) {
return new InvokeImpl(invokeClass);
}
public static ReturnError createComponentReturnError() {
return new ReturnErrorImpl();
}
public static ErrorCode createErrorCode(AsnInputStream ais) throws ParseException {
ErrorCode p = createErrorCode();
p.decode(ais);
return p;
}
public static ErrorCode createErrorCode() {
ErrorCode p = new ErrorCodeImpl();
return p;
}
public static TransactionID readTransactionID(AsnInputStream ais) throws ParseException {
try {
int tag = ais.readTag();
if (tag != TCQueryMessage._TAG_TRANSACTION_ID || ais.getTagClass() != Tag.CLASS_PRIVATE || !ais.isTagPrimitive())
throw new ParseException(PAbortCause.IncorrectTransactionPortion,
"Error decoding TransactionID: bad tag or tagClass or not primitive for TransactionId, found tagClass=" + ais.getTagClass() + ", tag="
+ tag);
byte[] buf = ais.readOctetString();
if (buf.length != 0 && buf.length != 4 && buf.length != 8)
throw new ParseException(PAbortCause.BadlyStructuredTransactionPortion,
"Error decoding TransactionID: originatingTransactionId bad length, must be 0, 4 or 8, found =" + buf.length);
TransactionID res = new TransactionID();
if (buf.length == 4) {
res.setFirstElem(buf);
}
if (buf.length == 8) {
byte[] firstElem = new byte[4];
byte[] secondElem = new byte[4];
System.arraycopy(buf, 0, firstElem, 0, 4);
System.arraycopy(buf, 4, secondElem, 0, 4);
res.setFirstElem(firstElem);
res.setSecondElem(secondElem);
}
return res;
} catch (IOException e) {
throw new ParseException(PAbortCause.BadlyStructuredTransactionPortion, "IOException while decoding TransactionID: " + e.getMessage(), e);
} catch (AsnException e) {
throw new ParseException(PAbortCause.BadlyStructuredTransactionPortion, "AsnException while decoding TransactionID: " + e.getMessage(), e);
}
}
public static Component[] readComponents(AsnInputStream ais) {
List<Component> cps = new ArrayList<Component>();
AsnInputStream compAis = null;
try {
int tag = ais.getTag();
if (tag != TCQueryMessage._TAG_COMPONENT_SEQUENCE || ais.getTagClass() != Tag.CLASS_PRIVATE || ais.isTagPrimitive()) {
throw new ParseException(RejectProblem.generalUnrecognisedComponentType, "Bad component sequence tag or tag class or is primitive, tag=" + tag
+ ", tagClass=" + ais.getTagClass());
}
try {
compAis = ais.readSequenceStream();
} catch (IOException e) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "IOException while decoding Components: " + e.getMessage(), e);
} catch (AsnException e) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "AsnException while decoding Components: " + e.getMessage(), e);
}
} catch (ParseException e) {
logger.error("Local Reject: " + e.getProblem() + ", " + e.getMessage(), e);
if (e.getProblem() != null) {
Reject rej = TcapFactory.createComponentReject();
rej.setLocalOriginated(true);
rej.setCorrelationId(e.getInvokeId());
rej.setProblem(e.getProblem());
cps.add(rej);
}
}
while (compAis != null && compAis.available() > 0) {
try {
Component c = TcapFactory.createComponent(compAis);
if (c == null) {
break;
}
cps.add(c);
} catch (ParseException e) {
logger.error("Local Reject: " + e.getProblem() + ", " + e.getMessage(), e);
if (e.getProblem() != null) {
Reject rej = TcapFactory.createComponentReject();
rej.setLocalOriginated(true);
rej.setCorrelationId(e.getInvokeId());
rej.setProblem(e.getProblem());
cps.add(rej);
}
}
}
Component[] res = new Component[cps.size()];
cps.toArray(res);
return res;
}
public static Component createComponent(AsnInputStream localAis) throws ParseException {
try {
int tag = localAis.readTag();
Component c = null;
if (localAis.getTagClass() != Tag.CLASS_PRIVATE) {
localAis.advanceElement();
throw new ParseException(RejectProblem.generalUnrecognisedComponentType, "Error decoding a component: bad tag class: " + localAis.getTagClass());
}
switch (tag) {
case Invoke._TAG_INVOKE_LAST:
case Invoke._TAG_INVOKE_NOT_LAST:
c = createComponentInvoke();
c.decode(localAis);
break;
case ReturnResultNotLast._TAG_RETURN_RESULT_NOT_LAST:
c = createComponentReturnResultNotLast();
c.decode(localAis);
break;
case ReturnResultLast._TAG_RETURN_RESULT_LAST:
c = createComponentReturnResultLast();
c.decode(localAis);
break;
case ReturnError._TAG_RETURN_ERROR:
c = createComponentReturnError();
c.decode(localAis);
break;
case Reject._TAG_REJECT:
c = createComponentReject();
c.decode(localAis);
break;
default:
localAis.advanceElement();
throw new ParseException(RejectProblem.generalUnrecognisedComponentType, "Error decoding a component: bad tag: " + tag);
}
return c;
} catch (IOException e) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "IOException while decoding component: " + e.getMessage(), e);
} catch (AsnException e) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "AsnException while decoding component: " + e.getMessage(), e);
}
}
public static Parameter readParameter(AsnInputStream localAis) throws ParseException {
if (localAis.available() == 0)
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "Parameter is not found when decoding a Parameter");
int tag;
try {
tag = localAis.readTag();
if ((tag != Parameter._TAG_SEQUENCE && tag != Parameter._TAG_SET) || localAis.getTagClass() != Tag.CLASS_PRIVATE || localAis.isTagPrimitive()) {
throw new ParseException(RejectProblem.generalIncorrectComponentPortion,
"Parameters sequence/set has bad tag or tag class or is primitive: tag=" + tag + ", tagClass=" + localAis.getTagClass());
}
Parameter par = TcapFactory.createParameter(localAis);
return par;
} catch (IOException e) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "IOException while decoding parameter: " + e.getMessage(), e);
}
}
public static byte[] readComponentId(AsnInputStream localAis, int minLen, int maxLen) throws ParseException {
try {
int tag = localAis.readTag();
if (tag != Component._TAG_INVOKE_ID || localAis.getTagClass() != Tag.CLASS_PRIVATE || !localAis.isTagPrimitive()) {
throw new ParseException(RejectProblem.generalIncorrectComponentPortion, "ComponentID has bad tag or tag class or is not primitive: tag=" + tag
+ ", tagClass=" + localAis.getTagClass());
}
byte[] buf = localAis.readOctetString();
if (buf.length < minLen || buf.length > maxLen) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "ComponentID has bad length: " + buf.length + ", minLength=" + minLen
+ ", maxLength=" + maxLen);
}
return buf;
} catch (IOException e) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "IOException while decoding ComponentId: " + e.getMessage(), e);
} catch (AsnException e) {
throw new ParseException(RejectProblem.generalBadlyStructuredCompPortion, "AsnException while decoding ComponentId: " + e.getMessage(), e);
}
}
}