|
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 } |