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  CCXX_NAMESPACES
00055 namespace ost {
00056 #endif
00057 
00058 // RTP version
00059 const uint8 CCRTP_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 
00192 typedef enum
00193 {
00194         RTPSOURCE_STATE_PREVALID,
00195         RTPSOURCE_STATE_VALID,
00196         RTPSOURCE_STATE_SAYINGBYE
00197 }       rtpsource_state_t;
00198 
00207 typedef enum
00208 {
00209         RTP_PURGE_SEND,        
00210         RTP_PURGE_RECV,        
00211         RTP_PURGE_BOTH         
00212 }       rtp_purge_t;
00213 
00214 typedef enum {
00215         CAST_MCAST,
00216         CAST_UCAST
00217 }       rtp_cast_t;
00218 
00219 class CCXX_CLASS_EXPORT IncomingRTPPkt;
00220 class CCXX_CLASS_EXPORT OutgoingRTPPkt;
00221 class CCXX_CLASS_EXPORT RTPQueue;
00222 class CCXX_CLASS_EXPORT QueueRTCPManager;
00223 class CCXX_CLASS_EXPORT RTPSource;
00224 
00237 class CCXX_CLASS_EXPORT RTPData
00238 {
00239 
00240 public:
00244         RTPData(const RTPData& origin);
00245 
00252         RTPData&
00253         operator=(const RTPData& source);
00254 
00255         inline const unsigned char*
00256         getData() const
00257         { return datablock->data; };
00258 
00259         inline size_t
00260         getSize() const
00261         { return datablock->size; };
00262 
00263         inline rtp_payload_t
00264         getPayloadType() const
00265         { return datablock->pt; }
00266 
00267 protected:
00268 
00269         RTPData(IncomingRTPPkt& packet);
00270 
00271         ~RTPData();
00272 
00273 private:
00274         // dataCounter holds the reference counter
00275         struct dataCounter {
00276                 uint16 count;
00277                 const unsigned char* data;
00278                 const size_t size;
00279                 rtp_payload_t pt;
00280                 dataCounter(const unsigned char* data, size_t size, rtp_payload_t pt);
00281                 ~dataCounter();
00282         };
00283 
00284         mutable dataCounter* datablock;
00285 
00286 
00287 
00288         // Who sent this data
00289         RTPSource* src;
00290 
00291         friend class RTPQueue;
00292 };
00293 
00310 class CCXX_CLASS_EXPORT RTPSource
00311 {
00312 public:
00313         bool getHello();
00314         bool getGoodbye();
00315 
00316         uint32 getID() const
00317         { return ssrc; };
00318 
00324         uint32 
00325         getRate() const;
00326 
00340         inline void
00341         setKitchenSize(microtimeout_t s)
00342         { kitchensize = ((s / 1000) * getRate() / 1000); };
00343          
00349         inline microtimeout_t
00350         getKitchenDuration() const
00351         { return (((kitchensize * 1000) / getRate())* 1000); };
00352 
00353         inline uint32
00354         getKitchenSize() const
00355         { return kitchensize; };
00356 
00365         inline microtimeout_t
00366         getCurrentKitchenDuration()
00367         { return (((currentkitchen * 1000) / getRate())* 1000); };
00368 
00369         inline microtimeout_t
00370         getCurrentKitchenSize()
00371         { return currentkitchen;};
00372 
00373         const char* const
00374         getSDESItem(sdes_item_type_t type) const;
00375         
00376         inline const char* const 
00377         getCNAME() const
00378         { return getSDESItem(RTCP_SDES_ITEM_CNAME); };
00379 
00380         inline const char* const
00381         getNAME() const
00382         { return getSDESItem(RTCP_SDES_ITEM_NAME); };
00383 
00384         inline const char* const
00385         getEMAIL() const
00386         { return getSDESItem(RTCP_SDES_ITEM_EMAIL); };
00387 
00388         inline const char* const
00389         getPHONE() const
00390         { return getSDESItem(RTCP_SDES_ITEM_PHONE); };
00391 
00392         inline const char* const 
00393         getLOC() const
00394         { return getSDESItem(RTCP_SDES_ITEM_LOC); };
00395 
00396         inline const char* const 
00397         getTOOL() const
00398         { return getSDESItem(RTCP_SDES_ITEM_TOOL); };
00399 
00400         inline const char* const 
00401         getNOTE() const
00402         { return getSDESItem(RTCP_SDES_ITEM_NOTE); };
00403 
00404         inline const char* const 
00405         getPRIV() const
00406         { return getSDESItem(RTCP_SDES_ITEM_PRIV); };
00407 
00408         inline const char* const 
00409         getH323_CADDR() const
00410         { return getSDESItem(RTCP_SDES_ITEM_H323_CADDR); };
00411 
00415         inline bool
00416         isSender() const
00417         { return active_sender; };
00418 
00419         bool isValid() const
00420         { return valid; };
00421 
00422         inline bool
00423         operator==(const RTPSource &rhs) const
00424         { return (this == &rhs); }
00425 
00426         inline bool
00427         operator!=(const RTPSource &rhs) const
00428         { return !(*this == rhs); }
00429 
00433         RTPSource(uint32 ssrc); 
00434 
00438         ~RTPSource();
00439 
00443         RTPSource(const RTPSource& origin);
00444 
00445         RTPSource&
00446         operator=(const RTPSource &origin);
00447 
00448 protected:
00449                 
00450 private:
00458         inline void
00459         setCurrentKitchenSize(uint32 s)
00460         { currentkitchen = s; };
00461 
00465         void endSource();
00466 
00467         void
00468         setSDESItem(sdes_item_type_t item, const char* const value);
00469 
00478         void 
00479         recordReception(IncomingRTPPkt& p);
00480 
00490         void 
00491         recordInsertion(IncomingRTPPkt& p);
00492 
00500         void 
00501         recordExtraction(IncomingRTPPkt& p);
00502 
00506         inline void
00507         setSender(bool active)
00508         { active_sender = active; };
00509 
00515         inline void 
00516         setInitialTimestamp(uint32 ts)
00517         { initial_timestamp = ts; }
00518 
00527         inline uint32 
00528         getInitialTimestamp()
00529         {return initial_timestamp; }
00530 
00537         inline uint16
00538         getExpectedSeqNum()
00539         { return expectedseqnum; }
00540 
00547         inline void
00548         setExpectedSeqNum(uint16 n)
00549         { expectedseqnum = n; }
00550 
00551         inline void
00552         setState(rtpsource_state_t st)
00553         { state = st; }
00554 
00555         // SSRC 32 bit identifier carried in RTP and RTCP packets (in
00556         // network order)
00557         uint32 ssrc;
00558         // validity state of this source
00559         rtpsource_state_t state;
00560         // timestamp of the first packet received from this source
00561         uint32 initial_timestamp;
00562         // number of packets received from this source
00563         uint32 packet_count;
00564         // time the last packet was received at
00565         struct timeval last_time;
00566         // required kitchen for this source. Represented as octets,
00567         // given the current transmission rate
00568         uint32 kitchensize;
00569         // current kitchen for this source. Represented as octets,
00570         // given the current transmission rate
00571         uint32 currentkitchen;
00572         // the expected sequence number of the next packet to be received.
00573         uint16 expectedseqnum;  
00574 
00575         // this flag assures we only call one gotHello and one gotGoodbye
00576         // for this src.
00577         bool flag;
00578 
00579         // before becoming valid, multiple packets from this source, 
00580         // or an SDES RTCP containing its CNAME should be received.
00581         bool valid; 
00582         // A valid source not always is active
00583         bool active_sender;
00584 
00585         // Sources located before and after this one in the list
00586         // of sources.
00587         RTPSource* prev, * next;
00588         // first/last packets from this source in the queue 
00589         IncomingRTPPkt* first, * last;
00590         // Prev and next inside the collision list
00591         RTPSource* nextcollis;  
00592         // dummy content for undetermined descriptors
00593         static const char* const unknown;
00594         // sender info from the last sender report of this source  
00595         SenderInfo* sender_info;
00596         // dummy content for the last sender info from this source
00597         static const SenderInfo* dummySI;
00598         // last report block this source sent about the local source
00599         ReceiverInfo* receiver_info;
00600         // dummy content for the last report from this source
00601         static const ReceiverInfo* dummyRB;
00602         // Data extracted from the SDES items sent by this source
00603         char **sdes_items;
00604 
00605         
00606         friend class MembershipControl;
00607         friend class RTPQueue;
00608         friend class QueueRTCPManager;
00609         friend class IncomingRTPPkt;
00610 };
00611 
00612 // TODO: implement this idea
00613 class CCXX_CLASS_EXPORT Members
00614 {
00615 public:
00616 
00617         Members() :     
00618                 members(static_cast<uint32>(-1)), 
00619                 // -1 to counteract dummysource
00620                 active_senders(0)
00621         { };
00622 
00627         inline void
00628         increaseMembersCount()
00629         { members++; };
00630 
00635         inline void
00636         decreaseMembersCount()
00637         { members--; };
00638 
00639         inline void
00640         setMembersCount(uint32 n)
00641         { members = n; };
00642 
00643         inline void
00644         increaseSendersCount()
00645         { active_senders++; };
00646 
00647         inline void
00648         decreaseSendersCount()
00649         { active_senders--; };
00650 
00651         inline void
00652         setSendersCount(uint32 n)
00653         { active_senders = n; };
00654 
00659         inline uint32 
00660         membersCount() const
00661         { return members; };
00662         
00663         inline uint32
00664         sendersCount() const
00665         { return active_senders; };
00666 
00667 
00668         // number of identified members
00669         uint32 members;
00670         // number of identified members that currently are active senders
00671         uint32 active_senders;
00672 };
00673 
00698 class CCXX_CLASS_EXPORT MembershipControl : public Members
00699 {
00700 public:
00709         inline const RTPSource&
00710         getSource(uint32 ssrc) const
00711         { return const_cast<MembershipControl*>(this)->getSourceBySSRC(ssrc,false); }
00712 
00721         inline const RTPSource&
00722         getOrCreateSource(uint32 ssrc)
00723         { return getSourceBySSRC(ssrc,true); }
00724 
00725 protected:
00731         RTPSource&
00732         addNewSource(uint32 ssrc);
00733 
00747         MembershipControl(uint32 initial_size = 7);
00748 
00754         virtual
00755         ~MembershipControl();
00756 
00761         void
00762         endMembers();
00763 
00773         RTPSource&
00774         getSourceBySSRC(uint32 ssrc, bool create = false);
00775 
00786         bool
00787         BYESource(uint32 ssrc);
00788 
00796         bool
00797         removeSource(uint32 ssrc);
00798 
00799         const RTPSource&
00800         NullSource() const
00801         { return dummysource; };
00802 
00803         // an empty RTPSource representing unidentified sources
00804         const static RTPSource dummysource;
00805 
00806         const RTPSource&
00807         getFirstPlayer();
00808 
00809         const RTPSource&
00810         getLastPlayer();
00811         
00812         const RTPSource&
00813         getNextPlayer();
00814 
00815         const RTPSource&
00816         getCurrentPlayer();
00817 
00818 private:
00819 
00820         MembershipControl(const MembershipControl &o);
00821 
00822         MembershipControl&
00823         operator=(const MembershipControl &o);
00824 
00825         // Hash table with sources of RTP and RTCP packets
00826         uint32 SOURCE_BUCKETS; 
00827         RTPSource** sources;
00828         // List of sources, ordered from older to newer
00829         RTPSource* first, * last;
00830         mutable Mutex playerslock;
00831 };
00832 
00858 class CCXX_CLASS_EXPORT RTPQueue : protected Thread, protected MembershipControl
00859 {
00860 public:
00864         inline void Start(void)
00865                 {Thread::Start();};
00866 
00872         inline const RTPSource& 
00873         getLocalInfo() const
00874         { return *localsrc; };
00875 
00882         bool 
00883         isWaiting(const RTPSource &src = dummysource) const;
00884 
00893         bool 
00894         isCookedWaiting(void) const;
00895  
00901         bool 
00902         isSending(void) const;
00903 
00918         void 
00919         putPacket(uint32 stamp, rtp_payload_t payload, const unsigned char* data = NULL, size_t len = 0, bool mark = false);
00920 
00979         const RTPData&
00980         getCookedPacket(const RTPSource &src = dummysource);
00981 
00988         uint32 
00989         getFirstTimestamp(const RTPSource &src = dummysource);
00990  
00997         uint16 
00998         getFirstSequence(const RTPSource &src = dummysource);
00999 
01007         const RTPData&
01008         getPacket(uint32 stamp, const RTPSource &src = dummysource);
01009 
01021         size_t 
01022         getPacket(uint32 stamp, unsigned char* data, size_t max,
01023                   const RTPSource &src = dummysource);
01024 
01032         rtp_payload_t 
01033         getPayloadType(uint32 timestamp, const RTPSource &src = dummysource);
01034 
01096         uint32 
01097         getCurrentTimestamp(rtp_payload_t pt) const;
01098 
01107         uint32
01108         getTimestampIncrement(size_t packet_size) const;
01109 
01117         void
01118         setSessionBandwidth(uint32 bw)
01119         { sessionbw = bw; };
01120 
01133         uint32 
01134         getRate(rtp_payload_t pt = RTP_PAYLOAD_EMPTY) const;
01135 
01142         rtp_payload_t
01143         getPayloadType(const RTPSource& src) const;
01144 
01153         inline const RTPSource&
01154         getSource(uint32 ssrc) const
01155         { return MembershipControl::getSource(htonl(ssrc)); };
01156 
01169         inline void
01170         setTypeOfService(type_of_service_t tos)
01171         { type_of_service = tos; }
01172  
01183         size_t 
01184         setPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01185 
01197         size_t 
01198         getPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01199 
01205         inline bool 
01206         isActive(void) const
01207         { return active; };
01208 
01215         inline void 
01216         setTimeout(microtimeout_t t)
01217         { timeout = t;};
01218 
01227         inline void 
01228         setExpired(microtimeout_t t)
01229         { expired = t;};
01230 
01254         void
01255         setGlobalKitchenDuration(microtimeout_t t);
01256 
01257         void
01258         setGlobalKitchenSize(uint32 s);
01259 
01268         inline microtimeout_t
01269         getGlobalKitchenDuration() const
01270         { return (((kitchensize * 1000) / getRate())*1000); };
01271         
01286         inline void
01287         setEndToEndDelay(microtimeout_t t)
01288                 { e2edelay = t; };
01289 
01295         inline void 
01296         setSegmentSize(size_t size)
01297                 {segment = size;};
01298 
01309         inline bool 
01310         isComplete()
01311         { return complete; };
01312 
01321         inline bool 
01322         isMarked(void)
01323                 {return marked;};
01324 
01328         inline void 
01329         setTimeclock(void)
01330                 {timeclock.setTimer();};
01331  
01337         inline timeout_t 
01338         getTimeclock(void)
01339                 {return timeclock.getElapsed();};
01340         
01346         inline uint32
01347         RTPSendCount() const
01348         { return sendcount;};
01349 
01356         inline uint32
01357         RTPOctetCount() const
01358         { return octetcount;};
01359 
01360 protected:
01361         
01369         RTPQueue(int pri, uint32 size = 7);
01370 
01387         RTPQueue(uint32 ssrc, int pri, uint32 size = 7);
01388         
01392         virtual 
01393         ~RTPQueue(); 
01394 
01401         virtual inline void 
01402         RTCPService(microtimeout_t& wait)
01403         { return; };
01404 
01408         virtual void 
01409         Bye(const char* const reason)
01410         { return; }
01411 
01415         virtual void timerTick(void)
01416         { return; };
01417 
01427         microtimeout_t
01428         getTimeout(void);
01429 
01437         virtual bool
01438         isPendingData(microtimeout_t timeout) = 0;
01439 
01446         void Purge(rtp_purge_t flag);
01447 
01454         size_t
01455         sendPacket(void);
01456 
01466         virtual size_t
01467         writeData(const unsigned char* const packet, size_t len) = 0;
01468 
01475         size_t
01476         recvPacket(void);
01477 
01487         virtual size_t
01488         readData(unsigned char* buffer, size_t len) = 0;
01489 
01498         virtual bool
01499         gotPacket(IncomingRTPPkt* packet)
01500         { return true; }
01501 
01507         virtual void expireSend(OutgoingRTPPkt *packet)
01508                 {return;};
01509 
01516         virtual void expireRecv(IncomingRTPPkt *packet)
01517                 {return ;};
01518 
01528         IncomingRTPPkt*
01529         getWaiting(uint32 timestamp, const RTPSource &src = dummysource);
01530 
01534         void
01535         endQueue();
01536 
01540         void Final()
01541         { delete this; };
01542 
01543         // true if connection "active"
01544         volatile bool active;       
01545         // Object representing the local source
01546         RTPSource* localsrc;
01547         // when the queue is created
01548         struct timeval initial_time;  
01549         uint32 current_rate;
01550         // ramdonly generated offset for the timestamp of sent packets
01551         uint32 initial_timestamp;
01552 
01553 private:
01554         friend class IncomingRTPPkt;
01555 
01556         RTPQueue(const RTPQueue &o);
01557 
01558         RTPQueue&
01559         operator=(const RTPQueue &o);
01560 
01566         void
01567         initQueue(uint32 localssrc);
01568 
01572         void 
01573         Run(void);
01574         
01575 
01581         void 
01582         RTPService(microtimeout_t& wait);
01583         
01592         void 
01593         insertRecvPacket(IncomingRTPPkt *packet);               
01594 
01595         type_of_service_t type_of_service;  
01596         uint32 sessionbw;
01597         rtp_cast_t sessioncast;
01598 
01599         // packet receive workspace size
01600         static const size_t RECVBUFFER_SIZE = 8192;     
01601         // number of packets sent from the beginning
01602         uint32 sendcount;
01603         // number of payload octets sent from the beginning
01604         uint32 octetcount;
01605 
01606         // transmission and reception queues
01607         OutgoingRTPPkt* sendfirst, * sendlast; 
01608         IncomingRTPPkt* recvfirst, * recvlast;
01609         mutable Mutex sendlock, recvlock;
01610         // the sequence number of the next packet to sent
01611         uint16 sendseq;    
01612         // contributing sources
01613         uint32 sendsources[16];
01614         // how many CSRCs to send.
01615         uint16 sendcc;       
01616         // maximum packet size before fragmenting sends.
01617         unsigned segment;      
01618         // bit M in RTP fixed header of the last packet
01619         bool marked;
01620         // whether there was not loss
01621         bool complete;
01622         
01623         TimerPort timeclock;
01624 
01625         // elapsed time accumulated through successive overflows of
01626         // the local timestamp field
01627         struct timeval overflow_time; 
01628 
01629         // transmission scheduling timeout for the service thread
01630         microtimeout_t timeout;
01631         // how old a packet can reach in the sending queue before deletetion
01632         microtimeout_t expired;
01633         
01634         // Maximun delay allowed between packet timestamping and
01635         // packet availability for the application.
01636         microtimeout_t e2edelay;  
01637         // Kitchen (reordering buffer) size in octets, given the
01638         // current transmission rate.
01639         uint32 kitchensize;
01640 
01641         // this is a global table holding the 
01642         // `payload_type <-> timestamp_rate' correpondence for 
01643         // the statically assigned payload types
01644         static uint32 payload_rate[96];
01645 };
01646 
01666 class CCXX_CLASS_EXPORT QueueRTCPManager : public RTPQueue
01667 {
01668 public:
01686         virtual void
01687         setControlBandwidth(float fraction)
01688         { controlbw = fraction; };
01689 
01703         virtual void
01704         setSendersControlFraction(float fraction)
01705         { sendcontrolbw = fraction; recvcontrolbw = 1 - fraction;};
01706 
01712         inline uint32
01713         RTCPSendCount() const
01714         { return ctrlsendcount; }
01715 
01720         void inline
01721         setNAME(const char* const name)
01722         { localsrc->setSDESItem(RTCP_SDES_ITEM_NAME,name); };
01723 
01724         void inline 
01725         setEMAIL(const char* const email)
01726         { localsrc->setSDESItem(RTCP_SDES_ITEM_EMAIL,email); };
01727 
01728         void inline setPHONE(const char* const phone)
01729         { localsrc->setSDESItem(RTCP_SDES_ITEM_PHONE,phone); };
01730 
01731         void inline 
01732         setLOC(const char* const loc) 
01733         { localsrc->setSDESItem(RTCP_SDES_ITEM_LOC,loc); };
01734 
01735         void inline
01736         setTOOL(const char* const tool)
01737         { localsrc->setSDESItem(RTCP_SDES_ITEM_TOOL,tool); };
01738 
01739         void inline 
01740         setNOTE(const char* const note)
01741         { localsrc->setSDESItem(RTCP_SDES_ITEM_NOTE,note); };
01742 
01743         void inline 
01744         setPRIV(const char* const priv)
01745         { localsrc->setSDESItem(RTCP_SDES_ITEM_PRIV,priv); };
01746 
01747         void inline 
01748         setH323_CADDR(const char* const h323ca)
01749         { localsrc->setSDESItem(RTCP_SDES_ITEM_H323_CADDR,h323ca); };
01750 
01751 protected:
01752         QueueRTCPManager(int pri);
01753 
01754         virtual 
01755         ~QueueRTCPManager();
01756 
01757         void
01758         endQueueRTCPManager();
01759 
01765         void 
01766         RTCPService(microtimeout_t& wait);
01767 
01775         void 
01776         Bye(const char* const reason = NULL);
01777 
01781         virtual void 
01782         gotHello(RTPSource &src)
01783         { return; }
01784 
01791         virtual void 
01792         gotGoodbye(RTPSource &src, char *reason)
01793         { return; }
01794 
01798         void
01799         handleSSRCCollision();
01800 
01813         virtual timeval 
01814         computeRTCPInterval();
01815 
01820         inline void
01821         setPrevMembersCount(uint32 count)
01822         { rtcp_pmembers = count; };
01823 
01828         inline uint32 
01829         PrevMembersCount() const
01830         { return rtcp_pmembers; };
01831 
01832 private:
01833         QueueRTCPManager(const QueueRTCPManager &o);
01834 
01835         QueueRTCPManager&
01836         operator=(const QueueRTCPManager &o);
01837 
01841         void 
01842         setSDESItem(sdes_item_type_t type, const char *const value);
01843 
01848         void
01849         findCNAME();
01850 
01855         void
01856         updateAvgRTCPSize(size_t len);
01857 
01863         void 
01864         ReverseReconsideration();
01865 
01870         bool
01871         TimerReconsideration();
01872 
01880         void 
01881         TimeOutSSRCs();
01882 
01887         bool
01888         getSDES_APP(RTCPPacket &pkt, uint32 &pointer, size_t len);
01889 
01902         bool
01903         getBYE(RTCPPacket &pkt, uint32 &pointer, size_t len);
01904 
01908         void
01909         getOnlyBye();
01910 
01922         inline virtual uint16
01923         networkHeaderSize()
01924         { return 20; }
01925 
01937         inline virtual uint16
01938         transportHeaderSize()
01939         { return 8; }
01940 
01946         size_t
01947         sendControl(void);
01948 
01958         void
01959         recvControl(void);
01960 
01967         bool
01968         packReportBlock(uint16& len);
01969 
01985         bool
01986         tryAnotherRR(RTCPPacket*& pkt, uint16& len, uint16& blocks);
01987 
01994         void 
01995         packSDES(uint16& len);
01996 
01997         size_t
01998         sendBYE(const char* const reason);
01999 
02004         virtual size_t 
02005         writeControl(const unsigned char* const buffer, size_t len) = 0;
02006 
02011         virtual size_t 
02012         readControl(unsigned char* buffer, size_t len) = 0;
02013 
02019         virtual bool 
02020         isPendingControl(microtimeout_t timeout) = 0;
02021         
02030         bool
02031         RTCPHeaderCheck(size_t len);
02032 
02033 
02034         // path MTU. RTCP packets should not be greater than this
02035         uint16 pathMTU;
02036 
02037         // buffer to hold RTCP compound packets being sent. Allocated
02038         // at construction time
02039         unsigned char* rtcpsend_buffer;
02040 
02041         // buffer to hold RTCP compound packets being
02042         // received. Allocated at construction time
02043         unsigned char* rtcprecv_buffer;
02044 
02045         // whether the RTCP service is active
02046         bool rtcp_active;
02047 
02048         float controlbw, sendcontrolbw, recvcontrolbw;
02049         // number of RTCP packets sent since the beginning
02050         uint32 ctrlsendcount;
02051 
02052         // Network + transport headers size, typically size of IP +
02053         // UDP headers
02054         uint16 lower_headers_size;
02055         // state for rtcp timing. Its meaning is defined in RFC ????, 6.3
02056         timeval rtcp_tp, rtcp_tc, rtcp_tn;
02057         uint32 rtcp_pmembers;
02058         uint32 rtcp_bw;
02059         bool rtcp_we_sent;      
02060         uint16 rtcp_avg_size;
02061         bool rtcp_initial;
02062         // last time we checked if there were incoming RTCP packets
02063         timeval rtcp_last_check;
02064         // interval to check if there are incoming RTCP packets
02065         timeval rtcp_check_interval;
02066         // next time to check if there are incoming RTCP packets
02067         timeval rtcp_next_check;
02068 
02069         // value of sendcount at the time of the last RTCP packet transmission
02070         uint32 last_sendcount;
02071 
02072         uint32 prev_nvalid_sources;
02073         timeval rtcp_calculated_interval;
02074         
02075         // length of CNAME as user@host
02076         size_t CNAME_len;
02077 
02078         // According to timer reconsideration and reverse reconsideration 
02079         // algorithms, sources do not become valid or deleted as soon as
02080         // they appear or send BYE. 
02081         // number of not yet valid, but noticed sources 
02082         uint32 nprevalid_srcs;
02083         // number of valid sources
02084         uint32 nvalid_srcs;
02085         // number of sources having sent a BYE, but not yet deleted 
02086         uint32 npredeleted_srcs;
02087         // number of already deleted sources
02088         uint32 ndeleted_srcs;
02089         // minimum interval for transmission of RTCP packets
02090         microtimeout_t rtcp_min_interval;
02091 
02092         // Nember of seconds ellapsed from 1900 to 1970
02093         const static uint32 NTP_EPOCH_OFFSET = static_cast<uint32>(2208992400u);
02094 
02095         // masks for RTCP header validation
02096 #if     __BYTE_ORDER == __BIG_ENDIAN
02097         static const uint16 RTCP_VALID_MASK;
02098         static const uint16 RTCP_VALID_VALUE;
02099 #else
02100         static const uint16 RTCP_VALID_MASK;
02101         static const uint16 RTCP_VALID_VALUE;
02102 #endif
02103         static const uint16 TIMEOUT_MULTIPLIER;
02104         static const double RECONSIDERATION_COMPENSATION;
02105 };
02106 
02122 class CCXX_CLASS_EXPORT UDPIPv4Socket: private UDPReceive, private UDPTransmit 
02123 {
02124 public:
02131         UDPIPv4Socket(const InetAddress& ia, tpport_t port) : 
02132                 UDPReceive(ia, port), UDPTransmit() 
02133         { };
02134 
02138         ~UDPIPv4Socket() 
02139         { };
02140 
02147         sockerror_t
02148         Connect(const InetHostAddress& ia, tpport_t port)
02149         { return UDPTransmit::Connect(ia,port); };
02150 
02157         sockerror_t
02158         Connect(const InetMcastAddress& ia, tpport_t port)
02159         { return UDPTransmit::Connect(ia,port); };
02160         
02164         inline bool 
02165         isPendingPacket(microtimeout_t timeout)
02166         { return UDPReceive::isInputReady(timeout/1000); };
02167         
02171         inline size_t 
02172         writePacket(const unsigned char* const buffer, size_t len)
02173         { return UDPTransmit::Transmit((const char* const)buffer,len); };
02174 
02178         inline size_t
02179         readPacket(unsigned char *buffer, size_t len)
02180         { return UDPReceive::Receive(buffer,len); };
02181 
02185         inline sockerror_t 
02186         setMulticast(bool enable)
02187         { 
02188                 sockerror_t error = UDPReceive::setMulticast(enable);
02189                 if (error) return error;
02190                 else return UDPTransmit::setMulticast(enable); 
02191         };
02192         
02199         inline sockerror_t
02200         joinGroup(const InetMcastAddress& ia)
02201         { return UDPReceive::Join(ia); };
02202         
02209         inline sockerror_t
02210         leaveGroup(const InetMcastAddress& ia)
02211         { return UDPReceive::Drop(ia); }; 
02212 
02219         inline sockerror_t
02220         setMcastTTL(uint8 ttl)
02221         { return UDPTransmit::setTimeToLive(ttl); };
02222 
02226         void 
02227         endSocket()
02228         { UDPTransmit::endTransmitter(); UDPReceive::endReceiver(); };
02229 };
02230 
02243 template <typename serviceQueue, typename dataSocket, typename controlSocket>
02244 class CCXX_CLASS_EXPORT T_RTPSocket  : public serviceQueue
02245 {
02246 public:
02252         T_RTPSocket(const InetHostAddress& ia, tpport_t port = 5004, int pri = 0) :
02253                 serviceQueue(pri)
02254         {
02255                 base = even_port(port);
02256                 dso = new dataSocket(ia,even_port(port));
02257                 cso = new controlSocket(ia,odd_port(port + 1));
02258         };
02259         
02265         T_RTPSocket(const InetMcastAddress& ia, tpport_t port = 5004, int pri = 0):             
02266                 serviceQueue(pri)
02267 
02268         {
02269                 base = even_port(port);
02270                 dso = new dataSocket(ia,even_port(port));
02271                 cso = new controlSocket(ia,odd_port(port + 1));
02272         };
02273 
02277         virtual 
02278         ~T_RTPSocket()
02279         { endSocket(); };
02280 
02289         inline sockerror_t 
02290         Connect(const InetHostAddress& ia, tpport_t port = 0)
02291         { 
02292                 sockerror_t error;
02293                 if ( !port )
02294                         port = base;
02295                 if ( active )
02296                         active = false;
02297                 // make both RTP (even) and RTCP (odd) connections
02298                 error = dso->Connect(ia, even_port(port));
02299                 if ( error )
02300                         return error;
02301                 error = cso->Connect(ia, odd_port(port + 1));
02302                 if ( error )
02303                         return error;
02304                 // Start running the RTP queue service thread
02305                 active = true;
02306                 Start();  
02307                 return SOCKET_SUCCESS;
02308         };
02309 
02315         inline sockerror_t 
02316         Connect(const InetMcastAddress& ia, tpport_t port = 0)
02317         {
02318                 sockerror_t error = dso->setMulticast(true);
02319                 if (error)
02320                         return error;
02321                 error = cso->setMulticast(true);
02322                 if (error)
02323                         return error;
02324 
02325                 if ( !port )
02326                         port = base;
02327                 if ( active )
02328                         active = false;
02329                 // make both RTP (even) and RTCP (odd) connections
02330                 error = dso->Connect(ia, even_port(port));
02331                 if ( error )
02332                         return error;
02333                 error = cso->Connect(ia, odd_port(port + 1));
02334                 if ( error )
02335                         return error;
02336                 // Start running the RTP queue service thread
02337                 active = true;
02338                 Start();  
02339                 return SOCKET_SUCCESS;
02340         };
02341 
02348         inline sockerror_t
02349         joinGroup(const InetMcastAddress& ia, tpport_t port = 0)
02350         { 
02351                 sockerror_t error  = dso->setMulticast(true);
02352                 if ( error ) return error;
02353                 error = dso->joinGroup(ia); 
02354                 if ( error ) return error;
02355                 error = cso->setMulticast(true);
02356                 if ( error ) {
02357                         dso->leaveGroup(ia);
02358                         return error;
02359                 }
02360                 error = cso->joinGroup(ia);
02361                 if ( error ) {
02362                         dso->leaveGroup(ia);
02363                         return error;
02364                 }
02365                 return Connect(ia,port);
02366         };
02367 
02374         inline sockerror_t
02375         leaveGroup(const InetMcastAddress& ia)
02376         { 
02377                 sockerror_t error = dso->setMulticast(false);
02378                 if ( error ) return error;
02379                 error = dso->leaveGroup(ia); 
02380                 if ( error ) return error;
02381                 error = cso->setMulticast(false);
02382                 if ( error ) return errror;
02383                 return cso->leaveGroup(ia);
02384         };
02385 
02392         inline sockerror_t
02393         setMcastTTL(uint8 ttl)
02394         { 
02395                 sockerror_t error = dso->setMulticast(true);
02396                 if ( error ) return error;
02397                 error = dso->setTimeToLive(ttl); 
02398                 if ( error ) return error;
02399                 error = cso->setMulticast(true);                
02400                 if ( error ) return error;              
02401                 return cso->setTimeToLive(ttl);
02402         };
02403         
02404 protected:
02408         inline bool 
02409         isPendingData(microtimeout_t timeout)
02410         { return dso->isPendingPacket(timeout); };
02411 
02416         inline size_t 
02417         readData(unsigned char* buffer, size_t len)
02418         { return dso->readPacket(buffer, len); };
02419 
02424         inline size_t 
02425         writeData(const unsigned char* const buffer, size_t len)
02426         { return dso->writePacket(buffer, len); };
02427 
02432         inline bool 
02433         isPendingControl(microtimeout_t timeout)
02434         { return cso->isPendingPacket(timeout); };
02435 
02441         inline size_t 
02442         readControl(unsigned char *buffer, size_t len)
02443         { return cso->readPacket(buffer,len); };
02444 
02450         inline size_t
02451         writeControl(const unsigned char* const buffer, size_t len)
02452         { return cso->writePacket(buffer,len); };
02453 
02454         inline void
02455         endSocket()
02456         { dso->endSocket(); cso->endSocket(); };
02457 
02458 private:
02466         inline tpport_t
02467         odd_port(tpport_t port)
02468         { return (port & 0x01)? (port) : (port - 1); };
02469         
02477         inline tpport_t 
02478         even_port(tpport_t port)
02479         { return (port & 0x01)? (port - 1) : (port); };
02480 
02481         tpport_t base;
02482         dataSocket* dso;
02483         controlSocket* cso;
02484 };
02485 
02492 typedef T_RTPSocket<QueueRTCPManager,UDPIPv4Socket,UDPIPv4Socket> RTPSocket;
02493 
02504 class CCXX_CLASS_EXPORT RTPDuplex : public RTPQueue, protected UDPReceive, public UDPTransmit
02505 {
02506 
02507 public:
02508 
02515         RTPDuplex(const InetAddress &bind, tpport_t local, tpport_t remote, int pri);
02516 
02520         virtual
02521         ~RTPDuplex();
02522 
02529         sockerror_t 
02530         Connect(const InetHostAddress &host, tpport_t port = 0);
02531 
02532 protected:
02533 
02538         bool 
02539         isPendingData(microtimeout_t timeout)
02540         { return isPendingReceive(timeout); }
02541 
02547         size_t 
02548         writeData(const unsigned char *const buffer, size_t len)
02549         { return Transmit((const char *)buffer, len); }
02550 
02556         size_t 
02557         readData(unsigned char *buffer, size_t len)
02558         { return Receive(buffer, len); }
02559 
02563         RTPSource &getPeer();
02564 
02565 private:
02566 
02567         tpport_t base;
02568 };
02569 
02570 #ifdef  CCXX_NAMESPACES
02571 };
02572 #endif
02573 
02574 #endif  //__CCXX_RTP_H__
02575 

Generated at Sat Jan 5 09:08:53 2002 for ccRTP by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001