00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
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
00782
00783
00784 static const uint16 RTP_INVALID_PT_MASK;
00785 static const uint16 RTP_INVALID_PT_VALUE;
00786 };
00787
00789
00790 #ifdef CCXX_NAMESPACES
00791 }
00792 #endif
00793
00794 #endif // ndef CCXX_RTP_RTPPKT_H_
00795