ccRTP
oqueue.h
Go to the documentation of this file.
00001 // Copyright (C) 2001-2015 Federico Montesino Pouzols <fedemp@altern.org>.
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 Lesser General Public License
00014 // along with GNU ccRTP.  If not, see <http://www.gnu.org/licenses/>.
00015 //
00016 // As a special exception, you may use this file as part of a free software
00017 // library without restriction.  Specifically, if other files instantiate
00018 // templates or use macros or inline functions from this file, or you compile
00019 // this file and link it with other files to produce an executable, this
00020 // file does not by itself cause the resulting executable to be covered by
00021 // the GNU General Public License.  This exception does not however
00022 // invalidate any other reasons why the executable file might be covered by
00023 // the GNU General Public License.
00024 //
00025 // This exception applies only to the code released under the name GNU
00026 // ccRTP.  If you copy code from other releases into a copy of GNU
00027 // ccRTP, as the General Public License permits, the exception does
00028 // not apply to the code that you add in this way.  To avoid misleading
00029 // anyone as to the status of such modified files, you must delete
00030 // this exception notice from them.
00031 //
00032 // If you write modifications of your own for GNU ccRTP, it is your choice
00033 // whether to permit this exception to apply to your modifications.
00034 // If you do not wish that, delete this exception notice.
00035 //
00036 
00043 #ifndef CCXX_RTP_OQUEUE_H_
00044 #define CCXX_RTP_OQUEUE_H_
00045 
00046 #include <ccrtp/queuebase.h>
00047 #include <ccrtp/CryptoContext.h>
00048 #include <list>
00049 
00050 NAMESPACE_COMMONCPP
00051 
00065 class __EXPORT DestinationListHandler
00066 {
00067 protected:
00068     struct TransportAddress;
00069     std::list<TransportAddress*> destList;
00070 
00071 public:
00072     DestinationListHandler();
00073 
00074     ~DestinationListHandler();
00075 
00079     inline bool isSingleDestination() const
00080     { return (1 == destList.size()); }
00081 
00082     inline TransportAddress* getFirstDestination() const
00083     { return destList.front(); }
00084 
00085     inline void lockDestinationList() const
00086     { destinationLock.readLock(); }
00087 
00088     inline void unlockDestinationList() const
00089     { destinationLock.unlock(); }
00090 
00091 protected:
00092     inline void writeLockDestinationList() const
00093     { destinationLock.writeLock(); }
00094 
00098     bool
00099     addDestinationToList(const InetAddress& ia, tpport_t data,
00100                  tpport_t control);
00101 
00105     bool removeDestinationFromList(const InetAddress& ia,
00106                        tpport_t dataPort,
00107                        tpport_t controlPort);
00108 
00109     struct TransportAddress
00110     {
00111         TransportAddress(InetAddress na, tpport_t dtp, tpport_t ctp) :
00112             networkAddress(na), dataTransportPort(dtp),
00113             controlTransportPort(ctp)
00114         {  }
00115 
00116         inline const InetAddress& getNetworkAddress() const
00117         { return networkAddress; }
00118 
00119         inline tpport_t getDataTransportPort() const
00120         { return dataTransportPort; }
00121 
00122         inline tpport_t getControlTransportPort() const
00123         { return controlTransportPort; }
00124 
00125         InetAddress networkAddress;
00126         tpport_t dataTransportPort, controlTransportPort;
00127     };
00128 
00129 private:
00130     mutable ThreadLock destinationLock;
00131 };
00132 
00133 #ifdef  CCXX_IPV6
00134 
00142 class __EXPORT DestinationListHandlerIPV6
00143 {
00144 protected:
00145     struct TransportAddressIPV6;
00146     std::list<TransportAddressIPV6*> destListIPV6;
00147 
00148 public:
00149     DestinationListHandlerIPV6();
00150 
00151     ~DestinationListHandlerIPV6();
00152 
00156     inline bool isSingleDestinationIPV6() const
00157     { return (1 == destListIPV6.size()); }
00158 
00159     inline TransportAddressIPV6* getFirstDestinationIPV6() const
00160     { return destListIPV6.front(); }
00161 
00162     inline void lockDestinationListIPV6() const
00163     { destinationLock.readLock(); }
00164 
00165     inline void unlockDestinationListIPV6() const
00166     { destinationLock.unlock(); }
00167 
00168 protected:
00169     inline void writeLockDestinationListIPV6() const
00170     { destinationLock.writeLock(); }
00171 
00175     bool
00176     addDestinationToListIPV6(const IPV6Address& ia, tpport_t data,
00177                  tpport_t control);
00178 
00182     bool removeDestinationFromListIPV6(const IPV6Address& ia,
00183                        tpport_t dataPort,
00184                        tpport_t controlPort);
00185 
00186     struct TransportAddressIPV6
00187     {
00188         TransportAddressIPV6(IPV6Address na, tpport_t dtp, tpport_t ctp) :
00189             networkAddress(na), dataTransportPort(dtp),
00190             controlTransportPort(ctp)
00191         {  }
00192 
00193         inline const IPV6Address& getNetworkAddress() const
00194         { return networkAddress; }
00195 
00196         inline tpport_t getDataTransportPort() const
00197         { return dataTransportPort; }
00198 
00199         inline tpport_t getControlTransportPort() const
00200         { return controlTransportPort; }
00201 
00202         IPV6Address networkAddress;
00203         tpport_t dataTransportPort, controlTransportPort;
00204     };
00205 
00206 private:
00207     mutable ThreadLock destinationLock;
00208 };
00209 
00210 #endif
00211 
00219 class __EXPORT OutgoingDataQueue:
00220     public OutgoingDataQueueBase,
00221 #ifdef  CCXX_IPV6
00222     protected DestinationListHandlerIPV6,
00223 #endif
00224     protected DestinationListHandler
00225 {
00226 public:
00227 #ifdef  CCXX_IPV6
00228     bool
00229     addDestination(const IPV6Address& ia,
00230                tpport_t dataPort = DefaultRTPDataPort,
00231                tpport_t controlPort = 0);
00232 
00233     bool
00234     forgetDestination(const IPV6Address& ia,
00235               tpport_t dataPort = DefaultRTPDataPort,
00236               tpport_t controlPort = 0);
00237 
00238 #endif
00239 
00240     bool
00241     addDestination(const InetHostAddress& ia,
00242                tpport_t dataPort = DefaultRTPDataPort,
00243                tpport_t controlPort = 0);
00244 
00245     bool
00246     addDestination(const InetMcastAddress& ia,
00247                tpport_t dataPort = DefaultRTPDataPort,
00248                tpport_t controlPort = 0);
00249 
00250     bool
00251     forgetDestination(const InetHostAddress& ia,
00252               tpport_t dataPort = DefaultRTPDataPort,
00253               tpport_t controlPort = 0);
00254 
00255     bool
00256     forgetDestination(const InetMcastAddress& ia,
00257               tpport_t dataPort = DefaultRTPDataPort,
00258               tpport_t controlPort = 0);
00259 
00265     void
00266     addContributor(uint32 csrc);
00267 
00271     bool
00272     removeContributor(uint32 csrc);
00273 
00279     bool
00280     isSending() const;
00281 
00282 
00295     void
00296     putData(uint32 stamp, const unsigned char* data = NULL, size_t len = 0);
00297 
00310         void
00311         sendImmediate(uint32 stamp, const unsigned char* data = NULL, size_t len = 0);
00312 
00313 
00320     void setPadding(uint8 paddinglen)
00321     { sendInfo.paddinglen = paddinglen; }
00322 
00331     void setMark(bool mark)
00332     { sendInfo.marked = mark; }
00333 
00337     inline bool getMark() const
00338     { return sendInfo.marked; }
00339 
00350     size_t
00351     setPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
00352 
00353     inline microtimeout_t
00354     getDefaultSchedulingTimeout() const
00355     { return defaultSchedulingTimeout; }
00356 
00363     inline void
00364     setSchedulingTimeout(microtimeout_t to)
00365     { schedulingTimeout = to; }
00366 
00367     inline microtimeout_t
00368     getDefaultExpireTimeout() const
00369     { return defaultExpireTimeout; }
00370 
00378     inline void
00379     setExpireTimeout(microtimeout_t to)
00380     { expireTimeout = to; }
00381 
00382     inline microtimeout_t getExpireTimeout() const
00383     { return expireTimeout; }
00384 
00390     inline uint32
00391     getSendPacketCount() const
00392     { return sendInfo.packetCount; }
00393 
00399     inline uint32
00400     getSendOctetCount() const
00401     { return sendInfo.octetCount; }
00402 
00408         inline uint16
00409         getSequenceNumber() const
00410         { return sendInfo.sendSeq; }
00411 
00420         void
00421         setOutQueueCryptoContext(CryptoContext* cc);
00422 
00431         void
00432         removeOutQueueCryptoContext(CryptoContext* cc);
00433 
00441         CryptoContext*
00442         getOutQueueCryptoContext(uint32 ssrc);
00443 
00444 
00445 protected:
00446     OutgoingDataQueue();
00447 
00448     virtual ~OutgoingDataQueue()
00449     { }
00450 
00451     struct OutgoingRTPPktLink
00452     {
00453         OutgoingRTPPktLink(OutgoingRTPPkt* pkt,
00454                    OutgoingRTPPktLink* p,
00455                    OutgoingRTPPktLink* n) :
00456             packet(pkt), prev(p), next(n) { }
00457 
00458         ~OutgoingRTPPktLink() { delete packet; }
00459 
00460         inline OutgoingRTPPkt* getPacket() { return packet; }
00461 
00462         inline void setPacket(OutgoingRTPPkt* pkt) { packet = pkt; }
00463 
00464         inline OutgoingRTPPktLink* getPrev() { return prev; }
00465 
00466         inline void setPrev(OutgoingRTPPktLink* p) { prev = p; }
00467 
00468         inline OutgoingRTPPktLink* getNext() { return next; }
00469 
00470         inline void setNext(OutgoingRTPPktLink* n) { next = n; }
00471 
00472         // the packet this link refers to.
00473         OutgoingRTPPkt* packet;
00474         // global outgoing packets queue.
00475         OutgoingRTPPktLink * prev, * next;
00476     };
00477 
00485     void
00486     dispatchImmediate(OutgoingRTPPkt *packet);
00487 
00497     microtimeout_t
00498     getSchedulingTimeout();
00499 
00506     size_t
00507     dispatchDataPacket();
00508 
00517     inline void
00518     setNextSeqNum(uint32 seqNum)
00519     { sendInfo.sendSeq = seqNum; }
00520 
00521     inline uint32
00522     getCurrentSeqNum(void)
00523     { return sendInfo.sendSeq; }
00524 
00527     inline void
00528     setInitialTimestamp(uint32 ts)
00529     { initialTimestamp = ts; }
00530 
00533     inline uint32
00534     getInitialTimestamp()
00535     { return initialTimestamp; }
00536 
00537     void purgeOutgoingQueue();
00538 
00539         virtual void
00540         setControlPeer(const InetAddress &host, tpport_t port) {}
00541 
00542 #ifdef  CCXX_IPV6
00543     virtual void
00544     setControlPeerIPV6(const IPV6Address &host, tpport_t port) {}
00545 #endif
00546 
00547         // The crypto contexts for outgoing SRTP sessions.
00548     mutable Mutex cryptoMutex;
00549         std::list<CryptoContext *> cryptoContexts;
00550 
00551 private:
00557     inline virtual void onExpireSend(OutgoingRTPPkt&)
00558     { }
00559 
00560     virtual void
00561         setDataPeer(const InetAddress &host, tpport_t port) {}
00562 
00563 #ifdef  CCXX_IPV6
00564     virtual void
00565     setDataPeerIPV6(const IPV6Address &host, tpport_t port) {}
00566 #endif
00567 
00577     virtual size_t
00578     sendData(const unsigned char* const buffer, size_t len) {return 0;}
00579 
00580 #ifdef  CCXX_IPV6
00581     virtual size_t
00582     sendDataIPV6(const unsigned char* const buffer, size_t len) {return 0;}
00583 #endif
00584 
00585     static const microtimeout_t defaultSchedulingTimeout;
00586     static const microtimeout_t defaultExpireTimeout;
00587     mutable ThreadLock sendLock;
00588     // outgoing data packets queue
00589     OutgoingRTPPktLink* sendFirst, * sendLast;
00590     uint32 initialTimestamp;
00591     // transmission scheduling timeout for the service thread
00592     microtimeout_t schedulingTimeout;
00593     // how old a packet can reach in the sending queue before deletetion
00594     microtimeout_t expireTimeout;
00595 
00596 
00597     struct {
00598         // number of packets sent from the beginning
00599         uint32 packetCount;
00600         // number of payload octets sent from the beginning
00601         uint32 octetCount;
00602         // the sequence number of the next packet to sent
00603         uint16 sendSeq;
00604         // contributing sources
00605         uint32 sendSources[16];
00606         // how many CSRCs to send.
00607         uint16 sendCC;
00608         // pad packets to a paddinglen multiple
00609         uint8 paddinglen;
00610         // This flags tells whether to set the bit M in the
00611         // RTP fixed header of the packet in which the next
00612         // provided data will be sent.
00613         bool marked;
00614         // whether there was not loss.
00615         bool complete;
00616         // ramdonly generated offset for the timestamp of sent packets
00617         uint32 initialTimestamp;
00618         // elapsed time accumulated through successive overflows of
00619         // the local timestamp field
00620         timeval overflowTime;
00621     } sendInfo;
00622 };
00623  // oqueue
00625 
00626 END_NAMESPACE
00627 
00628 #endif  //CCXX_RTP_OQUEUE_H_
00629