Commit b5d65b0a authored by Iztok Juvancic's avatar Iztok Juvancic
Browse files

week33-2020_TA

parent 0db4bdbc
Loading
Loading
Loading
Loading
+504 −0
Original line number Diff line number Diff line
/* ######################################################################### */
/* #                                                                       # */
/* #                                                                       # */
/* #                Copyright (c) 2012 Sintesio Org.                       # */
/* #                                                                       # */
/* #                                                                       # */
/* # File Name    : AVP.java                                               # */
/* #                                                                       # */
/* # File Code    :                                                        # */
/* #                                                                       # */
/* # Description  : Implementation of DIAMETER parser class.               # */
/* #                                                                       # */
/* # Revision     : 1.0                                                    # */
/* #                                                                       # */
/* # Project Name :                                                        # */
/* #                                                                       # */
/* # Date         : Apr 2012                                               # */
/* #                                                                       # */
/* # Author       : Sintesio                                               # */
/* #                                                                       # */
/* # Translation  : javac                                                  # */
/* #                                                                       # */
/* #                                                                       # */
/* ######################################################################### */

package com.iskratel.diameter.parser;

import java.util.Vector;

/**
 * Provides methods to create and manipulate of AVPs and Diameter messages.
 */

/**
 * This class defines the basic AVP data structure.
 * 
 * The attributes can be accessed directly.
 * <ul>
 * <li> If you know that one AVP is a grouped AVP then you can parse its content and fill 
 * the childs Vector by calling the avp.ungroup() method. This will also set the is_ungrouped flag.
 * <li> To create a new AVP just call one of the constructors. Don't forget to set the data with 
 * one of the setData functions or add the child avps if grouped.
 * <li> If you have child avps the data that you set with setData will be discarded on encoding,
 * as the grouped avps have priority.
 * </ul>
 */
public class AVP {
	
	/** The AVP code */
	public int code=0;
	
	/** The AVP Vendor Specific flag. If not set, vendor_id will not be used */
	public boolean flag_vendor_specific=false;
	
	/** The AVP Mandatory Flag */
	public boolean flag_mandatory=true;
	
	/** The AVP Protected Flag indicating the need for end-to-end security */
	public boolean flag_protected=false;
	
	/** The Vendor Identifier. Should only be used when the vendor specific flag is set */
	public int vendor_id=0;
		
	/** The length of the encoded data of this AVP  with padded bytes*/
	public int encoded_length=0;
	
	/** The length of the encoded data of this AVP */
	public int length=0;
	
	/** The binary data actually contained inside */
	public byte[] data={};
	
	/** The integer value, precomputed for faster operation if the data is an integer */
	public int int_data;
	public long long_data;
	
	/** Vector of child AVPs if the avps is a grouped one */
	public Vector childs = null;
	
	/** Indication if this AVP actually is a grouped AVP */
	public boolean is_ungrouped=false;

	
	/**
	 * Dumb constructor used on decoding
	 */
	public AVP()
	{
	}
	
	/**
	 * Creates a new AVP.
	 * 
	 * @param Code				AVP code.
	 * @param Vendor_Specific   true, if this AVP is vendor specific.
	 * @param Mandatory			true, if mandatory tag should be set.	
	 * @param Protected			true, if protected tag should be send.
	 * @param Vendor_id			Vendor-Id.
	 */
	public AVP(int Code,boolean Vendor_Specific,boolean Mandatory,boolean Protected,
			int Vendor_id)
	{
		this.code = Code;
		this.flag_vendor_specific = Vendor_Specific;
		this.flag_mandatory = Mandatory;
		this.flag_protected = Protected;
		this.vendor_id = Vendor_id;
		if (this.vendor_id!=0) this.flag_vendor_specific = true;
	}
	
	
	/**
	 * Creates a new AVP.
	 * 
	 * @param Code				AVP code.
	 * @param Mandatory			true, if mandatory tag should be set.	
	 * @param Vendor_id			Vendor-Id
	 */
	public AVP(int Code,boolean Mandatory,int Vendor_id)
	{
		this.code = Code;
		this.flag_mandatory = Mandatory;
		this.vendor_id = Vendor_id;
		if (this.vendor_id!=0) this.flag_vendor_specific = true;
	}

	/**
	 * Sets the data to an array of bytes.
	 * 
	 * @param Data 	Date field of an AVP represented in byte[].
	 */
	public void setData(byte[] Data)
	{
		this.data = Data;
		for(int i=0;i<4&&i<data.length;i++){
			int_data = (int_data<<8)|(0xFF & data[i]);
		    long_data = (long_data<<8)|(0xFF & data[i]);
		}
	}

	/**
	 * Sets the data to an array of bytes starting from start for len bytes.
	 * 
	 * @param Data	Date field of an AVP represented in byte[].
	 * @param start Start position. 
	 * @param len	Length of the array.
	 */
	public void setData(byte[] Data,int start,int len)
	{
		if (len<Data.length - start)
			len = Data.length - start;
		this.data = new byte[len];
		System.arraycopy(Data,start,this.data,0,len);
		for(int i=0;i<4&&i<data.length;i++){
			int_data = (int_data<<8)|(0xFF & data[i]);
		    long_data = (long_data<<8)|(0xFF & data[i]);
		}
	}
	
	/**
	 * Sets the data to an array of char.
	 * 
	 * @param Data	Data field of an AVP represented in char[].
	 */
	public void setData(char[] Data)
	{
		this.data = new byte[Data.length];
		System.arraycopy(Data,0,this.data,0,Data.length);
		for(int i=0;i<4&&i<data.length;i++){
			int_data = (int_data<<8)|(0xFFFF & data[i]);
		    long_data = (long_data<<8)|(0xFF & data[i]);
		}
	}

	/**
	 * Sets the data to the value inside the String.
	 * 
	 * @param Data	Data field of an AVP represented in String.
	 */
	public void setData(String Data)
	{
		this.data = Data.getBytes();
		for(int i=0;i<4&&i<data.length;i++){
			int_data = (int_data<<8)|(0xFF & data[i]);
			long_data = (long_data<<8)|(0xFF & data[i]);
		}
	}

	/**
	 * Sets the data to a 4 byte integer value
	 *
	 * @param Data	Data field of an AVP represented in int.
	 */
	public void setData(int Data)
	{
		data = new byte[4];
		data[0] = (byte)((Data>>24) &0xFF);
		data[1] = (byte)((Data>>16) &0xFF);
		data[2] = (byte)((Data>> 8) &0xFF);
		data[3] = (byte)((Data    ) &0xFF);
		int_data = Data;
		long_data= Data;
	}

	
	/**
	 * Get String value.
	 * 
	 * @return The data field of an AVP converted to string.
	 */
	public String getStringData() {
		StringBuffer x = new StringBuffer();
		
		for(int i=0;i<data.length;i++)
			if (data[i]>=32&&data[i]<=126)
				x.append((char)data[i]);
			else 
				x.append(".");
		
		return x.toString();
	}
	
	/**
	 * Get int value.
	 * 
	 * @return The data field of an AVP converted to int.
	 */
	public int getIntData() {
		return int_data;
	}
	
	/**
	 * Get int value.
	 * 
	 * @return The data field of an AVP converted to int.
	 */
	public long getLongData() {
		return long_data;
	}
	
	/**
	 * Get byte[] value.
	 * 
	 * @return The data field of an AVP converted to byte[]. 
	 */
	public byte[] getData() {
		return data;
	}
	
	/**
	 * Adds one child avp to the avp and converts it to a grouped one.
	 * 
	 * @param child Child AVP added to this AVP.
	 */
	public void addChildAVP(AVP child)
	{
		if (!is_ungrouped) is_ungrouped = true;
		if (childs == null) childs = new Vector();
		childs.add(child);
	}
	
	/**
	 * Returns the count of the child AVPs if the AVP is a grouped one, or 0 if not.
	 * 
	 * @return the count of child avps, 0 if not.
	 */
	public int getChildCount()
	{
		if (!is_ungrouped||childs==null) return 0;
		return childs.size();
	}
	
	/**
	 * Returns the child AVP at index if the AVP is a grouped one.
	 * 
	 * @param index	The position of the child AVP.
	 * @return the found AVP or null if out of bounds.
	 */
	public AVP getChildAVP(int index)
	{
		if (!is_ungrouped||childs==null) return null;
		if (index<childs.size())
			return (AVP)childs.get(index);
		else return null;
	}
	
	/**
	 * Deletes the given AVP from the list of child avps.
	 * 
	 * @param avp The Child AVP which should be deleted. 
	 */
	public void deleteChildAVP(AVP avp)
	{
		if (!is_ungrouped||childs==null) return;
		childs.remove(avp);
	}
	
	/**
	 * Searches for an AVP inside the Vector of child avps 
	 * if the AVP is a grouped one.
	 * 
	 * @param Code		AVP code.
	 * @return the found AVP, null if not found.
	 */
	public AVP findChildAVP(int Code)
	{
		AVP avp;
		if (!is_ungrouped) return null;
		for(int i=0;i<childs.size();i++){
			avp = (AVP) childs.get(i);
			if (avp.code == Code) {
				return avp;
			}
		}
		return null;
	}
	
	/**
	 * Searches for an AVP inside the Vector of child avps if the AVP is a grouped one.
	 * 
	 * @param Code		AVP code.
	 * @param Mandatory	true, if the AVP is set with Mandatory tag.
	 * @param Vendor_id Vendor-Id of the AVP.
	 * @return the found AVP, null if not found.
	 */
	public AVP findChildAVP(int Code,boolean Mandatory,int Vendor_id)
	{
		AVP avp;
		if (!is_ungrouped) return null;
		for(int i=0;i<childs.size();i++){
			avp = (AVP) childs.get(i);
			if (avp.code == Code &&
				avp.flag_mandatory == Mandatory &&
				avp.vendor_id == Vendor_id) 
					return avp;
		}
		return null;
	}
	
	/**
	 * Searches for all AVPs with the same code inside the Vector of child avps 
	 * if the AVP is a grouped one.
	 * 
	 * @param Code		AVP code.
	 * @return the found AVP[], null if not found.
	 */
	public AVP[] findChildAVPs(int Code)
	{
		
		AVP[] avpset;
		int j = 0, count = 0;
		AVP avp;
		
		if (!is_ungrouped) return null;
		
		for(int i=0;i<childs.size();i++){
			avp = (AVP) childs.get(i);
			if (avp.code == Code)
					count++;
		}
		
		if (count == 0) return null;
		avpset = new AVP[count];
		for(int i=0;i<childs.size();i++){
			avp = (AVP) childs.get(i);
			if (avp.code == Code) {
				avpset[j++] = avp;
				if (j == count) break;
			}
		}

		return avpset;
	}

	/**
	 *	Ungroups the AVP data into childs
	 *
	 *	@throws AVPDecodeException If upgroup fails.
	 */
	public void ungroup() throws AVPDecodeException
	{
		int i = 0;
		AVP x;
		if (is_ungrouped) return;
		is_ungrouped = true;
		childs = new Vector();
		while (i<data.length){
			x = Codec.decodeAVP(data,i);
			childs.add(x);
			i+=x.encoded_length;
		}
	}
	
	/**
	 * Groups the child AVPs into the data field.
	 *
	 */
	public void group() 
	{
		Vector temp;
		int i,len=0;
		byte[] t;
		if (!is_ungrouped||childs==null||childs.size()==0) {
			data = new byte[0];
		}
		temp = new Vector();
		for(i=0;i<childs.size();i++){
			t = Codec.encodeAVP((AVP)childs.get(i));
			temp.add(t);
			len += t.length;
		}
		data = new byte[len];
		len = 0;
		for(i=0;i<temp.size();i++){
			t = (byte[]) temp.get(i);
			System.arraycopy(t,0,data,len,t.length);
			len += t.length;
		}
	}
	
	/**
	 * Human readable version of the AVP for logging.
	 */
	public String toString()
	{
		StringBuffer x = new StringBuffer();

		int i;
		x.append("AVP:");
		x.append(" Code=");x.append(code);
		if (flag_vendor_specific) x.append(" V");
		if (flag_mandatory) x.append(" M");
		if (flag_protected) x.append(" P");
		x.append(" Len=");x.append(data.length);
		if (flag_vendor_specific){
			x.append(" V_ID=");x.append(vendor_id);
		}
		x.append(" Data=0x");
		for(i=0;i<data.length;i++){
			x.append(hexa[(data[i]>>4)&0x0F]);
			x.append(hexa[data[i]&0x0F]);
		}
		x.append(" INT_Data=");x.append(int_data);
		x.append(" Char_Data=\"");
		for(i=0;i<data.length;i++)
			if (data[i]>=32&&data[i]<=126)
				x.append((char)data[i]);
			else 
				x.append(".");
		x.append("\"");
		if (is_ungrouped){
			x.append(" {");
			for(i=0;i<childs.size();i++){
				if (i!=0) x.append(",");
				x.append(childs.get(i).toString());
			}
			x.append("}");
		}
		return x.toString();
	}

	
	private static char[] hexa={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
	
	/** Session-Id AVP code. */
	public static final int Session_Id			= 263;
	
	/** Origin-Host AVP code. */
	public static final int Origin_Host			= 264;
	
	/** Origin-Realm AVP code. */
	public static final int Origin_Realm		= 296;

	/** Destination-Host AVP code. */
	public static final int Destination_Host	= 293;
	
	/** Destination-Realm AVP code. */
	public static final int Destination_Realm	= 283;
	
	/** Auth-Application-Id AVP code */
	public static final int Auth_Application_Id	= 258;
	
	/** Acct-Application-Id AVP code */
	public static final int Acct_Application_Id	= 259;
	
	/** Vendor-Specific-Application-Id AVP code */
	public static final int Vendor_Specific_Application_Id	= 260;
	
	/** Vendor-Id AVP code */
	public static final int Vendor_Id			= 266;
	
	/** Result-Code AVP code */
	public static final int Result_Code			= 268;
	
	/** Host-IP-Address AVP code */
	public static final int Host_IP_Address		= 257;
	
	/** Product-Name AVP code */
	public static final int Product_Name		= 269;
	
	/** Disconnect-Cause AVP code */
	public static final int Disconnect_Cause	= 273;
	
}
+45 −0
Original line number Diff line number Diff line
/* ######################################################################### */
/* #                                                                       # */
/* #                                                                       # */
/* #                Copyright (c) 2012 Sintesio Org.                       # */
/* #                                                                       # */
/* #                                                                       # */
/* # File Name    : AVPDecodeException.java                                # */
/* #                                                                       # */
/* # File Code    :                                                        # */
/* #                                                                       # */
/* # Description  : Implementation of DIAMETER parser class.               # */
/* #                                                                       # */
/* # Revision     : 1.0                                                    # */
/* #                                                                       # */
/* # Project Name :                                                        # */
/* #                                                                       # */
/* # Date         : Apr 2012                                               # */
/* #                                                                       # */
/* # Author       : Sintesio                                               # */
/* #                                                                       # */
/* # Translation  : javac                                                  # */
/* #                                                                       # */
/* #                                                                       # */
/* ######################################################################### */

package com.iskratel.diameter.parser;

/**
 * Exception thrown by methods that decode an AVP.
 * 
 */
public class AVPDecodeException extends Exception {

	private static final long serialVersionUID = 5500365800621352144L;

	/**
	 * Constructs a AVPDecodeException with the specified detail message.
	 * 
	 * @param message	The detail message pertaining to this exception.
	 */
	public AVPDecodeException(String message)
	{
		super(message);
	}
}
+312 −0

File added.

Preview size limit exceeded, changes collapsed.

+294 −0
Original line number Diff line number Diff line
/* ######################################################################### */
/* #                                                                       # */
/* #                                                                       # */
/* #                Copyright (c) 2012 Sintesio Org.                       # */
/* #                                                                       # */
/* #                                                                       # */
/* # File Name    : DiameterMessage.java                                   # */
/* #                                                                       # */
/* # File Code    :                                                        # */
/* #                                                                       # */
/* # Description  : Implementation of DIAMETER parser class.               # */
/* #                                                                       # */
/* # Revision     : 1.0                                                    # */
/* #                                                                       # */
/* # Project Name :                                                        # */
/* #                                                                       # */
/* # Date         : Apr 2012                                               # */
/* #                                                                       # */
/* # Author       : Sintesio                                               # */
/* #                                                                       # */
/* # Translation  : javac                                                  # */
/* #                                                                       # */
/* #                                                                       # */
/* ######################################################################### */

package com.iskratel.diameter.parser;

import java.util.Vector;

//import org.apache.log4j.Logger;


/**
 * This class defines the basic Diameter Message structure
 *
 */
public class DiameterMessage {
	
	/** The logger */
	//private static final Logger LOGGER = Logger.getLogger(DiameterMessage.class);

	/** The version of the message */
	int version=1;
	
	/** Command Code */
	public int commandCode;
	
	/** Length */
	public int length=0;
	
	public byte flags=0;
	
	/** If the message is a Request*/
	public boolean flagRequest=true;
	
	/** If the message is proxiable */
	public boolean flagProxiable=true;
	
	/** If the message contains a protocol error */
	public boolean flagError=false;
	
	/** Potentially retransmission */
	public boolean flagRetransmission=false;
	
	/** Application ID */
	public int applicationID=0;
	
	/** Hop-by-Hop identifier */
	public int /*long*/ hopByHopID=0;

	/** End-to-End identifier */
	public int /*long*/ endToEndID=0;
	
	/** Contained AVPs */
	public Vector<AVP> avps;
	public int numberOfAvps=0;
	
	
	/** statistical time - close to media */
	public long networkTime=0;

	
	/**
	 * Dumb constructor.
	 */
	public DiameterMessage()
	{
		avps = new Vector<AVP>();
	}
	
	/**
	 * Constructor that initializes everything.
	 * @param Command_Code
	 * @param Request
	 * @param Proxiable
	 * @param Application_id
	 * @param HopByHop_id
	 * @param EndToEnd_id
	 */
	public DiameterMessage(int Command_Code,boolean Request,boolean Proxiable,
			int Application_id,/*long*/int HopByHop_id, /*long*/int EndToEnd_id)
	{
		this.commandCode = Command_Code;
		this.flagRequest = Request;
		this.flagProxiable = Proxiable;
		this.applicationID = Application_id;
		this.hopByHopID = HopByHop_id;
		this.endToEndID = EndToEnd_id;
		avps = new Vector<AVP>();
	}
	
	/**
	 * Constructor that initializes just the needed attributes.
	 * @param Command_Code
	 * @param Request
	 * @param Application_id
	 */
	public DiameterMessage(int Command_Code,boolean Request,int Application_id)
	{
		this.commandCode = Command_Code;
		this.flagRequest = Request;
		this.flagProxiable = false;
		this.applicationID = Application_id;
		avps = new Vector<AVP>();
	}
	
	/**
	 * Adds one AVP to the message.
	 * @param child
	 */
	public void addAVP(AVP child)
	{
		avps.add(child);
	}
	
	/**
	 * Returns the count of the AVPs.
	 * 
	 * @return The number of all available AVPs.
	 */
	public int getAVPCount()
	{
		return avps.size();
	}
	
	/**
	 * Returns the AVP. 
	 * @param index
	 * @return the found AVP or null if out of bounds
	 */
	public AVP getAVP(int index)
	{
		if (index<avps.size())
			return (AVP)avps.get(index);
		else return null;
	}
	
	/**
	 * Deletes the given AVP from the list of AVPs.
	 * @param avp
	 */
	public void deleteAVP(AVP avp)
	{
		avps.remove(avp);
	}
	
	/**
	 * Searches for an AVP inside the Vector of AVPs.
	 * @param Code
	 * @param Mandatory
	 * @param Vendor_id
	 * @return the found AVP, null if not found
	 */
	public AVP findAVP(int Code,boolean Mandatory,int Vendor_id)
	{
		AVP avp;
		for(int i=0;i<avps.size();i++){
			avp = (AVP) avps.get(i);
			if (avp.code == Code &&
				avp.flag_mandatory == Mandatory &&
				avp.vendor_id == Vendor_id) 
					return avp;
		}
		return null;
	}
	
	/**
	 * Searches for all AVPs with the same code inside the Vector of AVPs.
	 * @param Code
	 * @return the found AVP, null if not found
	 */
	public AVP[] findAVPs(int Code)
	{
		AVP[] avpset;
		int j = 0, count = 0;
		AVP avp;
		
		for(int i=0;i<avps.size();i++){
			avp = (AVP) avps.get(i);
			if (avp.code == Code)
				count++;
		}
		//System.out.print(Code + "avps count:"+count+"\n");
		if (count == 0) return null;
		
		avpset = new AVP[count];
		for(int i=0;i<avps.size();i++){
			avp = (AVP) avps.get(i);
			if (avp.code == Code) {
				avpset[j++] = avp;
				if (j == count) break;
			}
		}
		return avpset;
	}
	
	/**
	 * Searches for an AVP inside the Vector of AVPs.
	 * @param Code
	 * @return the found AVP, null if not found
	 */
	public AVP findAVP(int Code) {
		AVP avp;
		for(int i=0;i<avps.size();i++){
			avp = (AVP) avps.get(i);
			if (avp.code == Code) {
				
				return avp;
			}
		}
		return null;	
		
	}
	
	/**
	 * Searches for the Session-Id AVP inside a message
	 * @return the found Session-Id AVP, null if not found
	 */
	public AVP getSessionId() {
		return findAVP(AVP.Session_Id);
	}
	
	/**
	 * Human readable version of the AVP for logging
	 */
	public String toString()
	{
		StringBuffer x = new StringBuffer();
		x.append("Diameter: Code=");x.append(commandCode);
		if (flagRequest) x.append(" R");
		if (flagProxiable) x.append(" P");
		if (flagError) x.append(" E");
		if (flagRetransmission) x.append(" T");
		
		x.append(" AppID=");x.append(applicationID);
		x.append(" HbHID=");x.append(hopByHopID);
		x.append(" E2EID=");x.append(endToEndID);
		
		x.append("\n");
		for(int i=0;i<avps.size();i++){
			x.append("\t");
			x.append(avps.get(i).toString());
			x.append("\n");
		}		
		return x.toString();
	}
	
	/** Command code of Capabilities-Exchange Request/Answer */
	public static final int Code_CE=257;
	
	/** Command code of Device-Watchdog Request/Answer */
	public static final int Code_DW=280;
	
	/** Command code of Disconnect-Peer-Request/Answer */
	public static final int Code_DP=282;
	
	/** 
	 * ResultCode returned is 2001, when the request was successfully completed.
	 */
	public static final int DIAMETER_SUCCESS = 2001;
	
	/** 
	 * ResultCode returned is 5010, when CER message is received, and there are no common
	 * applications supported between the peers.
	 */
	public static final int DIAMETER_NO_COMMON_APPLICATION = 5010;
	
	/**
	 * ResultCode returned is 5012, when a request was received, whose version
	 * number is unsupported.
	 */
	public static final int DIAMETER_UNABLE_TO_COMPLY = 5012;
	
}
+47 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading