blob: 8a6ae6e6623a84cc335df806791a9c3003b4776c [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2002 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_RTPPKT_H_
39#define CCXX_RTP_RTPPKT_H_
40
41#include <ccrtp/base.h>
42#include <ccrtp/formats.h>
43#include <ccrtp/CryptoContext.h>
44
45#ifdef CCXX_NAMESPACES
46namespace ost {
47#endif
48
49/**
50 * @file rtppkt.h
51 *
52 * @short RTP packets handling.
53 **/
54
55/**
56 * @defgroup rtppacket RTP data packets manipulation.
57 * @{
58 **/
59
60/**
61 * @class RTPPacket
62 * @short A base class for both IncomingRTPPkt and OutgoingRTPPkt.
63 *
64 * Provides common low level header structures and related
65 * methods. This class provides an interface that allows for partial
66 * and generic manipulation of RTP data packets. Values are returned
67 * in host order, except raw structures, which are returned as they
68 * are sent through the network.
69 *
70 * @author David Sugar <dyfet@ostel.com>
71 **/
72
73class CryptoContext;
74
75class __EXPORT RTPPacket
76{
77private:
78 struct RTPFixedHeader;
79 struct RTPHeaderExt;
80
81public:
82 /**
83 * Constructor, construct a packet object given the memory
84 * zone its content (header and payload) is stored. Commonly
85 * used to build RTPPacket objects from incoming data.
86 *
87 * @param block whole packet
88 * @param len total length (header + payload + padding) of the
89 * packet
90 * @param duplicate whether to memcopy the packet. At present,
91 * this feature is not used.
92 * @note used in IncomingRTPPkt.
93 **/
94 RTPPacket(const unsigned char* const block, size_t len,
95 bool duplicate = false);
96
97 /**
98 * Construct a packet object without specifying its real
99 * content yet. Commonly used for outgoing packets. Header
100 * fields and payload must be filled in by another methods or
101 * by a derived constructor.
102 *
103 * @param hdrlen length of the header (including CSRC and extension).
104 * @param plen payload length.
105 * @param paddinglen pad packet to a multiple of paddinglen
106 * @note used in OutgoingRTPPkt.
107 */
108 RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen, CryptoContext* pcc= NULL);
109
110 /**
111 * Get the length of the header, including contributing
112 * sources identifiers and header extension, if present.
113 *
114 * @return number of octets.
115 **/
116 inline uint32
117 getHeaderSize() const
118 { return hdrSize; }
119
120 /**
121 * @return pointer to the payload section of the packet.
122 **/
123 inline const uint8* const
124 getPayload() const
125 { return (uint8*)(buffer + getHeaderSize()); }
126
127 /**
128 * @return length of the payload section, in octets.
129 **/
130 inline uint32
131 getPayloadSize() const
132 { return payloadSize; }
133
134 /**
135 * @return value of the PT header field.
136 **/
137 inline PayloadType
138 getPayloadType() const
139 { return static_cast<PayloadType>(getHeader()->payload); }
140
141 /**
142 * @return value of the sequence number header field, in host order.
143 **/
144 inline uint16
145 getSeqNum() const
146 { return cachedSeqNum; }
147
148 /**
149 * @return packet timestamp in host order.
150 **/
151 inline uint32
152 getTimestamp() const
153 { return cachedTimestamp; }
154
155 /**
156 * @return RTP protocol version of packet.
157 **/
158 inline uint8
159 getProtocolVersion() const
160 { return getHeader()->version; }
161
162 /**
163 * Ask whether the packet contains padding bytes at the end
164 * @return true if the header padding bit is 1.
165 **/
166 inline bool
167 isPadded() const
168 { return getHeader()->padding; }
169
170 /**
171 * Get the number of octets padding the end of the payload
172 * section.
173 *
174 * @return Padding length in octets.
175 **/
176 inline uint8
177 getPaddingSize() const
178 { return buffer[total - 1]; }
179
180 /**
181 * Ask whether the packet is marked (for isntance, is a new
182 * talk spurt in some audio profiles).
183 *
184 * @return true is the header marker bit is 1.
185 **/
186 inline bool
187 isMarked() const
188 { return getHeader()->marker; }
189
190 /**
191 * Ask whether the packet contains header extensions.
192 *
193 * @return true if the header extension bit is 1.
194 **/
195 inline bool
196 isExtended() const
197 { return getHeader()->extension; }
198
199 /**
200 * Get the number of contributing sources specified in the
201 * packet header.
202 **/
203 inline uint16
204 getCSRCsCount() const
205 { return getHeader()->cc; }
206
207 /**
208 * Get the 32-bit identifiers of the contributing sources for
209 * the packet as an array, of length getCSRCsCount().
210 *
211 * @return An array of CSRC identifiers as they are in the
212 * packet (in network order).
213 **/
214 inline const uint32*
215 getCSRCs() const
216 { return static_cast<const uint32*>(&(getHeader()->sources[1])); }
217
218 /**
219 * Get the first 16 bits (in network order) of the header of
220 * the RTP header extension. Its meaning is undefined at this
221 * level.
222 *
223 * @return 0 if the packet has no header extension, otherwise
224 * the first 16 bits of the header extension, in
225 * network order.
226 *
227 * @note 0 could be a valid value for the first 16 bits, in
228 * that case RTPPacket::isExtended() should be use.
229 **/
230 inline uint16
231 getHdrExtUndefined() const
232 { return (isExtended()? getHeaderExt()->undefined : 0); }
233
234 /**
235 * Get the length (in octets) of the data contained in the
236 * header extension. Note that this length does not include
237 * the four octets at the beginning of the header extension.
238 *
239 * @return 0 if the packet has no header extension, otherwise
240 * the length.
241 *
242 * @note 0 is a valid value for this field, so
243 * RTPPacket::isExtended() should be used.
244 **/
245 inline uint32
246 getHdrExtSize() const
247 { return (isExtended()?
248 (static_cast<uint32>(ntohs(getHeaderExt()->length)) << 2) :
249 0); }
250
251 /**
252 * Get the content of the header extension.
253 *
254 * @return NULL if the packet has no header extension, otherwise
255 * a pointer to the packet header extension content.
256 **/
257 inline const unsigned char*
258 getHdrExtContent() const
259 { return (isExtended() ?
260 (reinterpret_cast<const unsigned char*>(getHeaderExt()) +
261 sizeof(RTPHeaderExt)) :
262 NULL); }
263
264 /**
265 * Get the raw packet as it will be sent through the network.
266 *
267 * @return memory zone where the raw packet structure is
268 * stored in.
269 **/
270 inline const unsigned char* const
271 getRawPacket() const
272 { return buffer; }
273
274 /**
275 * Get the raw packet length, including header, extension,
276 * payload and padding.
277 *
278 * @return size of the raw packet structure.
279 **/
280 inline uint32
281 getRawPacketSize() const
282 { return total; }
283
284 inline uint32
285 getRawPacketSizeSrtp() const
286 { return total + srtpLength; }
287
288 inline size_t
289 getSizeOfFixedHeader() const
290 { return sizeof(RTPFixedHeader); }
291
292 /**
293 * Re-compute payload length.
294 *
295 * This recomputation may be necessary in case of SRTP. We need to decrypt
296 * the packet before we can handle padding. See @c takeInDataPacket in
297 * @c incqueue.cpp
298 *
299 * @param padding
300 * If true then set padding flag in RTP header and re-compute
301 * payloadSize.
302 */
303 void reComputePayLength(bool padding);
304
305protected:
306 /**
307 * Destructor, free the buffer provided in the constructor.
308 **/
309 inline virtual ~RTPPacket()
310 { endPacket(); }
311
312 /**
313 * Free memory allocated for the packet.
314 **/
315 void
316 endPacket();
317
318 /**
319 * Return low level structure for the header of the packet.
320 *
321 * @return RTPFixedHeader pointer to the header of the packet.
322 **/
323 inline RTPFixedHeader*
324 getHeader() const
325 { return reinterpret_cast<RTPFixedHeader*>(buffer); }
326
327 inline void
328 setExtension(bool e)
329 { getHeader()->extension = e; }
330
331 /**
332 * Get a pointer to RTPHeaderExt pointing after the RTP header
333 * (fixed part plus contributing sources). No check for
334 * for the X bit is done.
335 *
336 * @return header extension if present, garbage if not.
337 **/
338 inline const RTPHeaderExt*
339 getHeaderExt() const
340 {
341 uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2);
342 return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize));
343 }
344
345 /**
346 * Obtain the absolute timestamp carried in the packet header.
347 *
348 * @return 32-bit timestamp in host order.
349 **/
350 inline uint32
351 getRawTimestamp() const
352 { return ntohl(getHeader()->timestamp); }
353
354 inline void
355 setbuffer(const void* src, size_t len, size_t pos)
356 { memcpy(buffer + pos,src,len); }
357
358 /// Packet sequence number in host order.
359 uint16 cachedSeqNum;
360 /// Packet timestamp in host order (includes initial shift).
361 uint32 cachedTimestamp;
362
363 /**
364 * Offset into packet memory pointing to area for SRTP data.
365 *
366 * This offset points to the memory where the SRTP protect will
367 * store the authentication and MKI data.
368 */
369 uint32 srtpDataOffset;
370
371 /**
372 * Lebgth of additional SRTP data.
373 *
374 * Covers the SRTP authentication and MKI data.
375 */
376 int32 srtpLength;
377
378 /// total length, including header, payload and padding
379 uint32 total;
380
381 /// note: payload (not full packet) size.
382 uint32 payloadSize;
383
384private:
385 /// packet in memory
386 unsigned char* buffer;
387 /// size of the header, including contributing sources and extensions
388 uint32 hdrSize;
389 /// whether the object was contructed with duplicated = true
390 bool duplicated;
391
392#ifdef CCXX_PACKED
393#pragma pack(1)
394#endif
395 /**
396 * @struct RTPFixedHeader
397 * @short RTP fixed header as it is send through the network.
398 *
399 * A low-level representation for generic RTP packet header as
400 * defined in RFC 1889. A packet consists of the fixed RTP
401 * header, a possibly empty list of contributing sources and
402 * the payload. Header contents are kept in network (big
403 * endian) order.
404 **/
405 struct RTPFixedHeader
406 {
407#if __BYTE_ORDER == __BIG_ENDIAN
408 /// For big endian boxes
409 unsigned char version:2; ///< Version, currently 2
410 unsigned char padding:1; ///< Padding bit
411 unsigned char extension:1; ///< Extension bit
412 unsigned char cc:4; ///< CSRC count
413 unsigned char marker:1; ///< Marker bit
414 unsigned char payload:7; ///< Payload type
415#else
416 /// For little endian boxes
417 unsigned char cc:4; ///< CSRC count
418 unsigned char extension:1; ///< Extension bit
419 unsigned char padding:1; ///< Padding bit
420 unsigned char version:2; ///< Version, currently 2
421 unsigned char payload:7; ///< Payload type
422 unsigned char marker:1; ///< Marker bit
423#endif
424 uint16 sequence; ///< sequence number
425 uint32 timestamp; ///< timestamp
426 uint32 sources[1]; ///< contributing sources
427 };
428
429 /**
430 * @struct RFC2833Payload
431 * @short a structure defining RFC2833 Telephony events.
432 *
433 * structure to define RFC2833 telephony events in RTP. You can
434 * use this by recasing the pointer returned by getPayload().
435 */
436
437public:
438 struct RFC2833Payload
439 {
440#if __BYTE_ORDER == __BIG_ENDIAN
441 uint8 event : 8;
442 bool ebit : 1;
443 bool rbit : 1;
444 uint8 vol : 6;
445 uint16 duration : 16;
446#else
447 uint8 event : 8;
448 uint8 vol : 6;
449 bool rbit : 1;
450 bool ebit : 1;
451 uint16 duration : 16;
452#endif
453 };
454
455private:
456 /**
457 * @struct RTPHeaderExt
458 *
459 * Fixed component of the variable-length header extension,
460 * appended to the fixed header, after the CSRC list, when X
461 * == 1.
462 **/
463 struct RTPHeaderExt
464 {
465 uint16 undefined; ///< to be defined
466 uint16 length; ///< number of 32-bit words in the extension
467 };
468#ifdef CCXX_PACKED
469#pragma pack()
470#endif
471
472 /* definitions for access to most common 2833 fields... */
473
474public:
475 /**
476 * Fetch a raw 2833 packet.
477 *
478 * @return low level 2833 data structure.
479 */
480 inline struct RFC2833Payload *getRaw2833Payload(void)
481 {return (struct RFC2833Payload *)getPayload();}
482
483 /**
484 * Fetch 2833 duration field.
485 *
486 * @return 2833 duration in native host machine byte order.
487 */
488 inline uint16 get2833Duration(void)
489 {return ntohs(getRaw2833Payload()->duration);}
490
491 /**
492 * Set 2833 duration field.
493 *
494 * @param timestamp to use, native host machine byte order.
495 */
496 inline void set2833Duration(uint16 timestamp)
497 {getRaw2833Payload()->duration = htons(timestamp);}
498};
499
500/**
501 * @class OutgoingRTPPkt
502 * @short RTP packets being sent.
503 *
504 * This class is intented to construct packet objects just before they
505 * are inserted into the sending queue, so that they are processed in
506 * a understandable and format independent manner inside the stack.
507 *
508 * @author Federico Montesino Pouzols <fedemp@altern.org>
509 **/
510class __EXPORT OutgoingRTPPkt : public RTPPacket
511{
512public:
513 /**
514 * Construct a new packet to be sent, containing several
515 * contributing source identifiers, header extensions and
516 * payload.
517 *
518 * A new copy in memory (holding all this components
519 * along with the fixed header) is created. If the pointer
520 * to the SRTP CryptoContext is not NULL and holds a CryptoContext
521 * for the SSRC take the SSRC data into account when computing
522 * the required memory buffer.
523 *
524 * @param csrcs array of countributing source 32-bit
525 * identifiers, in host order.
526 * @param numcsrc number of CSRC identifiers in the array.
527 * @param hdrext whole header extension.
528 * @param hdrextlen size of whole header extension, in octets.
529 * @param data payload.
530 * @param datalen payload length, in octets.
531 * @param paddinglen pad packet to a multiple of paddinglen.
532 * @param pcc Pointer to the SRTP CryptoContext, defaults to NULL
533 * if not specified.
534 *
535 * @note For efficiency purposes, since this constructor is
536 * valid for all packets but is too complex for the common
537 * case, two simpler others are provided.
538 **/
539 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
540 const unsigned char* const hdrext, uint32 hdrextlen,
541 const unsigned char* const data, size_t datalen,
542 uint8 paddinglen= 0, CryptoContext* pcc= NULL);
543
544 /**
545 * Construct a new packet to be sent, containing several
546 * contributing source identifiers and payload.
547 *
548 * A new copy in
549 * memory (holding all this components along with the fixed
550 * header) is created. If the pointer
551 * to the SRTP CryptoContext is not NULL and holds a CryptoContext
552 * for the SSRC take the SSRC data into account when computing
553 * the required memory buffer.
554 *
555 * @param csrcs array of countributing source 32-bit
556 * identifiers, in host order.
557 * @param numcsrc number of CSRC identifiers in the array.
558 * @param data payload.
559 * @param datalen payload length, in octets.
560 * @param paddinglen pad packet to a multiple of paddinglen.
561 * @param pcc Pointer to the SRTP CryptoContext, defaults to NULL
562 * if not specified.
563 **/
564 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
565 const unsigned char* const data, size_t datalen,
566 uint8 paddinglen= 0, CryptoContext* pcc= NULL);
567
568 /**
569 * Construct a new packet (fast variant, with no contributing
570 * sources and no header extension) to be sent.
571 *
572 * A new copy in
573 * memory (holding the whole packet) is created. If the pointer
574 * to the SRTP CryptoContext is not NULL and holds a CryptoContext
575 * for the SSRC take the SSRC data into account when computing
576 * the required memory buffer.
577 *
578 * @param data payload.
579 * @param datalen payload length, in octets.
580 * @param paddinglen pad packet to a multiple of paddinglen.
581 * @param pcc Pointer to the SRTP CryptoContext, defaults to NULL
582 * if not specified.
583 **/
584 OutgoingRTPPkt(const unsigned char* const data, size_t datalen,
585 uint8 paddinglen= 0, CryptoContext* pcc= NULL);
586
587 ~OutgoingRTPPkt()
588 { }
589
590 /**
591 * @param pt Packet payload type.
592 **/
593 inline void
594 setPayloadType(PayloadType pt)
595 { getHeader()->payload = pt; }
596
597 /**
598 * Sets the sequence number in the header.
599 *
600 * @param seq Packet sequence number, in host order.
601 **/
602 inline void
603 setSeqNum(uint16 seq)
604 {
605 cachedSeqNum = seq;
606 getHeader()->sequence = htons(seq);
607 }
608
609 /**
610 * @param pts Packet timestamp, in host order.
611 **/
612 inline void
613 setTimestamp(uint32 pts)
614 {
615 cachedTimestamp = pts;
616 getHeader()->timestamp = htonl(pts);
617 }
618
619 /**
620 * Set synchronization source numeric identifier.
621 *
622 * @param ssrc 32-bit Synchronization SouRCe numeric
623 * identifier, in host order.
624 **/
625 inline void
626 setSSRC(uint32 ssrc) const
627 { getHeader()->sources[0] = htonl(ssrc); }
628
629 /**
630 * Set synchronization source numeric identifier. Special
631 * version to save endianness conversion.
632 *
633 * @param ssrc 32-bit Synchronization SouRCe numeric
634 * identifier, in network order.
635 **/
636 inline void
637 setSSRCNetwork(uint32 ssrc) const
638 { getHeader()->sources[0] = ssrc; }
639
640 /**
641 * Specify the value of the marker bit. By default, the marker
642 * bit of outgoing packets is false/0. This method allows to
643 * explicity specify and change that value.
644 *
645 * @param mark value for the market bit.
646 */
647 inline void
648 setMarker(bool mark)
649 { getHeader()->marker = mark; }
650
651 /**
652 * Called packet is setup.
653 *
654 * This private method computes the SRTP data and stores it in the
655 * packet. Then encrypt the payload data (ex padding).
656 */
657 void protect(uint32 ssrc, CryptoContext* pcc);
658
659 /**
660 * Outgoing packets are equal if their sequence numbers match.
661 **/
662 inline bool
663 operator==(const OutgoingRTPPkt &p) const
664 { return ( this->getSeqNum() == p.getSeqNum() ); }
665
666 /**
667 * Outgoing packets are not equal if their sequence numbers differ.
668 **/
669 inline bool
670 operator!=(const OutgoingRTPPkt &p) const
671 { return ( this->getSeqNum() != p.getSeqNum() ); }
672
673private:
674 /**
675 * Copy constructor from objects of its same kind, declared
676 * private to avoid its use.
677 **/
678 OutgoingRTPPkt(const OutgoingRTPPkt &o);
679
680 /**
681 * Assignment operator from objects of its same kind, declared
682 * private to avoid its use.
683 **/
684 OutgoingRTPPkt&
685 operator=(const OutgoingRTPPkt &o);
686
687 /**
688 * Set the list of CSRC identifiers in an RTP packet,
689 * switching host to network order.
690 */
691 void setCSRCArray(const uint32* const csrcs, uint16 numcsrc);
692
693};
694
695/**
696 * @class IncomingRTPPkt
697 *
698 * @short RTP packets received from other participants.
699 *
700 * This class is intented to construct a packet object just after
701 * every packet is received by the scheduled queue, so that they are
702 * processed in an understandable and format independent manner inside
703 * the stack.
704 *
705 * @author Federico Montesino Pouzols <fedemp@altern.org>
706 */
707class __EXPORT IncomingRTPPkt : public RTPPacket
708{
709public:
710 /**
711 * Build an RTP packet object from a data buffer. This
712 * constructor first performs a generic RTP data packet header
713 * check, whose result can be checked via isHeaderValid().
714 *
715 * @param block pointer to the buffer the whole packet is stored in.
716 * @param len length of the whole packet, expressed in octets.
717 *
718 * @note If check fails, the packet object is
719 * incomplete. checking isHeaderValid() is recommended before
720 * using a new RTPPacket object.
721 **/
722 IncomingRTPPkt(const unsigned char* block, size_t len);
723
724 ~IncomingRTPPkt()
725 { }
726
727 /**
728 * Get validity of this packet
729 * @return whether the header check performed at construction
730 * time ended successfully.
731 **/
732 inline bool
733 isHeaderValid()
734 { return headerValid; }
735
736 /**
737 * Get synchronization source numeric identifier.
738 *
739 * @return 32-bits Synchronization SouRCe numeric identifier,
740 * in host order.
741 **/
742 inline uint32
743 getSSRC() const
744 { return cachedSSRC; }
745
746 /**
747 * Unprotect a received packet.
748 *
749 * Perform SRTP processing on this packet.
750 *
751 * @param pcc Pointer to SRTP CryptoContext.
752 * @return
753 * one if no errors, -1 if authentication failed, -2 if
754 * replay check failed
755 */
756 int32
757 unprotect(CryptoContext* pcc);
758
759 /**
760 * Two incoming packets are equal if they come from sources
761 * with the same SSRC and have the same sequence number.
762 **/
763 inline bool
764 operator==(const IncomingRTPPkt &p) const
765 { return ( (this->getSeqNum() == p.getSeqNum()) &&
766 (this->getSSRC() == p.getSSRC()) ); }
767
768 /**
769 * Two incoming packets are not equal if they come from
770 * different sources or have different sequence numbers.
771 **/
772 inline bool
773 operator!=(const IncomingRTPPkt &p) const
774 { return !( *this == p ); }
775
776private:
777 /**
778 * Copy constructor from objects of its same kind, declared
779 * private to avoid its use.
780 **/
781 IncomingRTPPkt(const IncomingRTPPkt &ip);
782
783 /**
784 * Assignment operator from objects of its same kind, declared
785 * private to avoid its use.
786 */
787 IncomingRTPPkt&
788 operator=(const IncomingRTPPkt &ip);
789
790 /// Header validity, checked at construction time.
791 bool headerValid;
792 /// SSRC 32-bit identifier in host order.
793 uint32 cachedSSRC;
794 // Masks for RTP header validation: types matching RTCP SR or
795 // RR must be rejected to avoid accepting misaddressed RTCP
796 // packets.
797 static const uint16 RTP_INVALID_PT_MASK;
798 static const uint16 RTP_INVALID_PT_VALUE;
799};
800
801/** @}*/ // rtppacket
802
803#ifdef CCXX_NAMESPACES
804}
805#endif
806
807#endif // ndef CCXX_RTP_RTPPKT_H_
808
809/** EMACS **
810 * Local variables:
811 * mode: c++
812 * c-basic-offset: 8
813 * End:
814 */