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 #   ifndef   __CCXX_SOCKET_H__
00050 #      include <cc++/socket.h>
00051 #   else
00052 #      ifdef   __CCXX_NAMESPACE_H__
00053 #         include <cc++/macros.h>
00054 #      endif //__CCXX_NAMESPACE_H__
00055 #   endif  //__CCXX_SOCKET_H__
00056 
00057 // RTP version
00058 const uint8 RTP_VERSION = 2;
00059 
00060 // Time interval expressed in microseconds
00061 typedef uint32 microtimeout_t;
00062 
00063 // Time interval expressed in nanoseconds 
00064 typedef uint32 nanotimeout_t;
00065 
00066 struct RTCPPacket;
00067 struct SenderInfo;
00068 struct ReceiverInfo;
00069 
00082 typedef enum
00083 {
00084         RTP_PAYLOAD_PCMU = 0,   
00085         RTP_PAYLOAD_1016,       
00086         RTP_PAYLOAD_G726,       
00087         RTP_PAYLOAD_GSM,        
00088         RTP_PAYLOAD_G723,       
00089         RTP_PAYLOAD_DVI4_8000,  
00090         RTP_PAYLOAD_DVI4_16000, 
00091         RTP_PAYLOAD_LPC,        
00092         RTP_PAYLOAD_PCMA,       
00093         RTP_PAYLOAD_G722,       
00094         RTP_PAYLOAD_L16_DUAL,   
00095         RTP_PAYLOAD_L16_MONO,   
00096         RTP_PAYLOAD_QCELP,      
00097         RTP_PAYLOAD_MPA = 14,   
00098         RTP_PAYLOAD_G728,       
00099         RTP_PAYLOAD_DVI4_11025, 
00100         RTP_PAYLOAD_DVI4_22050, 
00101         RTP_PAYLOAD_G729,       
00102         RTP_PAYLOAD_CELB = 25,  
00103         RTP_PAYLOAD_JPEG,       
00104         RTP_PAYLOAD_NV = 28,    
00105         RTP_PAYLOAD_H261 = 31,  
00106         RTP_PAYLOAD_MPV,        
00107         RTP_PAYLOAD_MP2T,       
00108         RTP_PAYLOAD_H263,       
00109         RTP_PAYLOAD_INVALID = 128,
00110         // the payload types defined down here are allocated dynamically.
00111         RTP_PAYLOAD_G726_40,
00112         RTP_PAYLOAD_G726_24,
00113         RTP_PAYLOAD_G726_16,
00114         RTP_PAYLOAD_G729D,
00115         RTP_PAYLOAD_G729E,
00116         RTP_PAYLOAD_GSM_EFR,
00117         RTP_PAYLOAD_L8,
00118         RTP_PAYLOAD_RED,
00119         RTP_PAYLOAD_VDVI,
00120         RTP_PAYLOAD_BT656,      
00121         RTP_PAYLOAD_H263_1998,  
00122         RTP_PAYLOAD_MP1S,       
00123         RTP_PAYLOAD_MP2P,       
00124         RTP_PAYLOAD_BMPEG,      
00125         RTP_PAYLOAD_EMPTY       
00126 }       rtp_payload_t;
00127 
00133 typedef enum
00134 {
00135         RTCP_TYPE_SR = 200,             
00136         RTCP_TYPE_RR,                   
00137         RTCP_TYPE_SDES,                 
00138         RTCP_TYPE_BYE,                  
00139         RTCP_TYPE_APP                   
00140 }       rtcp_type_t;
00141 
00149 typedef enum
00150 {
00151         RTCP_SDES_ITEM_END = 0,         
00152         RTCP_SDES_ITEM_CNAME,           
00153         RTCP_SDES_ITEM_NAME,            
00154         RTCP_SDES_ITEM_EMAIL,           
00155         RTCP_SDES_ITEM_PHONE,           
00156         RTCP_SDES_ITEM_LOC,             
00157         RTCP_SDES_ITEM_TOOL,            
00158         RTCP_SDES_ITEM_NOTE,            
00159         RTCP_SDES_ITEM_PRIV,            
00160         RTCP_SDES_ITEM_H323_CADDR,      
00161 }       sdes_item_type_t;
00162 
00181 typedef enum
00182 {
00183         BEST_EFFORT_SERVICE,     
00184         ENHANCED_SERVICE         
00185 }       type_of_service_t;
00186 
00195 typedef enum
00196 {
00197         RTP_PURGE_SEND,        
00198         RTP_PURGE_RECV,        
00199         RTP_PURGE_BOTH         
00200 }       rtp_purge_t;
00201 
00202 typedef enum {
00203         CAST_MCAST,
00204         CAST_UCAST
00205 }       rtp_cast_t;
00206 
00207 class IncomingRTPPkt;
00208 class OutgoingRTPPkt;
00209 class RTPQueue;
00210 class QueueRTCPManager;
00211 class RTPSource;
00212 
00225 class __EXPORT RTPData
00226 {
00227 
00228 public:
00232         RTPData(const RTPData& origin);
00233 
00240         RTPData&
00241         operator=(const RTPData& source);
00242 
00243         inline const unsigned char*
00244         getData() const
00245         { return datablock->data; };
00246 
00247         inline size_t
00248         getSize() const
00249         { return datablock->size; };
00250 
00251         inline rtp_payload_t
00252         getPayloadType() const
00253         { return datablock->pt; }
00254 
00255 protected:
00256 
00257         RTPData(IncomingRTPPkt& packet);
00258 
00259         ~RTPData();
00260 
00261 private:
00262         // dataCounter holds the reference counter
00263         struct dataCounter {
00264                 uint16 count;
00265                 const unsigned char* data;
00266                 const size_t size;
00267                 rtp_payload_t pt;
00268                 dataCounter(const unsigned char* data, size_t size, rtp_payload_t pt);
00269                 ~dataCounter();
00270         };
00271 
00272         mutable dataCounter* datablock;
00273 
00274 
00275 
00276         // Who sent this data
00277         RTPSource* src;
00278 
00279         friend RTPQueue;
00280 };
00281 
00297 class __EXPORT RTPSource
00298 {
00299 
00300 public:
00301         uint32 getID() const
00302         { return ssrc; };
00303 
00309         uint32 
00310         getRate() const;
00311 
00325         inline void
00326         setKitchenSize(microtimeout_t s)
00327         { kitchensize = ((s / 1000) * getRate() / 1000); };
00328          
00334         inline microtimeout_t
00335         getKitchenDuration() const
00336         { return (((kitchensize * 1000) / getRate())* 1000); };
00337 
00338         inline uint32
00339         getKitchenSize() const
00340         { return kitchensize; };
00341 
00350         inline microtimeout_t
00351         getCurrentKitchenDuration()
00352         { return (((currentkitchen * 1000) / getRate())* 1000); };
00353 
00354         inline microtimeout_t
00355         getCurrentKitchenSize()
00356         { return currentkitchen;};
00357 
00358         const char* const
00359         getSDESItem(sdes_item_type_t type) const;
00360         
00361         inline const char* const 
00362         getCNAME() const
00363         { return getSDESItem(RTCP_SDES_ITEM_CNAME); };
00364 
00365         inline const char* const
00366         getNAME() const
00367         { return getSDESItem(RTCP_SDES_ITEM_NAME); };
00368 
00369         inline const char* const
00370         getEMAIL() const
00371         { return getSDESItem(RTCP_SDES_ITEM_EMAIL); };
00372 
00373         inline const char* const
00374         getPHONE() const
00375         { return getSDESItem(RTCP_SDES_ITEM_PHONE); };
00376 
00377         inline const char* const 
00378         getLOC() const
00379         { return getSDESItem(RTCP_SDES_ITEM_LOC); };
00380 
00381         inline const char* const 
00382         getTOOL() const
00383         { return getSDESItem(RTCP_SDES_ITEM_TOOL); };
00384 
00385         inline const char* const 
00386         getNOTE() const
00387         { return getSDESItem(RTCP_SDES_ITEM_NOTE); };
00388 
00389         inline const char* const 
00390         getPRIV() const
00391         { return getSDESItem(RTCP_SDES_ITEM_PRIV); };
00392 
00393         inline const char* const 
00394         getH323_CADDR() const
00395         { return getSDESItem(RTCP_SDES_ITEM_H323_CADDR); };
00396 
00400         inline bool
00401         isSender() const
00402         { return active_sender; };
00403 
00404         bool isValid() const
00405         { return valid; };
00406 
00407         inline bool
00408         operator==(const RTPSource &rhs) const
00409         { return (this == &rhs); }
00410 
00411         inline bool
00412         operator!=(const RTPSource &rhs) const
00413         { return !(*this == rhs); }
00414 
00415 protected:
00416                 
00417 private:
00421         RTPSource(uint32 ssrc); 
00422 
00426         ~RTPSource();
00427 
00431         RTPSource(const RTPSource& origin);
00432 
00433         RTPSource&
00434         operator=(const RTPSource &origin);
00435 
00443         inline void
00444         setCurrentKitchenSize(uint32 s)
00445         { currentkitchen = s; };
00446 
00450         void endSource();
00451 
00452         void
00453         setSDESItem(sdes_item_type_t item, const char* const value);
00454 
00463         void 
00464         recordReception(IncomingRTPPkt& p);
00465 
00475         void 
00476         recordInsertion(IncomingRTPPkt& p);
00477 
00485         void 
00486         recordExtraction(IncomingRTPPkt& p);
00487 
00491         inline void
00492         setSender(bool active)
00493         { active_sender = active; };
00494 
00500         inline void 
00501         setInitialTimestamp(uint32 ts)
00502         { initial_timestamp = ts; }
00503 
00512         inline uint32 
00513         getInitialTimestamp()
00514         {return initial_timestamp; }
00515 
00522         inline uint16
00523         getExpectedSeqNum()
00524         { return expectedseqnum; }
00525 
00532         inline void
00533         setExpectedSeqNum(uint16 n)
00534         { expectedseqnum = n; }
00535 
00536         // SSRC 32 bit identifier carried in RTP and RTCP packets (in
00537         // network order)
00538         uint32 ssrc;
00539         // timestamp of the first packet received from this source
00540         uint32 initial_timestamp; 
00541         // number of packets received from this source
00542         uint32 packet_count;
00543         // time the last packet was received at
00544         struct timeval last_time;
00545         // required kitchen for this source. Represented as octets,
00546         // given the current transmission rate
00547         uint32 kitchensize;
00548         // current kitchen for this source. Represented as octets,
00549         // given the current transmission rate
00550         uint32 currentkitchen;
00551         // the expected sequence number of the next packet to be received.
00552         uint16 expectedseqnum;  
00553 
00554         // before becoming valid, multiple packets from this source, 
00555         // or an SDES RTCP containing its CNAME should be received.
00556         bool valid; 
00557         // A valid source not always is active
00558         bool active_sender;
00559 
00560         // Sources located before and after this one in the list
00561         // of sources.
00562         RTPSource* prev, * next;
00563         // first/last packets from this source in the queue 
00564         IncomingRTPPkt* first, * last;
00565         // Prev and next inside the collision list
00566         RTPSource* nextcollis;  
00567         // dummy content for undetermined descriptors
00568         static const char* const unknown;
00569         // sender info from the last sender report of this source  
00570         SenderInfo* sender_info;
00571         // dummy content for the last sender info from this source
00572         static const SenderInfo* dummySI;
00573         // last report block this source sent about the local source
00574         ReceiverInfo* receiver_info;
00575         // dummy content for the last report from this source
00576         static const ReceiverInfo* dummyRB;
00577         // Data extracted from the SDES items sent by this source
00578         char **sdes_items;
00579         
00580         friend class MembershipControl;
00581         friend RTPQueue;
00582         friend QueueRTCPManager;
00583         friend IncomingRTPPkt;
00584 };
00585 
00586 // TODO: implement this idea
00587 class Members
00588 {
00589 public:
00590 
00591         Members() :     
00592                 members(static_cast<uint32>(-1)), // -1 to counteract dummysource
00593                 active_senders(0)
00594         { };
00599         inline void
00600         increaseMembersCount()
00601         { members++; };
00602 
00607         inline void
00608         decreaseMembersCount()
00609         { members--; };
00610 
00611         inline void
00612         setMembersCount(uint32 n)
00613         { members = n; };
00614 
00615         inline void
00616         increaseSendersCount()
00617         { active_senders++; };
00618 
00619         inline void
00620         decreaseSendersCount()
00621         { active_senders--; };
00622 
00623         inline void
00624         setSendersCount(uint32 n)
00625         { active_senders = n; };
00626 
00627 
00632         inline uint32 
00633         membersCount() const
00634         { return members; };
00635         
00636         inline uint32
00637         sendersCount() const
00638         { return active_senders; };
00639 
00640 
00641         // number of identified members
00642         uint32 members;
00643         // number of identified members that currently are active senders
00644         uint32 active_senders;
00645 };
00646 
00671 class __EXPORT MembershipControl : public Members
00672 {
00673 public:
00682         inline const RTPSource&
00683         getSource(uint32 ssrc) const
00684         { return const_cast<MembershipControl*>(this)->getSourceBySSRC(ssrc,false); }
00685 
00694         inline const RTPSource&
00695         getOrCreateSource(uint32 ssrc)
00696         { return getSourceBySSRC(ssrc,true); }
00697 
00698 protected:
00704         RTPSource&
00705         addNewSource(uint32 ssrc);
00706 
00720         MembershipControl(uint32 initial_size = 7);
00721 
00727         virtual
00728         ~MembershipControl();
00729 
00734         void
00735         endMembers();
00736 
00746         RTPSource&
00747         getSourceBySSRC(uint32 ssrc, bool create = false);
00748 
00756         bool
00757         removeSource(uint32 ssrc);
00758 
00759         const RTPSource&
00760         NullSource() const
00761         { return dummysource; };
00762 
00763         // an empty RTPSource representing unidentified sources
00764         const static RTPSource dummysource;
00765 
00766 private:
00767 
00768         MembershipControl(const MembershipControl &o);
00769 
00770         MembershipControl&
00771         operator=(const MembershipControl &o);
00772 
00773         // Hash table with sources of RTP and RTCP packets
00774         uint32 SOURCE_BUCKETS; 
00775         RTPSource** sources;
00776         // List of sources, ordered from older to newer
00777         RTPSource* first, * last;
00778 };
00779 
00805 class __EXPORT RTPQueue : protected Thread, protected MembershipControl
00806 {
00807 public:
00813         inline const RTPSource& 
00814         getLocalInfo() const
00815         { return *localsrc; };
00816 
00823         bool 
00824         isWaiting(const RTPSource &src = dummysource) const;
00825 
00834         bool 
00835         isCookedWaiting(void) const;
00836  
00842         bool 
00843         isSending(void) const;
00844 
00859         void 
00860         putPacket(uint32 stamp, rtp_payload_t payload, unsigned char* data = NULL, size_t len = 0, bool mark = false);
00861 
00920         const RTPData&
00921         getCookedPacket(const RTPSource &src = dummysource);
00922 
00929         uint32 
00930         getFirstTimestamp(const RTPSource &src = dummysource);
00931  
00938         uint16 
00939         getFirstSequence(const RTPSource &src = dummysource);
00940 
00948         const RTPData&
00949         getPacket(uint32 stamp, const RTPSource &src = dummysource);
00950 
00962         size_t 
00963         getPacket(uint32 stamp, unsigned char* data, size_t max,
00964                   const RTPSource &src = dummysource);
00965 
00973         rtp_payload_t 
00974         getPayloadType(uint32 timestamp, const RTPSource &src = dummysource);
00975 
01037         uint32 
01038         getCurrentTimestamp(rtp_payload_t pt) const;
01039 
01048         uint32
01049         getTimestampIncrement(size_t packet_size) const;
01050 
01058         void
01059         setSessionBandwidth(uint32 bw)
01060         { sessionbw = bw; };
01061 
01074         uint32 
01075         getRate(rtp_payload_t pt = RTP_PAYLOAD_EMPTY) const;
01076 
01083         rtp_payload_t
01084         getPayloadType(const RTPSource& src) const;
01085 
01094         inline const RTPSource&
01095         getSource(uint32 ssrc) const
01096         { return MembershipControl::getSource(htonl(ssrc)); };
01097 
01110         inline void
01111         setTypeOfService(type_of_service_t tos)
01112         { type_of_service = tos; }
01113  
01124         size_t 
01125         setPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01126 
01138         size_t 
01139         getPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01140 
01146         inline bool 
01147         isActive(void) const
01148         { return active; };
01149 
01156         inline void 
01157         setTimeout(microtimeout_t t)
01158         { timeout = t;};
01159 
01168         inline void 
01169         setExpired(microtimeout_t t)
01170         { expired = t;};
01171 
01195         void
01196         setGlobalKitchenDuration(microtimeout_t t);
01197 
01198         void
01199         setGlobalKitchenSize(uint32 s);
01200 
01209         inline microtimeout_t
01210         getGlobalKitchenDuration() const
01211         { return (((kitchensize * 1000) / getRate())*1000); };
01212         
01227         inline void
01228         setEndToEndDelay(microtimeout_t t)
01229                 { e2edelay = t; };
01230 
01236         inline void 
01237         setSegmentSize(size_t size)
01238                 {segment = size;};
01239 
01250         inline bool 
01251         isComplete(void)
01252                 {return complete;};
01253 
01262         inline bool 
01263         isMarked(void)
01264                 {return marked;};
01265 
01269         inline void 
01270         setTimeclock(void)
01271                 {timeclock.setTimer();};
01272  
01278         inline timeout_t 
01279         getTimeclock(void)
01280                 {return timeclock.getElapsed();};
01281         
01287         inline uint32
01288         RTPSendCount() const
01289         { return sendcount;};
01290 
01297         inline uint32
01298         RTPOctetCount() const
01299         { return octetcount;};
01300 
01301 protected:
01302         
01310         RTPQueue(int pri, uint32 size = 7);
01311 
01328         RTPQueue(uint32 ssrc, int pri, uint32 size = 7);
01329         
01333         virtual 
01334         ~RTPQueue(); 
01335 
01342         virtual inline void 
01343         RTCPService(microtimeout_t& wait)
01344         { return; };
01345 
01349         virtual void 
01350         Bye(const char* const reason)
01351         { return; }
01352 
01356         virtual void timerTick(void)
01357         { return; };
01358 
01368         microtimeout_t
01369         getTimeout(void);
01370 
01378         virtual bool
01379         isPendingData(microtimeout_t timeout) = 0;
01380 
01387         void Purge(rtp_purge_t flag);
01388 
01395         size_t
01396         sendPacket(void);
01397 
01407         virtual size_t
01408         writeData(const unsigned char* const packet, size_t len) = 0;
01409 
01416         size_t
01417         recvPacket(void);
01418 
01428         virtual size_t
01429         readData(unsigned char* buffer, size_t len) = 0;
01430 
01439         virtual bool
01440         gotPacket(IncomingRTPPkt* packet)
01441         { return true; }
01442 
01448         virtual void expireSend(OutgoingRTPPkt *packet)
01449                 {return;};
01450 
01457         virtual void expireRecv(IncomingRTPPkt *packet)
01458                 {return ;};
01459 
01469         IncomingRTPPkt*
01470         getWaiting(uint32 timestamp, const RTPSource &src = dummysource);
01471 
01475         void
01476         endQueue();
01477 
01481         void Final()
01482         { delete this; };
01483 
01484         // true if connection "active"
01485         volatile bool active;       
01486         // Object representing the local source
01487         RTPSource* localsrc;
01488         // when the queue is created
01489         struct timeval initial_time;  
01490         uint32 current_rate;
01491         // ramdonly generated offset for the timestamp of sent packets
01492         uint32 initial_timestamp;
01493 
01494 private:
01495         friend IncomingRTPPkt;
01496 
01497         RTPQueue(const RTPQueue &o);
01498 
01499         RTPQueue&
01500         operator=(const RTPQueue &o);
01501 
01507         void
01508         initQueue(uint32 localssrc);
01509 
01513         void 
01514         Run(void);
01515         
01516 
01522         void 
01523         RTPService(microtimeout_t& wait);
01524         
01533         void 
01534         insertRecvPacket(IncomingRTPPkt *packet);               
01535 
01536         type_of_service_t type_of_service;  
01537         uint32 sessionbw;
01538         rtp_cast_t sessioncast;
01539 
01540         // packet receive workspace size
01541         static const size_t RECVBUFFER_SIZE = 8192;     
01542         // number of packets sent from the beginning
01543         uint32 sendcount;
01544         // number of payload octets sent from the beginning
01545         uint32 octetcount;
01546 
01547         // transmission and reception queues
01548         OutgoingRTPPkt* sendfirst, * sendlast; 
01549         IncomingRTPPkt* recvfirst, * recvlast;
01550         mutable Mutex sendlock, recvlock;
01551         // the sequence number of the next packet to sent
01552         uint16 sendseq;    
01553         // contributing sources
01554         uint32 sendsources[16];
01555         // how many CSRCs to send.
01556         unsigned sendcc;       
01557         // maximum packet size before fragmenting sends.
01558         unsigned segment;      
01559         // bit M in RTP fixed header of the last packet
01560         bool marked;
01561         // whether there was not loss
01562         bool complete;
01563         
01564         TimerPort timeclock;
01565 
01566         // elapsed time accumulated through successive overflows of
01567         // the local timestamp field
01568         struct timeval overflow_time; 
01569 
01570         // transmission scheduling timeout for the service thread
01571         microtimeout_t timeout;
01572         // how old a packet can reach in the sending queue before deletetion
01573         microtimeout_t expired;
01574         
01575         // Maximun delay allowed between packet timestamping and
01576         // packet availability for the application.
01577         microtimeout_t e2edelay;  
01578         // Kitchen (reordering buffer) size in octets, given the
01579         // current transmission rate.
01580         uint32 kitchensize;
01581 
01582         // this is a global table holding the 
01583         // `payload_type <-> timestamp_rate' correpondence for 
01584         // the statically assigned payload types
01585         static uint32 payload_rate[96];
01586 };
01587 
01607 class __EXPORT QueueRTCPManager : public RTPQueue
01608 {
01609 public:
01627         virtual void
01628         setControlBandwidth(float fraction)
01629         { controlbw = fraction; };
01630 
01644         virtual void
01645         setSendersControlFraction(float fraction)
01646         { sendcontrolbw = fraction; recvcontrolbw = 1 - fraction;};
01647 
01653         inline uint32
01654         RTCPSendCount() const
01655         { return ctrlsendcount; }
01656 
01661         void inline
01662         setNAME(const char* const name)
01663         { localsrc->setSDESItem(RTCP_SDES_ITEM_NAME,name); };
01664 
01665         void inline 
01666         setEMAIL(const char* const email)
01667         { localsrc->setSDESItem(RTCP_SDES_ITEM_EMAIL,email); };
01668 
01669         void inline setPHONE(const char* const phone)
01670         { localsrc->setSDESItem(RTCP_SDES_ITEM_PHONE,phone); };
01671 
01672         void inline 
01673         setLOC(const char* const loc) 
01674         { localsrc->setSDESItem(RTCP_SDES_ITEM_LOC,loc); };
01675 
01676         void inline
01677         setTOOL(const char* const tool)
01678         { localsrc->setSDESItem(RTCP_SDES_ITEM_TOOL,tool); };
01679 
01680         void inline 
01681         setNOTE(const char* const note)
01682         { localsrc->setSDESItem(RTCP_SDES_ITEM_NOTE,note); };
01683 
01684         void inline 
01685         setPRIV(const char* const priv)
01686         { localsrc->setSDESItem(RTCP_SDES_ITEM_PRIV,priv); };
01687 
01688         void inline 
01689         setH323_CADDR(const char* const h323ca)
01690         { localsrc->setSDESItem(RTCP_SDES_ITEM_H323_CADDR,h323ca); };
01691 
01692 protected:
01693         QueueRTCPManager(int pri);
01694 
01695         virtual 
01696         ~QueueRTCPManager();
01697 
01698         void
01699         endQueueRTCPManager();
01700 
01706         void 
01707         RTCPService(microtimeout_t& wait);
01708 
01716         void 
01717         Bye(const char* const reason = NULL);
01718 
01722         void 
01723         gotHello(const char* sdes) 
01724         { return; }
01725  
01729         void 
01730         gotGoodbye(void)
01731         { return; }
01732 
01736         void
01737         handleSSRCCollision();
01738 
01751         virtual timeval 
01752         computeRTCPInterval();
01753 
01754 private:
01755         QueueRTCPManager(const QueueRTCPManager &o);
01756 
01757         QueueRTCPManager&
01758         operator=(const QueueRTCPManager &o);
01759 
01763         void 
01764         setSDESItem(sdes_item_type_t type, const char *const value);
01765 
01770         void
01771         findCNAME();
01772 
01777         void
01778         updateAvgRTCPSize(uint16 len);
01779 
01785         void 
01786         ReverseReconsideration();
01787 
01792         bool
01793         TimerReconsideration();
01794 
01802         void 
01803         TimeOutSSRCs();
01804 
01809         bool
01810         getSDES_APP(RTCPPacket &pkt, uint16 &pointer, uint16 len);
01811 
01821         bool
01822         getBYE(RTCPPacket &pkt, uint16 &pointer, uint16 len);
01823 
01827         void
01828         getOnlyBye();
01829 
01841         inline virtual uint16
01842         networkHeaderSize()
01843         { return 20; }
01844 
01856         inline virtual uint16
01857         transportHeaderSize()
01858         { return 8; }
01859 
01865         size_t
01866         sendControl(void);
01867 
01877         void
01878         recvControl(void);
01879 
01886         bool
01887         packReportBlock(uint16& len);
01888 
01904         bool
01905         tryAnotherRR(RTCPPacket*& pkt, uint16& len, uint16& blocks);
01906 
01913         void 
01914         packSDES(uint16& len);
01915 
01916         size_t
01917         sendBYE(const char* const reason);
01918 
01923         virtual size_t 
01924         writeControl(const unsigned char* const buffer, size_t len) = 0;
01925 
01930         virtual size_t 
01931         readControl(unsigned char* buffer, size_t len) = 0;
01932 
01938         virtual bool 
01939         isPendingControl(microtimeout_t timeout) = 0;
01940         
01949         bool
01950         RTCPHeaderCheck(size_t len);
01951 
01952 
01953         // path MTU. RTCP packets should not be greater than this
01954         uint16 pathMTU;
01955 
01956         // buffer to hold RTCP compound packets being sent. Allocated
01957         // at construction time
01958         unsigned char* rtcpsend_buffer;
01959 
01960         // buffer to hold RTCP compound packets being
01961         // received. Allocated at construction time
01962         unsigned char* rtcprecv_buffer;
01963 
01964         // whether the RTCP service is active
01965         bool rtcp_active;
01966 
01967         float controlbw, sendcontrolbw, recvcontrolbw;
01968         // number of RTCP packets sent since the beginning
01969         uint32 ctrlsendcount;
01970 
01971         // Network + transport headers size, typically size of IP +
01972         // UDP headers
01973         uint16 lower_headers_size;
01974         // state for rtcp timing. Its meaning is defined in RFC ????, 6.3
01975         timeval rtcp_tp, rtcp_tc, rtcp_tn;
01976         uint32 rtcp_pmembers;
01977         uint32 rtcp_bw;
01978         bool rtcp_we_sent;      
01979         uint16 rtcp_avg_size;
01980         bool rtcp_initial;
01981         // last time we checked if there were incoming RTCP packets
01982         timeval rtcp_last_check;
01983         // interval to check if there are incoming RTCP packets
01984         timeval rtcp_check_interval;
01985         // next time to check if there are incoming RTCP packets
01986         timeval rtcp_next_check;
01987 
01988         // value of sendcount at the time of the last RTCP packet transmission
01989         uint32 last_sendcount;
01990 
01991         uint32 prev_nvalid_sources;
01992         timeval rtcp_calculated_interval;
01993         
01994         // length of CNAME as user@host
01995         size_t CNAME_len;
01996 
01997         // According to timer reconsideration and reverse reconsideration 
01998         // algorithms, sources do not become valid or deleted as soon as
01999         // they appear or send BYE. 
02000         // number of not yet valid, but noticed sources 
02001         uint32 nprevalid_srcs;
02002         // number of valid sources
02003         uint32 nvalid_srcs;
02004         // number of sources having sent a BYE, but not yet deleted
02005         uint32 npredeleted_srcs;
02006         // number of already deleted sources
02007         uint32 ndeleted_srcs;
02008         // minimum interval for transmission of RTCP packets
02009         microtimeout_t rtcp_min_interval;
02010 
02011         // Nember of seconds ellapsed from 1900 to 1970
02012         const static uint32 NTP_EPOCH_OFFSET = static_cast<uint32>(2208992400u);
02013 
02014         // masks for RTCP header validation
02015 #if     __BYTE_ORDER == __BIG_ENDIAN
02016         static const uint16 RTCP_VALID_MASK = (0xc000 | 0x2000  | 0xfe);
02017         static const uint16 RTCP_VALID_VALUE = ((RTP_VERSION << 14) | 
02018                                                 RTCP_TYPE_SR);
02019 #else
02020         static const uint16 RTCP_VALID_MASK = (0x00c0 | 0x0020 | 0xfe00);
02021         static const uint16 RTCP_VALID_VALUE = ((RTP_VERSION << 6) | 
02022                                                 (RTCP_TYPE_SR << 8));
02023 #endif
02024         static const uint16 TIMEOUT_MULTIPLIER = 5;
02025         static const double RECONSIDERATION_COMPENSATION = 2.718281828 - 1.5;
02026 };
02027 
02040 class __EXPORT UDPIPv4Socket: protected UDPSocket 
02041 {
02042 public:
02049         UDPIPv4Socket(const InetAddress& ia, tpport_t port) : 
02050                 UDPSocket(ia, port) 
02051         { };
02052 
02056         ~UDPIPv4Socket() 
02057         { };
02058 
02065         sockerror_t
02066         Connect(const InetAddress& ia, tpport_t port);
02067         
02071         inline bool 
02072         isPendingPacket(microtimeout_t timeout)
02073         { return isPending(SOCKET_PENDING_INPUT, timeout/1000);};
02074         
02078         inline size_t 
02079         writePacket(const unsigned char* const buffer, size_t len)
02080         {return ::send(so, buffer, len, MSG_DONTWAIT);};
02081 
02085         inline size_t
02086         readPacket(unsigned char *buffer, size_t len)
02087         {return ::read(so, buffer, len);};
02088 
02092         inline sockerror_t 
02093         setMulticast(bool enable)
02094         { return setMulticast(enable); };
02095 
02102         inline sockerror_t
02103         joinGroup(const InetMcastAddress& ia)
02104         { return Join(ia); };
02105 
02112         inline sockerror_t
02113         leaveGroup(const InetMcastAddress& ia)
02114         { return Drop(ia); }; 
02115 
02122         inline sockerror_t
02123         setMcastTTL(uint8 ttl)
02124         { setTimeToLive(ttl); };
02125 
02129         void 
02130         endSocket()
02131         { UDPSocket::endSocket(); };
02132 };
02133 
02146 template <typename serviceQueue, typename dataSocket, typename controlSocket>
02147 class __EXPORT T_RTPSocket  : public serviceQueue
02148 {
02149 public:
02155         T_RTPSocket(const InetAddress& ia, tpport_t port = 5004, int pri = 0) :
02156                 serviceQueue(pri)
02157         {
02158                 base = even_port(port);
02159                 dso = new dataSocket(ia,even_port(port));
02160                 cso = new controlSocket(ia,odd_port(port + 1));
02161         };
02162         
02168         T_RTPSocket(const InetMcastAddress& bind, tpport_t port = 5004, int pri = 0)
02169         {
02170                 base = even_port(port);
02171                 dso = new dataSocket(ia,even_port(port));
02172                 cso = new controlSocket(ia,odd_port(port + 1));
02173         };
02174 
02178         ~T_RTPSocket()
02179         { endSocket(); };
02180 
02186         inline sockerror_t 
02187         Connect(const InetHostAddress& ia, tpport_t port = 0)
02188         { return connect(ia,port); };
02189 
02195         inline sockerror_t 
02196         Connect(const InetMcastAddress& ia, tpport_t port = 0)
02197         { return connect(ia,port); };
02198 
02205         inline sockerror_t
02206         joinGroup(const InetMcastAddress& ia, tpport_t port = 0)
02207         { 
02208                 sockerror_t error  = dso->setMulticast(true);
02209                 if ( error ) return error;
02210                 error = dso->joinGroup(ia); 
02211                 if ( error ) return error;
02212                 error = cso->setMulticast(true);
02213                 if ( error ) {
02214                         dso->leaveGroup(ia);
02215                         return error;
02216                 }
02217                 error = cso->joinGroup(ia);
02218                 if ( error ) {
02219                         dso->leaveGroup(ia);
02220                         return error;
02221                 }
02222                 return Connect(ia,port);
02223         };
02224 
02231         inline sockerror_t
02232         leaveGroup(const InetMcastAddress& ia)
02233         { 
02234                 sockerror_t error = dso->setMulticast(true);
02235                 if ( error ) return error;
02236                 error = dso->leaveGroup(ia); 
02237                 if ( error ) return error;
02238                 error = cso->setMulticast(true);
02239                 if ( error ) return errror;
02240                 return cso->leaveGroup(ia);
02241         };
02242 
02249         inline sockerror_t
02250         setMcastTTL(uint8 ttl)
02251         { 
02252                 sockerror_t error = dso->setMulticast(true);
02253                 if ( error ) return error;
02254                 error = dso->setTimeToLive(ttl); 
02255                 if ( error ) return error;
02256                 error = cso->setMulticast(true);                
02257                 if ( error ) return error;              
02258                 return cso->setTimeToLive(ttl);
02259         };
02260         
02261 protected:
02265         inline bool 
02266         isPendingData(microtimeout_t timeout)
02267         { return dso->isPendingPacket(timeout); };
02268 
02273         inline size_t 
02274         readData(unsigned char* buffer, size_t len)
02275         { return dso->readPacket(buffer, len); };
02276 
02281         inline size_t 
02282         writeData(const unsigned char* const buffer, size_t len)
02283         { return dso->writePacket(buffer, len); };
02284 
02289         inline bool 
02290         isPendingControl(microtimeout_t timeout)
02291         { return cso->isPendingPacket(timeout); };
02292 
02298         inline size_t 
02299         readControl(unsigned char *buffer, size_t len)
02300         { return cso->readPacket(buffer,len); };
02301 
02307         inline size_t
02308         writeControl(const unsigned char* const buffer, size_t len)
02309         { return cso->writePacket(buffer,len); };
02310 
02311         inline void
02312         endSocket()
02313         { dso->endSocket(); cso->endSocket(); };
02314 
02315 private:
02324         sockerror_t 
02325         connect(const InetAddress& ia, tpport_t port = 0)
02326         {
02327                 sockerror_t error;
02328                 if ( !port )
02329                         port = base;
02330                 if ( active )
02331                         active = false;
02332                 // make both RTP (even) and RTCP (odd) connections
02333                 error = dso->Connect(ia, even_port(port));
02334                 if ( error )
02335                         return error;
02336                 error = cso->Connect(ia, odd_port(port + 1));
02337                 if ( error )
02338                         return error;
02339                 // Start running the RTP queue service thread
02340                 active = true;
02341                 Start();  
02342                 return SOCKET_SUCCESS;
02343         };
02344 
02352         inline tpport_t
02353         odd_port(tpport_t port)
02354         { return (port & 0x01)? (port) : (port - 1); };
02355         
02363         inline tpport_t 
02364         even_port(tpport_t port)
02365         { return (port & 0x01)? (port - 1) : (port); };
02366 
02367         tpport_t base;
02368         dataSocket* dso;
02369         controlSocket* cso;
02370 };
02371 
02378 typedef T_RTPSocket<QueueRTCPManager,UDPIPv4Socket,UDPIPv4Socket> RTPSocket;
02379 
02390 class __EXPORT RTPDuplex : public RTPQueue, protected UDPReceive, public UDPTransmit
02391 {
02392 
02393 public:
02394 
02401         RTPDuplex(const InetAddress &bind, tpport_t local, tpport_t remote, int pri);
02402 
02406         virtual
02407         ~RTPDuplex();
02408 
02415         sockerror_t 
02416         Connect(const InetHostAddress &host, tpport_t port = 0);
02417 
02418 protected:
02419 
02424         bool 
02425         isPendingData(microtimeout_t timeout)
02426         { return isPendingReceive(timeout); }
02427 
02433         size_t 
02434         writeData(const unsigned char *const buffer, size_t len)
02435         { return Transmit((const char *)buffer, len); }
02436 
02442         size_t 
02443         readData(unsigned char *buffer, size_t len)
02444         { return Receive(buffer, len); }
02445 
02449         RTPSource &getPeer();
02450 
02451 private:
02452 
02453         tpport_t base;
02454 };
02455 
02456 #endif  //__CCXX_RTP_H__
02457 

Generated at Fri Oct 5 10:28:26 2001 for ccRTP by doxygen1.2.5 written by Dimitri van Heesch, © 1997-2001