ccRTP
rtppkt.h
Go to the documentation of this file.
1 // 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 NAMESPACE_COMMONCPP
46 
71 class CryptoContext;
72 
73 class __EXPORT RTPPacket
74 {
75 private:
76  struct RTPFixedHeader;
77  struct RTPHeaderExt;
78 
79 public:
92  RTPPacket(const unsigned char* const block, size_t len,
93  bool duplicate = false);
94 
106  RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen, CryptoContext* pcc= NULL);
107 
114  inline uint32
116  { return hdrSize; }
117 
121  inline const uint8* const
122  getPayload() const
123  { return (uint8*)(buffer + getHeaderSize()); }
124 
128  inline uint32
130  { return payloadSize; }
131 
135  inline PayloadType
137  { return static_cast<PayloadType>(getHeader()->payload); }
138 
142  inline uint16
143  getSeqNum() const
144  { return cachedSeqNum; }
145 
149  inline uint32
150  getTimestamp() const
151  { return cachedTimestamp; }
152 
156  inline uint8
158  { return getHeader()->version; }
159 
164  inline bool
165  isPadded() const
166  { return getHeader()->padding; }
167 
174  inline uint8
176  { return buffer[total - 1]; }
177 
184  inline bool
185  isMarked() const
186  { return getHeader()->marker; }
187 
193  inline bool
194  isExtended() const
195  { return getHeader()->extension; }
196 
201  inline uint16
203  { return getHeader()->cc; }
204 
212  inline const uint32*
213  getCSRCs() const
214  { return static_cast<const uint32*>(&(getHeader()->sources[1])); }
215 
228  inline uint16
230  { return (isExtended()? getHeaderExt()->undefined : 0); }
231 
243  inline uint32
245  { return (isExtended()?
246  (static_cast<uint32>(ntohs(getHeaderExt()->length)) << 2) :
247  0); }
248 
255  inline const unsigned char*
257  { return (isExtended() ?
258  (reinterpret_cast<const unsigned char*>(getHeaderExt()) +
259  sizeof(RTPHeaderExt)) :
260  NULL); }
261 
268  inline const unsigned char* const
269  getRawPacket() const
270  { return buffer; }
271 
278  inline uint32
280  { return total; }
281 
282  inline uint32
284  { return total + srtpLength; }
285 
286  inline size_t
288  { return sizeof(RTPFixedHeader); }
289 
301  void reComputePayLength(bool padding);
302 
303 protected:
307  inline virtual ~RTPPacket()
308  { endPacket(); }
309 
313  void
314  endPacket();
315 
321  inline RTPFixedHeader*
322  getHeader() const
323  { return reinterpret_cast<RTPFixedHeader*>(buffer); }
324 
325  inline void
326  setExtension(bool e)
327  { getHeader()->extension = e; }
328 
336  inline const RTPHeaderExt*
337  getHeaderExt() const
338  {
339  uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2);
340  return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize));
341  }
342 
348  inline uint32
350  { return ntohl(getHeader()->timestamp); }
351 
352  inline void
353  setbuffer(const void* src, size_t len, size_t pos)
354  { memcpy(buffer + pos,src,len); }
355 
357  uint16 cachedSeqNum;
360 
368 
374  int32 srtpLength;
375 
377  uint32 total;
378 
380  uint32 payloadSize;
381 
382 private:
384  unsigned char* buffer;
386  uint32 hdrSize;
388  bool duplicated;
389 
390 #ifdef CCXX_PACKED
391 #pragma pack(1)
392 #endif
393 
403  struct RTPFixedHeader
404  {
405 #if __BYTE_ORDER == __BIG_ENDIAN
406  unsigned char version:2;
408  unsigned char padding:1;
409  unsigned char extension:1;
410  unsigned char cc:4;
411  unsigned char marker:1;
412  unsigned char payload:7;
413 #else
414  unsigned char cc:4;
416  unsigned char extension:1;
417  unsigned char padding:1;
418  unsigned char version:2;
419  unsigned char payload:7;
420  unsigned char marker:1;
421 #endif
422  uint16 sequence;
423  uint32 timestamp;
424  uint32 sources[1];
425  };
426 
435 public:
437  {
438 #if __BYTE_ORDER == __BIG_ENDIAN
439  uint8 event : 8;
440  bool ebit : 1;
441  bool rbit : 1;
442  uint8 vol : 6;
443  uint16 duration : 16;
444 #else
445  uint8 event : 8;
446  uint8 vol : 6;
447  bool rbit : 1;
448  bool ebit : 1;
449  uint16 duration : 16;
450 #endif
451  };
452 
453 private:
461  struct RTPHeaderExt
462  {
463  uint16 undefined;
464  uint16 length;
465  };
466 #ifdef CCXX_PACKED
467 #pragma pack()
468 #endif
469 
470  /* definitions for access to most common 2833 fields... */
471 
472 public:
478  inline struct RFC2833Payload *getRaw2833Payload(void)
479  {return (struct RFC2833Payload *)getPayload();}
480 
486  inline uint16 get2833Duration(void)
487  {return ntohs(getRaw2833Payload()->duration);}
488 
494  inline void set2833Duration(uint16 timestamp)
495  {getRaw2833Payload()->duration = htons(timestamp);}
496 };
497 
508 class __EXPORT OutgoingRTPPkt : public RTPPacket
509 {
510 public:
537  OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
538  const unsigned char* const hdrext, uint32 hdrextlen,
539  const unsigned char* const data, size_t datalen,
540  uint8 paddinglen= 0, CryptoContext* pcc= NULL);
541 
562  OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
563  const unsigned char* const data, size_t datalen,
564  uint8 paddinglen= 0, CryptoContext* pcc= NULL);
565 
582  OutgoingRTPPkt(const unsigned char* const data, size_t datalen,
583  uint8 paddinglen= 0, CryptoContext* pcc= NULL);
584 
586  { }
587 
591  inline void
593  { getHeader()->payload = pt; }
594 
600  inline void
601  setSeqNum(uint16 seq)
602  {
603  cachedSeqNum = seq;
604  getHeader()->sequence = htons(seq);
605  }
606 
610  inline void
611  setTimestamp(uint32 pts)
612  {
613  cachedTimestamp = pts;
614  getHeader()->timestamp = htonl(pts);
615  }
616 
623  inline void
624  setSSRC(uint32 ssrc) const
625  { getHeader()->sources[0] = htonl(ssrc); }
626 
634  inline void
635  setSSRCNetwork(uint32 ssrc) const
636  { getHeader()->sources[0] = ssrc; }
637 
645  inline void
646  setMarker(bool mark)
647  { getHeader()->marker = mark; }
648 
655  void protect(uint32 ssrc, CryptoContext* pcc);
656 
660  inline bool
661  operator==(const OutgoingRTPPkt &p) const
662  { return ( this->getSeqNum() == p.getSeqNum() ); }
663 
667  inline bool
668  operator!=(const OutgoingRTPPkt &p) const
669  { return ( this->getSeqNum() != p.getSeqNum() ); }
670 
671 private:
676  OutgoingRTPPkt(const OutgoingRTPPkt &o);
677 
683  operator=(const OutgoingRTPPkt &o);
684 
689  void setCSRCArray(const uint32* const csrcs, uint16 numcsrc);
690 
691 };
692 
705 class __EXPORT IncomingRTPPkt : public RTPPacket
706 {
707 public:
720  IncomingRTPPkt(const unsigned char* block, size_t len);
721 
723  { }
724 
730  inline bool
732  { return headerValid; }
733 
740  inline uint32
741  getSSRC() const
742  { return cachedSSRC; }
743 
754  int32
755  unprotect(CryptoContext* pcc);
756 
761  inline bool
762  operator==(const IncomingRTPPkt &p) const
763  { return ( (this->getSeqNum() == p.getSeqNum()) &&
764  (this->getSSRC() == p.getSSRC()) ); }
765 
770  inline bool
771  operator!=(const IncomingRTPPkt &p) const
772  { return !( *this == p ); }
773 
774 private:
779  IncomingRTPPkt(const IncomingRTPPkt &ip);
780 
786  operator=(const IncomingRTPPkt &ip);
787 
789  bool headerValid;
791  uint32 cachedSSRC;
792  // Masks for RTP header validation: types matching RTCP SR or
793  // RR must be rejected to avoid accepting misaddressed RTCP
794  // packets.
795  static const uint16 RTP_INVALID_PT_MASK;
796  static const uint16 RTP_INVALID_PT_VALUE;
797 };
798  // rtppacket
800 
801 END_NAMESPACE
802 
803 #endif // ndef CCXX_RTP_RTPPKT_H_
804