Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

rtp.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2001 Open Source Telecom Corporation.
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 to the GNU General Public License, permission is 
00018 // granted for additional uses of the text contained in its release 
00019 // of ccRTP.
00020 // 
00021 // The exception is that, if you link the ccRTP library with other
00022 // files to produce an executable, this does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public License.
00024 // Your use of that executable is in no way restricted on account of
00025 // linking the ccRTP library code into it.
00026 // 
00027 // This exception does not however invalidate any other reasons why
00028 // the executable file might be covered by the GNU General Public License.
00029 // 
00030 // This exception applies only to the code released under the 
00031 // name ccRTP.  If you copy code from other releases into a copy of
00032 // ccRTP, as the General Public License permits, the exception does
00033 // not apply to the code that you add in this way.  To avoid misleading
00034 // anyone as to the status of such modified files, you must delete
00035 // this exception notice from them.
00036 // 
00037 // If you write modifications of your own for ccRTP, it is your choice
00038 // whether to permit this exception to apply to your modifications.
00039 // If you do not wish that, delete this exception notice.  
00040 
00047 #ifndef __CCXX_RTP_H__
00048 #define __CCXX_RTP_H__
00049 
00050 #ifndef __CCXX_SOCKET_H__
00051 #include <cc++/socket.h>
00052 #endif
00053 
00054 #ifdef  __NAMESPACES__
00055 namespace ost {
00056 #endif
00057 
00058 // RTP version
00059 const uint8 RTP_VERSION = 2;
00060 
00061 // Time interval expressed in microseconds
00062 typedef uint32 microtimeout_t;
00063 
00064 // Time interval expressed in nanoseconds 
00065 typedef uint32 nanotimeout_t;
00066 
00067 struct RTCPPacket;
00068 struct SenderInfo;
00069 struct ReceiverInfo;
00070 
00083 typedef enum
00084 {
00085         RTP_PAYLOAD_PCMU = 0,   
00086         RTP_PAYLOAD_1016,       
00087         RTP_PAYLOAD_G726,       
00088         RTP_PAYLOAD_GSM,        
00089         RTP_PAYLOAD_G723,       
00090         RTP_PAYLOAD_DVI4_8000,  
00091         RTP_PAYLOAD_DVI4_16000, 
00092         RTP_PAYLOAD_LPC,        
00093         RTP_PAYLOAD_PCMA,       
00094         RTP_PAYLOAD_G722,       
00095         RTP_PAYLOAD_L16_DUAL,   
00096         RTP_PAYLOAD_L16_MONO,   
00097         RTP_PAYLOAD_QCELP,      
00098         RTP_PAYLOAD_MPA = 14,   
00099         RTP_PAYLOAD_G728,       
00100         RTP_PAYLOAD_DVI4_11025, 
00101         RTP_PAYLOAD_DVI4_22050, 
00102         RTP_PAYLOAD_G729,       
00103         RTP_PAYLOAD_CELB = 25,  
00104         RTP_PAYLOAD_JPEG,       
00105         RTP_PAYLOAD_NV = 28,    
00106         RTP_PAYLOAD_H261 = 31,  
00107         RTP_PAYLOAD_MPV,        
00108         RTP_PAYLOAD_MP2T,       
00109         RTP_PAYLOAD_H263,       
00110         RTP_PAYLOAD_INVALID = 128,
00111         // the payload types defined down here are allocated dynamically.
00112         RTP_PAYLOAD_G726_40,
00113         RTP_PAYLOAD_G726_24,
00114         RTP_PAYLOAD_G726_16,
00115         RTP_PAYLOAD_G729D,
00116         RTP_PAYLOAD_G729E,
00117         RTP_PAYLOAD_GSM_EFR,
00118         RTP_PAYLOAD_L8,
00119         RTP_PAYLOAD_RED,
00120         RTP_PAYLOAD_VDVI,
00121         RTP_PAYLOAD_BT656,      
00122         RTP_PAYLOAD_H263_1998,  
00123         RTP_PAYLOAD_MP1S,       
00124         RTP_PAYLOAD_MP2P,       
00125         RTP_PAYLOAD_BMPEG,      
00126         RTP_PAYLOAD_EMPTY       
00127 }       rtp_payload_t;
00128 
00134 typedef enum
00135 {
00136         RTCP_TYPE_SR = 200,             
00137         RTCP_TYPE_RR,                   
00138         RTCP_TYPE_SDES,                 
00139         RTCP_TYPE_BYE,                  
00140         RTCP_TYPE_APP                   
00141 }       rtcp_type_t;
00142 
00150 typedef enum
00151 {
00152         RTCP_SDES_ITEM_END = 0,         
00153         RTCP_SDES_ITEM_CNAME,           
00154         RTCP_SDES_ITEM_NAME,            
00155         RTCP_SDES_ITEM_EMAIL,           
00156         RTCP_SDES_ITEM_PHONE,           
00157         RTCP_SDES_ITEM_LOC,             
00158         RTCP_SDES_ITEM_TOOL,            
00159         RTCP_SDES_ITEM_NOTE,            
00160         RTCP_SDES_ITEM_PRIV,            
00161         RTCP_SDES_ITEM_H323_CADDR,      
00162 }       sdes_item_type_t;
00163 
00182 typedef enum
00183 {
00184         BEST_EFFORT_SERVICE,     
00185         ENHANCED_SERVICE         
00186 }       type_of_service_t;
00187 
00196 typedef enum
00197 {
00198         RTP_PURGE_SEND,        
00199         RTP_PURGE_RECV,        
00200         RTP_PURGE_BOTH         
00201 }       rtp_purge_t;
00202 
00203 typedef enum {
00204         CAST_MCAST,
00205         CAST_UCAST
00206 }       rtp_cast_t;
00207 
00208 class CCXX_CLASS_EXPORT IncomingRTPPkt;
00209 class CCXX_CLASS_EXPORT OutgoingRTPPkt;
00210 class CCXX_CLASS_EXPORT RTPQueue;
00211 class CCXX_CLASS_EXPORT QueueRTCPManager;
00212 class CCXX_CLASS_EXPORT RTPSource;
00213 
00226 class CCXX_CLASS_EXPORT RTPData
00227 {
00228 
00229 public:
00233         RTPData(const RTPData& origin);
00234 
00241         RTPData&
00242         operator=(const RTPData& source);
00243 
00244         inline const unsigned char*
00245         getData() const
00246         { return datablock->data; };
00247 
00248         inline size_t
00249         getSize() const
00250         { return datablock->size; };
00251 
00252         inline rtp_payload_t
00253         getPayloadType() const
00254         { return datablock->pt; }
00255 
00256 protected:
00257 
00258         RTPData(IncomingRTPPkt& packet);
00259 
00260         ~RTPData();
00261 
00262 private:
00263         // dataCounter holds the reference counter
00264         struct dataCounter {
00265                 uint16 count;
00266                 const unsigned char* data;
00267                 const size_t size;
00268                 rtp_payload_t pt;
00269                 dataCounter(const unsigned char* data, size_t size, rtp_payload_t pt);
00270                 ~dataCounter();
00271         };
00272 
00273         mutable dataCounter* datablock;
00274 
00275 
00276 
00277         // Who sent this data
00278         RTPSource* src;
00279 
00280         friend RTPQueue;
00281 };
00282 
00298 class CCXX_CLASS_EXPORT RTPSource
00299 {
00300 
00301 public:
00302         uint32 getID() const
00303         { return ssrc; };
00304 
00310         uint32 
00311         getRate() const;
00312 
00326         inline void
00327         setKitchenSize(microtimeout_t s)
00328         { kitchensize = ((s / 1000) * getRate() / 1000); };
00329          
00335         inline microtimeout_t
00336         getKitchenDuration() const
00337         { return (((kitchensize * 1000) / getRate())* 1000); };
00338 
00339         inline uint32
00340         getKitchenSize() const
00341         { return kitchensize; };
00342 
00351         inline microtimeout_t
00352         getCurrentKitchenDuration()
00353         { return (((currentkitchen * 1000) / getRate())* 1000); };
00354 
00355         inline microtimeout_t
00356         getCurrentKitchenSize()
00357         { return currentkitchen;};
00358 
00359         const char* const
00360         getSDESItem(sdes_item_type_t type) const;
00361         
00362         inline const char* const 
00363         getCNAME() const
00364         { return getSDESItem(RTCP_SDES_ITEM_CNAME); };
00365 
00366         inline const char* const
00367         getNAME() const
00368         { return getSDESItem(RTCP_SDES_ITEM_NAME); };
00369 
00370         inline const char* const
00371         getEMAIL() const
00372         { return getSDESItem(RTCP_SDES_ITEM_EMAIL); };
00373 
00374         inline const char* const
00375         getPHONE() const
00376         { return getSDESItem(RTCP_SDES_ITEM_PHONE); };
00377 
00378         inline const char* const 
00379         getLOC() const
00380         { return getSDESItem(RTCP_SDES_ITEM_LOC); };
00381 
00382         inline const char* const 
00383         getTOOL() const
00384         { return getSDESItem(RTCP_SDES_ITEM_TOOL); };
00385 
00386         inline const char* const 
00387         getNOTE() const
00388         { return getSDESItem(RTCP_SDES_ITEM_NOTE); };
00389 
00390         inline const char* const 
00391         getPRIV() const
00392         { return getSDESItem(RTCP_SDES_ITEM_PRIV); };
00393 
00394         inline const char* const 
00395         getH323_CADDR() const
00396         { return getSDESItem(RTCP_SDES_ITEM_H323_CADDR); };
00397 
00401         inline bool
00402         isSender() const
00403         { return active_sender; };
00404 
00405         bool isValid() const
00406         { return valid; };
00407 
00408         inline bool
00409         operator==(const RTPSource &rhs) const
00410         { return (this == &rhs); }
00411 
00412         inline bool
00413         operator!=(const RTPSource &rhs) const
00414         { return !(*this == rhs); }
00415 
00419         RTPSource(uint32 ssrc); 
00420 
00424         ~RTPSource();
00425 
00429         RTPSource(const RTPSource& origin);
00430 
00431         RTPSource&
00432         operator=(const RTPSource &origin);
00433 
00434 protected:
00435                 
00436 private:
00444         inline void
00445         setCurrentKitchenSize(uint32 s)
00446         { currentkitchen = s; };
00447 
00451         void endSource();
00452 
00453         void
00454         setSDESItem(sdes_item_type_t item, const char* const value);
00455 
00464         void 
00465         recordReception(IncomingRTPPkt& p);
00466 
00476         void 
00477         recordInsertion(IncomingRTPPkt& p);
00478 
00486         void 
00487         recordExtraction(IncomingRTPPkt& p);
00488 
00492         inline void
00493         setSender(bool active)
00494         { active_sender = active; };
00495 
00501         inline void 
00502         setInitialTimestamp(uint32 ts)
00503         { initial_timestamp = ts; }
00504 
00513         inline uint32 
00514         getInitialTimestamp()
00515         {return initial_timestamp; }
00516 
00523         inline uint16
00524         getExpectedSeqNum()
00525         { return expectedseqnum; }
00526 
00533         inline void
00534         setExpectedSeqNum(uint16 n)
00535         { expectedseqnum = n; }
00536 
00537         // SSRC 32 bit identifier carried in RTP and RTCP packets (in
00538         // network order)
00539         uint32 ssrc;
00540         // timestamp of the first packet received from this source
00541         uint32 initial_timestamp; 
00542         // number of packets received from this source
00543         uint32 packet_count;
00544         // time the last packet was received at
00545         struct timeval last_time;
00546         // required kitchen for this source. Represented as octets,
00547         // given the current transmission rate
00548         uint32 kitchensize;
00549         // current kitchen for this source. Represented as octets,
00550         // given the current transmission rate
00551         uint32 currentkitchen;
00552         // the expected sequence number of the next packet to be received.
00553         uint16 expectedseqnum;  
00554 
00555         // before becoming valid, multiple packets from this source, 
00556         // or an SDES RTCP containing its CNAME should be received.
00557         bool valid; 
00558         // A valid source not always is active
00559         bool active_sender;
00560 
00561         // Sources located before and after this one in the list
00562         // of sources.
00563         RTPSource* prev, * next;
00564         // first/last packets from this source in the queue 
00565         IncomingRTPPkt* first, * last;
00566         // Prev and next inside the collision list
00567         RTPSource* nextcollis;  
00568         // dummy content for undetermined descriptors
00569         static const char* const unknown;
00570         // sender info from the last sender report of this source  
00571         SenderInfo* sender_info;
00572         // dummy content for the last sender info from this source
00573         static const SenderInfo* dummySI;
00574         // last report block this source sent about the local source
00575         ReceiverInfo* receiver_info;
00576         // dummy content for the last report from this source
00577         static const ReceiverInfo* dummyRB;
00578         // Data extracted from the SDES items sent by this source
00579         char **sdes_items;
00580         
00581         friend class MembershipControl;
00582         friend RTPQueue;
00583         friend QueueRTCPManager;
00584         friend IncomingRTPPkt;
00585 };
00586 
00587 // TODO: implement this idea
00588 class CCXX_CLASS_EXPORT Members
00589 {
00590 public:
00591 
00592         Members() :     
00593                 members(static_cast<uint32>(-1)), // -1 to counteract dummysource
00594                 active_senders(0)
00595         { };
00600         inline void
00601         increaseMembersCount()
00602         { members++; };
00603 
00608         inline void
00609         decreaseMembersCount()
00610         { members--; };
00611 
00612         inline void
00613         setMembersCount(uint32 n)
00614         { members = n; };
00615 
00616         inline void
00617         increaseSendersCount()
00618         { active_senders++; };
00619 
00620         inline void
00621         decreaseSendersCount()
00622         { active_senders--; };
00623 
00624         inline void
00625         setSendersCount(uint32 n)
00626         { active_senders = n; };
00627 
00628 
00633         inline uint32 
00634         membersCount() const
00635         { return members; };
00636         
00637         inline uint32
00638         sendersCount() const
00639         { return active_senders; };
00640 
00641 
00642         // number of identified members
00643         uint32 members;
00644         // number of identified members that currently are active senders
00645         uint32 active_senders;
00646 };
00647 
00672 class CCXX_CLASS_EXPORT MembershipControl : public Members
00673 {
00674 public:
00683         inline const RTPSource&
00684         getSource(uint32 ssrc) const
00685         { return const_cast<MembershipControl*>(this)->getSourceBySSRC(ssrc,false); }
00686 
00695         inline const RTPSource&
00696         getOrCreateSource(uint32 ssrc)
00697         { return getSourceBySSRC(ssrc,true); }
00698 
00699 protected:
00705         RTPSource&
00706         addNewSource(uint32 ssrc);
00707 
00721         MembershipControl(uint32 initial_size = 7);
00722 
00728         virtual
00729         ~MembershipControl();
00730 
00735         void
00736         endMembers();
00737 
00747         RTPSource&
00748         getSourceBySSRC(uint32 ssrc, bool create = false);
00749 
00757         bool
00758         removeSource(uint32 ssrc);
00759 
00760         const RTPSource&
00761         NullSource() const
00762         { return dummysource; };
00763 
00764         // an empty RTPSource representing unidentified sources
00765         const static RTPSource dummysource;
00766 
00767 private:
00768 
00769         MembershipControl(const MembershipControl &o);
00770 
00771         MembershipControl&
00772         operator=(const MembershipControl &o);
00773 
00774         // Hash table with sources of RTP and RTCP packets
00775         uint32 SOURCE_BUCKETS; 
00776         RTPSource** sources;
00777         // List of sources, ordered from older to newer
00778         RTPSource* first, * last;
00779 };
00780 
00806 class CCXX_CLASS_EXPORT RTPQueue : protected Thread, protected MembershipControl
00807 {
00808 public:
00814         inline const RTPSource& 
00815         getLocalInfo() const
00816         { return *localsrc; };
00817 
00824         bool 
00825         isWaiting(const RTPSource &src = dummysource) const;
00826 
00835         bool 
00836         isCookedWaiting(void) const;
00837  
00843         bool 
00844         isSending(void) const;
00845 
00860         void 
00861         putPacket(uint32 stamp, rtp_payload_t payload, unsigned char* data = NULL, size_t len = 0, bool mark = false);
00862 
00921         const RTPData&
00922         getCookedPacket(const RTPSource &src = dummysource);
00923 
00930         uint32 
00931         getFirstTimestamp(const RTPSource &src = dummysource);
00932  
00939         uint16 
00940         getFirstSequence(const RTPSource &src = dummysource);
00941 
00949         const RTPData&
00950         getPacket(uint32 stamp, const RTPSource &src = dummysource);
00951 
00963         size_t 
00964         getPacket(uint32 stamp, unsigned char* data, size_t max,
00965                   const RTPSource &src = dummysource);
00966 
00974         rtp_payload_t 
00975         getPayloadType(uint32 timestamp, const RTPSource &src = dummysource);
00976 
01038         uint32 
01039         getCurrentTimestamp(rtp_payload_t pt) const;
01040 
01049         uint32
01050         getTimestampIncrement(size_t packet_size) const;
01051 
01059         void
01060         setSessionBandwidth(uint32 bw)
01061         { sessionbw = bw; };
01062 
01075         uint32 
01076         getRate(rtp_payload_t pt = RTP_PAYLOAD_EMPTY) const;
01077 
01084         rtp_payload_t
01085         getPayloadType(const RTPSource& src) const;
01086 
01095         inline const RTPSource&
01096         getSource(uint32 ssrc) const
01097         { return MembershipControl::getSource(htonl(ssrc)); };
01098 
01111         inline void
01112         setTypeOfService(type_of_service_t tos)
01113         { type_of_service = tos; }
01114  
01125         size_t 
01126         setPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01127 
01139         size_t 
01140         getPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01141 
01147         inline bool 
01148         isActive(void) const
01149         { return active; };
01150 
01157         inline void 
01158         setTimeout(microtimeout_t t)
01159         { timeout = t;};
01160 
01169         inline void 
01170         setExpired(microtimeout_t t)
01171         { expired = t;};
01172 
01196         void
01197         setGlobalKitchenDuration(microtimeout_t t);
01198 
01199         void
01200         setGlobalKitchenSize(uint32 s);
01201 
01210         inline microtimeout_t
01211         getGlobalKitchenDuration() const
01212         { return (((kitchensize * 1000) / getRate())*1000); };
01213         
01228         inline void
01229         setEndToEndDelay(microtimeout_t t)
01230                 { e2edelay = t; };
01231 
01237         inline void 
01238         setSegmentSize(size_t size)
01239                 {segment = size;};
01240 
01251         inline bool 
01252         isComplete(void)
01253                 {return complete;};
01254 
01263         inline bool 
01264         isMarked(void)
01265                 {return marked;};
01266 
01270         inline void 
01271         setTimeclock(void)
01272                 {timeclock.setTimer();};
01273  
01279         inline timeout_t 
01280         getTimeclock(void)
01281                 {return timeclock.getElapsed();};
01282         
01288         inline uint32
01289         RTPSendCount() const
01290         { return sendcount;};
01291 
01298         inline uint32
01299         RTPOctetCount() const
01300         { return octetcount;};
01301 
01302 protected:
01303         
01311         RTPQueue(int pri, uint32 size = 7);
01312 
01329         RTPQueue(uint32 ssrc, int pri, uint32 size = 7);
01330         
01334         virtual 
01335         ~RTPQueue(); 
01336 
01343         virtual inline void 
01344         RTCPService(microtimeout_t& wait)
01345         { return; };
01346 
01350         virtual void 
01351         Bye(const char* const reason)
01352         { return; }
01353 
01357         virtual void timerTick(void)
01358         { return; };
01359 
01369         microtimeout_t
01370         getTimeout(void);
01371 
01379         virtual bool
01380         isPendingData(microtimeout_t timeout) = 0;
01381 
01388         void Purge(rtp_purge_t flag);
01389 
01396         size_t
01397         sendPacket(void);
01398 
01408         virtual size_t
01409         writeData(const unsigned char* const packet, size_t len) = 0;
01410 
01417         size_t
01418         recvPacket(void);
01419 
01429         virtual size_t
01430         readData(unsigned char* buffer, size_t len) = 0;
01431 
01440         virtual bool
01441         gotPacket(IncomingRTPPkt* packet)
01442         { return true; }
01443 
01449         virtual void expireSend(OutgoingRTPPkt *packet)
01450                 {return;};
01451 
01458         virtual void expireRecv(IncomingRTPPkt *packet)
01459                 {return ;};
01460 
01470         IncomingRTPPkt*
01471         getWaiting(uint32 timestamp, const RTPSource &src = dummysource);
01472 
01476         void
01477         endQueue();
01478 
01482         void Final()
01483         { delete this; };
01484 
01485         // true if connection "active"
01486         volatile bool active;       
01487         // Object representing the local source
01488         RTPSource* localsrc;
01489         // when the queue is created
01490         struct timeval initial_time;  
01491         uint32 current_rate;
01492         // ramdonly generated offset for the timestamp of sent packets
01493         uint32 initial_timestamp;
01494 
01495 private:
01496         friend IncomingRTPPkt;
01497 
01498         RTPQueue(const RTPQueue &o);
01499 
01500         RTPQueue&
01501         operator=(const RTPQueue &o);
01502 
01508         void
01509         initQueue(uint32 localssrc);
01510 
01514         void 
01515         Run(void);
01516         
01517 
01523         void 
01524         RTPService(microtimeout_t& wait);
01525         
01534         void 
01535         insertRecvPacket(IncomingRTPPkt *packet);               
01536 
01537         type_of_service_t type_of_service;  
01538         uint32 sessionbw;
01539         rtp_cast_t sessioncast;
01540 
01541         // packet receive workspace size
01542         static const size_t RECVBUFFER_SIZE = 8192;     
01543         // number of packets sent from the beginning
01544         uint32 sendcount;
01545         // number of payload octets sent from the beginning
01546         uint32 octetcount;
01547 
01548         // transmission and reception queues
01549         OutgoingRTPPkt* sendfirst, * sendlast; 
01550         IncomingRTPPkt* recvfirst, * recvlast;
01551         mutable Mutex sendlock, recvlock;
01552         // the sequence number of the next packet to sent
01553         uint16 sendseq;    
01554         // contributing sources
01555         uint32 sendsources[16];
01556         // how many CSRCs to send.
01557         unsigned sendcc;       
01558         // maximum packet size before fragmenting sends.
01559         unsigned segment;      
01560         // bit M in RTP fixed header of the last packet
01561         bool marked;
01562         // whether there was not loss
01563         bool complete;
01564         
01565         TimerPort timeclock;
01566 
01567         // elapsed time accumulated through successive overflows of
01568         // the local timestamp field
01569         struct timeval overflow_time; 
01570 
01571         // transmission scheduling timeout for the service thread
01572         microtimeout_t timeout;
01573         // how old a packet can reach in the sending queue before deletetion
01574         microtimeout_t expired;
01575         
01576         // Maximun delay allowed between packet timestamping and
01577         // packet availability for the application.
01578         microtimeout_t e2edelay;  
01579         // Kitchen (reordering buffer) size in octets, given the
01580         // current transmission rate.
01581         uint32 kitchensize;
01582 
01583         // this is a global table holding the 
01584         // `payload_type <-> timestamp_rate' correpondence for 
01585         // the statically assigned payload types
01586         static uint32 payload_rate[96];
01587 };
01588 
01608 class CCXX_CLASS_EXPORT QueueRTCPManager : public RTPQueue
01609 {
01610 public:
01628         virtual void
01629         setControlBandwidth(float fraction)
01630         { controlbw = fraction; };
01631 
01645         virtual void
01646         setSendersControlFraction(float fraction)
01647         { sendcontrolbw = fraction; recvcontrolbw = 1 - fraction;};
01648 
01654         inline uint32
01655         RTCPSendCount() const
01656         { return ctrlsendcount; }
01657 
01662         void inline
01663         setNAME(const char* const name)
01664         { localsrc->setSDESItem(RTCP_SDES_ITEM_NAME,name); };
01665 
01666         void inline 
01667         setEMAIL(const char* const email)
01668         { localsrc->setSDESItem(RTCP_SDES_ITEM_EMAIL,email); };
01669 
01670         void inline setPHONE(const char* const phone)
01671         { localsrc->setSDESItem(RTCP_SDES_ITEM_PHONE,phone); };
01672 
01673         void inline 
01674         setLOC(const char* const loc) 
01675         { localsrc->setSDESItem(RTCP_SDES_ITEM_LOC,loc); };
01676 
01677         void inline
01678         setTOOL(const char* const tool)
01679         { localsrc->setSDESItem(RTCP_SDES_ITEM_TOOL,tool); };
01680 
01681         void inline 
01682         setNOTE(const char* const note)
01683         { localsrc->setSDESItem(RTCP_SDES_ITEM_NOTE,note); };
01684 
01685         void inline 
01686         setPRIV(const char* const priv)
01687         { localsrc->setSDESItem(RTCP_SDES_ITEM_PRIV,priv); };
01688 
01689         void inline 
01690         setH323_CADDR(const char* const h323ca)
01691         { localsrc->setSDESItem(RTCP_SDES_ITEM_H323_CADDR,h323ca); };
01692 
01693 protected:
01694         QueueRTCPManager(int pri);
01695 
01696         virtual 
01697         ~QueueRTCPManager();
01698 
01699         void
01700         endQueueRTCPManager();
01701 
01707         void 
01708         RTCPService(microtimeout_t& wait);
01709 
01717         void 
01718         Bye(const char* const reason = NULL);
01719 
01723         void 
01724         gotHello(const char* sdes) 
01725         { return; }
01726  
01730         void 
01731         gotGoodbye(void)
01732         { return; }
01733 
01737         void
01738         handleSSRCCollision();
01739 
01752         virtual timeval 
01753         computeRTCPInterval();
01754 
01755 private:
01756         QueueRTCPManager(const QueueRTCPManager &o);
01757 
01758         QueueRTCPManager&
01759         operator=(const QueueRTCPManager &o);
01760 
01764         void 
01765         setSDESItem(sdes_item_type_t type, const char *const value);
01766 
01771         void
01772         findCNAME();
01773 
01778         void
01779         updateAvgRTCPSize(uint16 len);
01780 
01786         void 
01787         ReverseReconsideration();
01788 
01793         bool
01794         TimerReconsideration();
01795 
01803         void 
01804         TimeOutSSRCs();
01805 
01810         bool
01811         getSDES_APP(RTCPPacket &pkt, uint16 &pointer, uint16 len);
01812 
01822         bool
01823         getBYE(RTCPPacket &pkt, uint16 &pointer, uint16 len);
01824 
01828         void
01829         getOnlyBye();
01830 
01842         inline virtual uint16
01843         networkHeaderSize()
01844         { return 20; }
01845 
01857         inline virtual uint16
01858         transportHeaderSize()
01859         { return 8; }
01860 
01866         size_t
01867         sendControl(void);
01868 
01878         void
01879         recvControl(void);
01880 
01887         bool
01888         packReportBlock(uint16& len);
01889 
01905         bool
01906         tryAnotherRR(RTCPPacket*& pkt, uint16& len, uint16& blocks);
01907 
01914         void 
01915         packSDES(uint16& len);
01916 
01917         size_t
01918         sendBYE(const char* const reason);
01919 
01924         virtual size_t 
01925         writeControl(const unsigned char* const buffer, size_t len) = 0;
01926 
01931         virtual size_t 
01932         readControl(unsigned char* buffer, size_t len) = 0;
01933 
01939         virtual bool 
01940         isPendingControl(microtimeout_t timeout) = 0;
01941         
01950         bool
01951         RTCPHeaderCheck(size_t len);
01952 
01953 
01954         // path MTU. RTCP packets should not be greater than this
01955         uint16 pathMTU;
01956 
01957         // buffer to hold RTCP compound packets being sent. Allocated
01958         // at construction time
01959         unsigned char* rtcpsend_buffer;
01960 
01961         // buffer to hold RTCP compound packets being
01962         // received. Allocated at construction time
01963         unsigned char* rtcprecv_buffer;
01964 
01965         // whether the RTCP service is active
01966         bool rtcp_active;
01967 
01968         float controlbw, sendcontrolbw, recvcontrolbw;
01969         // number of RTCP packets sent since the beginning
01970         uint32 ctrlsendcount;
01971 
01972         // Network + transport headers size, typically size of IP +
01973         // UDP headers
01974         uint16 lower_headers_size;
01975         // state for rtcp timing. Its meaning is defined in RFC ????, 6.3
01976         timeval rtcp_tp, rtcp_tc, rtcp_tn;
01977         uint32 rtcp_pmembers;
01978         uint32 rtcp_bw;
01979         bool rtcp_we_sent;      
01980         uint16 rtcp_avg_size;
01981         bool rtcp_initial;
01982         // last time we checked if there were incoming RTCP packets
01983         timeval rtcp_last_check;
01984         // interval to check if there are incoming RTCP packets
01985         timeval rtcp_check_interval;
01986         // next time to check if there are incoming RTCP packets
01987         timeval rtcp_next_check;
01988 
01989         // value of sendcount at the time of the last RTCP packet transmission
01990         uint32 last_sendcount;
01991 
01992         uint32 prev_nvalid_sources;
01993         timeval rtcp_calculated_interval;
01994         
01995         // length of CNAME as user@host
01996         size_t CNAME_len;
01997 
01998         // According to timer reconsideration and reverse reconsideration 
01999         // algorithms, sources do not become valid or deleted as soon as
02000         // they appear or send BYE. 
02001         // number of not yet valid, but noticed sources 
02002         uint32 nprevalid_srcs;
02003         // number of valid sources
02004         uint32 nvalid_srcs;
02005         // number of sources having sent a BYE, but not yet deleted
02006         uint32 npredeleted_srcs;
02007         // number of already deleted sources
02008         uint32 ndeleted_srcs;
02009         // minimum interval for transmission of RTCP packets
02010         microtimeout_t rtcp_min_interval;
02011 
02012         // Nember of seconds ellapsed from 1900 to 1970
02013         const static uint32 NTP_EPOCH_OFFSET = static_cast<uint32>(2208992400u);
02014 
02015         // masks for RTCP header validation
02016 #if     __BYTE_ORDER == __BIG_ENDIAN
02017         static const uint16 RTCP_VALID_MASK = (0xc000 | 0x2000  | 0xfe);
02018         static const uint16 RTCP_VALID_VALUE = ((RTP_VERSION << 14) | 
02019                                                 RTCP_TYPE_SR);
02020 #else
02021         static const uint16 RTCP_VALID_MASK = (0x00c0 | 0x0020 | 0xfe00);
02022         static const uint16 RTCP_VALID_VALUE = ((RTP_VERSION << 6) | 
02023                                                 (RTCP_TYPE_SR << 8));
02024 #endif
02025         static const uint16 TIMEOUT_MULTIPLIER = 5;
02026         static const double RECONSIDERATION_COMPENSATION = 2.718281828 - 1.5;
02027 };
02028 
02041 class CCXX_CLASS_EXPORT UDPIPv4Socket: protected UDPSocket 
02042 {
02043 public:
02050         UDPIPv4Socket(const InetAddress& ia, tpport_t port) : 
02051                 UDPSocket(ia, port) 
02052         { };
02053 
02057         ~UDPIPv4Socket() 
02058         { };
02059 
02066         sockerror_t
02067         Connect(const InetAddress& ia, tpport_t port);
02068         
02072         inline bool 
02073         isPendingPacket(microtimeout_t timeout)
02074         { return isPending(SOCKET_PENDING_INPUT, timeout/1000);};
02075         
02079         inline size_t 
02080         writePacket(const unsigned char* const buffer, size_t len)
02081         {return ::send(so, buffer, len, MSG_DONTWAIT);};
02082 
02086         inline size_t
02087         readPacket(unsigned char *buffer, size_t len)
02088         {return ::read(so, buffer, len);};
02089 
02093         inline sockerror_t 
02094         setMulticast(bool enable)
02095         { return setMulticast(enable); };
02096 
02103         inline sockerror_t
02104         joinGroup(const InetMcastAddress& ia)
02105         { return Join(ia); };
02106 
02113         inline sockerror_t
02114         leaveGroup(const InetMcastAddress& ia)
02115         { return Drop(ia); }; 
02116 
02123         inline sockerror_t
02124         setMcastTTL(uint8 ttl)
02125         { setTimeToLive(ttl); };
02126 
02130         void 
02131         endSocket()
02132         { UDPSocket::endSocket(); };
02133 };
02134 
02147 template <typename serviceQueue, typename dataSocket, typename controlSocket>
02148 class __EXPORT T_RTPSocket  : public serviceQueue
02149 {
02150 public:
02156         T_RTPSocket(const InetAddress& ia, tpport_t port = 5004, int pri = 0) :
02157                 serviceQueue(pri)
02158         {
02159                 base = even_port(port);
02160                 dso = new dataSocket(ia,even_port(port));
02161                 cso = new controlSocket(ia,odd_port(port + 1));
02162         };
02163         
02169         T_RTPSocket(const InetMcastAddress& bind, tpport_t port = 5004, int pri = 0)
02170         {
02171                 base = even_port(port);
02172                 dso = new dataSocket(ia,even_port(port));
02173                 cso = new controlSocket(ia,odd_port(port + 1));
02174         };
02175 
02179         ~T_RTPSocket()
02180         { endSocket(); };
02181 
02187         inline sockerror_t 
02188         Connect(const InetHostAddress& ia, tpport_t port = 0)
02189         { return connect(ia,port); };
02190 
02196         inline sockerror_t 
02197         Connect(const InetMcastAddress& ia, tpport_t port = 0)
02198         { return connect(ia,port); };
02199 
02206         inline sockerror_t
02207         joinGroup(const InetMcastAddress& ia, tpport_t port = 0)
02208         { 
02209                 sockerror_t error  = dso->setMulticast(true);
02210                 if ( error ) return error;
02211                 error = dso->joinGroup(ia); 
02212                 if ( error ) return error;
02213                 error = cso->setMulticast(true);
02214                 if ( error ) {
02215                         dso->leaveGroup(ia);
02216                         return error;
02217                 }
02218                 error = cso->joinGroup(ia);
02219                 if ( error ) {
02220                         dso->leaveGroup(ia);
02221                         return error;
02222                 }
02223                 return Connect(ia,port);
02224         };
02225 
02232         inline sockerror_t
02233         leaveGroup(const InetMcastAddress& ia)
02234         { 
02235                 sockerror_t error = dso->setMulticast(true);
02236                 if ( error ) return error;
02237                 error = dso->leaveGroup(ia); 
02238                 if ( error ) return error;
02239                 error = cso->setMulticast(true);
02240                 if ( error ) return errror;
02241                 return cso->leaveGroup(ia);
02242         };
02243 
02250         inline sockerror_t
02251         setMcastTTL(uint8 ttl)
02252         { 
02253                 sockerror_t error = dso->setMulticast(true);
02254                 if ( error ) return error;
02255                 error = dso->setTimeToLive(ttl); 
02256                 if ( error ) return error;
02257                 error = cso->setMulticast(true);                
02258                 if ( error ) return error;              
02259                 return cso->setTimeToLive(ttl);
02260         };
02261         
02262 protected:
02266         inline bool 
02267         isPendingData(microtimeout_t timeout)
02268         { return dso->isPendingPacket(timeout); };
02269 
02274         inline size_t 
02275         readData(unsigned char* buffer, size_t len)
02276         { return dso->readPacket(buffer, len); };
02277 
02282         inline size_t 
02283         writeData(const unsigned char* const buffer, size_t len)
02284         { return dso->writePacket(buffer, len); };
02285 
02290         inline bool 
02291         isPendingControl(microtimeout_t timeout)
02292         { return cso->isPendingPacket(timeout); };
02293 
02299         inline size_t 
02300         readControl(unsigned char *buffer, size_t len)
02301         { return cso->readPacket(buffer,len); };
02302 
02308         inline size_t
02309         writeControl(const unsigned char* const buffer, size_t len)
02310         { return cso->writePacket(buffer,len); };
02311 
02312         inline void
02313         endSocket()
02314         { dso->endSocket(); cso->endSocket(); };
02315 
02316 private:
02325         sockerror_t 
02326         connect(const InetAddress& ia, tpport_t port = 0)
02327         {
02328                 sockerror_t error;
02329                 if ( !port )
02330                         port = base;
02331                 if ( active )
02332                         active = false;
02333                 // make both RTP (even) and RTCP (odd) connections
02334                 error = dso->Connect(ia, even_port(port));
02335                 if ( error )
02336                         return error;
02337                 error = cso->Connect(ia, odd_port(port + 1));
02338                 if ( error )
02339                         return error;
02340                 // Start running the RTP queue service thread
02341                 active = true;
02342                 Start();  
02343                 return SOCKET_SUCCESS;
02344         };
02345 
02353         inline tpport_t
02354         odd_port(tpport_t port)
02355         { return (port & 0x01)? (port) : (port - 1); };
02356         
02364         inline tpport_t 
02365         even_port(tpport_t port)
02366         { return (port & 0x01)? (port - 1) : (port); };
02367 
02368         tpport_t base;
02369         dataSocket* dso;
02370         controlSocket* cso;
02371 };
02372 
02379 typedef T_RTPSocket<QueueRTCPManager,UDPIPv4Socket,UDPIPv4Socket> RTPSocket;
02380 
02391 class CCXX_CLASS_EXPORT RTPDuplex : public RTPQueue, protected UDPReceive, public UDPTransmit
02392 {
02393 
02394 public:
02395 
02402         RTPDuplex(const InetAddress &bind, tpport_t local, tpport_t remote, int pri);
02403 
02407         virtual
02408         ~RTPDuplex();
02409 
02416         sockerror_t 
02417         Connect(const InetHostAddress &host, tpport_t port = 0);
02418 
02419 protected:
02420 
02425         bool 
02426         isPendingData(microtimeout_t timeout)
02427         { return isPendingReceive(timeout); }
02428 
02434         size_t 
02435         writeData(const unsigned char *const buffer, size_t len)
02436         { return Transmit((const char *)buffer, len); }
02437 
02443         size_t 
02444         readData(unsigned char *buffer, size_t len)
02445         { return Receive(buffer, len); }
02446 
02450         RTPSource &getPeer();
02451 
02452 private:
02453 
02454         tpport_t base;
02455 };
02456 
02457 #ifdef  __NAMESPACES__
02458 };
02459 #endif
02460 
02461 #endif  //__CCXX_RTP_H__
02462 

Generated at Sat Nov 3 09:44:13 2001 for ccRTP by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001