src/org/sipdroid/net/RtpPacket.java
changeset 839 0e5b95573614
parent 835 4e40f3481f23
equal deleted inserted replaced
822:696b2880c994 839:0e5b95573614
       
     1 /*
       
     2  * Copyright (C) 2009 The Sipdroid Open Source Project
       
     3  * Copyright (C) 2005 Luca Veltri - University of Parma - Italy
       
     4  * 
       
     5  * This file is part of Sipdroid (http://www.sipdroid.org)
       
     6  * 
       
     7  * Sipdroid is free software; you can redistribute it and/or modify
       
     8  * it under the terms of the GNU General Public License as published by
       
     9  * the Free Software Foundation; either version 3 of the License, or
       
    10  * (at your option) any later version.
       
    11  * 
       
    12  * This source code is distributed in the hope that it will be useful,
       
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    15  * GNU General Public License for more details.
       
    16  * 
       
    17  * You should have received a copy of the GNU General Public License
       
    18  * along with this source code; if not, write to the Free Software
       
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    20  */
       
    21 
       
    22 package org.sipdroid.net;
       
    23 
       
    24 import com.beem.project.beem.utils.Random;
       
    25 
       
    26 /**
       
    27  * RtpPacket implements a RTP packet.
       
    28  */
       
    29 public class RtpPacket {
       
    30     /* RTP packet buffer containing both the RTP header and payload */
       
    31     byte[] packet;
       
    32 
       
    33     /* RTP packet length */
       
    34     int packet_len;
       
    35 
       
    36     /* RTP header length */
       
    37     // int header_len;
       
    38     /** Gets the RTP packet */
       
    39     public byte[] getPacket() {
       
    40 	return packet;
       
    41     }
       
    42 
       
    43     /** Gets the RTP packet length */
       
    44     public int getLength() {
       
    45 	return packet_len;
       
    46     }
       
    47 
       
    48     /** Gets the RTP header length */
       
    49     public int getHeaderLength() {
       
    50 	if (packet_len >= 12)
       
    51 	    return 12 + 4 * getCscrCount();
       
    52 	else
       
    53 	    return packet_len; // broken packet
       
    54     }
       
    55 
       
    56     /** Gets the RTP header length */
       
    57     public int getPayloadLength() {
       
    58 	if (packet_len >= 12)
       
    59 	    return packet_len - getHeaderLength();
       
    60 	else
       
    61 	    return 0; // broken packet
       
    62     }
       
    63 
       
    64     /** Sets the RTP payload length */
       
    65     public void setPayloadLength(int len) {
       
    66 	packet_len = getHeaderLength() + len;
       
    67     }
       
    68 
       
    69     // version (V): 2 bits
       
    70     // padding (P): 1 bit
       
    71     // extension (X): 1 bit
       
    72     // CSRC count (CC): 4 bits
       
    73     // marker (M): 1 bit
       
    74     // payload type (PT): 7 bits
       
    75     // sequence number: 16 bits
       
    76     // timestamp: 32 bits
       
    77     // SSRC: 32 bits
       
    78     // CSRC list: 0 to 15 items, 32 bits each
       
    79 
       
    80     /** Gets the version (V) */
       
    81     public int getVersion() {
       
    82 	if (packet_len >= 12)
       
    83 	    return (packet[0] >> 6 & 0x03);
       
    84 	else
       
    85 	    return 0; // broken packet
       
    86     }
       
    87 
       
    88     /** Sets the version (V) */
       
    89     public void setVersion(int v) {
       
    90 	if (packet_len >= 12)
       
    91 	    packet[0] = (byte) ((packet[0] & 0x3F) | ((v & 0x03) << 6));
       
    92     }
       
    93 
       
    94     /** Whether has padding (P) */
       
    95     public boolean hasPadding() {
       
    96 	if (packet_len >= 12)
       
    97 	    return getBit(packet[0], 5);
       
    98 	else
       
    99 	    return false; // broken packet
       
   100     }
       
   101 
       
   102     /** Set padding (P) */
       
   103     public void setPadding(boolean p) {
       
   104 	if (packet_len >= 12)
       
   105 	    packet[0] = setBit(p, packet[0], 5);
       
   106     }
       
   107 
       
   108     /** Whether has extension (X) */
       
   109     public boolean hasExtension() {
       
   110 	if (packet_len >= 12)
       
   111 	    return getBit(packet[0], 4);
       
   112 	else
       
   113 	    return false; // broken packet
       
   114     }
       
   115 
       
   116     /** Set extension (X) */
       
   117     public void setExtension(boolean x) {
       
   118 	if (packet_len >= 12)
       
   119 	    packet[0] = setBit(x, packet[0], 4);
       
   120     }
       
   121 
       
   122     /** Gets the CSCR count (CC) */
       
   123     public int getCscrCount() {
       
   124 	if (packet_len >= 12)
       
   125 	    return (packet[0] & 0x0F);
       
   126 	else
       
   127 	    return 0; // broken packet
       
   128     }
       
   129 
       
   130     /** Whether has marker (M) */
       
   131     public boolean hasMarker() {
       
   132 	if (packet_len >= 12)
       
   133 	    return getBit(packet[1], 7);
       
   134 	else
       
   135 	    return false; // broken packet
       
   136     }
       
   137 
       
   138     /** Set marker (M) */
       
   139     public void setMarker(boolean m) {
       
   140 	if (packet_len >= 12)
       
   141 	    packet[1] = setBit(m, packet[1], 7);
       
   142     }
       
   143 
       
   144     /** Gets the payload type (PT) */
       
   145     public int getPayloadType() {
       
   146 	if (packet_len >= 12)
       
   147 	    return (packet[1] & 0x7F);
       
   148 	else
       
   149 	    return -1; // broken packet
       
   150     }
       
   151 
       
   152     /** Sets the payload type (PT) */
       
   153     public void setPayloadType(int pt) {
       
   154 	if (packet_len >= 12)
       
   155 	    packet[1] = (byte) ((packet[1] & 0x80) | (pt & 0x7F));
       
   156     }
       
   157 
       
   158     /** Gets the sequence number */
       
   159     public int getSequenceNumber() {
       
   160 	if (packet_len >= 12)
       
   161 	    return getInt(packet, 2, 4);
       
   162 	else
       
   163 	    return 0; // broken packet
       
   164     }
       
   165 
       
   166     /** Sets the sequence number */
       
   167     public void setSequenceNumber(int sn) {
       
   168 	if (packet_len >= 12)
       
   169 	    setInt(sn, packet, 2, 4);
       
   170     }
       
   171 
       
   172     /** Gets the timestamp */
       
   173     public long getTimestamp() {
       
   174 	if (packet_len >= 12)
       
   175 	    return getLong(packet, 4, 8);
       
   176 	else
       
   177 	    return 0; // broken packet
       
   178     }
       
   179 
       
   180     /** Sets the timestamp */
       
   181     public void setTimestamp(long timestamp) {
       
   182 	if (packet_len >= 12)
       
   183 	    setLong(timestamp, packet, 4, 8);
       
   184     }
       
   185 
       
   186     /** Gets the SSCR */
       
   187     public long getSscr() {
       
   188 	if (packet_len >= 12)
       
   189 	    return getLong(packet, 8, 12);
       
   190 	else
       
   191 	    return 0; // broken packet
       
   192     }
       
   193 
       
   194     /** Sets the SSCR */
       
   195     public void setSscr(long ssrc) {
       
   196 	if (packet_len >= 12)
       
   197 	    setLong(ssrc, packet, 8, 12);
       
   198     }
       
   199 
       
   200     /** Gets the CSCR list */
       
   201     public long[] getCscrList() {
       
   202 	int cc = getCscrCount();
       
   203 	long[] cscr = new long[cc];
       
   204 	for (int i = 0; i < cc; i++)
       
   205 	    cscr[i] = getLong(packet, 12 + 4 * i, 16 + 4 * i);
       
   206 	return cscr;
       
   207     }
       
   208 
       
   209     /** Sets the CSCR list */
       
   210     public void setCscrList(long[] cscr) {
       
   211 	if (packet_len >= 12) {
       
   212 	    int cc = cscr.length;
       
   213 	    if (cc > 15)
       
   214 		cc = 15;
       
   215 	    packet[0] = (byte) (((packet[0] >> 4) << 4) + cc);
       
   216 	    cscr = new long[cc];
       
   217 	    for (int i = 0; i < cc; i++)
       
   218 		setLong(cscr[i], packet, 12 + 4 * i, 16 + 4 * i);
       
   219 	    // header_len=12+4*cc;
       
   220 	}
       
   221     }
       
   222 
       
   223     /** Sets the payload */
       
   224     public void setPayload(byte[] payload, int len) {
       
   225 	if (packet_len >= 12) {
       
   226 	    int header_len = getHeaderLength();
       
   227 	    for (int i = 0; i < len; i++)
       
   228 		packet[header_len + i] = payload[i];
       
   229 	    packet_len = header_len + len;
       
   230 	}
       
   231     }
       
   232 
       
   233     /** Gets the payload */
       
   234     public byte[] getPayload() {
       
   235 	int header_len = getHeaderLength();
       
   236 	int len = packet_len - header_len;
       
   237 	byte[] payload = new byte[len];
       
   238 	for (int i = 0; i < len; i++)
       
   239 	    payload[i] = packet[header_len + i];
       
   240 	return payload;
       
   241     }
       
   242 
       
   243     /** Creates a new RTP packet */
       
   244     public RtpPacket(byte[] buffer, int packet_length) {
       
   245 	packet = buffer;
       
   246 	packet_len = packet_length;
       
   247 	if (packet_len < 12)
       
   248 	    packet_len = 12;
       
   249 	init(0x0F);
       
   250     }
       
   251 
       
   252     /** init the RTP packet header (only PT) */
       
   253     public void init(int ptype) {
       
   254 	init(ptype, Random.nextLong());
       
   255     }
       
   256 
       
   257     /** init the RTP packet header (PT and SSCR) */
       
   258     public void init(int ptype, long sscr) {
       
   259 	init(ptype, Random.nextInt(), Random.nextLong(), sscr);
       
   260     }
       
   261 
       
   262     /** init the RTP packet header (PT, SQN, TimeStamp, SSCR) */
       
   263     public void init(int ptype, int seqn, long timestamp, long sscr) {
       
   264 	setVersion(2);
       
   265 	setPayloadType(ptype);
       
   266 	setSequenceNumber(seqn);
       
   267 	setTimestamp(timestamp);
       
   268 	setSscr(sscr);
       
   269     }
       
   270 
       
   271     // *********************** Private and Static ***********************
       
   272 
       
   273     /** Gets int value */
       
   274     private static int getInt(byte b) {
       
   275 	return ((int) b + 256) % 256;
       
   276     }
       
   277 
       
   278     /** Gets long value */
       
   279     private static long getLong(byte[] data, int begin, int end) {
       
   280 	long n = 0;
       
   281 	for (; begin < end; begin++) {
       
   282 	    n <<= 8;
       
   283 	    n += data[begin];
       
   284 	}
       
   285 	return n;
       
   286     }
       
   287 
       
   288     /** Sets long value */
       
   289     private static void setLong(long n, byte[] data, int begin, int end) {
       
   290 	for (end--; end >= begin; end--) {
       
   291 	    data[end] = (byte) (n % 256);
       
   292 	    n >>= 8;
       
   293 	}
       
   294     }
       
   295 
       
   296     /** Gets Int value */
       
   297     private static int getInt(byte[] data, int begin, int end) {
       
   298 	return (int) getLong(data, begin, end);
       
   299     }
       
   300 
       
   301     /** Sets Int value */
       
   302     private static void setInt(int n, byte[] data, int begin, int end) {
       
   303 	setLong(n, data, begin, end);
       
   304     }
       
   305 
       
   306     /** Gets bit value */
       
   307     private static boolean getBit(byte b, int bit) {
       
   308 	return (b >> bit) == 1;
       
   309     }
       
   310 
       
   311     /** Sets bit value */
       
   312     private static byte setBit(boolean value, byte b, int bit) {
       
   313 	if (value)
       
   314 	    return (byte) (b | (1 << bit));
       
   315 	else
       
   316 	    return (byte) ((b | (1 << bit)) ^ (1 << bit));
       
   317     }
       
   318 }