blob: 6187b7e9c118be37249c05401360183b66556b66 [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
Alexandre Lisionddd731e2014-01-31 11:50:08 -050044#ifndef CCXX_RTP_CQUEUE_H_
Emeric Vigier2f625822012-08-06 11:09:52 -040045#define CCXX_RTP_CQUEUE_H_
46
47#include <ccrtp/ioqueue.h>
Alexandre Lisionddd731e2014-01-31 11:50:08 -050048#include <ccrtp/CryptoContextCtrl.h>
49#include <list>
Emeric Vigier2f625822012-08-06 11:09:52 -040050
Alexandre Lisionddd731e2014-01-31 11:50:08 -050051NAMESPACE_COMMONCPP
Emeric Vigier2f625822012-08-06 11:09:52 -040052
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,
Alexandre Lisionddd731e2014-01-31 11:50:08 -050081 protected RTCPCompoundHandler
Emeric Vigier2f625822012-08-06 11:09:52 -040082{
83public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -050084 /**
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);
Emeric Vigier2f625822012-08-06 11:09:52 -040094
Alexandre Lisionddd731e2014-01-31 11:50:08 -050095 /**
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);
Emeric Vigier2f625822012-08-06 11:09:52 -0400106
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500107 /**
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; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400117
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500118 /**
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; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400135
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500136 inline microtimeout_t
137 getDefaultEnd2EndDelay() const
138 { return defaultEnd2EndDelay; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400139
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500140 inline microtimeout_t
141 getEnd2EndDelay() const
142 { return end2EndDelay; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400143
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500144 /**
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;}
Emeric Vigier2f625822012-08-06 11:09:52 -0400160
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500161 /**
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; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400173
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500174 /**
175 * Get the total number of RTCP packets sent until now
176 **/
177 inline uint32
178 getSendRTCPPacketCount() const
179 { return ctrlSendCount; }
180
181 /**
182 * Set ouput queue CryptoContext.
183 *
184 * The endQueue method (provided by RTPQueue) deletes all
185 * registered CryptoContexts.
186 *
187 * @param cc Pointer to initialized CryptoContext.
188 */
189 void
190 setOutQueueCryptoContextCtrl(CryptoContextCtrl* cc);
191
192 /**
193 * Remove output queue CryptoContext.
194 *
195 * The endQueue method (provided by RTPQueue) also deletes all
196 * registered CryptoContexts.
197 *
198 * @param cc Pointer to initialized CryptoContext to remove.
199 */
200 void
201 removeOutQueueCryptoContextCtrl(CryptoContextCtrl* cc);
202
203 /**
204 * Get an output queue CryptoContext identified by SSRC
205 *
206 * @param ssrc Request CryptoContext for this incoming SSRC
207 * @return Pointer to CryptoContext of the SSRC of NULL if no context
208 * available for this SSRC.
209 */
210 CryptoContextCtrl*
211 getOutQueueCryptoContextCtrl(uint32 ssrc);
212
213
214 /**
215 * Set input queue CryptoContext.
216 *
217 * The endQueue method (provided by RTPQueue) deletes all
218 * registered CryptoContexts.
219 *
220 * @param cc Pointer to initialized CryptoContext.
221 */
222 void
223 setInQueueCryptoContextCtrl(CryptoContextCtrl* cc);
224
225 /**
226 * Remove input queue CryptoContext.
227 *
228 * The endQueue method (provided by RTPQueue) also deletes all
229 * registered CryptoContexts.
230 *
231 * @param cc
232 * Pointer to initialized CryptoContext to remove. If pointer
233 * if <code>NULL</code> then delete the whole queue
234 */
235 void
236 removeInQueueCryptoContextCtrl(CryptoContextCtrl* cc);
237
238 /**
239 * Get an input queue CryptoContext identified by SSRC
240 *
241 * @param ssrc Request CryptoContext for this incoming SSRC
242 * @return Pointer to CryptoContext of the SSRC of NULL if no context
243 * available for this SSRC.
244 */
245 CryptoContextCtrl*
246 getInQueueCryptoContextCtrl(uint32 ssrc);
Emeric Vigier2f625822012-08-06 11:09:52 -0400247
248protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500249 QueueRTCPManager(uint32 size = RTPDataQueue::defaultMembersHashSize,
250 RTPApplication& app = defaultApplication());
Emeric Vigier2f625822012-08-06 11:09:52 -0400251
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500252 QueueRTCPManager(uint32 ssrc,
253 uint32 size = RTPDataQueue::defaultMembersHashSize,
254 RTPApplication& app = defaultApplication());
Emeric Vigier2f625822012-08-06 11:09:52 -0400255
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500256 virtual
257 ~QueueRTCPManager();
Emeric Vigier2f625822012-08-06 11:09:52 -0400258
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500259 const RTPApplication&
260 getApplication()
261 { return queueApplication; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400262
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500263 inline void
264 setControlBandwidth(float fraction)
265 { controlBwFract = fraction; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400266
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500267 float
268 getControlBandwidth() const
269 { return controlBwFract; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400270
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500271 /**
272 * Build and send RTCP packets following timing rules
273 * (including the "timer reconsideration" algorithm).
274 **/
275 void
276 controlTransmissionService();
Emeric Vigier2f625822012-08-06 11:09:52 -0400277
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500278 /**
279 * Process incoming RTCP packets pending in the control
280 * reception socket.
281 **/
282 void
283 controlReceptionService();
Emeric Vigier2f625822012-08-06 11:09:52 -0400284
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500285 /**
286 * Appy collision and loop detection and correction algorithm
287 * when receiving RTCP packets. Follows section 8.2 in
288 * draft-ietf-avp-rtp-new.
289 *
290 * @param sourceLink link to the source object.
291 * @param is_new whether the source has been just recorded.
292 * @param na RTCP packet network address.
293 * @param tp RTCP packet source transport port.
294 *
295 * @return whether the packet must not be discarded.
296 **/
297 bool checkSSRCInRTCPPkt(SyncSourceLink& sourceLink, bool is_new,
298 InetAddress& na, tpport_t tp);
Emeric Vigier2f625822012-08-06 11:09:52 -0400299
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500300 void
301 endQueueRTCPManager();
Emeric Vigier2f625822012-08-06 11:09:52 -0400302
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500303 /**
304 * Plug-in for processing (acquire information carried in) an
305 * incoming RTCP Sender Report. The default implementation in
306 * this class only processes the sender information and the
307 * receiver report blocks about the local source.
308 *
309 * @param source Synchronization source this report comes from.
310 * @param SR Sender report structure.
311 * @param blocks Number of report blocks in the packet.
312 **/
313 virtual void
314 onGotSR(SyncSource& source, SendReport& SR, uint8 blocks);
Emeric Vigier2f625822012-08-06 11:09:52 -0400315
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500316 /**
317 * Plug-in for processing (acquire information carried in) an
318 * incoming RTCP Receiver Report. The default implementation
319 * in this class only processes the receiver report blocks
320 * about the local source.
321 *
322 * @param source Synchronization source this report comes from.
323 * @param RR Receiver report structure
324 * @param blocks Number of report blocks in the packet
325 **/
326 virtual void
327 onGotRR(SyncSource& source, RecvReport& RR, uint8 blocks);
Emeric Vigier2f625822012-08-06 11:09:52 -0400328
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500329 /**
330 * @param source Synchronization source of SDES RTCP packet.
331 * @param pkt SDES RTCP packet received.
332 **/
333 bool
334 onGotSDES(SyncSource& source, RTCPPacket& pkt);
Emeric Vigier2f625822012-08-06 11:09:52 -0400335
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500336 /**
337 * Plug-in for handling of SDES chunks.
338 *
339 * @param source Synchronization source of SDES chunk.
340 * @param chunk SDES chunk structure.
341 * @param len Length of chunk, in octets.
342 *
343 * @return whether there was a CNAME.
344 **/
345 virtual bool
346 onGotSDESChunk(SyncSource& source, SDESChunk& chunk, size_t len);
Emeric Vigier2f625822012-08-06 11:09:52 -0400347
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500348 /**
349 * Plug-in for handling of APP (application specific) RTCP
350 * packets.
351 *
352 * @param - Synchronization source of this packet.
353 * @param - RTCP APP packet struct.
354 * @param - Length of the app data packet, including ssrc.
355 * name and app. specific data.
356 **/
357 inline virtual void
358 onGotAPP(SyncSource&, RTCPCompoundHandler::APPPacket&,
359 size_t)
360 { return; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400361
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500362 inline timeval
363 getRTCPCheckInterval()
364 { return rtcpCheckInterval; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400365
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500366 /**
367 * Get the number of data packets sent at the time the last SR
368 * was generated.
369 **/
370 uint32
371 getLastSendPacketCount() const
372 { return lastSendPacketCount; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400373
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500374 /**
375 * @param n Number of members.
376 **/
377 inline void
378 setPrevMembersNum(uint32 n)
379 { reconsInfo.rtcpPMembers = n; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400380
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500381 inline uint32
382 getPrevMembersCount() const
383 { return reconsInfo.rtcpPMembers; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400384
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500385 /**
386 * This method is used to send an RTCP BYE packet. An RTCP
387 * BYE packet is sent when one of the the following
388 * circumstances occur:
389 * - when leaving the session
390 * - when we have detected that another synchronization source
391 * in the same session is using the same SSRC identifier as
392 * us.
393 *
394 * Try to post a BYE message. It will send a BYE packet as
395 * long as at least one RTP or RTCP packet has been sent
396 * before. If the number of members in the session is more
397 * than 50, the algorithm described in section 6.3.7 of
398 * RFC 3550 is applied in order to avoid a flood
399 * of BYE messages.
400 *
401 * @param reason reason to specify in the BYE packet.
402 **/
403 size_t
404 dispatchBYE(const std::string& reason);
Emeric Vigier2f625822012-08-06 11:09:52 -0400405
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500406 size_t
407 sendControlToDestinations(unsigned char* buffer, size_t len);
Emeric Vigier2f625822012-08-06 11:09:52 -0400408
409private:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500410 QueueRTCPManager(const QueueRTCPManager &o);
Emeric Vigier2f625822012-08-06 11:09:52 -0400411
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500412 QueueRTCPManager&
413 operator=(const QueueRTCPManager &o);
Emeric Vigier2f625822012-08-06 11:09:52 -0400414
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500415 /**
416 * Posting of RTCP messages.
417 *
418 * @return std::size_t number of octets sent
419 */
420 size_t
421 dispatchControlPacket();
Emeric Vigier2f625822012-08-06 11:09:52 -0400422
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500423 /**
424 * For picking up incoming RTCP packets if they are waiting. A
425 * timeout for the maximum interval since the last RTCP packet
426 * had been received is also returned. This is checked every
427 * rtcpCheckInterval seconds.
428 *
429 * This method decomposes all incoming RTCP compound packets
430 * pending in the control socket and processes each RTCP
431 * packet.
432 *
433 **/
434 void
435 takeInControlPacket();
Emeric Vigier2f625822012-08-06 11:09:52 -0400436
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500437 /**
438 * Computes the interval for sending RTCP compound packets,
439 * based on the average size of RTCP packets sent and
440 * received, and the current estimated number of participants
441 * in the session.
442 *
443 * @note This currently follows the rules in section 6 of
444 * RFC 3550
445 * @todo make it more flexible as recommended in the draft. For now,
446 * we have setMinRTCPInterval.
447 *
448 * @return interval for sending RTCP compound packets
449 **/
450 virtual timeval
451 computeRTCPInterval();
Emeric Vigier2f625822012-08-06 11:09:52 -0400452
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500453 /**
454 * Choose which should be the type of the next SDES item
455 * sent. This method is called when packing SDES chunks in a
456 * new RTCP packet.
457 *
458 * @return type of the next SDES item to be sent
459 **/
460 virtual SDESItemType
461 scheduleSDESItem();
Emeric Vigier2f625822012-08-06 11:09:52 -0400462
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500463 /**
464 * Plug-in for SSRC collision handling.
465 *
466 * @param - previously identified source.
467 **/
468 inline virtual void
469 onSSRCCollision(const SyncSource&)
470 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400471
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500472 /**
473 * Virtual reimplemented from RTPDataQueue
474 **/
475 virtual bool
476 end2EndDelayed(IncomingRTPPktLink& p);
Emeric Vigier2f625822012-08-06 11:09:52 -0400477
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500478 /**
479 * Plug-in for processing of SR/RR RTCP packet
480 * profile-specific extensions (third part of SR reports or
481 * second part of RR reports).
482 *
483 * @param - Content of the profile extension.
484 * @param - Length of the extension, in octets.
485 **/
486 inline virtual void
487 onGotRRSRExtension(unsigned char*, size_t)
488 { return; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400489
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500490 /**
491 * A plugin point for goodbye message. Called when a BYE RTCP
492 * packet has been received from a valid synchronization
493 * source.
494 *
495 * @param - synchronization source from what a BYE RTCP
496 * packet has been just received.
497 * @param - reason string the source has provided.
498 **/
499 inline virtual void
500 onGotGoodbye(const SyncSource&, const std::string&)
501 { return; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400502
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500503 /**
504 * Process a BYE packet just received and identified.
505 *
506 * @param pkt previously identified RTCP BYE packet
507 * @param pointer octet number in the RTCP reception buffer
508 * where the packet is stored
509 * @param len total length of the compount RTCP packet the BYE
510 * packet to process is contained
511 *
512 * @bug if the bye packet contains several SSRCs,
513 * eventSourceLeaving is only called for the last one
514 **/
515 bool
516 getBYE(RTCPPacket &pkt, size_t &pointer, size_t len);
Emeric Vigier2f625822012-08-06 11:09:52 -0400517
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500518 /**
519 * @return number of Report Blocks packed
520 **/
521 uint8
522 packReportBlocks(RRBlock* blocks, uint16& len, uint16& available);
Emeric Vigier2f625822012-08-06 11:09:52 -0400523
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500524 /**
525 * Builds an SDES RTCP packet. Each chunk is built following
526 * appendix A.4 in draft-ietf-avt-rtp-new.
527 *
528 * @param len provisionary length of the RTCP compound packet
529 *
530 * @return
531 **/
532 void
533 packSDES(uint16& len);
Emeric Vigier2f625822012-08-06 11:09:52 -0400534
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500535 /**
536 * This must be called in order to update the average RTCP compound
537 * packet size estimation when:
538 *
539 * a compoung RTCP packet is received (6.3.3).
540 *
541 * a compound RTCP packet is transmitted (6.3.6).
542 *
543 * @param len length in octets of the compound RTCP packet
544 * just received/transmitted.
545 **/
546 void
547 updateAvgRTCPSize(size_t len);
Emeric Vigier2f625822012-08-06 11:09:52 -0400548
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500549 /**
550 * Apply reverse reconsideration adjustment to timing
551 * parameters when receiving BYE packets and not waiting to
552 * send a BYE.
553 **/
554 void
555 reverseReconsideration();
Emeric Vigier2f625822012-08-06 11:09:52 -0400556
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500557 bool
558 timerReconsideration();
Emeric Vigier2f625822012-08-06 11:09:52 -0400559
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500560 /**
561 * Purge sources that do not seem active any more.
562 *
563 * @note MUST be perform at least every RTCP transmission
564 * interval
565 * @todo implement it. It may be dangerous and anyway should
566 * be optional.
567 **/
568 void
569 expireSSRCs();
Emeric Vigier2f625822012-08-06 11:09:52 -0400570
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500571 /**
572 * To be executed when whe are leaving the session.
573 **/
574 void
575 getOnlyBye();
Emeric Vigier2f625822012-08-06 11:09:52 -0400576
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500577 /**
578 * Set item value from a string without null termination (as
579 * it is transported in RTCP packets).
580 **/
581 void
582 setSDESItem(Participant* part, SDESItemType type,
583 const char* const value, size_t len);
Emeric Vigier2f625822012-08-06 11:09:52 -0400584
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500585 /**
586 * Set PRIV item previx value from a string without null
587 * termination (as it is transported in RTCP packets).
588 **/
589 void
590 setPRIVPrefix(Participant* part, const char* const value, size_t len);
Emeric Vigier2f625822012-08-06 11:09:52 -0400591
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500592 /**
593 * For certain control calculations in RTCP, the size of the
594 * underlying network and transport protocols is needed. This
595 * method provides the size of the network level header for
596 * the default case of IP (20 octets). In case other protocol
597 * with different header size is used, this method should be
598 * redefined in a new specialized class.
599 *
600 * @return size of the headers of the network level. IP (20) by
601 * default.
602 **/
603 inline virtual uint16
604 networkHeaderSize()
605 { return 20; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400606
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500607 /**
608 * For certain control calculations in RTCP, the size of the
609 * underlying network and transport protocols is needed. This
610 * method provides the size of the transport level header for
611 * the default case of UDP (8 octets). In case other protocol
612 * with different header size is used, this method should be
613 * redefined in a new specialized class.
614 *
615 * return size of the headers of the transport level. UDP (8)
616 * by default
617 **/
618 inline virtual uint16
619 transportHeaderSize()
620 { return 8; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400621
Emeric Vigier2f625822012-08-06 11:09:52 -0400622
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500623 int32 protect(uint8* pkt, size_t len, CryptoContextCtrl* cc);
624 int32 unprotect(uint8* pkt, size_t len, CryptoContextCtrl* cc);
625
626
627 SDESItemType
628 nextSDESType(SDESItemType t);
Emeric Vigier2f625822012-08-06 11:09:52 -0400629
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500630 virtual size_t
631 sendControl(const unsigned char* const buffer, size_t len) = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -0400632
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500633 virtual size_t
634 recvControl(unsigned char* buffer, size_t len,
635 InetHostAddress& na, tpport_t& tp) = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -0400636
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500637 virtual bool
638 isPendingControl(microtimeout_t timeout) = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -0400639
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500640 // whether the RTCP service is active
641 volatile bool controlServiceActive;
642 float controlBwFract, sendControlBwFract, recvControlBwFract;
643 // number of RTCP packets sent since the beginning
644 uint32 ctrlSendCount;
Emeric Vigier2f625822012-08-06 11:09:52 -0400645
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500646 // Network + transport headers size, typically size of IP +
647 // UDP headers
648 uint16 lowerHeadersSize;
Emeric Vigier2f625822012-08-06 11:09:52 -0400649
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500650 SDESItemType nextScheduledSDESItem;
651 static const SDESItemType firstSchedulable;
652 static const SDESItemType lastSchedulable;
Emeric Vigier2f625822012-08-06 11:09:52 -0400653
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500654 // state for rtcp timing. Its meaning is defined in
655 // draft-ietf-avt-rtp-new, 6.3.
Emeric Vigier2f625822012-08-06 11:09:52 -0400656
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500657 // Parameters for timer reconsideration algorithm
658 struct {
659 timeval rtcpTp, rtcpTc, rtcpTn;
660 uint32 rtcpPMembers;
661 } reconsInfo;
662 bool rtcpWeSent;
663 uint16 rtcpAvgSize;
664 bool rtcpInitial;
665 // last time we checked if there were incoming RTCP packets
666 timeval rtcpLastCheck;
667 // interval to check if there are incoming RTCP packets
668 timeval rtcpCheckInterval;
669 // next time to check if there are incoming RTCP packets
670 timeval rtcpNextCheck;
Emeric Vigier2f625822012-08-06 11:09:52 -0400671
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500672 // number of RTP data packets sent at the time of the last
673 // RTCP packet transmission.
674 uint32 lastSendPacketCount;
Emeric Vigier2f625822012-08-06 11:09:52 -0400675
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500676 // minimum interval for transmission of RTCP packets. The
677 // result of computeRTCPInterval will always be >= (times a
678 // random number between 0.5 and 1.5).
679 microtimeout_t rtcpMinInterval;
Emeric Vigier2f625822012-08-06 11:09:52 -0400680
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500681 microtimeout_t leavingDelay;
682 static const microtimeout_t defaultEnd2EndDelay;
683 // Maximum delay allowed between packet timestamping and
684 // packet availability for the application.
685 microtimeout_t end2EndDelay;
686 // Application this queue is bound to.
687 RTPApplication& queueApplication;
688
689 // an empty RTPData
690 static const uint16 TIMEOUT_MULTIPLIER;
691 static const double RECONSIDERATION_COMPENSATION;
692
693 mutable Mutex outCryptoMutex;
694 std::list<CryptoContextCtrl *> outCryptoContexts;
695 uint32 srtcpIndex;
696
697 mutable Mutex inCryptoMutex;
698 std::list<CryptoContextCtrl *> inCryptoContexts;
699
Emeric Vigier2f625822012-08-06 11:09:52 -0400700};
701
702/**
703 * This class, an RTP/RTCP queue, adds audio/video profile (AVP)
704 * specific methods to the generic RTCP service queue
705 * (QueueRTCPManager).
706 *
707 * @author Federico Montesino Pouzols <fedemp@altern.org>
708 **/
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500709class __EXPORT AVPQueue : public QueueRTCPManager
Emeric Vigier2f625822012-08-06 11:09:52 -0400710{
711public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500712 /**
713 * Specify the bandwith available for control (RTCP) packets.
714 * This method sets the global control bandwidth for both
715 * sender and receiver reports. As recommended in RFC 1890,
716 * 1/4 of the total control bandwidth is dedicated to senders,
717 * whereas 3/4 are dedicated to receivers.
718 *
719 * @param fraction fraction of the session bandwidth, between
720 * 0 and 1
721 *
722 * @note If this method is not called, it is assumed that the
723 * control bandwidth is equal to 5% of the session
724 * bandwidth. Note also that the RFC RECOMMENDS the 5%.
725 *
726 **/
727 inline void
728 setControlBandwidth(float fraction)
729 { QueueRTCPManager::setControlBandwidth(fraction); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400730
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500731 float
732 getControlBandwidth() const
733 { return QueueRTCPManager::getControlBandwidth(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400734
735protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500736 AVPQueue(uint32 size = RTPDataQueue::defaultMembersHashSize,
737 RTPApplication& app = defaultApplication()) :
738 QueueRTCPManager(size,app)
739 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400740
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500741 /**
742 * Local SSRC is given instead of computed by the queue.
743 **/
744 AVPQueue(uint32 ssrc, uint32 size =
745 RTPDataQueue::defaultMembersHashSize,
746 RTPApplication& app = defaultApplication()) :
747 QueueRTCPManager(ssrc,size,app)
748 { }
749 inline virtual ~AVPQueue()
750 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400751};
752
753/** @}*/ // cqueue
754
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500755END_NAMESPACE
Emeric Vigier2f625822012-08-06 11:09:52 -0400756
757#endif //CCXX_RTP_CQUEUE_H_
758
759/** EMACS **
760 * Local variables:
761 * mode: c++
762 * c-basic-offset: 8
763 * End:
764 */