blob: eebd21e41d33b7534a4dbeed56a5d0baff887cd5 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001,2002,2004 Federico Montesino Pouzols <fedemp@altern.org>.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16//
17// As a special exception, you may use this file as part of a free software
18// library without restriction. Specifically, if other files instantiate
19// templates or use macros or inline functions from this file, or you compile
20// this file and link it with other files to produce an executable, this
21// file does not by itself cause the resulting executable to be covered by
22// the GNU General Public License. This exception does not however
23// invalidate any other reasons why the executable file might be covered by
24// the GNU General Public License.
25//
26// This exception applies only to the code released under the name GNU
27// ccRTP. If you copy code from other releases into a copy of GNU
28// ccRTP, as the General Public License permits, the exception does
29// not apply to the code that you add in this way. To avoid misleading
30// anyone as to the status of such modified files, you must delete
31// this exception notice from them.
32//
33// If you write modifications of your own for GNU ccRTP, it is your choice
34// whether to permit this exception to apply to your modifications.
35// If you do not wish that, delete this exception notice.
36//
37
38/**
39 * @file cqueue.h
40 *
41 * @short Generic RTCP control queues.
42 **/
43
44#ifndef CCXX_RTP_CQUEUE_H_
45#define CCXX_RTP_CQUEUE_H_
46
47#include <ccrtp/ioqueue.h>
48
49#ifdef CCXX_NAMESPACES
50namespace ost {
51#endif
52
53/**
54 * @defgroup cqueue Generic RTCP control queues.
55 * @{
56 **/
57
58/**
59 * @class QueueRTCPManager
60 * @short Adds generic management of RTCP functions to an RTP data
61 * queue.
62 *
63 * Extends an RTP data i/o queue adding management of RTCP functions:
64 *
65 * Provide feedback on the quality of the data distribution.
66 *
67 * Convey the CNAME (persistent transport-level identifier) for every
68 * RTP source.
69 *
70 * Control the sending rate of RTCP packets
71 *
72 * Convey minimal control information about the participants
73 *
74 * This class implements generic RTCP behaviour (as specified in RFC
75 * 1889/draft-ietf-avt-rtp-new) and may be specialized for specific
76 * profiles (see AVPQueue) or particular RTCP extensions.
77 *
78 * @author Federico Montesino Pouzols <fedemp@altern.org>
79 **/
80class __EXPORT QueueRTCPManager : public RTPDataQueue,
81 protected RTCPCompoundHandler
82{
83public:
84 /**
85 * Get the most recent sender report received from a
86 * synchronization source.
87 *
88 * @param src Synchronization source of the sender info.
89 * @return Most recent sender info received from src.
90 * @retval NULL when no sender report has been received from
91 * the specified source.
92 **/
93 RTCPSenderInfo* getMRSenderInfo(SyncSource& src);
94
95 /**
96 * Ask for the info in the most recent receiver report about
97 * the local source received from the source given as
98 * parameter.
99 *
100 * @param srcFrom Source of the receiver info.
101 * @return most recent receiver info received from src.
102 * @retval NULL when no receiver report has been received from
103 * the specified source.
104 */
105 RTCPReceiverInfo* getMRReceiverInfo(SyncSource& srcFrom);
106
107 /**
108 * Set how much time the stack will wait before deleting a
109 * synchronization source that has sent an RTCP BYE packet.
110 *
111 * @param delay delay in microseconds.
112 *
113 * @note The default delay is 1000000 microseconds
114 **/
115 void setLeavingDelay(microtimeout_t delay)
116 { leavingDelay = delay; }
117
118 /**
119 * This method sets the maximum end to end delay allowed. If
120 * the processing delay plus the trip time for a packet is
121 * greater than the end to end delay, the packet is discarded,
122 * and the application cannot get it.
123 *
124 * This is a way of setting an upper bound to the end to end
125 * delay, computed as the elapsed time between the packet
126 * timestamping at the sender side, and the picking of the
127 * packet at the receiver side.
128 *
129 * @param t maximum end to end delay allowed. A value of 0
130 * implies there is no limit and is the default
131 */
132 inline void
133 setEnd2EndDelay(microtimeout_t t)
134 { end2EndDelay = t; }
135
136 inline microtimeout_t
137 getDefaultEnd2EndDelay() const
138 { return defaultEnd2EndDelay; }
139
140 inline microtimeout_t
141 getEnd2EndDelay() const
142 { return end2EndDelay; }
143
144 /**
145 * Specify the fraction of the total control bandwith to be
146 * dedicated to senders reports.
147 *
148 * @param fraction fraction of bandwidth, must be between 0 an 1.
149 *
150 * This method sets the fraction of the global control
151 * bandwidth that will be dedicated to senders reports. Of
152 * course, <code>1 - fraction</code> will be dedicated to
153 * receivers reports.
154 *
155 * @see setControlBandwidth
156 */
157 inline void
158 setSendersControlFraction(float fraction)
159 { sendControlBwFract = fraction; recvControlBwFract = 1 - fraction;}
160
161 /**
162 * Manually set the minimum interval for sending RTP compound
163 * packets
164 *
165 * @param interval minimum interval between RTCP packets, in
166 * microseconds.
167 *
168 * @see computeRTCPInterval()
169 **/
170 void
171 setMinRTCPInterval(microtimeout_t interval)
172 { rtcpMinInterval = interval; }
173
174 /**
175 * Get the total number of RTCP packets sent until now
176 **/
177 inline uint32
178 getSendRTCPPacketCount() const
179 { return ctrlSendCount; }
180
181protected:
182 QueueRTCPManager(uint32 size = RTPDataQueue::defaultMembersHashSize,
183 RTPApplication& app = defaultApplication());
184
185 QueueRTCPManager(uint32 ssrc,
186 uint32 size = RTPDataQueue::defaultMembersHashSize,
187 RTPApplication& app = defaultApplication());
188
189 virtual
190 ~QueueRTCPManager();
191
192 const RTPApplication&
193 getApplication()
194 { return queueApplication; }
195
196 inline void
197 setControlBandwidth(float fraction)
198 { controlBwFract = fraction; }
199
200 float
201 getControlBandwidth() const
202 { return controlBwFract; }
203
204 /**
205 * Build and send RTCP packets following timing rules
206 * (including the "timer reconsideration" algorithm).
207 **/
208 void
209 controlTransmissionService();
210
211 /**
212 * Process incoming RTCP packets pending in the control
213 * reception socket.
214 **/
215 void
216 controlReceptionService();
217
218 /**
219 * Appy collision and loop detection and correction algorithm
220 * when receiving RTCP packets. Follows section 8.2 in
221 * draft-ietf-avp-rtp-new.
222 *
223 * @param sourceLink link to the source object.
224 * @param is_new whether the source has been just recorded.
225 * @param na RTCP packet network address.
226 * @param tp RTCP packet source transport port.
227 *
228 * @return whether the packet must not be discarded.
229 **/
230 bool checkSSRCInRTCPPkt(SyncSourceLink& sourceLink, bool is_new,
231 InetAddress& na, tpport_t tp);
232
233 void
234 endQueueRTCPManager();
235
236 /**
237 * Plug-in for processing (acquire information carried in) an
238 * incoming RTCP Sender Report. The default implementation in
239 * this class only processes the sender information and the
240 * receiver report blocks about the local source.
241 *
242 * @param source Synchronization source this report comes from.
243 * @param SR Sender report structure.
244 * @param blocks Number of report blocks in the packet.
245 **/
246 virtual void
247 onGotSR(SyncSource& source, SendReport& SR, uint8 blocks);
248
249 /**
250 * Plug-in for processing (acquire information carried in) an
251 * incoming RTCP Receiver Report. The default implementation
252 * in this class only processes the receiver report blocks
253 * about the local source.
254 *
255 * @param source Synchronization source this report comes from.
256 * @param RR Receiver report structure
257 * @param blocks Number of report blocks in the packet
258 **/
259 virtual void
260 onGotRR(SyncSource& source, RecvReport& RR, uint8 blocks);
261
262 /**
263 * @param source Synchronization source of SDES RTCP packet.
264 * @param pkt SDES RTCP packet received.
265 **/
266 bool
267 onGotSDES(SyncSource& source, RTCPPacket& pkt);
268
269 /**
270 * Plug-in for handling of SDES chunks.
271 *
272 * @param source Synchronization source of SDES chunk.
273 * @param chunk SDES chunk structure.
274 * @param len Length of chunk, in octets.
275 *
276 * @return whether there was a CNAME.
277 **/
278 virtual bool
279 onGotSDESChunk(SyncSource& source, SDESChunk& chunk, size_t len);
280
281 /**
282 * Plug-in for handling of APP (application specific) RTCP
283 * packets.
284 *
285 * @param - Synchronization source of this packet.
286 * @param - RTCP APP packet struct.
287 * @param - Length of the app data packet, including ssrc.
288 * name and app. specific data.
289 **/
290 inline virtual void
291 onGotAPP(SyncSource&, RTCPCompoundHandler::APPPacket&,
292 size_t)
293 { return; }
294
295 inline timeval
296 getRTCPCheckInterval()
297 { return rtcpCheckInterval; }
298
299 /**
300 * Get the number of data packets sent at the time the last SR
301 * was generated.
302 **/
303 uint32
304 getLastSendPacketCount() const
305 { return lastSendPacketCount; }
306
307 /**
308 * @param n Number of members.
309 **/
310 inline void
311 setPrevMembersNum(uint32 n)
312 { reconsInfo.rtcpPMembers = n; }
313
314 inline uint32
315 getPrevMembersCount() const
316 { return reconsInfo.rtcpPMembers; }
317
318 /**
319 * This method is used to send an RTCP BYE packet. An RTCP
320 * BYE packet is sent when one of the the following
321 * circumstances occur:
322 * - when leaving the session
323 * - when we have detected that another synchronization source
324 * in the same session is using the same SSRC identifier as
325 * us.
326 *
327 * Try to post a BYE message. It will send a BYE packet as
328 * long as at least one RTP or RTCP packet has been sent
329 * before. If the number of members in the session is more
330 * than 50, the algorithm described in section 6.3.7 of
331 * RFC 3550 is applied in order to avoid a flood
332 * of BYE messages.
333 *
334 * @param reason reason to specify in the BYE packet.
335 **/
336 size_t
337 dispatchBYE(const std::string& reason);
338
339 size_t
340 sendControlToDestinations(unsigned char* buffer, size_t len);
341
342private:
343 QueueRTCPManager(const QueueRTCPManager &o);
344
345 QueueRTCPManager&
346 operator=(const QueueRTCPManager &o);
347
348 /**
349 * Posting of RTCP messages.
350 *
351 * @return std::size_t number of octets sent
352 */
353 size_t
354 dispatchControlPacket();
355
356 /**
357 * For picking up incoming RTCP packets if they are waiting. A
358 * timeout for the maximum interval since the last RTCP packet
359 * had been received is also returned. This is checked every
360 * rtcpCheckInterval seconds.
361 *
362 * This method decomposes all incoming RTCP compound packets
363 * pending in the control socket and processes each RTCP
364 * packet.
365 *
366 **/
367 void
368 takeInControlPacket();
369
370 /**
371 * Computes the interval for sending RTCP compound packets,
372 * based on the average size of RTCP packets sent and
373 * received, and the current estimated number of participants
374 * in the session.
375 *
376 * @note This currently follows the rules in section 6 of
377 * RFC 3550
378 * @todo make it more flexible as recommended in the draft. For now,
379 * we have setMinRTCPInterval.
380 *
381 * @return interval for sending RTCP compound packets
382 **/
383 virtual timeval
384 computeRTCPInterval();
385
386 /**
387 * Choose which should be the type of the next SDES item
388 * sent. This method is called when packing SDES chunks in a
389 * new RTCP packet.
390 *
391 * @return type of the next SDES item to be sent
392 **/
393 virtual SDESItemType
394 scheduleSDESItem();
395
396 /**
397 * Plug-in for SSRC collision handling.
398 *
399 * @param - previously identified source.
400 **/
401 inline virtual void
402 onSSRCCollision(const SyncSource&)
403 { }
404
405 /**
406 * Virtual reimplemented from RTPDataQueue
407 **/
408 virtual bool
409 end2EndDelayed(IncomingRTPPktLink& p);
410
411 /**
412 * Plug-in for processing of SR/RR RTCP packet
413 * profile-specific extensions (third part of SR reports or
414 * second part of RR reports).
415 *
416 * @param - Content of the profile extension.
417 * @param - Length of the extension, in octets.
418 **/
419 inline virtual void
420 onGotRRSRExtension(unsigned char*, size_t)
421 { return; }
422
423 /**
424 * A plugin point for goodbye message. Called when a BYE RTCP
425 * packet has been received from a valid synchronization
426 * source.
427 *
428 * @param - synchronization source from what a BYE RTCP
429 * packet has been just received.
430 * @param - reason string the source has provided.
431 **/
432 inline virtual void
433 onGotGoodbye(const SyncSource&, const std::string&)
434 { return; }
435
436 /**
437 * Process a BYE packet just received and identified.
438 *
439 * @param pkt previously identified RTCP BYE packet
440 * @param pointer octet number in the RTCP reception buffer
441 * where the packet is stored
442 * @param len total length of the compount RTCP packet the BYE
443 * packet to process is contained
444 *
445 * @bug if the bye packet contains several SSRCs,
446 * eventSourceLeaving is only called for the last one
447 **/
448 bool
449 getBYE(RTCPPacket &pkt, size_t &pointer, size_t len);
450
451 /**
452 * @return number of Report Blocks packed
453 **/
454 uint8
455 packReportBlocks(RRBlock* blocks, uint16& len, uint16& available);
456
457 /**
458 * Builds an SDES RTCP packet. Each chunk is built following
459 * appendix A.4 in draft-ietf-avt-rtp-new.
460 *
461 * @param len provisionary length of the RTCP compound packet
462 *
463 * @return
464 **/
465 void
466 packSDES(uint16& len);
467
468 /**
469 * This must be called in order to update the average RTCP compound
470 * packet size estimation when:
471 *
472 * a compoung RTCP packet is received (6.3.3).
473 *
474 * a compound RTCP packet is transmitted (6.3.6).
475 *
476 * @param len length in octets of the compound RTCP packet
477 * just received/transmitted.
478 **/
479 void
480 updateAvgRTCPSize(size_t len);
481
482 /**
483 * Apply reverse reconsideration adjustment to timing
484 * parameters when receiving BYE packets and not waiting to
485 * send a BYE.
486 **/
487 void
488 reverseReconsideration();
489
490 bool
491 timerReconsideration();
492
493 /**
494 * Purge sources that do not seem active any more.
495 *
496 * @note MUST be perform at least every RTCP transmission
497 * interval
498 * @todo implement it. It may be dangerous and anyway should
499 * be optional.
500 **/
501 void
502 expireSSRCs();
503
504 /**
505 * To be executed when whe are leaving the session.
506 **/
507 void
508 getOnlyBye();
509
510 /**
511 * Set item value from a string without null termination (as
512 * it is transported in RTCP packets).
513 **/
514 void
515 setSDESItem(Participant* part, SDESItemType type,
516 const char* const value, size_t len);
517
518 /**
519 * Set PRIV item previx value from a string without null
520 * termination (as it is transported in RTCP packets).
521 **/
522 void
523 setPRIVPrefix(Participant* part, const char* const value, size_t len);
524
525 /**
526 * For certain control calculations in RTCP, the size of the
527 * underlying network and transport protocols is needed. This
528 * method provides the size of the network level header for
529 * the default case of IP (20 octets). In case other protocol
530 * with different header size is used, this method should be
531 * redefined in a new specialized class.
532 *
533 * @return size of the headers of the network level. IP (20) by
534 * default.
535 **/
536 inline virtual uint16
537 networkHeaderSize()
538 { return 20; }
539
540 /**
541 * For certain control calculations in RTCP, the size of the
542 * underlying network and transport protocols is needed. This
543 * method provides the size of the transport level header for
544 * the default case of UDP (8 octets). In case other protocol
545 * with different header size is used, this method should be
546 * redefined in a new specialized class.
547 *
548 * return size of the headers of the transport level. UDP (8)
549 * by default
550 **/
551 inline virtual uint16
552 transportHeaderSize()
553 { return 8; }
554
555 SDESItemType
556 nextSDESType(SDESItemType t);
557
558 virtual size_t
559 sendControl(const unsigned char* const buffer, size_t len) = 0;
560
561 virtual size_t
562 recvControl(unsigned char* buffer, size_t len,
563 InetHostAddress& na, tpport_t& tp) = 0;
564
565 virtual bool
566 isPendingControl(microtimeout_t timeout) = 0;
567
568 // whether the RTCP service is active
569 volatile bool controlServiceActive;
570 float controlBwFract, sendControlBwFract, recvControlBwFract;
571 // number of RTCP packets sent since the beginning
572 uint32 ctrlSendCount;
573
574 // Network + transport headers size, typically size of IP +
575 // UDP headers
576 uint16 lowerHeadersSize;
577
578 SDESItemType nextScheduledSDESItem;
579 static const SDESItemType firstSchedulable;
580 static const SDESItemType lastSchedulable;
581
582 // state for rtcp timing. Its meaning is defined in
583 // draft-ietf-avt-rtp-new, 6.3.
584
585 // Parameters for timer reconsideration algorithm
586 struct {
587 timeval rtcpTp, rtcpTc, rtcpTn;
588 uint32 rtcpPMembers;
589 } reconsInfo;
590 bool rtcpWeSent;
591 uint16 rtcpAvgSize;
592 bool rtcpInitial;
593 // last time we checked if there were incoming RTCP packets
594 timeval rtcpLastCheck;
595 // interval to check if there are incoming RTCP packets
596 timeval rtcpCheckInterval;
597 // next time to check if there are incoming RTCP packets
598 timeval rtcpNextCheck;
599
600 // number of RTP data packets sent at the time of the last
601 // RTCP packet transmission.
602 uint32 lastSendPacketCount;
603
604 // minimum interval for transmission of RTCP packets. The
605 // result of computeRTCPInterval will always be >= (times a
606 // random number between 0.5 and 1.5).
607 microtimeout_t rtcpMinInterval;
608
609 microtimeout_t leavingDelay;
610 static const microtimeout_t defaultEnd2EndDelay;
611 // Maximum delay allowed between packet timestamping and
612 // packet availability for the application.
613 microtimeout_t end2EndDelay;
614 // Application this queue is bound to.
615 RTPApplication& queueApplication;
616
617 // an empty RTPData
618 static const uint16 TIMEOUT_MULTIPLIER;
619 static const double RECONSIDERATION_COMPENSATION;
620};
621
622/**
623 * This class, an RTP/RTCP queue, adds audio/video profile (AVP)
624 * specific methods to the generic RTCP service queue
625 * (QueueRTCPManager).
626 *
627 * @author Federico Montesino Pouzols <fedemp@altern.org>
628 **/
629class AVPQueue : public QueueRTCPManager
630{
631public:
632 /**
633 * Specify the bandwith available for control (RTCP) packets.
634 * This method sets the global control bandwidth for both
635 * sender and receiver reports. As recommended in RFC 1890,
636 * 1/4 of the total control bandwidth is dedicated to senders,
637 * whereas 3/4 are dedicated to receivers.
638 *
639 * @param fraction fraction of the session bandwidth, between
640 * 0 and 1
641 *
642 * @note If this method is not called, it is assumed that the
643 * control bandwidth is equal to 5% of the session
644 * bandwidth. Note also that the RFC RECOMMENDS the 5%.
645 *
646 **/
647 inline void
648 setControlBandwidth(float fraction)
649 { QueueRTCPManager::setControlBandwidth(fraction); }
650
651 float
652 getControlBandwidth() const
653 { return QueueRTCPManager::getControlBandwidth(); }
654
655protected:
656 AVPQueue(uint32 size = RTPDataQueue::defaultMembersHashSize,
657 RTPApplication& app = defaultApplication()) :
658 QueueRTCPManager(size,app)
659 { }
660
661 /**
662 * Local SSRC is given instead of computed by the queue.
663 **/
664 AVPQueue(uint32 ssrc, uint32 size =
665 RTPDataQueue::defaultMembersHashSize,
666 RTPApplication& app = defaultApplication()) :
667 QueueRTCPManager(ssrc,size,app)
668 { }
669 inline virtual ~AVPQueue()
670 { }
671};
672
673/** @}*/ // cqueue
674
675#ifdef CCXX_NAMESPACES
676}
677#endif
678
679#endif //CCXX_RTP_CQUEUE_H_
680
681/** EMACS **
682 * Local variables:
683 * mode: c++
684 * c-basic-offset: 8
685 * End:
686 */