Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages | Examples

rtp.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2005 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, you may use this file as part of a free software
00018 // library without restriction.  Specifically, if other files instantiate
00019 // templates or use macros or inline functions from this file, or you compile
00020 // this file and link it with other files to produce an executable, this
00021 // file does not by itself cause the resulting executable to be covered by
00022 // the GNU General Public License.  This exception does not however
00023 // invalidate any other reasons why the executable file might be covered by
00024 // the GNU General Public License.
00025 //
00026 // This exception applies only to the code released under the name GNU
00027 // ccRTP.  If you copy code from other releases into a copy of GNU
00028 // ccRTP, as the General Public License permits, the exception does
00029 // not apply to the code that you add in this way.  To avoid misleading
00030 // anyone as to the status of such modified files, you must delete
00031 // this exception notice from them.
00032 //
00033 // If you write modifications of your own for GNU ccRTP, it is your choice
00034 // whether to permit this exception to apply to your modifications.
00035 // If you do not wish that, delete this exception notice.
00036 //
00037 
00049 #ifndef CCXX_RTP_RTP_H_
00050 #define CCXX_RTP_RTP_H_
00051 
00052 #include <ccrtp/cqueue.h>
00053 #include <ccrtp/channel.h>
00054 
00055 #ifdef  CCXX_NAMESPACES
00056 namespace ost {
00057 #endif
00058 
00085         template <class RTPDataChannel = DualRTPUDPIPv4Channel,
00086                   class RTCPChannel = DualRTPUDPIPv4Channel,
00087                   class ServiceQueue = AVPQueue>
00088         class __EXPORT TRTPSessionBase : public ServiceQueue
00089         {
00090         public:
00100                 TRTPSessionBase(const InetHostAddress& ia, tpport_t dataPort,
00101                                 tpport_t controlPort, uint32 membersSize,
00102                                 RTPApplication& app) :
00103                         ServiceQueue(membersSize,app)
00104                         { build(ia,dataPort,controlPort); }
00105 
00117                 TRTPSessionBase(uint32 ssrc,
00118                                 const InetHostAddress& ia,
00119                                 tpport_t dataPort, tpport_t controlPort,
00120                                 uint32 membersSize, RTPApplication& app):
00121                         ServiceQueue(ssrc,membersSize,app)
00122                         { build(ia,dataPort,controlPort); }
00123 
00136                 TRTPSessionBase(const InetMcastAddress& ia, tpport_t dataPort,
00137                                 tpport_t controlPort, uint32 membersSize,
00138                                 RTPApplication& app, uint32 iface) :
00139                         ServiceQueue(membersSize,app)
00140                         { build(ia,dataPort,controlPort,iface); }
00141 
00156                 TRTPSessionBase(uint32 ssrc,
00157                                 const InetMcastAddress& ia, tpport_t dataPort,
00158                                 tpport_t controlPort, uint32 membersSize,
00159                                 RTPApplication& app, uint32 iface) :
00160                         ServiceQueue(ssrc,membersSize,app)
00161                         { build(ia,dataPort,controlPort,iface); }
00162 
00163                 virtual size_t dispatchBYE(const std::string &str)
00164                         {
00165                                 return QueueRTCPManager::dispatchBYE(str);
00166                         }
00167 
00174                 inline Socket::Error
00175                 setMcastTTL(uint8 ttl)
00176                         {
00177                                 Socket::Error error = dso->setMulticast(true);
00178                                 if ( error ) return error;
00179                                 error = dso->setTimeToLive(ttl);
00180                                 if ( error ) return error;
00181                                 error = cso->setMulticast(true);
00182                                 if ( error ) return error;
00183                                 return cso->setTimeToLive(ttl);
00184                         }
00185 
00186                 inline virtual
00187                 ~TRTPSessionBase()
00188                         {
00189                                 endSocket();
00190                         }
00191 
00192                 inline RTPDataChannel *getDSO(void)
00193                         {return dso;};
00194 
00195         protected:
00199                 inline bool
00200                 isPendingData(microtimeout_t timeout)
00201                         { return dso->isPendingRecv(timeout); }
00202 
00203                 InetHostAddress
00204                 getDataSender(tpport_t *port = NULL) const
00205                         { return dso->getSender(port); }
00206 
00207                 inline size_t
00208                 getNextDataPacketSize() const
00209                         { return dso->getNextPacketSize(); }
00210 
00220                 inline size_t
00221                 recvData(unsigned char* buffer, size_t len,
00222                          InetHostAddress& na, tpport_t& tp)
00223                         { na = dso->getSender(tp); return dso->recv(buffer, len); }
00224 
00225                 inline void
00226                 setDataPeer(const InetAddress &host, tpport_t port)
00227                         { dso->setPeer(host,port); }
00228 
00229 
00234                 inline size_t
00235                 sendData(const unsigned char* const buffer, size_t len)
00236                         { return dso->send(buffer, len); }
00237 
00238                 inline SOCKET getDataRecvSocket() const
00239                         { return dso->getRecvSocket(); }
00240 
00245                 inline bool
00246                 isPendingControl(microtimeout_t timeout)
00247                         { return cso->isPendingRecv(timeout); }
00248 
00249                 InetHostAddress
00250                 getControlSender(tpport_t *port = NULL) const
00251                         { return cso->getSender(port); }
00252 
00262                 inline size_t
00263                 recvControl(unsigned char *buffer, size_t len,
00264                             InetHostAddress& na, tpport_t& tp)
00265                         { na = cso->getSender(tp); return cso->recv(buffer,len); }
00266 
00267                 inline void
00268                 setControlPeer(const InetAddress &host, tpport_t port)
00269                         { cso->setPeer(host,port); }
00270 
00276                 inline size_t
00277                 sendControl(const unsigned char* const buffer, size_t len)
00278                         { return cso->send(buffer,len); }
00279 
00280                 inline SOCKET getControlRecvSocket() const
00281                         { return cso->getRecvSocket(); }
00282 
00289                 inline Socket::Error
00290                 joinGroup(const InetMcastAddress& ia, uint32 iface)
00291                         {
00292                                 Socket::Error error  = dso->setMulticast(true);
00293                                 if ( error ) return error;
00294                                 error = dso->join(ia,iface);
00295                                 if ( error ) return error;
00296                                 error = cso->setMulticast(true);
00297                                 if ( error ) {
00298                                         dso->drop(ia);
00299                                         return error;
00300                                 }
00301                                 error = cso->join(ia,iface);
00302                                 if ( error ) {
00303                                         dso->drop(ia);
00304                                         return error;
00305                                 }
00306                                 return Socket::errSuccess;
00307                         }
00308 
00315                 inline Socket::Error
00316                 leaveGroup(const InetMcastAddress& ia)
00317                         {
00318                                 Socket::Error error = dso->setMulticast(false);
00319                                 if ( error ) return error;
00320                                 error = dso->leaveGroup(ia);
00321                                 if ( error ) return error;
00322                                 error = cso->setMulticast(false);
00323                                 if ( error ) return error;
00324                                 return cso->leaveGroup(ia);
00325                         }
00326 
00327                 inline void
00328                 endSocket()
00329                         {
00330                                 if (dso) {
00331                                         dso->endSocket();
00332                                         delete dso;
00333                                 }
00334                                 dso = NULL;
00335                                 if (cso) {
00336                                         cso->endSocket();
00337                                         delete cso;
00338                                 }
00339                                 cso = NULL;
00340                         }
00341 
00342         private:
00343                 void
00344                 build(const InetHostAddress& ia, tpport_t dataPort,
00345                       tpport_t controlPort)
00346                         {
00347                                 if ( 0 == controlPort ) {
00348                                         dataBasePort = even_port(dataPort);
00349                                         controlBasePort = dataBasePort + 1;
00350                                 } else {
00351                                         dataBasePort = dataPort;
00352                                         controlBasePort = controlPort;
00353                                 }
00354                                 dso = new RTPDataChannel(ia,dataBasePort);
00355                                 cso = new RTCPChannel(ia,controlBasePort);
00356                         }
00357 
00358                 void
00359                 build(const InetMcastAddress& ia, tpport_t dataPort,
00360                       tpport_t controlPort, uint32 iface)
00361                         {
00362                                 if ( 0 == controlPort ) {
00363                                         dataBasePort = even_port(dataPort);
00364                                         controlBasePort = dataBasePort + 1;
00365                                 } else {
00366                                         dataBasePort = dataPort;
00367                                         controlBasePort = controlPort;
00368                                 }
00369                                 dso = new RTPDataChannel(InetHostAddress("0.0.0.0"),dataBasePort);
00370                                 cso = new RTCPChannel(InetHostAddress("0.0.0.0"),controlBasePort);
00371                                 joinGroup(ia,iface);
00372                         }
00373 
00381                 inline tpport_t
00382                 odd_port(tpport_t port)
00383                         { return (port & 0x01)? (port) : (port - 1); }
00384 
00392                 inline tpport_t
00393                 even_port(tpport_t port)
00394                         { return (port & 0x01)? (port - 1) : (port); }
00395 
00396                 tpport_t dataBasePort;
00397                 tpport_t controlBasePort;
00398 
00399         protected:
00400                 RTPDataChannel* dso;
00401                 RTCPChannel* cso;
00402                 friend class RTPSessionBaseHandler;
00403         };
00404 
00415         template
00416         <class RTPDataChannel = DualRTPUDPIPv4Channel,
00417          class RTCPChannel = DualRTPUDPIPv4Channel,
00418          class ServiceQueue = AVPQueue>
00419         class __EXPORT SingleThreadRTPSession :
00420                 protected Thread,
00421                 public TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00422         {
00423         public:
00424                 SingleThreadRTPSession(const InetHostAddress& ia,
00425                                        tpport_t dataPort = DefaultRTPDataPort,
00426                                        tpport_t controlPort = 0,
00427                                        int pri = 0,
00428                                        uint32 memberssize =
00429                                        MembershipBookkeeping::defaultMembersHashSize,
00430                                        RTPApplication& app = defaultApplication()
00431 #if defined(_MSC_VER) && _MSC_VER >= 1300
00432                         );
00433 #else
00434                 ):
00435                 Thread(pri),
00436                 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00437                 (ia,dataPort,controlPort,memberssize,app)
00438                 { }
00439 #endif
00440 
00441         SingleThreadRTPSession(uint32 ssrc, const InetHostAddress& ia,
00442                                tpport_t dataPort = DefaultRTPDataPort,
00443                                tpport_t controlPort = 0,
00444                                int pri = 0,
00445                                uint32 memberssize =
00446                                MembershipBookkeeping::defaultMembersHashSize,
00447                                RTPApplication& app = defaultApplication()
00448 #if defined(_MSC_VER) && _MSC_VER >= 1300
00449                 );
00450 #else
00451         ):
00452         Thread(pri),
00453         TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00454         (ssrc, ia,dataPort,controlPort,memberssize,app)
00455 { }
00456 #endif
00457 
00458 SingleThreadRTPSession(const InetMcastAddress& ia,
00459                        tpport_t dataPort = DefaultRTPDataPort,
00460                        tpport_t controlPort = 0,
00461                        int pri = 0,
00462                        uint32 memberssize =
00463                        MembershipBookkeeping::defaultMembersHashSize,
00464                        RTPApplication& app = defaultApplication(),
00465                        uint32 iface = 0
00466 #if defined(_MSC_VER) && _MSC_VER >= 1300
00467                );
00468 #else
00469         ):
00470         Thread(pri),
00471         TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00472         (ia,dataPort,controlPort,memberssize,app,iface)
00473         { }
00474 #endif
00475 
00476 SingleThreadRTPSession(uint32 ssrc, const InetMcastAddress& ia,
00477                        tpport_t dataPort = DefaultRTPDataPort,
00478                        tpport_t controlPort = 0,
00479                        int pri = 0,
00480                        uint32 memberssize =
00481                        MembershipBookkeeping::defaultMembersHashSize,
00482                        RTPApplication& app = defaultApplication(),
00483                        uint32 iface = 0
00484 #if defined(_MSC_VER) && _MSC_VER >= 1300
00485                       );
00486 #else
00487                 ):
00488                 Thread(pri),
00489                 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00490                 (ssrc,ia,dataPort,controlPort,memberssize,app,iface)
00491 { }
00492 #endif
00493 
00494 
00495 ~SingleThreadRTPSession()
00496 {
00497     if (isRunning()) {
00498         disableStack(); Thread::join();
00499     }
00500 }
00501 
00502 #if defined(_MSC_VER) && _MSC_VER >= 1300
00503 virtual void startRunning();
00504 #else
00505 
00508 void
00509 startRunning()
00510 { enableStack(); Thread::start(); }
00511 #endif
00512 
00513 
00514 protected:
00515 inline void disableStack(void)
00516 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}
00517 
00518 inline void enableStack(void)
00519 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
00520 
00521 inline microtimeout_t getSchedulingTimeout(void)
00522 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
00523 
00524 inline void controlReceptionService(void)
00525 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
00526 
00527 inline void controlTransmissionService(void)
00528 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
00529 
00530 inline timeval getRTCPCheckInterval(void)
00531 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();};
00532 
00533 inline size_t dispatchDataPacket(void)
00534 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();};
00535 
00536 #if defined(_MSC_VER) && _MSC_VER >= 1300
00537 virtual void run(void);
00538 
00539 virtual void timerTick(void);
00540 
00541 virtual bool isPendingData(microtimeout_t timeout);
00542 #else
00543 
00544 virtual void timerTick(void)
00545 {return;}
00546 
00547 virtual bool isPendingData(microtimeout_t timeout)
00548 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
00549 
00554 virtual void run(void)
00555 {
00556         microtimeout_t timeout = 0;
00557         while ( ServiceQueue::isActive() ) {
00558                 if ( timeout < 1000 ){ // !(timeout/1000)
00559                         timeout = getSchedulingTimeout();
00560                 }
00561                 setCancel(cancelDeferred);
00562                 controlReceptionService();
00563                 controlTransmissionService();
00564                 setCancel(cancelImmediate);
00565                 microtimeout_t maxWait =
00566                         timeval2microtimeout(getRTCPCheckInterval());
00567                 // make sure the scheduling timeout is
00568                 // <= the check interval for RTCP
00569                 // packets
00570                 timeout = (timeout > maxWait)? maxWait : timeout;
00571                 if ( timeout < 1000 ) { // !(timeout/1000)
00572                         setCancel(cancelDeferred);
00573                         dispatchDataPacket();
00574                         setCancel(cancelImmediate);
00575                         timerTick();
00576                 } else {
00577                         if ( isPendingData(timeout/1000) ) {
00578                                 setCancel(cancelDeferred);
00579                                 if (ServiceQueue::isActive()) { // take in only if active
00580                                     takeInDataPacket();
00581                                 }
00582                                 setCancel(cancelImmediate);
00583                         }
00584                         timeout = 0;
00585                 }
00586         }
00587         dispatchBYE("GNU ccRTP stack finishing.");
00588         Thread::exit();
00589 }
00590 
00591 #endif
00592 
00593 inline size_t takeInDataPacket(void)
00594 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
00595 
00596 inline size_t dispatchBYE(const std::string &str)
00597 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
00598 };
00599 
00608 typedef SingleThreadRTPSession<> RTPSession;
00609 
00615 typedef RTPSession RTPSocket;
00616 
00625 typedef SingleThreadRTPSession<SymmetricRTPChannel,
00626                                SymmetricRTPChannel> SymmetricRTPSession;
00627 
00628 #ifdef  CCXX_IPV6
00629 
00651 template <class RTPDataChannel = DualRTPUDPIPv6Channel,
00652           class RTCPChannel = DualRTPUDPIPv6Channel,
00653           class ServiceQueue = AVPQueue>
00654 class __EXPORT TRTPSessionBaseIPV6 : public ServiceQueue
00655 {
00656 public:
00666 TRTPSessionBaseIPV6(const IPV6Host& ia, tpport_t dataPort,
00667         tpport_t controlPort, uint32 membersSize,
00668         RTPApplication& app) :
00669         ServiceQueue(membersSize,app)
00670 { build(ia,dataPort,controlPort); }
00671 
00683         TRTPSessionBaseIPV6(uint32 ssrc,
00684                             const IPV6Host& ia,
00685                             tpport_t dataPort, tpport_t controlPort,
00686                             uint32 membersSize, RTPApplication& app):
00687                 ServiceQueue(ssrc,membersSize,app)
00688                 { build(ia,dataPort,controlPort); }
00689 
00702         TRTPSessionBaseIPV6(const IPV6Multicast& ia, tpport_t dataPort,
00703                             tpport_t controlPort, uint32 membersSize,
00704                             RTPApplication& app, uint32 iface) :
00705                 ServiceQueue(membersSize,app)
00706                 { build(ia,dataPort,controlPort,iface); }
00707 
00722         TRTPSessionBaseIPV6(uint32 ssrc,
00723                             const IPV6Multicast& ia, tpport_t dataPort,
00724                             tpport_t controlPort, uint32 membersSize,
00725                             RTPApplication& app, uint32 iface) :
00726                 ServiceQueue(ssrc,membersSize,app)
00727                 { build(ia,dataPort,controlPort,iface); }
00728 
00729         virtual size_t dispatchBYE(const std::string &str)
00730                 {
00731                         return QueueRTCPManager::dispatchBYE(str);
00732                 }
00733 
00734         inline virtual
00735         ~TRTPSessionBaseIPV6()
00736                 {
00737                         endSocket();
00738                 }
00739 
00740         inline RTPDataChannel *getDSO(void)
00741                 {return dso;};
00742 
00743 protected:
00747         inline bool
00748         isPendingData(microtimeout_t timeout)
00749                 { return dso->isPendingRecv(timeout); }
00750 
00751         inline IPV6Host
00752         getDataSender(tpport_t *port = NULL) const
00753                 { return dso->getSender(port); }
00754 
00755         inline size_t
00756         getNextDataPacketSize() const
00757                 { return dso->getNextPacketSize(); }
00758 
00768         inline size_t
00769         recvData(unsigned char* buffer, size_t len,
00770                  IPV6Host& na, tpport_t& tp)
00771                 { na = dso->getSender(tp); return dso->recv(buffer, len); }
00772 
00773         inline void
00774         setDataPeerIPV6(const IPV6Host &host, tpport_t port)
00775                 { dso->setPeer(host,port); }
00776 
00781         inline size_t
00782         sendDataIPV6(const unsigned char* const buffer, size_t len)
00783                 { return dso->send(buffer, len); }
00784 
00785         inline SOCKET getDataRecvSocket() const
00786                 { return dso->getRecvSocket(); }
00787 
00792         inline bool
00793         isPendingControl(microtimeout_t timeout)
00794                 { return cso->isPendingRecv(timeout); }
00795 
00796         inline IPV6Host
00797         getControlSender(tpport_t *port = NULL) const
00798                 { return cso->getSender(port); }
00799 
00809         inline size_t
00810         recvControl(unsigned char *buffer, size_t len,
00811                     IPV6Host& na, tpport_t& tp)
00812                 { na = cso->getSender(tp); return cso->recv(buffer,len); }
00813 
00814         inline void
00815         setControlPeerIPV6(const IPV6Host &host, tpport_t port)
00816                 { cso->setPeer(host,port); }
00817 
00823         inline size_t
00824         sendControl(const unsigned char* const buffer, size_t len)
00825                 { return cso->send(buffer,len); }
00826 
00827         inline SOCKET getControlRecvSocket() const
00828                 { return cso->getRecvSocket(); }
00829 
00830         inline void
00831         endSocket()
00832                 {
00833                         dso->endSocket();
00834                         cso->endSocket();
00835                         if (dso) delete dso;
00836                         dso = NULL;
00837                         if (cso) delete cso;
00838                         cso = NULL;
00839                 }
00840 
00841 private:
00842         void
00843         build(const IPV6Host& ia, tpport_t dataPort,
00844               tpport_t controlPort)
00845                 {
00846                         if ( 0 == controlPort ) {
00847                                 dataBasePort = even_port(dataPort);
00848                                 controlBasePort = dataBasePort + 1;
00849                         } else {
00850                                 dataBasePort = dataPort;
00851                                 controlBasePort = controlPort;
00852                         }
00853                         dso = new RTPDataChannel(ia,dataBasePort);
00854                         cso = new RTCPChannel(ia,controlBasePort);
00855                 }
00856 
00857         void
00858         build(const IPV6Multicast& ia, tpport_t dataPort,
00859               tpport_t controlPort, uint32 iface)
00860                 {
00861                         if ( 0 == controlPort ) {
00862                                 dataBasePort = even_port(dataPort);
00863                                 controlBasePort = dataBasePort + 1;
00864                         } else {
00865                                 dataBasePort = dataPort;
00866                                 controlBasePort = controlPort;
00867                         }
00868                         dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort);
00869                         cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort);
00870                         joinGroup(ia,iface);
00871                 }
00872 
00879         inline Socket::Error
00880         joinGroup(const IPV6Multicast& ia, uint32 iface)
00881                 {
00882                         Socket::Error error  = dso->setMulticast(true);
00883                         if ( error ) return error;
00884                         error = dso->join(ia,iface);
00885                         if ( error ) return error;
00886                         error = cso->setMulticast(true);
00887                         if ( error ) {
00888                                 dso->drop(ia);
00889                                 return error;
00890                         }
00891                         error = cso->join(ia,iface);
00892                         if ( error ) {
00893                                 dso->drop(ia);
00894                                 return error;
00895                         }
00896                         return Socket::errSuccess;
00897                 }
00898 
00905         inline Socket::Error
00906         leaveGroup(const IPV6Multicast& ia)
00907                 {
00908                         Socket::Error error = dso->setMulticast(false);
00909                         if ( error ) return error;
00910                         error = dso->leaveGroup(ia);
00911                         if ( error ) return error;
00912                         error = cso->setMulticast(false);
00913                         if ( error ) return error;
00914                         return cso->leaveGroup(ia);
00915                 }
00916 
00923         inline Socket::Error
00924         setMcastTTL(uint8 ttl)
00925                 {
00926                         Socket::Error error = dso->setMulticast(true);
00927                         if ( error ) return error;
00928                         error = dso->setTimeToLive(ttl);
00929                         if ( error ) return error;
00930                         error = cso->setMulticast(true);
00931                         if ( error ) return error;
00932                         return cso->setTimeToLive(ttl);
00933                 }
00934 
00942         inline tpport_t
00943         odd_port(tpport_t port)
00944                 { return (port & 0x01)? (port) : (port - 1); }
00945 
00953         inline tpport_t
00954         even_port(tpport_t port)
00955                 { return (port & 0x01)? (port - 1) : (port); }
00956 
00957         tpport_t dataBasePort;
00958         tpport_t controlBasePort;
00959 
00960 protected:
00961         RTPDataChannel* dso;
00962         RTCPChannel* cso;
00963         friend class RTPSessionBaseHandler;
00964 };
00965 
00976 template
00977 <class RTPDataChannel = DualRTPUDPIPv6Channel,
00978  class RTCPChannel = DualRTPUDPIPv6Channel,
00979  class ServiceQueue = AVPQueue>
00980 class __EXPORT SingleThreadRTPSessionIPV6 :
00981         protected Thread,
00982         public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00983 {
00984 public:
00985         SingleThreadRTPSessionIPV6(const IPV6Host& ia,
00986                                    tpport_t dataPort = DefaultRTPDataPort,
00987                                    tpport_t controlPort = 0,
00988                                    int pri = 0,
00989                                    uint32 memberssize =
00990                                    MembershipBookkeeping::defaultMembersHashSize,
00991                                    RTPApplication& app = defaultApplication()
00992 #if defined(_MSC_VER) && _MSC_VER >= 1300
00993                 );
00994 #else
00995         ):
00996         Thread(pri),
00997         TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00998         (ia,dataPort,controlPort,memberssize,app)
00999 { }
01000 #endif
01001 
01002 SingleThreadRTPSessionIPV6(const IPV6Multicast& ia,
01003                            tpport_t dataPort = DefaultRTPDataPort,
01004                            tpport_t controlPort = 0,
01005                            int pri = 0,
01006                            uint32 memberssize =
01007                            MembershipBookkeeping::defaultMembersHashSize,
01008                            RTPApplication& app = defaultApplication(),
01009                            uint32 iface = 0
01010 #if defined(_MSC_VER) && _MSC_VER >= 1300
01011         );
01012 #else
01013         ):
01014         Thread(pri),
01015         TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
01016         (ia,dataPort,controlPort,memberssize,app,iface)
01017 { }
01018 #endif
01019 
01020 ~SingleThreadRTPSessionIPV6()
01021 {
01022     if (isRunning()) {
01023         disableStack(); Thread::join();
01024     }
01025 }
01026 
01027 #if defined(_MSC_VER) && _MSC_VER >= 1300
01028 virtual void startRunning();
01029 #else
01030 
01033 void
01034 startRunning()
01035 { enableStack(); Thread::start(); }
01036 #endif
01037 
01038 
01039 protected:
01040 inline void enableStack(void)
01041 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
01042 
01043 inline void disableStack(void)
01044 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}
01045 
01046 inline microtimeout_t getSchedulingTimeout(void)
01047 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
01048 
01049 inline void controlReceptionService(void)
01050 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
01051 
01052 inline void controlTransmissionService(void)
01053 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
01054 
01055 inline timeval getRTCPCheckInterval(void)
01056 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();};
01057 
01058 inline size_t dispatchDataPacket(void)
01059 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();};
01060 
01061 #if defined(_MSC_VER) && _MSC_VER >= 1300
01062 virtual void run(void);
01063 
01064 virtual void timerTick(void);
01065 
01066 virtual bool isPendingData(microtimeout_t timeout);
01067 #else
01068 
01069 virtual void timerTick(void)
01070 {return;}
01071 
01072 virtual bool isPendingData(microtimeout_t timeout)
01073 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
01074 
01079 virtual void run(void)
01080 {
01081         microtimeout_t timeout = 0;
01082         while ( ServiceQueue::isActive() ) {
01083                 if ( timeout < 1000 ){ // !(timeout/1000)
01084                         timeout = getSchedulingTimeout();
01085                 }
01086                 setCancel(cancelDeferred);
01087                 controlReceptionService();
01088                 controlTransmissionService();
01089                 setCancel(cancelImmediate);
01090                 microtimeout_t maxWait =
01091                         timeval2microtimeout(getRTCPCheckInterval());
01092                 // make sure the scheduling timeout is
01093                 // <= the check interval for RTCP
01094                 // packets
01095                 timeout = (timeout > maxWait)? maxWait : timeout;
01096                 if ( timeout < 1000 ) { // !(timeout/1000)
01097                         setCancel(cancelDeferred);
01098                         dispatchDataPacket();
01099                         setCancel(cancelImmediate);
01100                         timerTick();
01101                 } else {
01102                         if ( isPendingData(timeout/1000) ) {
01103                                 setCancel(cancelDeferred);
01104                                 takeInDataPacket();
01105                                 setCancel(cancelImmediate);
01106                         }
01107                         timeout = 0;
01108                 }
01109         }
01110         dispatchBYE("GNU ccRTP stack finishing.");
01111         Thread::exit();
01112 }
01113 
01114 #endif
01115 
01116 inline size_t takeInDataPacket(void)
01117 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
01118 
01119 inline size_t dispatchBYE(const std::string &str)
01120 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
01121 };
01122 
01131 typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6;
01132 
01138 typedef RTPSessionIPV6 RTPSocketIPV6;
01139 
01148  typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6,
01149                                     SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6;
01150 
01151 
01152 #endif
01153  // sessions
01155 
01156 #ifdef  CCXX_NAMESPACES
01157 }
01158 #endif
01159 
01160 #endif  //CCXX_RTP_RTP_H_
01161 

Generated on Sun Sep 14 21:00:18 2008 for ccRTP by  doxygen 1.3.9.1