/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, 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.m3ua.impl.parameter; import java.nio.ByteBuffer; import javolution.text.TextBuilder; import javolution.util.FastList; import javolution.xml.XMLFormat; import javolution.xml.XMLSerializable; import javolution.xml.stream.XMLStreamException; import org.mobicents.protocols.ss7.m3ua.parameter.DestinationPointCode; import org.mobicents.protocols.ss7.m3ua.parameter.LocalRKIdentifier; import org.mobicents.protocols.ss7.m3ua.parameter.NetworkAppearance; import org.mobicents.protocols.ss7.m3ua.parameter.OPCList; import org.mobicents.protocols.ss7.m3ua.parameter.Parameter; import org.mobicents.protocols.ss7.m3ua.parameter.RoutingContext; import org.mobicents.protocols.ss7.m3ua.parameter.RoutingKey; import org.mobicents.protocols.ss7.m3ua.parameter.ServiceIndicators; import org.mobicents.protocols.ss7.m3ua.parameter.TrafficModeType; /** * * @author amit bhayani * */ public class RoutingKeyImpl extends ParameterImpl implements RoutingKey, XMLSerializable { private static final String LOCAL_RK_ID = "localRkId"; private static final String ROUTING_CONTEXT = "rc"; private static final String TRAFFIC_MODE = "trafficMode"; private static final String NETWORK_APPEARANCE = "netAppearance"; private static final String DPCS = "dpcs"; private static final String DPC_ARRAY_SIZE = "dpcsSize"; private static final String SIS = "sis"; private static final String SI_ARRAY_SIZE = "sisSize"; private static final String OPC_LIST = "opcList"; private static final String OPC_ARRAY_SIZE = "opcSize"; private LocalRKIdentifier localRkId; private RoutingContext rc; private TrafficModeType trafMdTy; private NetworkAppearance netApp; private DestinationPointCode[] dpc; private ServiceIndicators[] servInds; private OPCList[] opcList; private ByteBuffer buffer = ByteBuffer.allocate(256); private byte[] value; public RoutingKeyImpl() { this.tag = Parameter.Routing_Key; } protected RoutingKeyImpl(byte[] value) { this.tag = Parameter.Routing_Key; this.value = value; this.decode(value); this.value = value; } protected RoutingKeyImpl(LocalRKIdentifier localRkId, RoutingContext rc, TrafficModeType trafMdTy, NetworkAppearance netApp, DestinationPointCode[] dpc, ServiceIndicators[] servInds, OPCList[] opcList) { this.tag = Parameter.Routing_Key; this.localRkId = localRkId; this.rc = rc; this.trafMdTy = trafMdTy; this.netApp = netApp; this.dpc = dpc; this.servInds = servInds; this.opcList = opcList; this.encode(); } private void decode(byte[] data) { int pos = 0; FastList<DestinationPointCode> dpcList = new FastList<DestinationPointCode>(); FastList<ServiceIndicators> serIndList = new FastList<ServiceIndicators>(); FastList<OPCList> opcListList = new FastList<OPCList>(); while (pos < data.length) { short tag = (short) ((data[pos] & 0xff) << 8 | (data[pos + 1] & 0xff)); short len = (short) ((data[pos + 2] & 0xff) << 8 | (data[pos + 3] & 0xff)); byte[] value = new byte[len - 4]; System.arraycopy(data, pos + 4, value, 0, value.length); pos += len; // parameters.put(tag, factory.createParameter(tag, value)); switch (tag) { case ParameterImpl.Local_Routing_Key_Identifier: this.localRkId = new LocalRKIdentifierImpl(value); break; case ParameterImpl.Routing_Context: this.rc = new RoutingContextImpl(value); break; case ParameterImpl.Traffic_Mode_Type: this.trafMdTy = new TrafficModeTypeImpl(value); break; case ParameterImpl.Network_Appearance: this.netApp = new NetworkAppearanceImpl(value); break; case ParameterImpl.Destination_Point_Code: dpcList.add(new DestinationPointCodeImpl(value)); break; case ParameterImpl.Service_Indicators: serIndList.add(new ServiceIndicatorsImpl(value)); break; case ParameterImpl.Originating_Point_Code_List: opcListList.add(new OPCListImpl(value)); break; } // The Parameter Length does not include any padding octets. We have // to consider padding here pos += (pos % 4); }// end of while this.dpc = new DestinationPointCode[dpcList.size()]; this.dpc = dpcList.toArray(this.dpc); if (serIndList.size() > 0) { this.servInds = new ServiceIndicators[serIndList.size()]; this.servInds = serIndList.toArray(this.servInds); } if (opcListList.size() > 0) { this.opcList = new OPCList[opcListList.size()]; this.opcList = opcListList.toArray(this.opcList); } } private void encode() { if (this.localRkId != null) { ((LocalRKIdentifierImpl) this.localRkId).write(buffer); } if (this.rc != null) { ((RoutingContextImpl) rc).write(buffer); } if (this.trafMdTy != null) { ((TrafficModeTypeImpl) trafMdTy).write(buffer); } if (this.netApp != null) { ((NetworkAppearanceImpl) this.netApp).write(buffer); } for (int i = 0; i < this.dpc.length; i++) { ((DestinationPointCodeImpl) this.dpc[i]).write(buffer); if (this.servInds != null) { ((ServiceIndicatorsImpl) this.servInds[i]).write(buffer); } if (this.opcList != null) { ((OPCListImpl) this.opcList[i]).write(buffer); } } this.value = new byte[buffer.position()]; buffer.flip(); buffer.get(this.value); } @Override protected byte[] getValue() { return this.value; } public DestinationPointCode[] getDestinationPointCodes() { return this.dpc; } public LocalRKIdentifier getLocalRKIdentifier() { return this.localRkId; } public NetworkAppearance getNetworkAppearance() { return this.netApp; } public OPCList[] getOPCLists() { return this.opcList; } public RoutingContext getRoutingContext() { return this.rc; } public ServiceIndicators[] getServiceIndicators() { return this.servInds; } public TrafficModeType getTrafficModeType() { return this.trafMdTy; } @Override public String toString() { TextBuilder tb = TextBuilder.newInstance(); tb.append("RoutingKey("); if (localRkId != null) { tb.append(localRkId.toString()); } if (rc != null) { tb.append(rc.toString()); } if (trafMdTy != null) { tb.append(trafMdTy.toString()); } if (netApp != null) { tb.append(netApp.toString()); } if (dpc != null) { tb.append(dpc.toString()); } if (servInds != null) { tb.append(servInds.toString()); } if (opcList != null) { tb.append(opcList.toString()); } tb.append(")"); return tb.toString(); } /** * XML Serialization/Deserialization */ protected static final XMLFormat<RoutingKeyImpl> RC_XML = new XMLFormat<RoutingKeyImpl>(RoutingKeyImpl.class) { @Override public void read(javolution.xml.XMLFormat.InputElement xml, RoutingKeyImpl routingKey) throws XMLStreamException { int dpcArraySize = xml.getAttribute(DPC_ARRAY_SIZE).toInt(); int opcArraySize = xml.getAttribute(OPC_ARRAY_SIZE).toInt(); int siArraySize = xml.getAttribute(SI_ARRAY_SIZE).toInt(); routingKey.localRkId = xml.get(LOCAL_RK_ID); routingKey.rc = xml.get(ROUTING_CONTEXT); routingKey.trafMdTy = xml.get(TRAFFIC_MODE); routingKey.netApp = xml.get(NETWORK_APPEARANCE); if (dpcArraySize != -1) { routingKey.dpc = new DestinationPointCodeImpl[dpcArraySize]; for (int i = 0; i < dpcArraySize; i++) { routingKey.dpc[i] = xml.get(DPCS); } } if (opcArraySize != -1) { routingKey.opcList = new OPCList[opcArraySize]; for (int i = 0; i < opcArraySize; i++) { routingKey.opcList[i] = xml.get(OPC_LIST); } } if (siArraySize != -1) { routingKey.servInds = new ServiceIndicators[siArraySize]; for (int i = 0; i < siArraySize; i++) { routingKey.servInds[i] = xml.get(SIS); } } routingKey.encode(); } @Override public void write(RoutingKeyImpl routingKey, javolution.xml.XMLFormat.OutputElement xml) throws XMLStreamException { if (routingKey.dpc != null) { xml.setAttribute(DPC_ARRAY_SIZE, routingKey.dpc.length); } else { xml.setAttribute(DPC_ARRAY_SIZE, -1); } if (routingKey.opcList != null) { xml.setAttribute(OPC_ARRAY_SIZE, routingKey.opcList.length); } else { xml.setAttribute(OPC_ARRAY_SIZE, -1); } if (routingKey.servInds != null) { xml.setAttribute(SI_ARRAY_SIZE, routingKey.servInds.length); } else { xml.setAttribute(SI_ARRAY_SIZE, -1); } xml.add(routingKey.localRkId, LOCAL_RK_ID); xml.add(routingKey.rc, ROUTING_CONTEXT); xml.add(routingKey.trafMdTy, TRAFFIC_MODE); xml.add(routingKey.netApp, NETWORK_APPEARANCE); if (routingKey.dpc != null) { for (int i = 0; i < routingKey.dpc.length; i++) { xml.add(routingKey.dpc[i], DPCS); } } if (routingKey.opcList != null) { for (int i = 0; i < routingKey.opcList.length; i++) { xml.add(routingKey.opcList[i], OPC_LIST); } } if (routingKey.servInds != null) { for (int i = 0; i < routingKey.servInds.length; i++) { xml.add(routingKey.servInds[i], SIS); } } } }; }