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 00303 void reComputePayLength(bool padding); 00304 00305 protected: 00309 inline virtual ~RTPPacket() 00310 { endPacket(); } 00311 00315 void 00316 endPacket(); 00317 00323 inline RTPFixedHeader* 00324 getHeader() const 00325 { return reinterpret_cast<RTPFixedHeader*>(buffer); } 00326 00327 inline void 00328 setExtension(bool e) 00329 { getHeader()->extension = e; } 00330 00338 inline const RTPHeaderExt* 00339 getHeaderExt() const 00340 { 00341 uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2); 00342 return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize)); 00343 } 00344 00350 inline uint32 00351 getRawTimestamp() const 00352 { return ntohl(getHeader()->timestamp); } 00353 00354 inline void 00355 setbuffer(const void* src, size_t len, size_t pos) 00356 { memcpy(buffer + pos,src,len); } 00357 00359 uint16 cachedSeqNum; 00361 uint32 cachedTimestamp; 00362 00369 uint32 srtpDataOffset; 00370 00376 int32 srtpLength; 00377 00379 uint32 total; 00380 00382 uint32 payloadSize; 00383 00384 private: 00386 unsigned char* buffer; 00388 uint32 hdrSize; 00390 bool duplicated; 00391 00392 #ifdef CCXX_PACKED 00393 #pragma pack(1) 00394 #endif 00395 00405 struct RTPFixedHeader 00406 { 00407 #if __BYTE_ORDER == __BIG_ENDIAN 00408 00409 unsigned char version:2; 00410 unsigned char padding:1; 00411 unsigned char extension:1; 00412 unsigned char cc:4; 00413 unsigned char marker:1; 00414 unsigned char payload:7; 00415 #else 00416 00417 unsigned char cc:4; 00418 unsigned char extension:1; 00419 unsigned char padding:1; 00420 unsigned char version:2; 00421 unsigned char payload:7; 00422 unsigned char marker:1; 00423 #endif 00424 uint16 sequence; 00425 uint32 timestamp; 00426 uint32 sources[1]; 00427 }; 00428 00437 public: 00438 struct RFC2833Payload 00439 { 00440 #if __BYTE_ORDER == __BIG_ENDIAN 00441 uint8 event : 8; 00442 bool ebit : 1; 00443 bool rbit : 1; 00444 uint8 vol : 6; 00445 uint16 duration : 16; 00446 #else 00447 uint8 event : 8; 00448 uint8 vol : 6; 00449 bool rbit : 1; 00450 bool ebit : 1; 00451 uint16 duration : 16; 00452 #endif 00453 }; 00454 00455 private: 00463 struct RTPHeaderExt 00464 { 00465 uint16 undefined; 00466 uint16 length; 00467 }; 00468 #ifdef CCXX_PACKED 00469 #pragma pack() 00470 #endif 00471 00472 /* definitions for access to most common 2833 fields... */ 00473 00474 public: 00480 inline struct RFC2833Payload *getRaw2833Payload(void) 00481 {return (struct RFC2833Payload *)getPayload();} 00482 00488 inline uint16 get2833Duration(void) 00489 {return ntohs(getRaw2833Payload()->duration);} 00490 00496 inline void set2833Duration(uint16 timestamp) 00497 {getRaw2833Payload()->duration = htons(timestamp);} 00498 }; 00499 00510 class __EXPORT OutgoingRTPPkt : public RTPPacket 00511 { 00512 public: 00539 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc, 00540 const unsigned char* const hdrext, uint32 hdrextlen, 00541 const unsigned char* const data, size_t datalen, 00542 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00543 00564 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc, 00565 const unsigned char* const data, size_t datalen, 00566 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00567 00584 OutgoingRTPPkt(const unsigned char* const data, size_t datalen, 00585 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00586 00587 ~OutgoingRTPPkt() 00588 { } 00589 00593 inline void 00594 setPayloadType(PayloadType pt) 00595 { getHeader()->payload = pt; } 00596 00602 inline void 00603 setSeqNum(uint16 seq) 00604 { 00605 cachedSeqNum = seq; 00606 getHeader()->sequence = htons(seq); 00607 } 00608 00612 inline void 00613 setTimestamp(uint32 pts) 00614 { 00615 cachedTimestamp = pts; 00616 getHeader()->timestamp = htonl(pts); 00617 } 00618 00625 inline void 00626 setSSRC(uint32 ssrc) const 00627 { getHeader()->sources[0] = htonl(ssrc); } 00628 00636 inline void 00637 setSSRCNetwork(uint32 ssrc) const 00638 { getHeader()->sources[0] = ssrc; } 00639 00647 inline void 00648 setMarker(bool mark) 00649 { getHeader()->marker = mark; } 00650 00657 void protect(uint32 ssrc, CryptoContext* pcc); 00658 00662 inline bool 00663 operator==(const OutgoingRTPPkt &p) const 00664 { return ( this->getSeqNum() == p.getSeqNum() ); } 00665 00669 inline bool 00670 operator!=(const OutgoingRTPPkt &p) const 00671 { return ( this->getSeqNum() != p.getSeqNum() ); } 00672 00673 private: 00678 OutgoingRTPPkt(const OutgoingRTPPkt &o); 00679 00684 OutgoingRTPPkt& 00685 operator=(const OutgoingRTPPkt &o); 00686 00691 void setCSRCArray(const uint32* const csrcs, uint16 numcsrc); 00692 00693 }; 00694 00707 class __EXPORT IncomingRTPPkt : public RTPPacket 00708 { 00709 public: 00722 IncomingRTPPkt(const unsigned char* block, size_t len); 00723 00724 ~IncomingRTPPkt() 00725 { } 00726 00732 inline bool 00733 isHeaderValid() 00734 { return headerValid; } 00735 00742 inline uint32 00743 getSSRC() const 00744 { return cachedSSRC; } 00745 00756 int32 00757 unprotect(CryptoContext* pcc); 00758 00763 inline bool 00764 operator==(const IncomingRTPPkt &p) const 00765 { return ( (this->getSeqNum() == p.getSeqNum()) && 00766 (this->getSSRC() == p.getSSRC()) ); } 00767 00772 inline bool 00773 operator!=(const IncomingRTPPkt &p) const 00774 { return !( *this == p ); } 00775 00776 private: 00781 IncomingRTPPkt(const IncomingRTPPkt &ip); 00782 00787 IncomingRTPPkt& 00788 operator=(const IncomingRTPPkt &ip); 00789 00791 bool headerValid; 00793 uint32 cachedSSRC; 00794 // Masks for RTP header validation: types matching RTCP SR or 00795 // RR must be rejected to avoid accepting misaddressed RTCP 00796 // packets. 00797 static const uint16 RTP_INVALID_PT_MASK; 00798 static const uint16 RTP_INVALID_PT_VALUE; 00799 }; 00800 // rtppacket 00802 00803 #ifdef CCXX_NAMESPACES 00804 } 00805 #endif 00806 00807 #endif // ndef CCXX_RTP_RTPPKT_H_ 00808