ccRTP
rtppkt.h
Go to the documentation of this file.
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 NAMESPACE_COMMONCPP
00046 
00071 class CryptoContext;
00072 
00073 class  __EXPORT RTPPacket
00074 {
00075 private:
00076     struct RTPFixedHeader;
00077     struct RTPHeaderExt;
00078 
00079 public:
00092     RTPPacket(const unsigned char* const block, size_t len,
00093           bool duplicate = false);
00094 
00106         RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen, CryptoContext* pcc= NULL);
00107 
00114     inline uint32
00115     getHeaderSize() const
00116     { return hdrSize; }
00117 
00121     inline const uint8* const
00122     getPayload() const
00123     { return (uint8*)(buffer + getHeaderSize()); }
00124 
00128     inline uint32
00129     getPayloadSize() const
00130     { return payloadSize; }
00131 
00135     inline PayloadType
00136     getPayloadType() const
00137     { return static_cast<PayloadType>(getHeader()->payload); }
00138 
00142     inline uint16
00143     getSeqNum() const
00144     { return cachedSeqNum; }
00145 
00149     inline uint32
00150     getTimestamp() const
00151     { return cachedTimestamp; }
00152 
00156     inline uint8
00157     getProtocolVersion() const
00158     { return getHeader()->version; }
00159 
00164     inline bool
00165     isPadded() const
00166     { return getHeader()->padding; }
00167 
00174     inline uint8
00175     getPaddingSize() const
00176     { return buffer[total - 1]; }
00177 
00184     inline bool
00185     isMarked() const
00186     { return getHeader()->marker; }
00187 
00193     inline bool
00194     isExtended() const
00195     { return getHeader()->extension; }
00196 
00201     inline uint16
00202     getCSRCsCount() const
00203     { return getHeader()->cc; }
00204 
00212     inline const uint32*
00213     getCSRCs() const
00214     { return static_cast<const uint32*>(&(getHeader()->sources[1])); }
00215 
00228     inline uint16
00229     getHdrExtUndefined() const
00230     { return (isExtended()? getHeaderExt()->undefined : 0); }
00231 
00243     inline uint32
00244     getHdrExtSize() const
00245     { return (isExtended()?
00246           (static_cast<uint32>(ntohs(getHeaderExt()->length)) << 2) :
00247           0); }
00248 
00255     inline const unsigned char*
00256     getHdrExtContent() const
00257     { return (isExtended() ?
00258           (reinterpret_cast<const unsigned char*>(getHeaderExt()) +
00259            sizeof(RTPHeaderExt)) :
00260           NULL); }
00261 
00268     inline const unsigned char* const
00269     getRawPacket() const
00270     { return buffer; }
00271 
00278     inline uint32
00279     getRawPacketSize() const
00280     { return total; }
00281 
00282         inline uint32
00283         getRawPacketSizeSrtp() const
00284         { return total + srtpLength; }
00285 
00286         inline size_t
00287     getSizeOfFixedHeader() const
00288     { return sizeof(RTPFixedHeader); }
00289 
00301     void reComputePayLength(bool padding);
00302 
00303 protected:
00307     inline virtual ~RTPPacket()
00308     { endPacket(); }
00309 
00313     void
00314     endPacket();
00315 
00321     inline RTPFixedHeader*
00322     getHeader() const
00323     { return reinterpret_cast<RTPFixedHeader*>(buffer); }
00324 
00325     inline void
00326     setExtension(bool e)
00327     { getHeader()->extension = e; }
00328 
00336     inline const RTPHeaderExt*
00337     getHeaderExt() const
00338     {
00339          uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2);
00340      return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize));
00341     }
00342 
00348     inline uint32
00349     getRawTimestamp() const
00350     { return ntohl(getHeader()->timestamp); }
00351 
00352     inline void
00353     setbuffer(const void* src, size_t len, size_t pos)
00354     { memcpy(buffer + pos,src,len); }
00355 
00357     uint16 cachedSeqNum;
00359     uint32 cachedTimestamp;
00360 
00367         uint32 srtpDataOffset;
00368 
00374         int32 srtpLength;
00375 
00377         uint32 total;
00378 
00380         uint32 payloadSize;
00381 
00382 private:
00384     unsigned char* buffer;
00386     uint32 hdrSize;
00388     bool duplicated;
00389 
00390 #ifdef  CCXX_PACKED
00391 #pragma pack(1)
00392 #endif
00393 
00403     struct RTPFixedHeader
00404     {
00405 #if __BYTE_ORDER == __BIG_ENDIAN
00406 
00407         unsigned char version:2;       
00408         unsigned char padding:1;       
00409         unsigned char extension:1;     
00410         unsigned char cc:4;            
00411         unsigned char marker:1;        
00412         unsigned char payload:7;       
00413 #else
00414 
00415         unsigned char cc:4;            
00416         unsigned char extension:1;     
00417         unsigned char padding:1;       
00418         unsigned char version:2;       
00419         unsigned char payload:7;       
00420         unsigned char marker:1;        
00421 #endif
00422         uint16 sequence;        
00423         uint32 timestamp;       
00424         uint32 sources[1];      
00425     };
00426 
00435 public:
00436     struct RFC2833Payload
00437     {
00438 #if __BYTE_ORDER == __BIG_ENDIAN
00439             uint8 event : 8;
00440             bool ebit : 1;
00441             bool rbit : 1;
00442             uint8 vol : 6;
00443             uint16 duration : 16;
00444 #else
00445             uint8 event : 8;
00446             uint8 vol : 6;
00447             bool rbit : 1;
00448             bool ebit : 1;
00449             uint16 duration : 16;
00450 #endif
00451     };
00452 
00453 private:
00461     struct RTPHeaderExt
00462     {
00463         uint16 undefined; 
00464         uint16 length;    
00465     };
00466 #ifdef  CCXX_PACKED
00467 #pragma pack()
00468 #endif
00469 
00470     /* definitions for access to most common 2833 fields... */
00471 
00472 public:
00478     inline struct RFC2833Payload *getRaw2833Payload(void)
00479         {return (struct RFC2833Payload *)getPayload();}
00480 
00486     inline uint16 get2833Duration(void)
00487         {return ntohs(getRaw2833Payload()->duration);}
00488 
00494     inline void set2833Duration(uint16 timestamp)
00495         {getRaw2833Payload()->duration = htons(timestamp);}
00496 };
00497 
00508 class __EXPORT OutgoingRTPPkt : public RTPPacket
00509 {
00510 public:
00537     OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
00538                const unsigned char* const hdrext, uint32 hdrextlen,
00539                const unsigned char* const data, size_t datalen,
00540                        uint8 paddinglen= 0, CryptoContext* pcc= NULL);
00541 
00562     OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
00563                const unsigned char* const data, size_t datalen,
00564                        uint8 paddinglen= 0, CryptoContext* pcc= NULL);
00565 
00582     OutgoingRTPPkt(const unsigned char* const data, size_t datalen,
00583                        uint8 paddinglen= 0, CryptoContext* pcc= NULL);
00584 
00585     ~OutgoingRTPPkt()
00586     { }
00587 
00591     inline void
00592     setPayloadType(PayloadType pt)
00593     { getHeader()->payload = pt; }
00594 
00600     inline void
00601     setSeqNum(uint16 seq)
00602     {
00603         cachedSeqNum = seq;
00604         getHeader()->sequence = htons(seq);
00605     }
00606 
00610     inline void
00611     setTimestamp(uint32 pts)
00612     {
00613         cachedTimestamp = pts;
00614         getHeader()->timestamp = htonl(pts);
00615     }
00616 
00623     inline void
00624     setSSRC(uint32 ssrc) const
00625     { getHeader()->sources[0] = htonl(ssrc); }
00626 
00634     inline void
00635     setSSRCNetwork(uint32 ssrc) const
00636     { getHeader()->sources[0] = ssrc; }
00637 
00645     inline void
00646     setMarker(bool mark)
00647     { getHeader()->marker = mark; }
00648 
00655         void protect(uint32 ssrc, CryptoContext* pcc);
00656 
00660     inline bool
00661     operator==(const OutgoingRTPPkt &p) const
00662     { return ( this->getSeqNum() == p.getSeqNum() ); }
00663 
00667     inline bool
00668     operator!=(const OutgoingRTPPkt &p) const
00669     { return ( this->getSeqNum() != p.getSeqNum() ); }
00670 
00671 private:
00676     OutgoingRTPPkt(const OutgoingRTPPkt &o);
00677 
00682     OutgoingRTPPkt&
00683     operator=(const OutgoingRTPPkt &o);
00684 
00689     void setCSRCArray(const uint32* const csrcs, uint16 numcsrc);
00690 
00691 };
00692 
00705 class __EXPORT IncomingRTPPkt : public RTPPacket
00706 {
00707 public:
00720     IncomingRTPPkt(const unsigned char* block, size_t len);
00721 
00722     ~IncomingRTPPkt()
00723     { }
00724 
00730     inline bool
00731     isHeaderValid()
00732     { return headerValid; }
00733 
00740     inline uint32
00741     getSSRC() const
00742     { return cachedSSRC; }
00743 
00754         int32
00755         unprotect(CryptoContext* pcc);
00756 
00761     inline bool
00762     operator==(const IncomingRTPPkt &p) const
00763     { return ( (this->getSeqNum() == p.getSeqNum()) &&
00764            (this->getSSRC() == p.getSSRC()) ); }
00765 
00770     inline bool
00771     operator!=(const IncomingRTPPkt &p) const
00772     { return !( *this == p ); }
00773 
00774 private:
00779     IncomingRTPPkt(const IncomingRTPPkt &ip);
00780 
00785     IncomingRTPPkt&
00786     operator=(const IncomingRTPPkt &ip);
00787 
00789     bool headerValid;
00791     uint32 cachedSSRC;
00792     // Masks for RTP header validation: types matching RTCP SR or
00793     // RR must be rejected to avoid accepting misaddressed RTCP
00794     // packets.
00795     static const uint16 RTP_INVALID_PT_MASK;
00796     static const uint16 RTP_INVALID_PT_VALUE;
00797 };
00798  // rtppacket
00800 
00801 END_NAMESPACE
00802 
00803 #endif  // ndef CCXX_RTP_RTPPKT_H_
00804