• Main Page
  • Related Pages
  • Packages
  • Classes
  • Files
  • File List

protocol/ProtocolDataUnit.java

Go to the documentation of this file.
00001 
00002 package protocol;
00003 
00004 import utils.Log;
00005 import utils.OctetBuffer;
00006 
00007 /**
00008  *  Represents a Protocol Data Unit (PDU).
00009  *
00010  *  <pre>
00011  *                       1                   2                   3
00012  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1        Octets:
00013  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  +---------------+
00014  *  |1|     Source Call Number      |0|   Destination Call Number   |    0   1   2   3
00015  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  +---------------+
00016  *  |                           Time-Stamp                          |    4   5   6   7
00017  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  +---------------+
00018  *  |  Out Seq No   |   In Seq No   |0|  PDU Type   |   Sub Class   |    8   9  10  11
00019  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  +---------------+
00020  *  |                                                               |   12  ...
00021  *  :                            Payload                            :
00022  *  |                                                               |
00023  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
00024  *  </pre>
00025  *
00026  */
00027 public abstract class ProtocolDataUnit 
00028 {
00029     /** PDU Type: Data Audio Compression Format Raw Voice Data */
00030     protected final static int VOICE = 0x02;
00031 
00032     /** The call object */
00033     protected CallContext call;
00034 
00035     /** The payload data */
00036     protected OctetBuffer payload;
00037     
00038     /** The time-stamp */
00039     protected Long timeStamp;
00040 
00041     /** The source call number */
00042     protected int sourceCallNumber;
00043 
00044     /** The destination call number */
00045     protected int destinationCallNumber;
00046 
00047     /** The outbound stream sequence number */
00048     protected int outSeqNo;
00049 
00050     /** The inbound stream sequence number */
00051     protected int inSeqNo;
00052 
00053     /** The frame type */
00054     protected int pduType;
00055     
00056     /** The subclass */
00057     protected int pduSubclass;
00058 
00059     /**
00060      * The constructor for outbound PDUs.
00061      *
00062      * @param call  The Call object
00063      */
00064     public ProtocolDataUnit( CallContext call ) 
00065     {
00066         this.call = call;
00067         
00068         this.destinationCallNumber = call.getDestinationCallNumber ();
00069         this.sourceCallNumber      = call.getSourceCallNumber  ();
00070         
00071         this.setTimestamp( call.getTimestamp () );
00072     }
00073 
00074     /**
00075      * The constructor for inbound PDUs.
00076      *
00077      * @param call      The Call object
00078      * @param pduOctets The incoming message bytes
00079      */
00080     public ProtocolDataUnit( CallContext call, byte[] pduOctets ) 
00081     {
00082         this.call = call;
00083 
00084         OctetBuffer buf = OctetBuffer.wrap( pduOctets );
00085         
00086         this.sourceCallNumber = buf.getShort ();
00087         this.sourceCallNumber &= 0x7FFF; // strip F bit
00088         
00089         this.destinationCallNumber = buf.getShort();
00090         this.destinationCallNumber &= 0x7FFF; // strip R bit
00091         
00092         this.setTimestamp( ( buf.getInt () + 0x100000000L ) & 0xFFFFFFFFL );
00093         
00094         this.outSeqNo = OctetBuffer.toInt( buf.get() );
00095         this.inSeqNo = OctetBuffer.toInt( buf.get() );
00096         
00097         this.pduType = OctetBuffer.toInt( buf.get() );
00098         this.pduSubclass = OctetBuffer.toInt( buf.get() );
00099         
00100         this.payload = buf.slice ();
00101     }
00102 
00103     /**
00104      * Sets the time stamp as long.
00105      */
00106     void setTimestamp( long v )
00107     {
00108         this.timeStamp = new Long( v );
00109     }
00110 
00111     /**
00112      * Returns the timestamp as long.
00113      */
00114     long getTimestamp ()
00115     {
00116         return this.timeStamp != null ? this.timeStamp.longValue () : 0;
00117     }
00118     
00119     /**
00120      * Creates a new PDU of the correct type.
00121      *
00122      * @param call Call
00123      * @param pduOctets byte[]
00124      * @return a PDU
00125      */
00126     public static ProtocolDataUnit create( CallContext call, byte[] pduOctets ) 
00127     {
00128         if ( pduOctets == null || pduOctets.length < 12 ) {
00129             return null;
00130         }
00131 
00132         ProtocolDataUnit pdu = null;
00133 
00134         int pduType = OctetBuffer.toInt( pduOctets[10] ); 
00135 
00136         switch ( pduType ) 
00137         {
00138             case VOICE:
00139                 pdu = new VoicePDU( call, pduOctets );
00140                 break;
00141             default:
00142                 Log.warn( "Unknown PDU type " + pduType );
00143                 pdu = new ProtocolDataUnit( call, pduOctets ) {};
00144                 break;
00145         }
00146 
00147         return pdu;
00148     }
00149 
00150     /**
00151      *  Sends a specified payload. Payload represents the data field in
00152      *  the frame.
00153      *
00154      * @param payload  The payload data
00155      */
00156     public void sendPayload( byte[] payload )
00157     {
00158         this.outSeqNo = this.call.getOutSeqNoInc();
00159         this.inSeqNo = this.call.getInSeqNo();
00160 
00161         OctetBuffer pdu = OctetBuffer.allocate( payload.length + 12 );
00162         
00163         pdu.putChar( (char) ( this.sourceCallNumber | 0x8000 ) );
00164         pdu.putChar( (char) this.destinationCallNumber );
00165         
00166         long ts = this.getTimestamp ();
00167         ts =  ( (0x100000000L & ts) > 0 ) ? ts - 0x100000000L : ts;
00168         pdu.putInt( (int) ts );
00169 
00170         pdu.put( (byte) outSeqNo );
00171         pdu.put( (byte) inSeqNo );
00172         pdu.put( (byte) pduType );
00173         pdu.put( (byte) pduSubclass );
00174         
00175         pdu.put( payload );
00176         
00177         log( "Sent" );
00178         
00179         this.call.send( pdu );
00180     }
00181 
00182     /**
00183      *  Arrived is called when a packet arrives. This method doesn't do anything 
00184      *  more than dumping the frame. It should be overridden in derived class.
00185      */
00186     void onArrivedPDU ()
00187     {
00188         dump( "Inbound" );
00189     }
00190 
00191     /**
00192      * Logs the time-stamp and the inbound/outbound stream sequence number.
00193      *
00194      * @param prefix Text to include
00195      */
00196     protected void log( String prefix )
00197     {
00198         StringBuffer sb = new StringBuffer( "Time: " );
00199         
00200         sb.append( this.call.getTimestamp () ).append( ", " );
00201         sb.append( prefix );
00202         sb.append( ", Timestamp: " ).append( this.getTimestamp () );
00203         sb.append( ", iseq: "      ).append( inSeqNo              );
00204         sb.append( ", oseq: "      ).append( outSeqNo             );
00205         
00206         Log.debug( sb.toString () );
00207     }
00208 
00209     /**
00210      * Logs this frame.
00211      */
00212     void dump( String prefix )
00213     {
00214         if ( ! Log.isEnabled( Log.VERB ) ) {
00215             return;
00216         }
00217 
00218         StringBuffer sb = new StringBuffer ();
00219         
00220         if ( prefix != null ) {
00221             sb.append( prefix ).append( " " );
00222         }
00223         
00224         sb.append( "PDU:" );
00225         sb.append( "\n    Source Call = " ).append( sourceCallNumber      );
00226         sb.append( "\n    Dest Call   = " ).append( destinationCallNumber );
00227         sb.append( "\n    Timestamp   = " ).append( timeStamp             );
00228         sb.append( "\n    Out Seq No  = " ).append( outSeqNo              );
00229         sb.append( "\n    In Seq No   = " ).append( inSeqNo               );
00230         sb.append( "\n    PDU Type    = " ).append( pduType               );
00231         sb.append( "\n    Subclass    = " ).append( pduSubclass           );
00232         
00233         Log.verb( sb.toString () );
00234     }
00235 }
00236 

Generated on Thu Dec 16 2010 14:44:42 for VoIP Kryptofon by  doxygen 1.7.2