ccRTP
rtppkt.h
Go to the documentation of this file.
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