com.devoteam.srit.xmlloader.sctp.MsgSctp.java Source code

Java tutorial

Introduction

Here is the source code for com.devoteam.srit.xmlloader.sctp.MsgSctp.java

Source

/* 
 * Copyright 2012 Devoteam http://www.devoteam.com
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * 
 * This file is part of Multi-Protocol Test Suite (MTS).
 * 
 * Multi-Protocol Test Suite (MTS) is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, either version 3 of the
 * License.
 * 
 * Multi-Protocol Test Suite (MTS) 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Multi-Protocol Test Suite (MTS).
 * If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package com.devoteam.srit.xmlloader.sctp;

import gp.utils.arrays.Array;
import gp.utils.arrays.DefaultArray;

import java.net.InetAddress;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.dom4j.Element;

import com.devoteam.srit.xmlloader.core.Parameter;
import com.devoteam.srit.xmlloader.core.Runner;
import com.devoteam.srit.xmlloader.core.coding.text.FirstLine;
import com.devoteam.srit.xmlloader.core.log.GlobalLogger;
import com.devoteam.srit.xmlloader.core.log.TextEvent;
import com.devoteam.srit.xmlloader.core.protocol.Msg;
import com.devoteam.srit.xmlloader.core.protocol.Stack;
import com.devoteam.srit.xmlloader.core.protocol.StackFactory;
import com.devoteam.srit.xmlloader.core.utils.Utils;

import dk.i1.sctp.AssociationId;
import dk.i1.sctp.SCTPData;

public class MsgSctp extends Msg {

    private enum DataType {
        text, binary
    }

    private SCTPData sctpData;

    /** Creates a new instance */
    public MsgSctp(Stack stack) throws Exception {
        super(stack);
    }

    /** Creates a new instance */
    public MsgSctp(Stack stack, byte[] bytes) throws Exception {
        this(stack);

        this.sctpData = new SCTPData(bytes);
    }

    /** Get the protocol of this message */
    @Override
    public String getProtocol() {
        return StackFactory.PROTOCOL_SCTP;
    }

    /** 
     * Return true if the message is a request else return false
     */
    @Override
    public boolean isRequest() {
        return true;
    }

    /** 
     * Get the type of the message
     * Used for message filtering with "type" attribute and for statistic counters 
     */
    @Override
    public String getType() {
        return this.type;
    }

    /** Set the type of this message */
    public void setType(String type) {
        this.type = type;
    }

    /** 
     * Get the result of the message (null if request)
     * Used for message filtering with "result" attribute and for statistic counters 
     */
    @Override
    public String getResult() throws Exception {
        return null;
    }

    /// a utiliser
    public void setAidFromMsg() {
        ((ChannelSctp) getChannel()).setAssociationId(sctpData.sndrcvinfo.sinfo_assoc_id);
    }

    //-------------------------------------------------
    // methods for the encoding / decoding of the message
    //-------------------------------------------------

    /** 
     * encode the message to binary data 
     */
    @Override
    public byte[] encode() throws Exception {
        return this.sctpData.getData();
    }

    /** 
     * decode the message from binary data 
     */
    @Override
    public void decode(byte[] data) throws Exception {
        this.sctpData = new SCTPData(data);
    }

    //---------------------------------------------------------------------
    // methods for the XML display / parsing of the message
    //---------------------------------------------------------------------

    /** Returns a short description of the message. Used for logging as INFO level */
    /** This methods HAS TO be quick to execute for performance reason */
    @Override
    public String toShortString() throws Exception {
        String ret = super.toShortString();
        ret += "\n";
        try {
            ret += Utils.toStringBinary(sctpData.getData(), Math.min(sctpData.getData().length, 100));
        } catch (Exception e) {
            GlobalLogger.instance().getApplicationLogger().warn(TextEvent.Topic.PROTOCOL, e,
                    "An error occured while logging the SCTP message : ", ret);
            e.printStackTrace();
        }
        return ret;
    }

    /** 
     * Convert the message to XML document 
     */
    @Override
    public String toXml() throws Exception {
        String xml = getTypeComplete();
        xml += "\n";
        if (sctpData.sndrcvinfo != null) {
            xml += "<header stream=\"" + sctpData.sndrcvinfo.sinfo_stream + "\", ";
            xml += "ssn=\"" + sctpData.sndrcvinfo.sinfo_ssn + "\", ";
            xml += "ppid=\"" + sctpData.sndrcvinfo.sinfo_ppid + "\", ";
            xml += "tsn=\"" + sctpData.sndrcvinfo.sinfo_tsn + "\", ";
            xml += "aid=\"" + sctpData.sndrcvinfo.sinfo_assoc_id + "\"/>\n";
            xml += "\n";
        }
        xml += Utils.byteTabToString(sctpData.getData());
        return xml;

    }

    /** 
     * Parse the message from XML element 
     */
    @Override
    public void parseFromXml(Boolean request, Element root, Runner runner) throws Exception {
        List<Element> elements = root.elements("data");
        List<byte[]> datas = new LinkedList<byte[]>();
        for (Element element : elements) {
            switch (DataType.valueOf(element.attributeValue("format"))) {
            case text: {
                String text = element.getText();
                // change the \n caractre to \r\n caracteres because the dom librairy return only \n.
                // this could make some trouble when the length is calculated in the scenario
                text = text.replace("\r\n", "\n");
                text = text.replace("\n", "\r\n");
                datas.add(text.getBytes("UTF8"));
                break;
            }
            case binary: {
                String text = element.getTextTrim();
                datas.add(Utils.parseBinaryString(text));
            }
            }
        }

        //
        // Compute total length
        //
        int length = 0;
        for (byte[] data : datas) {
            length += data.length;
        }

        byte[] data = new byte[length];

        int i = 0;
        for (byte[] aData : datas) {
            for (int j = 0; j < aData.length; j++) {
                data[i] = aData[j];
                i++;
            }
        }

        SCTPData sctpData = new SCTPData(data);

        String stream = root.attributeValue("stream");
        if (stream != null) {
            sctpData.sndrcvinfo.sinfo_stream = (short) Integer.parseInt(stream);
        }
        String ssn = root.attributeValue("ssn");
        if (ssn != null) {
            sctpData.sndrcvinfo.sinfo_ssn = (short) Integer.parseInt(ssn);
        }
        String flags = root.attributeValue("flags");
        if (flags != null) {
            sctpData.sndrcvinfo.sinfo_flags = (short) Integer.parseInt(flags);
        }
        String ppid = root.attributeValue("ppid");
        if (ppid != null) {
            sctpData.sndrcvinfo.sinfo_ppid = Integer.parseInt(ppid);
        }
        String context = root.attributeValue("context");
        if (context != null) {
            sctpData.sndrcvinfo.sinfo_context = Integer.parseInt(context);
        }
        String ttl = root.attributeValue("ttl");
        if (ttl != null) {
            sctpData.sndrcvinfo.sinfo_timetolive = Integer.parseInt(ttl);
        }
        String tsn = root.attributeValue("tsn");
        if (tsn != null) {
            sctpData.sndrcvinfo.sinfo_tsn = Integer.parseInt(tsn);
        }
        String cumtsn = root.attributeValue("cumtsn");
        if (cumtsn != null) {
            sctpData.sndrcvinfo.sinfo_cumtsn = Integer.parseInt(cumtsn);
        }
        String aid = root.attributeValue("aid");
        if (aid != null) {
            sctpData.sndrcvinfo.sinfo_assoc_id = new AssociationId(Long.parseLong(aid));
        }

        this.sctpData = new SCTPData(sctpData.sndrcvinfo, sctpData.getData());
        this.type = "DATA";
    }

    //------------------------------------------------------
    // method for the "setFromMessage" <parameter> operation
    //------------------------------------------------------

    /** 
     * Get a parameter from the message
     */
    @Override
    public Parameter getParameter(String path) throws Exception {
        Parameter var = super.getParameter(path);
        if (null != var) {
            return var;
        }

        var = new Parameter();
        path = path.trim();
        String[] params = Utils.splitPath(path);

        if (params[0].equalsIgnoreCase("header")) {
            if (this.sctpData != null && this.sctpData.sndrcvinfo != null) {
                if (params[1].equalsIgnoreCase("stream")) {
                    var.add(Integer.toString(this.sctpData.sndrcvinfo.sinfo_stream));
                } else if (params[1].equalsIgnoreCase("ssn")) {
                    var.add(Integer.toString(this.sctpData.sndrcvinfo.sinfo_ssn));
                } else if (params[1].equalsIgnoreCase("ppid")) {
                    int ppid = Utils.convertLittleBigIndian(this.sctpData.sndrcvinfo.sinfo_ppid);
                    var.add(Integer.toString(ppid));
                } else if (params[1].equalsIgnoreCase("tsn")) {
                    int tsn = Utils.convertLittleBigIndian(this.sctpData.sndrcvinfo.sinfo_tsn);
                    var.add(Long.toString(tsn));
                } else if (params[1].equalsIgnoreCase("aid")) {
                    int aid = Utils.convertLittleBigIndian(this.sctpData.sndrcvinfo.sinfo_assoc_id.hashCode());
                    var.add(Integer.toString(aid));
                    setAidFromMsg();
                } else if (params[1].equalsIgnoreCase("sourceHost")) {
                    SocketSctp socketSctp = ((ChannelSctp) getChannel()).getSocketSctp();
                    Collection<InetAddress> col = socketSctp.getSctpSocket()
                            .getPeerInetAddresses(sctpData.sndrcvinfo.sinfo_assoc_id);
                    for (InetAddress ia : col) {
                        // support IPV6 address
                        // if (ia instanceof Inet4Address)
                        {
                            var.add(ia.getHostAddress());
                            break;
                        }
                    }
                } else if (params[1].equalsIgnoreCase("sourcePort")) {
                    ChannelSctp connSctp = ((ChannelSctp) getChannel());
                    int port = connSctp.getSocketSctp().getSctpSocket()
                            .getPeerInetPort(sctpData.sndrcvinfo.sinfo_assoc_id);
                    var.add(Integer.toString(port));
                } else {
                    Parameter.throwBadPathKeywordException(path);
                }
            }
        } else if (params[0].equalsIgnoreCase("data")) {
            if (params[1].equalsIgnoreCase("text")) {
                var.add(new String(this.sctpData.getData()));
            } else if (params[1].equalsIgnoreCase("binary")) {
                var.add(Array.toHexString(new DefaultArray(this.sctpData.getData())));
            } else {
                Parameter.throwBadPathKeywordException(path);
            }
        } else if (params[0].equalsIgnoreCase("ua") && params[1].equalsIgnoreCase("ppid")) {
            var.add("1111");
        } else {
            Parameter.throwBadPathKeywordException(path);
        }

        return var;
    }

}