ccRTP
|
00001 // Copyright (C) 2002 Federico Montesino Pouzols <fedemp@altern.org>. 00002 // 00003 // This program is free software; you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation; either version 2 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program; if not, write to the Free Software 00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00016 // 00017 // As a special exception, you may use this file as part of a free software 00018 // library without restriction. Specifically, if other files instantiate 00019 // templates or use macros or inline functions from this file, or you compile 00020 // this file and link it with other files to produce an executable, this 00021 // file does not by itself cause the resulting executable to be covered by 00022 // the GNU General Public License. This exception does not however 00023 // invalidate any other reasons why the executable file might be covered by 00024 // the GNU General Public License. 00025 // 00026 // This exception applies only to the code released under the name GNU 00027 // ccRTP. If you copy code from other releases into a copy of GNU 00028 // ccRTP, as the General Public License permits, the exception does 00029 // not apply to the code that you add in this way. To avoid misleading 00030 // anyone as to the status of such modified files, you must delete 00031 // this exception notice from them. 00032 // 00033 // If you write modifications of your own for GNU ccRTP, it is your choice 00034 // whether to permit this exception to apply to your modifications. 00035 // If you do not wish that, delete this exception notice. 00036 // 00037 00038 #ifndef CCXX_RTP_RTPPKT_H_ 00039 #define CCXX_RTP_RTPPKT_H_ 00040 00041 #include <ccrtp/base.h> 00042 #include <ccrtp/formats.h> 00043 #include <ccrtp/CryptoContext.h> 00044 00045 #ifdef CCXX_NAMESPACES 00046 namespace ost { 00047 #endif 00048 00073 class CryptoContext; 00074 00075 class __EXPORT RTPPacket 00076 { 00077 private: 00078 struct RTPFixedHeader; 00079 struct RTPHeaderExt; 00080 00081 public: 00094 RTPPacket(const unsigned char* const block, size_t len, 00095 bool duplicate = false); 00096 00108 RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen, CryptoContext* pcc= NULL); 00109 00116 inline uint32 00117 getHeaderSize() const 00118 { return hdrSize; } 00119 00123 inline const uint8* const 00124 getPayload() const 00125 { return (uint8*)(buffer + getHeaderSize()); } 00126 00130 inline uint32 00131 getPayloadSize() const 00132 { return payloadSize; } 00133 00137 inline PayloadType 00138 getPayloadType() const 00139 { return static_cast<PayloadType>(getHeader()->payload); } 00140 00144 inline uint16 00145 getSeqNum() const 00146 { return cachedSeqNum; } 00147 00151 inline uint32 00152 getTimestamp() const 00153 { return cachedTimestamp; } 00154 00158 inline uint8 00159 getProtocolVersion() const 00160 { return getHeader()->version; } 00161 00166 inline bool 00167 isPadded() const 00168 { return getHeader()->padding; } 00169 00176 inline uint8 00177 getPaddingSize() const 00178 { return buffer[total - 1]; } 00179 00186 inline bool 00187 isMarked() const 00188 { return getHeader()->marker; } 00189 00195 inline bool 00196 isExtended() const 00197 { return getHeader()->extension; } 00198 00203 inline uint16 00204 getCSRCsCount() const 00205 { return getHeader()->cc; } 00206 00214 inline const uint32* 00215 getCSRCs() const 00216 { return static_cast<const uint32*>(&(getHeader()->sources[1])); } 00217 00230 inline uint16 00231 getHdrExtUndefined() const 00232 { return (isExtended()? getHeaderExt()->undefined : 0); } 00233 00245 inline uint32 00246 getHdrExtSize() const 00247 { return (isExtended()? 00248 (static_cast<uint32>(ntohs(getHeaderExt()->length)) << 2) : 00249 0); } 00250 00257 inline const unsigned char* 00258 getHdrExtContent() const 00259 { return (isExtended() ? 00260 (reinterpret_cast<const unsigned char*>(getHeaderExt()) + 00261 sizeof(RTPHeaderExt)) : 00262 NULL); } 00263 00270 inline const unsigned char* const 00271 getRawPacket() const 00272 { return buffer; } 00273 00280 inline uint32 00281 getRawPacketSize() const 00282 { return total; } 00283 00284 inline uint32 00285 getRawPacketSizeSrtp() const 00286 { return total + srtpLength; } 00287 00288 inline size_t 00289 getSizeOfFixedHeader() const 00290 { return sizeof(RTPFixedHeader); } 00291 00292 protected: 00296 inline virtual ~RTPPacket() 00297 { endPacket(); } 00298 00302 void 00303 endPacket(); 00304 00310 inline RTPFixedHeader* 00311 getHeader() const 00312 { return reinterpret_cast<RTPFixedHeader*>(buffer); } 00313 00314 inline void 00315 setExtension(bool e) 00316 { getHeader()->extension = e; } 00317 00325 inline const RTPHeaderExt* 00326 getHeaderExt() const 00327 { 00328 uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2); 00329 return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize)); 00330 } 00331 00337 inline uint32 00338 getRawTimestamp() const 00339 { return ntohl(getHeader()->timestamp); } 00340 00341 inline void 00342 setbuffer(const void* src, size_t len, size_t pos) 00343 { memcpy(buffer + pos,src,len); } 00344 00346 uint16 cachedSeqNum; 00348 uint32 cachedTimestamp; 00349 00356 uint32 srtpDataOffset; 00357 00363 int32 srtpLength; 00364 00366 uint32 total; 00367 00369 uint32 payloadSize; 00370 00371 private: 00373 unsigned char* buffer; 00375 uint32 hdrSize; 00377 bool duplicated; 00378 00379 #ifdef CCXX_PACKED 00380 #pragma pack(1) 00381 #endif 00382 00392 struct RTPFixedHeader 00393 { 00394 #if __BYTE_ORDER == __BIG_ENDIAN 00395 00396 unsigned char version:2; 00397 unsigned char padding:1; 00398 unsigned char extension:1; 00399 unsigned char cc:4; 00400 unsigned char marker:1; 00401 unsigned char payload:7; 00402 #else 00403 00404 unsigned char cc:4; 00405 unsigned char extension:1; 00406 unsigned char padding:1; 00407 unsigned char version:2; 00408 unsigned char payload:7; 00409 unsigned char marker:1; 00410 #endif 00411 uint16 sequence; 00412 uint32 timestamp; 00413 uint32 sources[1]; 00414 }; 00415 00424 public: 00425 struct RFC2833Payload 00426 { 00427 #if __BYTE_ORDER == __BIG_ENDIAN 00428 uint8 event : 8; 00429 bool ebit : 1; 00430 bool rbit : 1; 00431 uint8 vol : 6; 00432 uint16 duration : 16; 00433 #else 00434 uint8 event : 8; 00435 uint8 vol : 6; 00436 bool rbit : 1; 00437 bool ebit : 1; 00438 uint16 duration : 16; 00439 #endif 00440 }; 00441 00442 private: 00450 struct RTPHeaderExt 00451 { 00452 uint16 undefined; 00453 uint16 length; 00454 }; 00455 #ifdef CCXX_PACKED 00456 #pragma pack() 00457 #endif 00458 00459 /* definitions for access to most common 2833 fields... */ 00460 00461 public: 00467 inline struct RFC2833Payload *getRaw2833Payload(void) 00468 {return (struct RFC2833Payload *)getPayload();} 00469 00475 inline uint16 get2833Duration(void) 00476 {return ntohs(getRaw2833Payload()->duration);} 00477 00483 inline void set2833Duration(uint16 timestamp) 00484 {getRaw2833Payload()->duration = htons(timestamp);} 00485 }; 00486 00497 class __EXPORT OutgoingRTPPkt : public RTPPacket 00498 { 00499 public: 00526 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc, 00527 const unsigned char* const hdrext, uint32 hdrextlen, 00528 const unsigned char* const data, size_t datalen, 00529 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00530 00551 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc, 00552 const unsigned char* const data, size_t datalen, 00553 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00554 00571 OutgoingRTPPkt(const unsigned char* const data, size_t datalen, 00572 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00573 00574 ~OutgoingRTPPkt() 00575 { } 00576 00580 inline void 00581 setPayloadType(PayloadType pt) 00582 { getHeader()->payload = pt; } 00583 00589 inline void 00590 setSeqNum(uint16 seq) 00591 { 00592 cachedSeqNum = seq; 00593 getHeader()->sequence = htons(seq); 00594 } 00595 00599 inline void 00600 setTimestamp(uint32 pts) 00601 { 00602 cachedTimestamp = pts; 00603 getHeader()->timestamp = htonl(pts); 00604 } 00605 00612 inline void 00613 setSSRC(uint32 ssrc) const 00614 { getHeader()->sources[0] = htonl(ssrc); } 00615 00623 inline void 00624 setSSRCNetwork(uint32 ssrc) const 00625 { getHeader()->sources[0] = ssrc; } 00626 00634 inline void 00635 setMarker(bool mark) 00636 { getHeader()->marker = mark; } 00637 00644 void protect(uint32 ssrc, CryptoContext* pcc); 00645 00649 inline bool 00650 operator==(const OutgoingRTPPkt &p) const 00651 { return ( this->getSeqNum() == p.getSeqNum() ); } 00652 00656 inline bool 00657 operator!=(const OutgoingRTPPkt &p) const 00658 { return ( this->getSeqNum() != p.getSeqNum() ); } 00659 00660 private: 00665 OutgoingRTPPkt(const OutgoingRTPPkt &o); 00666 00671 OutgoingRTPPkt& 00672 operator=(const OutgoingRTPPkt &o); 00673 00678 void setCSRCArray(const uint32* const csrcs, uint16 numcsrc); 00679 00680 }; 00681 00694 class __EXPORT IncomingRTPPkt : public RTPPacket 00695 { 00696 public: 00709 IncomingRTPPkt(const unsigned char* block, size_t len); 00710 00711 ~IncomingRTPPkt() 00712 { } 00713 00719 inline bool 00720 isHeaderValid() 00721 { return headerValid; } 00722 00729 inline uint32 00730 getSSRC() const 00731 { return cachedSSRC; } 00732 00743 int32 00744 unprotect(CryptoContext* pcc); 00745 00750 inline bool 00751 operator==(const IncomingRTPPkt &p) const 00752 { return ( (this->getSeqNum() == p.getSeqNum()) && 00753 (this->getSSRC() == p.getSSRC()) ); } 00754 00759 inline bool 00760 operator!=(const IncomingRTPPkt &p) const 00761 { return !( *this == p ); } 00762 00763 private: 00768 IncomingRTPPkt(const IncomingRTPPkt &ip); 00769 00774 IncomingRTPPkt& 00775 operator=(const IncomingRTPPkt &ip); 00776 00778 bool headerValid; 00780 uint32 cachedSSRC; 00781 // Masks for RTP header validation: types matching RTCP SR or 00782 // RR must be rejected to avoid accepting misaddressed RTCP 00783 // packets. 00784 static const uint16 RTP_INVALID_PT_MASK; 00785 static const uint16 RTP_INVALID_PT_VALUE; 00786 }; 00787 // rtppacket 00789 00790 #ifdef CCXX_NAMESPACES 00791 } 00792 #endif 00793 00794 #endif // ndef CCXX_RTP_RTPPKT_H_ 00795