blob: 36350d47afe2ed5ad7667efd3b85a66025fcf1df [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 iqueue.h
40 *
41 * @short Generic RTP input queues.
42 **/
43
Alexandre Lisionddd731e2014-01-31 11:50:08 -050044#ifndef CCXX_RTP_IQUEUE_H_
Emeric Vigier2f625822012-08-06 11:09:52 -040045#define CCXX_RTP_IQUEUE_H_
46
47#include <ccrtp/queuebase.h>
48#include <ccrtp/CryptoContext.h>
49
50#include <list>
51
Alexandre Lisionddd731e2014-01-31 11:50:08 -050052NAMESPACE_COMMONCPP
Emeric Vigier2f625822012-08-06 11:09:52 -040053
54/**
55 * @defgroup iqueue Generic RTP input queues.
56 * @{
57 **/
58
59/**
60 * @class Members rtp.h
61 * @short members and senders accounting
62 *
63 * Records the number of members as well as active senders. For now,
64 * it is too simple.
65 *
66 * @author Federico Montesino Pouzols <fedemp@altern.org>
67 **/
68class __EXPORT Members
69{
70public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -050071 inline void
72 setMembersCount(uint32 n)
73 { members = n; }
Emeric Vigier2f625822012-08-06 11:09:52 -040074
Alexandre Lisionddd731e2014-01-31 11:50:08 -050075 inline void
76 increaseMembersCount()
77 { members++; }
Emeric Vigier2f625822012-08-06 11:09:52 -040078
Alexandre Lisionddd731e2014-01-31 11:50:08 -050079 inline void
80 decreaseMembersCount()
81 { members--; }
Emeric Vigier2f625822012-08-06 11:09:52 -040082
Alexandre Lisionddd731e2014-01-31 11:50:08 -050083 inline uint32
84 getMembersCount() const
85 { return members; }
Emeric Vigier2f625822012-08-06 11:09:52 -040086
Alexandre Lisionddd731e2014-01-31 11:50:08 -050087 inline void
88 setSendersCount(uint32 n)
89 { activeSenders = n; }
Emeric Vigier2f625822012-08-06 11:09:52 -040090
Alexandre Lisionddd731e2014-01-31 11:50:08 -050091 inline void
92 increaseSendersCount()
93 { activeSenders++; }
Emeric Vigier2f625822012-08-06 11:09:52 -040094
Alexandre Lisionddd731e2014-01-31 11:50:08 -050095 inline void
96 decreaseSendersCount()
97 { activeSenders--; }
Emeric Vigier2f625822012-08-06 11:09:52 -040098
Alexandre Lisionddd731e2014-01-31 11:50:08 -050099 inline uint32
100 getSendersCount() const
101 { return activeSenders; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400102
103protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500104 Members() :
105 members(0),
106 activeSenders(0)
107 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400108
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500109 inline virtual ~Members()
110 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400111
112private:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500113 /// number of identified members
114 uint32 members;
115 /// number of identified members that currently are active senders
116 uint32 activeSenders;
Emeric Vigier2f625822012-08-06 11:09:52 -0400117};
118
119/**
120 * @class SyncSourceHandler
121 * @short SyncSource objects modification methods.
122 *
123 * @author Federico Montesino Pouzols <fedemp@altern.org>
124 **/
125class __EXPORT SyncSourceHandler
126{
127public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500128 /**
129 * This requires SyncSource - SyncSourceHandler friendship.
130 *
131 * Get the SyncSourceLink corresponding to a SyncSource
132 * object.
133 **/
134 inline void*
135 getLink(const SyncSource& source) const
136 { return source.getLink(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400137
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500138 inline void
139 setLink(SyncSource& source, void* link)
140 { source.setLink(link); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400141
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500142 inline void
143 setParticipant(SyncSource& source, Participant& p)
144 { source.setParticipant(p); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400145
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500146 inline void
147 setState(SyncSource& source, SyncSource::State ns)
148 { source.setState(ns); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400149
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500150 inline void
151 setSender(SyncSource& source, bool active)
152 { source.setSender(active); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400153
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500154 inline void
155 setDataTransportPort(SyncSource& source, tpport_t p)
156 { source.setDataTransportPort(p); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400157
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500158 inline void
159 setControlTransportPort(SyncSource& source, tpport_t p)
160 { source.setControlTransportPort(p); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400161
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500162 inline void
163 setNetworkAddress(SyncSource& source, InetAddress addr)
164 { source.setNetworkAddress(addr); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400165
166protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500167 SyncSourceHandler()
168 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400169
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500170 inline virtual ~SyncSourceHandler()
171 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400172};
173
174/**
175 * @class ParticipantHandler
176 * @short Participant objects modification methods.
177 *
178 * @author Federico Montesino Pouzols <fedemp@altern.org>
179 **/
180class __EXPORT ParticipantHandler
181{
182public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500183 inline void
184 setSDESItem(Participant* part, SDESItemType item,
185 const std::string& val)
186 { part->setSDESItem(item,val); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400187
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500188 inline void
189 setPRIVPrefix(Participant* part, const std::string val)
190 { part->setPRIVPrefix(val); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400191
192protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500193 ParticipantHandler()
194 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400195
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500196 inline virtual ~ParticipantHandler()
197 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400198};
199
200/**
201 * @class ApplicationHandler
202 * @short Application objects modification methods.
203 *
204 * @author Federico Montesino Pouzols <fedemp@altern.org>
205 **/
206class __EXPORT ApplicationHandler
207{
208public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500209 inline void
210 addParticipant(RTPApplication& app, Participant& part)
211 { app.addParticipant(part); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400212
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500213 inline void
214 removeParticipant(RTPApplication& app,
215 RTPApplication::ParticipantLink* pl)
216 { app.removeParticipant(pl); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400217
218protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500219 ApplicationHandler()
220 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400221
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500222 inline virtual ~ApplicationHandler()
223 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400224};
225
226/**
227 * @class ConflictHandler
228 * @short To track addresses of sources conflicting with the local
229 * one.
230 *
231 * @author Federico Montesino Pouzols <fedemp@altern.org>
232 **/
233class __EXPORT ConflictHandler
234{
235public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500236 struct ConflictingTransportAddress
237 {
238 ConflictingTransportAddress(InetAddress na,
239 tpport_t dtp, tpport_t ctp);
Emeric Vigier2f625822012-08-06 11:09:52 -0400240
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500241 void setNext(ConflictingTransportAddress* nc)
242 { next = nc; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400243
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500244 inline const InetAddress& getNetworkAddress( ) const
245 { return networkAddress; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400246
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500247 inline tpport_t getDataTransportPort() const
248 { return dataTransportPort; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400249
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500250 inline tpport_t getControlTransportPort() const
251 { return controlTransportPort; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400252
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500253 InetAddress networkAddress;
254 tpport_t dataTransportPort;
255 tpport_t controlTransportPort;
256 ConflictingTransportAddress* next;
257 // arrival time of last data or control packet.
258 timeval lastPacketTime;
259 };
Emeric Vigier2f625822012-08-06 11:09:52 -0400260
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500261 /**
262 * @param na Inet network address.
263 * @param dtp Data transport port.
264 **/
265 ConflictingTransportAddress* searchDataConflict(InetAddress na,
266 tpport_t dtp);
267 /**
268 * @param na Inet network address.
269 * @param ctp Data transport port.
270 **/
271 ConflictingTransportAddress* searchControlConflict(InetAddress na,
272 tpport_t ctp);
Emeric Vigier2f625822012-08-06 11:09:52 -0400273
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500274 void updateConflict(ConflictingTransportAddress& ca)
275 { SysTime::gettimeofday(&(ca.lastPacketTime),NULL); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400276
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500277 void addConflict(const InetAddress& na, tpport_t dtp, tpport_t ctp);
Emeric Vigier2f625822012-08-06 11:09:52 -0400278
279protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500280 ConflictHandler()
281 { firstConflict = lastConflict = NULL; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400282
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500283 inline virtual ~ConflictHandler()
284 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400285
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500286 ConflictingTransportAddress* firstConflict, * lastConflict;
Emeric Vigier2f625822012-08-06 11:09:52 -0400287};
288
289/**
290 * @class MembershipBookkeeping
291 * @short Controls the group membership in the current session.
292 *
293 * For now, this class implements only a hash table of members, but
294 * its design and relation with other classes is intented to support
295 * group membership sampling in case scalability problems arise.
296 *
297 * @author Federico Montesino Pouzols <fedemp@altern.org>
298 */
299class __EXPORT MembershipBookkeeping :
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500300 public SyncSourceHandler,
301 public ParticipantHandler,
302 public ApplicationHandler,
303 public ConflictHandler,
304 private Members
Emeric Vigier2f625822012-08-06 11:09:52 -0400305{
306public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500307 inline size_t getDefaultMembersHashSize()
308 { return defaultMembersHashSize; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400309
310protected:
311
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500312 /**
313 * @short The initial size is a hint to allocate the resources
314 * needed in order to keep the members' identifiers and
315 * associated information.
316 *
317 * Although ccRTP will reallocate resources when it becomes
318 * necessary, a good hint may save a lot of unpredictable time
319 * penalties.
320 *
321 * @param initialSize an estimation of how many participants
322 * the session will consist of.
323 *
324 */
325 MembershipBookkeeping(uint32 initialSize = defaultMembersHashSize);
Emeric Vigier2f625822012-08-06 11:09:52 -0400326
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500327 /**
328 * Purges all RTPSource structures created during the session,
329 * as well as the hash table and the list of sources.
330 **/
331 inline virtual
332 ~MembershipBookkeeping()
333 { endMembers(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400334
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500335 struct SyncSourceLink;
Emeric Vigier2f625822012-08-06 11:09:52 -0400336
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500337 inline SyncSourceLink* getLink(const SyncSource& source) const
338 { return static_cast<SyncSourceLink*>(SyncSourceHandler::getLink(source)); }
339 /**
340 * Get whether a synchronization source is recorded in this
341 * membership controller.
342 **/
343 inline bool isMine(const SyncSource& source) const
344 { return getLink(source)->getMembership() == this; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400345
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500346 /**
347 * @struct IncomingRTPPktLink
348 *
349 * @short Incoming RTP data packets control structure within
350 * the incoming packet queue class.
351 **/
352 struct IncomingRTPPktLink
353 {
354 IncomingRTPPktLink(IncomingRTPPkt* pkt, SyncSourceLink* sLink,
355 struct timeval& recv_ts,
356 uint32 shifted_ts,
357 IncomingRTPPktLink* sp,
358 IncomingRTPPktLink* sn,
359 IncomingRTPPktLink* p,
360 IncomingRTPPktLink* n) :
361 packet(pkt),
362 sourceLink(sLink),
363 prev(p), next(n),
364 srcPrev(sp), srcNext(sn),
365 receptionTime(recv_ts),
366 shiftedTimestamp(shifted_ts)
367 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400368
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500369 ~IncomingRTPPktLink()
370 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400371
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500372 inline SyncSourceLink* getSourceLink() const
373 { return sourceLink; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400374
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500375 inline void setSourceLink(SyncSourceLink* src)
376 { sourceLink = src; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400377
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500378 inline IncomingRTPPktLink* getNext() const
379 { return next; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400380
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500381 inline void setNext(IncomingRTPPktLink* nl)
382 { next = nl; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400383
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500384 inline IncomingRTPPktLink* getPrev() const
385 { return prev; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400386
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500387 inline void setPrev(IncomingRTPPktLink* pl)
388 { prev = pl; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400389
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500390 inline IncomingRTPPktLink* getSrcNext() const
391 { return srcNext; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400392
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500393 inline void setSrcNext(IncomingRTPPktLink* sn)
394 { srcNext = sn; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400395
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500396 inline IncomingRTPPktLink* getSrcPrev() const
397 { return srcPrev; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400398
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500399 inline void setSrcPrev(IncomingRTPPktLink* sp)
400 { srcPrev = sp; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400401
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500402 inline IncomingRTPPkt* getPacket() const
403 { return packet; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400404
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500405 inline void setPacket(IncomingRTPPkt* pkt)
406 { packet = pkt; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400407
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500408 /**
409 * Set the time this packet was received at.
410 *
411 * @param t time of reception.
412 * @note this has almost nothing to do with the 32-bit
413 * timestamp contained in the packet header.
414 **/
415 inline void setRecvTime(const timeval &t)
416 { receptionTime = t; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400417
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500418 /**
419 * Get the time this packet was received at.
420 **/
421 inline timeval getRecvTime() const
422 { return receptionTime; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400423
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500424 /**
425 * Get timestamp of this packet. The timestamp of
426 * incoming packets is filtered so that the timestamp
427 * this method provides for the first packet received
428 * from every source starts from 0.
429 *
430 * @return 32 bit timestamp starting from 0 for each source.
431 */
432 inline uint32 getTimestamp() const
433 { return shiftedTimestamp; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400434
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500435 inline void setTimestamp(uint32 ts)
436 { shiftedTimestamp = ts;}
Emeric Vigier2f625822012-08-06 11:09:52 -0400437
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500438 // the packet this link refers to.
439 IncomingRTPPkt* packet;
440 // the synchronization source this packet comes from.
441 SyncSourceLink* sourceLink;
442 // global incoming packet queue links.
443 IncomingRTPPktLink* prev, * next;
444 // source specific incoming packet queue links.
445 IncomingRTPPktLink* srcPrev, * srcNext;
446 // time this packet was received at
447 struct timeval receptionTime;
448 // timestamp of the packet in host order and after
449 // substracting the initial timestamp for its source
450 // (it is an increment from the initial timestamp).
451 uint32 shiftedTimestamp;
452 };
Emeric Vigier2f625822012-08-06 11:09:52 -0400453
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500454 /**
455 * @struct SyncSourceLink
456 *
457 * @short Synchronization Source internal handler within the
458 * incoming packets queue.
459 *
460 * Incoming packets queue objects hold a hash table and a
461 * linked list of synchronization sources. For each of these
462 * sources, there is also a linked list of incoming rtp
463 * packets, which are linked in an "all incoming packets" list
464 * as well. SyncSourceLink objects hold the necessary data to
465 * maintain these data estructures, as well as source specific
466 * information and statistics for RTCP,
467 *
468 * @author Federico Montesino Pouzols <fedemp@altern.org>
469 **/
470 struct SyncSourceLink
471 {
472 // 2^16
473 static const uint32 SEQNUMMOD;
Emeric Vigier2f625822012-08-06 11:09:52 -0400474
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500475 SyncSourceLink(MembershipBookkeeping* m,
476 SyncSource* s,
477 IncomingRTPPktLink* fp = NULL,
478 IncomingRTPPktLink* lp = NULL,
479 SyncSourceLink* ps = NULL,
480 SyncSourceLink* ns = NULL,
481 SyncSourceLink* ncollis = NULL) :
482 membership(m), source(s), first(fp), last(lp),
483 prev(ps), next(ns), nextCollis(ncollis),
484 prevConflict(NULL)
485 { m->setLink(*s,this); // record that the source is associated
486 initStats(); // to this link.
487 }
Emeric Vigier2f625822012-08-06 11:09:52 -0400488
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500489 /**
490 * Note it deletes the source.
491 **/
492 ~SyncSourceLink();
Emeric Vigier2f625822012-08-06 11:09:52 -0400493
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500494 inline MembershipBookkeeping* getMembership()
495 { return membership; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400496
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500497 /**
498 * Get the synchronization source object this link
499 * objet holds information for.
500 **/
501 inline SyncSource* getSource() { return source; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400502
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500503 /**
504 * Get first RTP (data) packet in the queue of packets
505 * received from this socket.
506 **/
507 inline IncomingRTPPktLink* getFirst()
508 { return first; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400509
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500510 inline void setFirst(IncomingRTPPktLink* fp)
511 { first = fp; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400512
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500513 /**
514 * Get last RTP (data) packet in the queue of packets
515 * received from this socket.
516 **/
517 inline IncomingRTPPktLink* getLast()
518 { return last; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400519
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500520 inline void setLast(IncomingRTPPktLink* lp)
521 { last = lp; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400522
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500523 /**
524 * Get the link object for the previous RTP source.
525 **/
526 inline SyncSourceLink* getPrev()
527 { return prev; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400528
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500529 inline void setPrev(SyncSourceLink* ps)
530 { prev = ps; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400531
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500532 /**
533 * Get the link object for the next RTP source.
534 **/
535 inline SyncSourceLink* getNext()
536 { return next; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400537
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500538 inline void setNext(SyncSourceLink *ns)
539 { next = ns; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400540
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500541 /**
542 * Get the link object for the next RTP source in the
543 * hash table entry collision list. Note that
544 * collision does not refer to SSRC collision, but
545 * hash table collision.
546 **/
547 inline SyncSourceLink* getNextCollis()
548 { return nextCollis; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400549
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500550 inline void setNextCollis(SyncSourceLink* ns)
551 { nextCollis = ns; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400552
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500553 inline ConflictingTransportAddress* getPrevConflict() const
554 { return prevConflict; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400555
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500556 /**
557 * Get conflicting address.
558 **/
559 void setPrevConflict(InetAddress& addr, tpport_t dataPort,
560 tpport_t controlPort);
Emeric Vigier2f625822012-08-06 11:09:52 -0400561
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500562 unsigned char* getSenderInfo()
563 { return senderInfo; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400564
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500565 void setSenderInfo(unsigned char* si);
Emeric Vigier2f625822012-08-06 11:09:52 -0400566
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500567 unsigned char* getReceiverInfo()
568 { return receiverInfo; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400569
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500570 void setReceiverInfo(unsigned char* ri);
Emeric Vigier2f625822012-08-06 11:09:52 -0400571
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500572 inline timeval getLastPacketTime() const
573 { return lastPacketTime; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400574
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500575 inline timeval getLastRTCPPacketTime() const
576 { return lastRTCPPacketTime; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400577
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500578 inline timeval getLastRTCPSRTime() const
579 { return lastRTCPSRTime; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400580
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500581 /**
582 * Get the total number of RTP packets received from this
583 * source.
584 */
585 inline uint32 getObservedPacketCount() const
586 { return obsPacketCount; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400587
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500588 inline void incObservedPacketCount()
589 { obsPacketCount++; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400590
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500591 /**
592 * Get the total number of payload octets received from this
593 * source.
594 **/
595 inline uint32 getObservedOctetCount() const
596 { return obsOctetCount; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400597
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500598 inline void incObservedOctetCount(uint32 n)
599 { obsOctetCount += n; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400600
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500601 /**
602 * Get the highest valid sequence number received.
603 **/
604 uint16
605 getMaxSeqNum() const
606 { return maxSeqNum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400607
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500608 /**
609 * Set the highest valid sequence number recived.
610 * @param max Sequence number.
611 **/
612 void
613 setMaxSeqNum(uint16 max)
614 { maxSeqNum = max; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400615
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500616 inline uint32
617 getExtendedMaxSeqNum() const
618 { return extendedMaxSeqNum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400619
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500620 inline void
621 setExtendedMaxSeqNum(uint32 seq)
622 { extendedMaxSeqNum = seq; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400623
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500624 inline uint32 getCumulativePacketLost() const
625 { return cumulativePacketLost; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400626
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500627 inline void setCumulativePacketLost(uint32 pl)
628 { cumulativePacketLost = pl; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400629
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500630 inline uint8 getFractionLost() const
631 { return fractionLost; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400632
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500633 inline void setFractionLost(uint8 fl)
634 { fractionLost = fl; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400635
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500636 inline uint32 getLastPacketTransitTime()
637 { return lastPacketTransitTime; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400638
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500639 inline void setLastPacketTransitTime(uint32 time)
640 { lastPacketTransitTime = time; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400641
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500642 inline float getJitter() const
643 { return jitter; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400644
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500645 inline void setJitter(float j)
646 { jitter = j; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400647
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500648 inline uint32 getInitialDataTimestamp() const
649 { return initialDataTimestamp; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400650
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500651 inline void setInitialDataTimestamp(uint32 ts)
652 { initialDataTimestamp = ts; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400653
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500654 inline timeval getInitialDataTime() const
655 { return initialDataTime; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400656
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500657 inline void setInitialDataTime(timeval it)
658 { initialDataTime = it; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400659
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500660 /**
661 * Mark this source as having sent a BYE control packet.
662 *
663 * @return whether some packet from this source had
664 * been received before (getHello() has been called at
665 * least once)
666 **/
667 bool getGoodbye()
668 {
669 if(!flag)
670 return false;
671 flag = false;
672 return true;
673 }
Emeric Vigier2f625822012-08-06 11:09:52 -0400674
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500675 /**
676 * Mark this source as having sent some packet.
677 *
678 * @return whether no packet from this source had been
679 * received before
680 **/
681 bool getHello() {
682 if(flag)
683 return false;
684 flag = true;
685 return true;
686 }
Emeric Vigier2f625822012-08-06 11:09:52 -0400687
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500688 inline uint32 getBadSeqNum() const
689 { return badSeqNum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400690
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500691 inline void setBadSeqNum(uint32 seq)
692 { badSeqNum = seq; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400693
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500694 uint8 getProbation() const
695 { return probation; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400696
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500697 inline void setProbation(uint8 p)
698 { probation = p; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400699
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500700 inline void decProbation()
701 { --probation; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400702
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500703 bool isValid() const
704 { return 0 == probation; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400705
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500706 inline uint16 getBaseSeqNum() const
707 { return baseSeqNum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400708
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500709 inline uint32 getSeqNumAccum() const
710 { return seqNumAccum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400711
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500712 inline void incSeqNumAccum()
713 { seqNumAccum += SEQNUMMOD; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400714
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500715 /**
716 * Start a new sequence of received packets.
717 **/
718 inline void initSequence(uint16 seqnum)
719 { maxSeqNum = seqNumAccum = seqnum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400720
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500721 /**
722 * Record the insertion of an RTP packet from this
723 * source into the scheduled reception queue. All
724 * received packets should be registered with
725 * recordReception(), but only those actually inserted
726 * into the queue should be registered via this
727 * method.
728 *
729 * @param pl Link structure for packet inserted into the queue.
730 **/
731 void recordInsertion(const IncomingRTPPktLink& pl);
Emeric Vigier2f625822012-08-06 11:09:52 -0400732
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500733 void initStats();
Emeric Vigier2f625822012-08-06 11:09:52 -0400734
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500735 /**
736 * Compute cumulative packet lost and fraction of
737 * packets lost during the last reporting interval.
738 **/
739 void computeStats();
Emeric Vigier2f625822012-08-06 11:09:52 -0400740
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500741 MembershipBookkeeping* membership;
742 // The source this link object refers to.
743 SyncSource* source;
744 // first/last packets from this source in the queue.
745 IncomingRTPPktLink* first, * last;
746 // Links for synchronization sources located before
747 // and after this one in the list of sources.
748 SyncSourceLink* prev, * next;
749 // Prev and next inside the hash table collision list.
750 SyncSourceLink* nextCollis;
751 ConflictingTransportAddress* prevConflict;
752 unsigned char* senderInfo;
753 unsigned char* receiverInfo;
754 // time the last RTP packet from this source was
755 // received at.
756 timeval lastPacketTime;
757 // time the last RTCP packet was received.
758 timeval lastRTCPPacketTime;
759 // time the lasrt RTCP SR was received. Required for
760 // DLSR computation.
761 timeval lastRTCPSRTime;
Emeric Vigier2f625822012-08-06 11:09:52 -0400762
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500763 // for outgoing RR reports.
764 // number of packets received from this source.
765 uint32 obsPacketCount;
766 // number of octets received from this source.
767 uint32 obsOctetCount;
768 // the higher sequence number seen from this source
769 uint16 maxSeqNum;
770 uint32 extendedMaxSeqNum;
771 uint32 cumulativePacketLost;
772 uint8 fractionLost;
773 // for interarrivel jitter computation
774 uint32 lastPacketTransitTime;
775 // interarrival jitter of packets from this source.
776 float jitter;
777 uint32 initialDataTimestamp;
778 timeval initialDataTime;
Emeric Vigier2f625822012-08-06 11:09:52 -0400779
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500780 // this flag assures we only call one gotHello and one
781 // gotGoodbye for this src.
782 bool flag;
Emeric Vigier2f625822012-08-06 11:09:52 -0400783
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500784 // for source validation:
785 uint32 badSeqNum;
786 uint8 probation; // packets in sequence before valid.
787 uint16 baseSeqNum;
788 uint32 expectedPrior;
789 uint32 receivedPrior;
790 uint32 seqNumAccum;
791 };
Emeric Vigier2f625822012-08-06 11:09:52 -0400792
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500793 /**
794 * Returns whether there is already a synchronizacion source
795 * with "ssrc" SSRC identifier.
796 **/
797 bool
798 isRegistered(uint32 ssrc);
Emeric Vigier2f625822012-08-06 11:09:52 -0400799
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500800 /**
801 * Get the description of a source by its <code>ssrc</code> identifier.
802 *
803 * @param ssrc SSRC identifier, in host order.
804 * @param created whether a new source has been created.
805 * @return Pointer to the SyncSource object identified by
806 * <code>ssrc</code>.
807 */
808 SyncSourceLink*
809 getSourceBySSRC(uint32 ssrc, bool& created);
Emeric Vigier2f625822012-08-06 11:09:52 -0400810
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500811 /**
812 * Mark the source identified by <code>ssrc</code> as having
813 * sent a BYE packet. It is not deleted until a timeout
814 * expires, so that in case some packets from this source
815 * arrive a bit later the source is not inserted again in the
816 * table of known sources.
817 *
818 * @return true if the source had been previously identified.
819 * false if it was not in the table of known sources.
820 **/
821 bool
822 BYESource(uint32 ssrc);
Emeric Vigier2f625822012-08-06 11:09:52 -0400823
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500824 /**
825 * Remove the description of the source identified by
826 * <code>ssrc</code>
827 *
828 * @return whether the source has been actually removed or it
829 * did not exist.
830 */
831 bool
832 removeSource(uint32 ssrc);
Emeric Vigier2f625822012-08-06 11:09:52 -0400833
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500834 inline SyncSourceLink* getFirst()
835 { return first; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400836
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500837 inline SyncSourceLink* getLast()
838 { return last; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400839
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500840 inline uint32
841 getMembersCount()
842 { return Members::getMembersCount(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400843
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500844 inline void
845 setMembersCount(uint32 n)
846 { Members::setMembersCount(n); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400847
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500848 inline uint32
849 getSendersCount()
850 { return Members::getSendersCount(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400851
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500852 static const size_t defaultMembersHashSize;
853 static const uint32 SEQNUMMOD;
Emeric Vigier2f625822012-08-06 11:09:52 -0400854
855private:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500856 MembershipBookkeeping(const MembershipBookkeeping &o);
Emeric Vigier2f625822012-08-06 11:09:52 -0400857
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500858 MembershipBookkeeping&
859 operator=(const MembershipBookkeeping &o);
Emeric Vigier2f625822012-08-06 11:09:52 -0400860
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500861 /**
862 * Purge all RTPSource structures, the hash table and the list
863 * of sources.
864 **/
865 void
866 endMembers();
Emeric Vigier2f625822012-08-06 11:09:52 -0400867
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500868 // Hash table with sources of RTP and RTCP packets
869 uint32 sourceBucketsNum;
870 SyncSourceLink** sourceLinks;
871 // List of sources, ordered from older to newer
872 SyncSourceLink* first, * last;
Emeric Vigier2f625822012-08-06 11:09:52 -0400873};
874
875/**
876 * @class IncomingDataQueue
877 * @short Queue for incoming RTP data packets in an RTP session.
878 *
879 * @author Federico Montesino Pouzols <fedemp@altern.org>
880 **/
881class __EXPORT IncomingDataQueue: public IncomingDataQueueBase,
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500882 protected MembershipBookkeeping
Emeric Vigier2f625822012-08-06 11:09:52 -0400883{
884public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500885 /**
886 * @class SyncSourcesIterator
887 * @short iterator through the list of synchronizations
888 * sources in this session
889 **/
890 class SyncSourcesIterator
891 {
892 public:
893 typedef std::forward_iterator_tag iterator_category;
894 typedef SyncSource value_type;
895 typedef std::ptrdiff_t difference_type;
896 typedef const SyncSource* pointer;
897 typedef const SyncSource& reference;
Emeric Vigier2f625822012-08-06 11:09:52 -0400898
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500899 SyncSourcesIterator(SyncSourceLink* l = NULL) :
900 link(l)
901 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400902
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500903 SyncSourcesIterator(const SyncSourcesIterator& si) :
904 link(si.link)
905 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400906
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500907 reference operator*() const
908 { return *(link->getSource()); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400909
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500910 pointer operator->() const
911 { return link->getSource(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400912
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500913 SyncSourcesIterator& operator++() {
914 link = link->getNext();
915 return *this;
916 }
Emeric Vigier2f625822012-08-06 11:09:52 -0400917
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500918 SyncSourcesIterator operator++(int) {
919 SyncSourcesIterator result(*this);
920 ++(*this);
921 return result;
922 }
Emeric Vigier2f625822012-08-06 11:09:52 -0400923
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500924 friend bool operator==(const SyncSourcesIterator& l,
925 const SyncSourcesIterator& r)
926 { return l.link == r.link; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400927
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500928 friend bool operator!=(const SyncSourcesIterator& l,
929 const SyncSourcesIterator& r)
930 { return l.link != r.link; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400931
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500932 private:
933 SyncSourceLink *link;
934 };
Emeric Vigier2f625822012-08-06 11:09:52 -0400935
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500936 SyncSourcesIterator begin()
937 { return SyncSourcesIterator(MembershipBookkeeping::getFirst()); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400938
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500939 SyncSourcesIterator end()
940 { return SyncSourcesIterator(NULL); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400941
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500942 /**
943 * Retreive data from a specific timestamped packet if such a
944 * packet is currently available in the receive buffer.
945 *
946 * @param stamp Data unit timestamp.
947 * @param src Optional synchronization source selector.
948 * @return data retrieved from the reception buffer.
949 * @retval null pointer if no packet with such timestamp is available.
950 **/
951 const AppDataUnit*
952 getData(uint32 stamp, const SyncSource* src = NULL);
Emeric Vigier2f625822012-08-06 11:09:52 -0400953
954
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500955 /**
956 * Determine if packets are waiting in the reception queue.
957 *
958 * @param src Optional synchronization source selector.
959 * @return True if packets are waiting.
960 */
961 bool
962 isWaiting(const SyncSource* src = NULL) const;
Emeric Vigier2f625822012-08-06 11:09:52 -0400963
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500964 /**
965 * Get timestamp of first packet waiting in the queue.
966 *
967 * @param src optional source selector.
968 * @return timestamp of first arrival packet.
969 **/
970 uint32
971 getFirstTimestamp(const SyncSource* src = NULL) const;
Emeric Vigier2f625822012-08-06 11:09:52 -0400972
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500973 /**
974 * When receiving packets from a new source, it may be
975 * convenient to reject a first few packets before we are
976 * really sure the source is valid. This method sets how many
977 * data packets must be received in sequence before the source
978 * is considered valid and the stack starts to accept its
979 * packets.
980 *
981 * @note the default (see defaultMinValidPacketSequence())
982 * value for this parameter is 0, so that no packets are
983 * rejected (data packets are accepted from the first one).
984 *
985 * @note this validation is performed after the generic header
986 * validation and the additional validation done in
987 * onRTPPacketRecv().
988 *
989 * @note if any valid RTCP packet is received from this
990 * source, it will be immediatly considered valid regardless
991 * of the number of sequential data packets received.
992 *
993 * @param packets number of sequential packet required
994 **/
995 void
996 setMinValidPacketSequence(uint8 packets)
997 { minValidPacketSequence = packets; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400998
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500999 uint8
1000 getDefaultMinValidPacketSequence() const
1001 { return defaultMinValidPacketSequence; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001002
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001003 /**
1004 * Get the minimun number of consecutive packets that must be
1005 * received from a source before accepting its data packets.
1006 **/
1007 uint8
1008 getMinValidPacketSequence() const
1009 { return minValidPacketSequence; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001010
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001011 void
1012 setMaxPacketMisorder(uint16 packets)
1013 { maxPacketMisorder = packets; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001014
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001015 uint16
1016 getDefaultMaxPacketMisorder() const
1017 { return defaultMaxPacketMisorder; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001018
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001019 uint16
1020 getMaxPacketMisorder() const
1021 { return maxPacketMisorder; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001022
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001023 /**
1024 *
1025 * It also prevents packets sent after a restart of the source
1026 * being immediately accepted.
1027 **/
1028 void
1029 setMaxPacketDropout(uint16 packets) // default: 3000.
1030 { maxPacketDropout = packets; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001031
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001032 uint16
1033 getDefaultMaxPacketDropout() const
1034 { return defaultMaxPacketDropout; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001035
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001036 uint16
1037 getMaxPacketDropout() const
1038 { return maxPacketDropout; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001039
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001040 // default value for constructors that allow to specify
1041 // members table s\ize
Emeric Vigier2f625822012-08-06 11:09:52 -04001042 inline static size_t
1043 getDefaultMembersSize()
1044 { return defaultMembersSize; }
1045
1046 /**
1047 * Set input queue CryptoContext.
1048 *
1049 * The endQueue method (provided by RTPQueue) deletes all
1050 * registered CryptoContexts.
1051 *
1052 * @param cc Pointer to initialized CryptoContext.
1053 */
1054 void
1055 setInQueueCryptoContext(CryptoContext* cc);
1056
1057 /**
1058 * Remove input queue CryptoContext.
1059 *
1060 * The endQueue method (provided by RTPQueue) also deletes all
1061 * registered CryptoContexts.
1062 *
1063 * @param cc
1064 * Pointer to initialized CryptoContext to remove. If pointer
1065 * if <code>NULL</code> then delete the whole queue
1066 */
1067 void
1068 removeInQueueCryptoContext(CryptoContext* cc);
1069
1070 /**
1071 * Get an input queue CryptoContext identified by SSRC
1072 *
1073 * @param ssrc Request CryptoContext for this incoming SSRC
1074 * @return Pointer to CryptoContext of the SSRC of NULL if no context
1075 * available for this SSRC.
1076 */
1077 CryptoContext*
1078 getInQueueCryptoContext(uint32 ssrc);
1079
1080protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001081 /**
1082 * @param size initial size of the membership table.
1083 **/
1084 IncomingDataQueue(uint32 size);
Emeric Vigier2f625822012-08-06 11:09:52 -04001085
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001086 virtual ~IncomingDataQueue()
1087 { }
Emeric Vigier2f625822012-08-06 11:09:52 -04001088
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001089 /**
1090 * Apply collision and loop detection and correction algorithm
1091 * when receiving RTP data packets. Follows section 8.2 in
1092 * draft-ietf-avt-rtp-new.
1093 *
1094 * @param sourceLink link to the source object.
1095 * @param is_new whether the source has been just recorded.
1096 * @param na data packet network address.
1097 * @param tp data packet source transport port.
1098 *
1099 * @return whether the packet must not be discarded.
1100 **/
1101 bool checkSSRCInIncomingRTPPkt(SyncSourceLink& sourceLink,
1102 bool is_new, InetAddress& na,
1103 tpport_t tp);
Emeric Vigier2f625822012-08-06 11:09:52 -04001104
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001105 /**
1106 * Set the number of RTCP intervals that the stack will wait
1107 * to change the state of a source from stateActive to
1108 * stateInactive, or to delete the source after being in
1109 * stateInactive.
1110 *
1111 * Note that this value should be uniform accross all
1112 * participants and SHOULD be fixed for a particular profile.
1113 *
1114 * @param intervals number of RTCP report intervals
1115 *
1116 * @note If RTCP is not being used, the RTCP interval is
1117 * assumed to be the default: 5 seconds.
1118 * @note The default for this value is, as RECOMMENDED, 5.
1119 **/
1120 void setSourceExpirationPeriod(uint8 intervals)
1121 { sourceExpirationPeriod = intervals; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001122
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001123 /**
1124 * This function is used by the service thread to process
1125 * the next incoming packet and place it in the receive list.
1126 *
1127 * @return number of payload bytes received. <0 if error.
1128 */
1129 virtual size_t
1130 takeInDataPacket();
Emeric Vigier2f625822012-08-06 11:09:52 -04001131
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001132 void renewLocalSSRC();
Emeric Vigier2f625822012-08-06 11:09:52 -04001133
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001134 /**
1135 * This is used to fetch a packet in the receive queue and to
1136 * expire packets older than the current timestamp.
1137 *
1138 * @return packet buffer object for current timestamp if found.
1139 * @param timestamp timestamp requested.
1140 * @param src optional source selector
1141 * @note if found, the packet is removed from the reception queue
1142 **/
1143 IncomingDataQueue::IncomingRTPPktLink*
1144 getWaiting(uint32 timestamp, const SyncSource *src = NULL);
Emeric Vigier2f625822012-08-06 11:09:52 -04001145
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001146 /**
1147 * Log reception of a new RTP packet from this source. Usually
1148 * updates data such as the packet counter, the expected
1149 * sequence number for the next packet and the time the last
1150 * packet was received at.
1151 *
1152 * @param srcLink Link structure for the synchronization
1153 * source of this packet.
1154 * @param pkt Packet just created and to be logged.
1155 * @param recvtime Reception time.
1156 *
1157 * @return whether, according to the source state and
1158 * statistics, the packet is considered valid and must be
1159 * inserted in the incoming packets queue.
1160 **/
1161 bool
1162 recordReception(SyncSourceLink& srcLink, const IncomingRTPPkt& pkt,
1163 const timeval recvtime);
Emeric Vigier2f625822012-08-06 11:09:52 -04001164
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001165 /**
1166 * Log extraction of a packet from this source from the
1167 * scheduled reception queue.
1168 *
1169 * @param pkt Packet extracted from the queue.
1170 **/
1171 void
1172 recordExtraction(const IncomingRTPPkt& pkt);
Emeric Vigier2f625822012-08-06 11:09:52 -04001173
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001174 void purgeIncomingQueue();
Emeric Vigier2f625822012-08-06 11:09:52 -04001175
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001176 /**
1177 * Virtual called when a new synchronization source has joined
1178 * the session.
1179 *
1180 * @param - new synchronization source
1181 **/
1182 inline virtual void
1183 onNewSyncSource(const SyncSource&)
1184 { }
Emeric Vigier2f625822012-08-06 11:09:52 -04001185
1186protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001187 /**
1188 * A virtual function to support parsing of arriving packets
1189 * to determine if they should be kept in the queue and to
1190 * dispatch events.
1191 *
1192 * A generic header validity check (as specified in RFC 1889)
1193 * is performed on every incoming packet. If the generic check
1194 * completes succesfully, this method is called before the
1195 * packet is actually inserted into the reception queue.
1196 *
1197 * May be used to perform additional validity checks or to do
1198 * some application specific processing.
1199 *
1200 * @param - packet just received.
1201 * @return true if packet is kept in the incoming packets queue.
1202 **/
1203 inline virtual bool
1204 onRTPPacketRecv(IncomingRTPPkt&)
1205 { return true; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001206
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001207 /**
1208 * A hook to filter packets in the receive queue that are being
1209 * expired. This hook may be used to do some application
1210 * specific processing on expired packets before they are
1211 * deleted.
1212 *
1213 * @param - packet expired from the recv queue.
1214 **/
1215 inline virtual void onExpireRecv(IncomingRTPPkt&)
1216 { return; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001217
1218 /**
1219 * A hook that gets called if the decoding of an incoming SRTP was erroneous
1220 *
1221 * @param pkt
1222 * The SRTP packet with error.
1223 * @param errorCode
1224 * The error code: -1 - SRTP authentication failure, -2 - replay
1225 * check failed
1226 * @return
1227 * True: put the packet in incoming queue for further processing
1228 * by the applications; false: dismiss packet. The default
1229 * implementation returns false.
1230 **/
1231 inline virtual bool
1232 onSRTPPacketError(IncomingRTPPkt& pkt, int32 errorCode)
1233 { return false; }
1234
1235 inline virtual bool
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001236 end2EndDelayed(IncomingRTPPktLink&)
1237 { return false; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001238
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001239 /**
1240 * Insert a just received packet in the queue (both general
1241 * and source specific queues). If the packet was already in
1242 * the queue (same SSRC and sequence number), it is not
1243 * inserted but deleted.
1244 *
1245 * @param packetLink link to a packet just received and
1246 * generally validated and processed by onRTPPacketRecv.
1247 *
1248 * @return whether the packet was successfully inserted.
1249 * @retval false when the packet is duplicated (there is
1250 * already a packet from the same source with the same
1251 * timestamp).
1252 * @retval true when the packet is not duplicated.
1253 **/
1254 bool
1255 insertRecvPacket(IncomingRTPPktLink* packetLink);
Emeric Vigier2f625822012-08-06 11:09:52 -04001256
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001257 /**
1258 * This function performs the physical I/O for reading a
1259 * packet from the source. It is a virtual that is
1260 * overriden in the derived class.
1261 *
1262 * @return number of bytes read.
1263 * @param buffer of read packet.
1264 * @param length of data to read.
1265 * @param host address of source.
1266 * @param port number of source.
1267 **/
1268 virtual size_t
1269 recvData(unsigned char* buffer, size_t length,
1270 InetHostAddress& host, tpport_t& port) = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -04001271
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001272 virtual size_t
1273 getNextDataPacketSize() const = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -04001274
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001275 mutable ThreadLock recvLock;
1276 // reception queue
1277 IncomingRTPPktLink* recvFirst, * recvLast;
1278 // values for packet validation.
1279 static const uint8 defaultMinValidPacketSequence;
1280 static const uint16 defaultMaxPacketMisorder;
1281 static const uint16 defaultMaxPacketDropout;
1282 uint8 minValidPacketSequence;
1283 uint16 maxPacketMisorder;
1284 uint16 maxPacketDropout;
1285 static const size_t defaultMembersSize;
1286 uint8 sourceExpirationPeriod;
1287 mutable Mutex cryptoMutex;
Emeric Vigier2f625822012-08-06 11:09:52 -04001288 std::list<CryptoContext *> cryptoContexts;
1289};
1290
1291/** @}*/ // iqueue
1292
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001293END_NAMESPACE
Emeric Vigier2f625822012-08-06 11:09:52 -04001294
1295#endif //CCXX_RTP_IQUEUE_H_
1296
1297/** EMACS **
1298 * Local variables:
1299 * mode: c++
1300 * c-basic-offset: 8
1301 * End:
1302 */