Codec.java

Go to the documentation of this file.
00001 /*
00002  * $Id: Codec.java 2 2006-11-14 22:37:20Z vingarzan $
00003  *
00004  * Copyright (C) 2004-2006 FhG Fokus
00005  *
00006  * This file is part of Open IMS Core - an open source IMS CSCFs & HSS
00007  * implementation
00008  *
00009  * Open IMS Core is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * For a license to use the Open IMS Core software under conditions
00015  * other than those described here, or to purchase support for this
00016  * software, please contact Fraunhofer FOKUS by e-mail at the following
00017  * addresses:
00018  *     info@open-ims.org
00019  *
00020  * Open IMS Core is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU General Public License
00026  * along with this program; if not, write to the Free Software
00027  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  *
00029  */
00030 
00031 package de.fhg.fokus.diameter.DiameterPeer.data;
00032 
00033 import java.util.Arrays;
00034 import java.util.Vector;
00035 
00036 
00037 
00059 public class Codec {
00060 
00069     public static AVP decodeAVP(byte[] from,int start) throws AVPDecodeException
00070     {
00071         AVP to = new AVP();
00072         int i,j,len;
00073         
00074         if (from.length-start<8) throw new AVPDecodeException("Data is shorter than AVP Header");
00075         
00076         to.code =   ((int)from[start+0]&0xFF)<<24 |
00077                     ((int)from[start+1]&0xFF)<<16 |
00078                     ((int)from[start+2]&0xFF)<< 8 |
00079                     ((int)from[start+3]&0xFF);
00080         
00081         to.flag_vendor_specific =   (from[start+4] & 0x80)!=0;
00082         to.flag_mandatory =         (from[start+4] & 0x40)!=0;
00083         to.flag_protected =         (from[start+4] & 0x20)!=0;
00084         len =   ((int)from[start+5]&0xFF)<<16 |
00085                 ((int)from[start+6]&0xFF)<< 8 |
00086                 ((int)from[start+7]&0xFF);
00087 
00088         if (to.flag_vendor_specific){
00089             to.vendor_id =  ((int)from[start+ 8]&0xFF)<<24 |
00090                             ((int)from[start+ 9]&0xFF)<<16 |
00091                             ((int)from[start+10]&0xFF)<< 8 |
00092                             ((int)from[start+11]&0xFF);
00093             j = 12;
00094         } else {
00095             to.vendor_id = 0;
00096             j = 8;
00097         }
00098 
00099         if (len>from.length-start) len = from.length-start;
00100         to.data = new byte[len-j];
00101         System.arraycopy(from,start+j,to.data,0,len-j);
00102         
00103         if (len!=0)
00104         for(i=0;i<4&&i<len-j;i++)
00105             to.int_data = (to.int_data<<8)| ((byte) to.data[i]&0xFF);
00106         
00107         to.encoded_length = len;
00108         if (to.encoded_length%4!=0) 
00109             to.encoded_length = (to.encoded_length/4+1)*4; 
00110         
00111         return to;
00112     }
00113 
00119     public static byte[] encodeAVP(AVP from)
00120     {
00121         byte[] to = null;
00122         int total_len,send_len;
00123         int j;
00124 
00125         /* if it is ungrouped, we group it first */
00126         if (from.is_ungrouped)
00127             from.group();
00128         
00129         total_len=4+4+from.data.length;
00130         
00131         if (from.flag_vendor_specific) total_len+=4;
00132         send_len = total_len;
00133         if (total_len%4!=0) 
00134             total_len = (total_len/4+1)*4; 
00135         to = new byte[total_len];
00136         Arrays.fill(to,(byte)0);
00137         
00138         to[0] = (byte) ((from.code >> 24) & 0xFF);
00139         to[1] = (byte) ((from.code >> 16) & 0xFF);
00140         to[2] = (byte) ((from.code >>  8) & 0xFF);
00141         to[3] = (byte) ( from.code        & 0xFF);
00142         
00143         if (from.flag_vendor_specific) to[4] |= 0x80;
00144         if (from.flag_mandatory) to[4] |= 0x40;
00145         if (from.flag_protected) to[4] |= 0x20;
00146         to[5] = (byte) ((send_len >> 16) & 0xFF);
00147         to[6] = (byte) ((send_len >>  8) & 0xFF);
00148         to[7] = (byte) ( send_len        & 0xFF);
00149         
00150         if (from.flag_vendor_specific){
00151             to[ 8] = (byte) ((from.vendor_id >> 24) & 0xFF);
00152             to[ 9] = (byte) ((from.vendor_id >> 16) & 0xFF);
00153             to[10] = (byte) ((from.vendor_id >>  8) & 0xFF);
00154             to[11] = (byte) ( from.vendor_id        & 0xFF);
00155             j = 12;
00156         }
00157         else j = 8;
00158         
00159         if (from.data.length!=0)
00160             System.arraycopy(from.data,0,to,j,from.data.length);
00161     
00162         return to;
00163     }
00164     
00171     public static int getEncodedAVPSize(AVP avp)
00172     {
00173         AVP avp2;
00174         int datalen=0;
00175         int i;
00176         if (avp.is_ungrouped&&avp.childs!=null){
00177             for(i=0;i<avp.childs.size();i++){
00178                 avp2 = (AVP) avp.childs.get(i);
00179                 datalen += getEncodedAVPSize(avp2);
00180             }   
00181         }else{
00182             datalen += avp.data.length;
00183             if (datalen%4!=0) datalen = (datalen/4+1)*4;
00184         }
00185         if (avp.flag_vendor_specific) return 12+datalen;
00186         else return 8+datalen;
00187     }
00188     
00197     public static DiameterMessage decodeDiameterMessage(byte[] from,int start) throws DiameterMessageDecodeException
00198     {
00199         DiameterMessage to = new DiameterMessage();
00200         int i,len;
00201         AVP avp;
00202         
00203         if (from.length-start<20) throw new DiameterMessageDecodeException("Data is shorter than Diameter Message Header");
00204         
00205         to.version = ((int)from[start+0]&0xFF);
00206         if (to.version!=1) throw new DiameterMessageDecodeException("Unknown Diameter Message Version "+to.version);
00207         
00208         len =   ((int)from[start+ 1]&0xFF)<<16 |
00209                 ((int)from[start+ 2]&0xFF)<< 8 |
00210                 ((int)from[start+ 3]&0xFF);
00211         
00212         if (len>from.length-start) len=from.length-start;
00213         
00214         to.flagRequest =            (from[start+4] & 0x80)!=0;
00215         to.flagProxiable =      (from[start+4] & 0x40)!=0;
00216         to.flagError =          (from[start+4] & 0x20)!=0;
00217         to.flagRetransmission =     (from[start+4] & 0x10)!=0;
00218 
00219         to.commandCode =    ((int)from[start+ 5]&0xFF)<<16 |
00220                             ((int)from[start+ 6]&0xFF)<< 8 |
00221                             ((int)from[start+ 7]&0xFF);
00222         
00223         to.applicationID =  ((int)from[start+ 8]&0xFF)<<24 |
00224                             ((int)from[start+ 9]&0xFF)<<16 |
00225                             ((int)from[start+10]&0xFF)<< 8 |
00226                             ((int)from[start+11]&0xFF);
00227 
00228         to.hopByHopID = ((int)from[start+12]&0xFF)<<24 |
00229                             ((int)from[start+13]&0xFF)<<16 |
00230                             ((int)from[start+14]&0xFF)<< 8 |
00231                             ((int)from[start+15]&0xFF);
00232 
00233         to.endToEndID = ((int)from[start+16]&0xFF)<<24 |
00234                             ((int)from[start+17]&0xFF)<<16 |
00235                             ((int)from[start+18]&0xFF)<< 8 |
00236                             ((int)from[start+19]&0xFF);
00237 
00238         i = start+20;
00239         while (i<start+len){
00240             try {
00241                 avp = Codec.decodeAVP(from,i);
00242             } catch (AVPDecodeException e) {
00243                 e.printStackTrace();
00244                 throw new DiameterMessageDecodeException(e.getMessage());
00245             }
00246             to.avps.add(avp);
00247             i+=avp.encoded_length;
00248         }       
00249         return to;
00250     }
00251     
00257     public static byte[] encodeDiameterMessage(DiameterMessage from)
00258     {
00259         byte[] to = null;
00260         int total_len;
00261         int i,len=0;
00262         Vector<byte[]> temp;
00263         byte[] t;
00264         
00265         temp = new Vector<byte[]>();
00266         for(i=0;i<from.avps.size();i++){
00267             t = Codec.encodeAVP((AVP)from.avps.get(i));
00268             temp.add(t);
00269             len += t.length;
00270         }
00271         total_len=20+len;
00272         
00273         to = new byte[total_len];
00274         Arrays.fill(to,(byte)0);
00275 
00276         to[0] = (byte) ( from.version     & 0xFF);
00277         to[1] = (byte) ((total_len >> 16) & 0xFF);
00278         to[2] = (byte) ((total_len >>  8) & 0xFF);
00279         to[3] = (byte) ( total_len        & 0xFF);
00280         
00281         if (from.flagRequest)           to[4] |= 0x80;
00282         if (from.flagProxiable)         to[4] |= 0x40;
00283         if (from.flagError)             to[4] |= 0x20;
00284         if (from.flagRetransmission)    to[4] |= 0x10;
00285         to[5] = (byte) ((from.commandCode >> 16) & 0xFF);
00286         to[6] = (byte) ((from.commandCode >>  8) & 0xFF);
00287         to[7] = (byte) ( from.commandCode        & 0xFF);
00288         
00289         to[ 8] = (byte) ((from.applicationID >> 24) & 0xFF);
00290         to[ 9] = (byte) ((from.applicationID >> 16) & 0xFF);
00291         to[10] = (byte) ((from.applicationID >>  8) & 0xFF);
00292         to[11] = (byte) ( from.applicationID        & 0xFF);        
00293 
00294         to[12] = (byte) ((from.hopByHopID >> 24) & 0xFF);
00295         to[13] = (byte) ((from.hopByHopID >> 16) & 0xFF);
00296         to[14] = (byte) ((from.hopByHopID >>  8) & 0xFF);
00297         to[15] = (byte) ( from.hopByHopID        & 0xFF);       
00298 
00299         to[16] = (byte) ((from.endToEndID >> 24) & 0xFF);
00300         to[17] = (byte) ((from.endToEndID >> 16) & 0xFF);
00301         to[18] = (byte) ((from.endToEndID >>  8) & 0xFF);
00302         to[19] = (byte) ( from.endToEndID        & 0xFF);       
00303 
00304         len = 20;
00305         for(i=0;i<temp.size();i++){
00306             t = temp.get(i);
00307             System.arraycopy(t,0,to,len,t.length);
00308             len += t.length;
00309         }       
00310     
00311         return to;
00312     }
00313 
00314 }

Generated on Thu Oct 23 04:07:36 2008 for Open IMS Core JavaDiameterPeer by  doxygen 1.5.2