blob: 7213ab68fd58bc352506419bc85520e47824b8ac [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001,2002,2004,2007 Federico Montesino Pouzols <fedemp@altern.org>.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16//
17// As a special exception, you may use this file as part of a free software
18// library without restriction. Specifically, if other files instantiate
19// templates or use macros or inline functions from this file, or you compile
20// this file and link it with other files to produce an executable, this
21// file does not by itself cause the resulting executable to be covered by
22// the GNU General Public License. This exception does not however
23// invalidate any other reasons why the executable file might be covered by
24// the GNU General Public License.
25//
26// This exception applies only to the code released under the name GNU
27// ccRTP. If you copy code from other releases into a copy of GNU
28// ccRTP, as the General Public License permits, the exception does
29// not apply to the code that you add in this way. To avoid misleading
30// anyone as to the status of such modified files, you must delete
31// this exception notice from them.
32//
33// If you write modifications of your own for GNU ccRTP, it is your choice
34// whether to permit this exception to apply to your modifications.
35// If you do not wish that, delete this exception notice.
36//
37
38#ifndef CCXX_RTP_RTCPPKT_H_
39#define CCXX_RTP_RTCPPKT_H_
40
41#include <ccrtp/base.h>
42
43#ifdef CCXX_NAMESPACES
44namespace ost {
45#endif
46
47/**
48 * @file rtcppkt.h
49 *
50 * @short RTCP packets handling.
51 **/
52
53/**
54 * @defgroup rtcppacket RTCP compound packets manipulation.
55 * @{
56 **/
57
58/**
59 * @enum SDESItemType
60 * @short SDES items that may be carried in a Source DEScription RTCP packet.
61 *
62 * CNAME is mandatory in each RTCP compound packet (except when
63 * splitted for partial encryption), the others are optional and have
64 * different sending frequencies, though with recommended default
65 * values.
66 **/
67typedef enum
68{
69 SDESItemTypeEND = 0, ///< END of SDES item list.
70 SDESItemTypeCNAME, ///< Canonical end-point identifier.
71 SDESItemTypeNAME, ///< Personal NAME of the user.
72 SDESItemTypeEMAIL, ///< EMAIL address of the user.
73 SDESItemTypePHONE, ///< Phone number of the user.
74 SDESItemTypeLOC, ///< Location where the user is.
75 SDESItemTypeTOOL, ///< Application or tool.
76 SDESItemTypeNOTE, ///< Comment usually reporting state.
77 SDESItemTypePRIV, ///< Private extension.
78 SDESItemTypeH323CADDR, ///< H323 callable address.
79 SDESItemTypeLast = SDESItemTypeH323CADDR ///< Last defined code.
80} SDESItemType;
81
82/**
83 * @class RTCPCompoundHandler
84 * @short low level structs and RTCP packet parsing and building
85 * methods.
86 *
87 * Intended to be used, through inheritance, in RTCP management
88 * classes, such as QueueRTCPManager.
89 *
90 * @author Federico Montesino Pouzols <fedemp@altern.org>
91 **/
92class __EXPORT RTCPCompoundHandler
93{
94public:
95 inline void setPathMTU(uint16 mtu)
96 { pathMTU = mtu; }
97
98 inline uint16 getPathMTU()
99 { return pathMTU; }
100
101#ifdef CCXX_PACKED
102#pragma pack(1)
103#endif
104 /**
105 * @struct ReceiverInfo
106 *
107 * Struct for the data contained in a receiver info
108 * block. Receiver info blocks can be found in SR (sender
109 * report) or RR (receiver report) RTCP packets.
110 **/
111 struct ReceiverInfo
112 {
113 uint8 fractionLost; ///< packet fraction lost.
114 uint8 lostMSB; ///< cumulative lost MSB of 3 octets.
115 uint16 lostLSW; ///< cumulative lost two LSB.
116 uint32 highestSeqNum; ///< highest sequence number.
117 uint32 jitter; ///< arrival jitter.
118 uint32 lsr; ///< last sender report timestamp.
119 uint32 dlsr; ///< delay since last sender report.
120 };
121
122 /**
123 * @struct RRBlock
124 *
125 * Struct for a receiver info block in a SR (sender report) or an RR
126 * (receiver report) RTCP packet.
127 **/
128 struct RRBlock
129 {
130 uint32 ssrc; ///< source identifier.
131 ReceiverInfo rinfo; ///< info about the source.
132 };
133
134 /**
135 * @struct RecvReport
136 *
137 * @short raw structure of the source and every receiver report in an
138 * SR or RR RTCP packet.
139 **/
140 struct RecvReport
141 {
142 uint32 ssrc; ///< source identifier.
143 RRBlock blocks[1]; ///< receiver report blocks.
144 };
145
146 /**
147 * @struct SenderInfo
148 *
149 * Struct for the sender info block in a SR (sender report)
150 * RTCP packet.
151 **/
152 struct SenderInfo
153 {
154 uint32 NTPMSW; ///< NTP timestamp higher octets.
155 uint32 NTPLSW; ///< NTP timestamp lower octets.
156 uint32 RTPTimestamp; ///< RTP timestamp.
157 uint32 packetCount; ///< cumulative packet counter.
158 uint32 octetCount; ///< cumulative octet counter.
159 };
160
161 /**
162 * @struct SendReport
163 *
164 * Struct for SR (sender report) RTCP packets.
165 **/
166 struct SendReport
167 {
168 uint32 ssrc; ///< source identifier.
169 SenderInfo sinfo; ///< actual sender info.
170 RRBlock blocks[1]; ///< possibly several receiver info blocks.
171 };
172
173 /**
174 * @struct SDESItem
175 *
176 * Struct for an item description of a SDES packet.
177 **/
178 struct SDESItem
179 {
180 uint8 type; ///< item identifier.
181 uint8 len; ///< item len in octets.
182 char data[1]; ///< item content.
183 };
184
185 /**
186 * @struct SDESChunk
187 *
188 * Struct for a chunk of items in a SDES RTCP packet.
189 **/
190 struct SDESChunk
191 {
192 uint32 getSSRC() const
193 { return (ntohl(ssrc)); }
194
195 uint32 ssrc; ///< SSRC identifer from sender.
196 SDESItem item; ///< SDES item from sender.
197 };
198
199 /**
200 * @struct BYEPacket
201 *
202 * @short Struct for BYE (leaving session) RTCP packets.
203 **/
204 struct BYEPacket
205 {
206 uint32 ssrc; ///< ssrc identifier of source leaving.
207 uint8 length; ///< [optional] length of reason.
208 };
209
210 /**
211 * @struct APPPacket
212 *
213 * @short Struct for APP (application specific) RTCP packets.
214 **/
215 struct APPPacket
216 {
217 uint32 ssrc; ///< ssrc identifier of source.
218 char name [4]; ///< Name of the APP packet,
219 ///interpreted as a sequence of
220 ///four characters.
221 unsigned char data[1]; ///< application dependent data.
222 };
223
224 /**
225 * @struct FIRPacket
226 *
227 * @short Struct for Full Intra-frame Request (FIR) RTCP
228 * packet. Specific for H.261 sessions (see RFC 2032).
229 **/
230 struct FIRPacket
231 {
232 uint32 ssrc; ///< ssrc identifier of source.
233 };
234
235 /**
236 * @struct NACKPacket
237 *
238 * @short Struct for Negative ACKnowledgements (NACK) RTCP
239 * packet. Specific for H.261 sessions (see RFC 2032).
240 **/
241 struct NACKPacket
242 {
243 uint32 ssrc; ///< ssrc identifier of source.
244 uint16 fsn; ///< First Sequence Number lost.
245 uint16 blp; ///< Bitmask of following Lost Packets.
246 };
247
248 /**
249 * @struct RTCPFixedHeader
250 * Fixed RTCP packet header. First 32-bit word in any RTCP
251 * packet.
252 */
253 struct RTCPFixedHeader
254 {
255#if __BYTE_ORDER == __BIG_ENDIAN
256 ///< For big endian boxes
257 unsigned char version:2; ///< Version, currently 2.
258 unsigned char padding:1; ///< Padding bit.
259 unsigned char block_count:5; ///< Number of RR, SR, or SDES chunks.
260#else
261 ///< For little endian boxes
262 unsigned char block_count:5; ///< Number of RR, SR, or SDES chunks.
263 unsigned char padding:1; ///< Padding bit.
264 unsigned char version:2; ///< Version, currently 2.
265#endif
266 uint8 type; ///< type of RTCP packet.
267 uint16 length; ///< number of 32-bit words in the packet (*minus one*).
268 };
269
270 /**
271 * @struct RTCPPacket
272 *
273 * @short Struct representing general RTCP packet headers as they are
274 * sent through the network.
275 *
276 * This struct consists of a fixed header, always at the
277 * beginning of any RTCP packet, and a union for all the RTCP
278 * packet types supported.
279 **/
280 struct RTCPPacket
281 {
282 /**
283 * @enum Type rtp.h cc++/rtp.h
284 *
285 * RTCP packet types. They are registered with IANA.
286 */
287 typedef enum {
288 tSR = 200, ///< Sender Report.
289 tRR, ///< Receiver Report.
290 tSDES, ///< Source DEScription.
291 tBYE, ///< End of participation.
292 tAPP, ///< APPlication specific.
293 tFIR = 192, ///< Full Intra-frame request.
294 tNACK = 193, ///< Negative ACK.
295 tXR ///< Extended Report.
296 } Type;
297
298 /**
299 * Get the packet length specified in its header, in
300 * octets and in host order.
301 **/
302 uint32 getLength() const
303 { return ((ntohs(fh.length) + 1) << 2); }
304
305 /**
306 * Get the SSRC identifier specified in the packet
307 * header, in host order.
308 **/
309 uint32 getSSRC() const
310 { return (ntohl(info.RR.ssrc)); } // SSRC is always the first
311 // word after fh.
312
313 RTCPFixedHeader fh; ///< Fixed RTCP header.
314
315 // An RTCP packet may be of any of the types defined
316 // above, including APP specific ones.
317 union
318 {
319 SendReport SR;
320 RecvReport RR;
321 SDESChunk SDES;
322 BYEPacket BYE;
323 APPPacket APP;
324 NACKPacket NACK;
325 FIRPacket FIR;
326 } info; ///< Union for SR, RR, SDES, BYE and APP
327 };
328#ifdef CCXX_PACKED
329#pragma pack()
330#endif
331
332protected:
333 enum { defaultPathMTU = 1500 };
334
335 RTCPCompoundHandler(uint16 mtu = defaultPathMTU);
336
337 ~RTCPCompoundHandler();
338
339 /**
340 * Perform RTCP compound packet header validity check as
341 * specified in draft-ietv-avt-rtp-new. This method follows
342 * appendix A.2. Correct version, payload type, padding bit
343 * and length of every RTCP packet in the compound are
344 * verified.
345 *
346 * @param len length of the RTCP compound packet in
347 * the reception buffer
348 * @return whether the header is valid.
349 */
350 bool
351 checkCompoundRTCPHeader(size_t len);
352
353 // buffer to hold RTCP compound packets being sent. Allocated
354 // in construction time
355 unsigned char* rtcpSendBuffer;
356 // buffer to hold RTCP compound packets being
357 // received. Allocated at construction time
358 unsigned char* rtcpRecvBuffer;
359
360 friend class RTCPSenderInfo;
361 friend class RTCPReceiverInfo;
362private:
363 // path MTU. RTCP packets should not be greater than this
364 uint16 pathMTU;
365 // masks for RTCP header validation;
366 static const uint16 RTCP_VALID_MASK;
367 static const uint16 RTCP_VALID_VALUE;
368};
369
370/**
371 * @class RTCPReceiverInfo
372 * @short Report block information of SR/RR RTCP reports.
373 *
374 * @author Federico Montesino Pouzols <fedemp@altern.org>
375 **/
376class __EXPORT RTCPReceiverInfo
377{
378public:
379 RTCPReceiverInfo(void* ri)
380 { memcpy(&receiverInfo,&ri,
381 sizeof(RTCPCompoundHandler::ReceiverInfo));}
382
383 RTCPReceiverInfo(RTCPCompoundHandler::ReceiverInfo& si)
384 : receiverInfo( si )
385 {
386 }
387
388 ~RTCPReceiverInfo()
389 { }
390
391 /**
392 * Get fraction of lost packets, as a number between 0 and
393 * 255.
394 **/
395 inline uint8
396 getFractionLost() const
397 { return receiverInfo.fractionLost; }
398
399 inline uint32
400 getCumulativePacketLost() const
401 { return ( ((uint32)ntohs(receiverInfo.lostLSW)) +
402 (((uint32)receiverInfo.lostMSB) << 16) ); }
403
404 inline uint32
405 getExtendedSeqNum() const
406 { return ntohl(receiverInfo.highestSeqNum); }
407
408 /**
409 * Get the statistical variance of the RTP data packets
410 * interarrival time.
411 *
412 * @return Interarrival jitter, in timestamp units.
413 **/
414 uint32
415 getJitter() const
416 { return ntohl(receiverInfo.jitter); }
417
418 /**
419 * Get the integer part of the NTP timestamp of the last SR
420 * RTCP packet received from the source this receiver report
421 * refers to.
422 **/
423 uint16
424 getLastSRNTPTimestampInt() const
425 { return (uint16)((ntohl(receiverInfo.lsr) & 0xFFFF0000) >> 16); }
426
427 /**
428 * Get the fractional part of the NTP timestamp of the last SR
429 * RTCP packet received from the source this receiver report
430 * refers to.
431 **/
432 uint16
433 getLastSRNTPTimestampFrac() const
434 { return (uint16)(ntohl(receiverInfo.lsr) & 0xFFFF); }
435
436 /**
437 * Get the delay between the last SR packet received and the
438 * transmission of this report.
439 *
440 * @return Delay, in units of 1/65536 seconds
441 **/
442 uint32
443 getDelayLastSR() const
444 { return ntohl(receiverInfo.dlsr); }
445
446private:
447 RTCPCompoundHandler::ReceiverInfo receiverInfo;
448};
449
450/**
451 * @class RTCPSenderInfo
452 * @short Sender block information of SR RTCP reports.
453 *
454 * @author Federico Montesino Pouzols <fedemp@altern.org>
455 **/
456class __EXPORT RTCPSenderInfo
457{
458public:
459 RTCPSenderInfo(void* si)
460 { memcpy(&senderInfo,&si,
461 sizeof(RTCPCompoundHandler::SenderInfo));}
462
463 RTCPSenderInfo(RTCPCompoundHandler::SenderInfo& si)
464 : senderInfo( si )
465 {
466 }
467
468 ~RTCPSenderInfo()
469 { }
470
471 /**
472 * Get integer part of the NTP timestamp of this packet.
473 * @see NTP2Timeval
474 **/
475 uint32
476 getNTPTimestampInt() const
477 { return ntohl(senderInfo.NTPMSW); }
478
479 /**
480 * Get fractional part of the NTP timestamp of this packet.
481 * @see NTP2Timeval
482 **/
483 uint32
484 getNTPTimestampFrac() const
485 { return ntohl(senderInfo.NTPLSW); }
486
487 inline uint32
488 getRTPTimestamp() const
489 { return ntohl(senderInfo.RTPTimestamp); }
490
491 /**
492 * Get count of sent data packets.
493 **/
494 inline uint32
495 getPacketCount() const
496 { return ntohl(senderInfo.packetCount); }
497
498 inline uint32
499 getOctetCount() const
500 { return ntohl(senderInfo.octetCount); }
501
502private:
503 RTCPCompoundHandler::SenderInfo senderInfo;
504};
505
506/**
507 * Convert a NTP timestamp, expressed as two 32-bit long words, into a
508 * timeval value.
509 *
510 * @param msw Integer part of NTP timestamp.
511 * @param lsw Fractional part of NTP timestamp.
512 * @return timeval value corresponding to the given NTP timestamp.
513 **/
514timeval
515NTP2Timeval(uint32 msw, uint32 lsw);
516
517/**
518 * Convert a time interval, expressed as a timeval, into a 32-bit time
519 * interval expressed in units of 1/65536 seconds.
520 *
521 * @param t Timeval interval.
522 * @return 32-bit value corresponding to the given timeval interval.
523 **/
524uint32
525timevalIntervalTo65536(timeval& t);
526
527/** @}*/ // rtcppacket
528
529#ifdef CCXX_NAMESPACES
530}
531#endif
532
533#endif // ndef CCXX_RTP_RTCPPKT_H_
534
535/** EMACS **
536 * Local variables:
537 * mode: c++
538 * c-basic-offset: 8
539 * End:
540 */
541