ccRTP
|
00001 // Copyright (C) 2002-2015 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 Lesser General Public License 00014 // along with GNU ccRTP. If not, see <http://www.gnu.org/licenses/>. 00015 // 00016 // As a special exception, you may use this file as part of a free software 00017 // library without restriction. Specifically, if other files instantiate 00018 // templates or use macros or inline functions from this file, or you compile 00019 // this file and link it with other files to produce an executable, this 00020 // file does not by itself cause the resulting executable to be covered by 00021 // the GNU General Public License. This exception does not however 00022 // invalidate any other reasons why the executable file might be covered by 00023 // the GNU General Public License. 00024 // 00025 // This exception applies only to the code released under the name GNU 00026 // ccRTP. If you copy code from other releases into a copy of GNU 00027 // ccRTP, as the General Public License permits, the exception does 00028 // not apply to the code that you add in this way. To avoid misleading 00029 // anyone as to the status of such modified files, you must delete 00030 // this exception notice from them. 00031 // 00032 // If you write modifications of your own for GNU ccRTP, it is your choice 00033 // whether to permit this exception to apply to your modifications. 00034 // If you do not wish that, delete this exception notice. 00035 // 00036 00037 #ifndef CCXX_RTP_RTPPKT_H_ 00038 #define CCXX_RTP_RTPPKT_H_ 00039 00040 #include <ccrtp/base.h> 00041 #include <ccrtp/formats.h> 00042 #include <ccrtp/CryptoContext.h> 00043 00044 NAMESPACE_COMMONCPP 00045 00070 class CryptoContext; 00071 00072 class __EXPORT RTPPacket 00073 { 00074 private: 00075 struct RTPFixedHeader; 00076 struct RTPHeaderExt; 00077 00078 public: 00091 RTPPacket(const unsigned char* const block, size_t len, 00092 bool duplicate = false); 00093 00105 RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen, CryptoContext* pcc= NULL); 00106 00113 inline uint32 00114 getHeaderSize() const 00115 { return hdrSize; } 00116 00120 inline const uint8* const 00121 getPayload() const 00122 { return (uint8*)(buffer + getHeaderSize()); } 00123 00127 inline uint32 00128 getPayloadSize() const 00129 { return payloadSize; } 00130 00134 inline PayloadType 00135 getPayloadType() const 00136 { return static_cast<PayloadType>(getHeader()->payload); } 00137 00141 inline uint16 00142 getSeqNum() const 00143 { return cachedSeqNum; } 00144 00148 inline uint32 00149 getTimestamp() const 00150 { return cachedTimestamp; } 00151 00155 inline uint8 00156 getProtocolVersion() const 00157 { return getHeader()->version; } 00158 00163 inline bool 00164 isPadded() const 00165 { return getHeader()->padding; } 00166 00173 inline uint8 00174 getPaddingSize() const 00175 { return buffer[total - 1]; } 00176 00183 inline bool 00184 isMarked() const 00185 { return getHeader()->marker; } 00186 00192 inline bool 00193 isExtended() const 00194 { return getHeader()->extension; } 00195 00200 inline uint16 00201 getCSRCsCount() const 00202 { return getHeader()->cc; } 00203 00211 inline const uint32* 00212 getCSRCs() const 00213 { return static_cast<const uint32*>(&(getHeader()->sources[1])); } 00214 00227 inline uint16 00228 getHdrExtUndefined() const 00229 { return (isExtended()? getHeaderExt()->undefined : 0); } 00230 00242 inline uint32 00243 getHdrExtSize() const 00244 { return (isExtended()? 00245 (static_cast<uint32>(ntohs(getHeaderExt()->length)) << 2) : 00246 0); } 00247 00254 inline const unsigned char* 00255 getHdrExtContent() const 00256 { return (isExtended() ? 00257 (reinterpret_cast<const unsigned char*>(getHeaderExt()) + 00258 sizeof(RTPHeaderExt)) : 00259 NULL); } 00260 00267 inline const unsigned char* const 00268 getRawPacket() const 00269 { return buffer; } 00270 00277 inline uint32 00278 getRawPacketSize() const 00279 { return total; } 00280 00281 inline uint32 00282 getRawPacketSizeSrtp() const 00283 { return total + srtpLength; } 00284 00285 inline size_t 00286 getSizeOfFixedHeader() const 00287 { return sizeof(RTPFixedHeader); } 00288 00300 void reComputePayLength(bool padding); 00301 00302 protected: 00306 inline virtual ~RTPPacket() 00307 { endPacket(); } 00308 00312 void 00313 endPacket(); 00314 00320 inline RTPFixedHeader* 00321 getHeader() const 00322 { return reinterpret_cast<RTPFixedHeader*>(buffer); } 00323 00324 inline void 00325 setExtension(bool e) 00326 { getHeader()->extension = e; } 00327 00335 inline const RTPHeaderExt* 00336 getHeaderExt() const 00337 { 00338 uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2); 00339 return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize)); 00340 } 00341 00347 inline uint32 00348 getRawTimestamp() const 00349 { return ntohl(getHeader()->timestamp); } 00350 00351 inline void 00352 setbuffer(const void* src, size_t len, size_t pos) 00353 { memcpy(buffer + pos,src,len); } 00354 00356 uint16 cachedSeqNum; 00358 uint32 cachedTimestamp; 00359 00366 uint32 srtpDataOffset; 00367 00373 int32 srtpLength; 00374 00376 uint32 total; 00377 00379 uint32 payloadSize; 00380 00381 private: 00383 unsigned char* buffer; 00385 uint32 hdrSize; 00387 bool duplicated; 00388 00389 #ifdef CCXX_PACKED 00390 #pragma pack(1) 00391 #endif 00392 00402 struct RTPFixedHeader 00403 { 00404 #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN 00405 00406 unsigned char version:2; 00407 unsigned char padding:1; 00408 unsigned char extension:1; 00409 unsigned char cc:4; 00410 unsigned char marker:1; 00411 unsigned char payload:7; 00412 #else 00413 00414 unsigned char cc:4; 00415 unsigned char extension:1; 00416 unsigned char padding:1; 00417 unsigned char version:2; 00418 unsigned char payload:7; 00419 unsigned char marker:1; 00420 #endif 00421 uint16 sequence; 00422 uint32 timestamp; 00423 uint32 sources[1]; 00424 }; 00425 00434 public: 00435 struct RFC2833Payload 00436 { 00437 #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN 00438 uint8 event : 8; 00439 bool ebit : 1; 00440 bool rbit : 1; 00441 uint8 vol : 6; 00442 uint16 duration : 16; 00443 #else 00444 uint8 event : 8; 00445 uint8 vol : 6; 00446 bool rbit : 1; 00447 bool ebit : 1; 00448 uint16 duration : 16; 00449 #endif 00450 }; 00451 00452 private: 00460 struct RTPHeaderExt 00461 { 00462 uint16 undefined; 00463 uint16 length; 00464 }; 00465 #ifdef CCXX_PACKED 00466 #pragma pack() 00467 #endif 00468 00469 /* definitions for access to most common 2833 fields... */ 00470 00471 public: 00477 inline struct RFC2833Payload *getRaw2833Payload(void) 00478 {return (struct RFC2833Payload *)getPayload();} 00479 00485 inline uint16 get2833Duration(void) 00486 {return ntohs(getRaw2833Payload()->duration);} 00487 00493 inline void set2833Duration(uint16 timestamp) 00494 {getRaw2833Payload()->duration = htons(timestamp);} 00495 }; 00496 00507 class __EXPORT OutgoingRTPPkt : public RTPPacket 00508 { 00509 public: 00536 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc, 00537 const unsigned char* const hdrext, uint32 hdrextlen, 00538 const unsigned char* const data, size_t datalen, 00539 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00540 00561 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc, 00562 const unsigned char* const data, size_t datalen, 00563 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00564 00581 OutgoingRTPPkt(const unsigned char* const data, size_t datalen, 00582 uint8 paddinglen= 0, CryptoContext* pcc= NULL); 00583 00584 ~OutgoingRTPPkt() 00585 { } 00586 00590 inline void 00591 setPayloadType(PayloadType pt) 00592 { getHeader()->payload = pt; } 00593 00599 inline void 00600 setSeqNum(uint16 seq) 00601 { 00602 cachedSeqNum = seq; 00603 getHeader()->sequence = htons(seq); 00604 } 00605 00609 inline void 00610 setTimestamp(uint32 pts) 00611 { 00612 cachedTimestamp = pts; 00613 getHeader()->timestamp = htonl(pts); 00614 } 00615 00622 inline void 00623 setSSRC(uint32 ssrc) const 00624 { getHeader()->sources[0] = htonl(ssrc); } 00625 00633 inline void 00634 setSSRCNetwork(uint32 ssrc) const 00635 { getHeader()->sources[0] = ssrc; } 00636 00644 inline void 00645 setMarker(bool mark) 00646 { getHeader()->marker = mark; } 00647 00654 void protect(uint32 ssrc, CryptoContext* pcc); 00655 00659 inline bool 00660 operator==(const OutgoingRTPPkt &p) const 00661 { return ( this->getSeqNum() == p.getSeqNum() ); } 00662 00666 inline bool 00667 operator!=(const OutgoingRTPPkt &p) const 00668 { return ( this->getSeqNum() != p.getSeqNum() ); } 00669 00670 private: 00675 OutgoingRTPPkt(const OutgoingRTPPkt &o); 00676 00681 OutgoingRTPPkt& 00682 operator=(const OutgoingRTPPkt &o); 00683 00688 void setCSRCArray(const uint32* const csrcs, uint16 numcsrc); 00689 00690 }; 00691 00704 class __EXPORT IncomingRTPPkt : public RTPPacket 00705 { 00706 public: 00719 IncomingRTPPkt(const unsigned char* block, size_t len); 00720 00721 ~IncomingRTPPkt() 00722 { } 00723 00729 inline bool 00730 isHeaderValid() 00731 { return headerValid; } 00732 00739 inline uint32 00740 getSSRC() const 00741 { return cachedSSRC; } 00742 00753 int32 00754 unprotect(CryptoContext* pcc); 00755 00760 inline bool 00761 operator==(const IncomingRTPPkt &p) const 00762 { return ( (this->getSeqNum() == p.getSeqNum()) && 00763 (this->getSSRC() == p.getSSRC()) ); } 00764 00769 inline bool 00770 operator!=(const IncomingRTPPkt &p) const 00771 { return !( *this == p ); } 00772 00773 private: 00778 IncomingRTPPkt(const IncomingRTPPkt &ip); 00779 00784 IncomingRTPPkt& 00785 operator=(const IncomingRTPPkt &ip); 00786 00788 bool headerValid; 00790 uint32 cachedSSRC; 00791 // Masks for RTP header validation: types matching RTCP SR or 00792 // RR must be rejected to avoid accepting misaddressed RTCP 00793 // packets. 00794 static const uint16 RTP_INVALID_PT_MASK; 00795 static const uint16 RTP_INVALID_PT_VALUE; 00796 }; 00797 // rtppacket 00799 00800 END_NAMESPACE 00801 00802 #endif // ndef CCXX_RTP_RTPPKT_H_ 00803