src/org/sipdroid/net/RtpPacket.java
changeset 834 e8d6255306f8
child 835 4e40f3481f23
equal deleted inserted replaced
833:f5a5d9237d69 834:e8d6255306f8
       
     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 src.org.sipdroid.net;
       
    23 
       
    24 import org.zoolu.tools.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 }