blob: f4bfc697f53cfbf6328e7d71ff4210eddf57d0d4 [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 Lision243cd182014-04-06 23:22:44 -0400709 inline void setBaseSeqNum(uint16 seqnum)
710 { baseSeqNum = seqnum; }
711
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500712 inline uint32 getSeqNumAccum() const
713 { return seqNumAccum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400714
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500715 inline void incSeqNumAccum()
716 { seqNumAccum += SEQNUMMOD; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400717
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500718 /**
719 * Start a new sequence of received packets.
720 **/
721 inline void initSequence(uint16 seqnum)
722 { maxSeqNum = seqNumAccum = seqnum; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400723
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500724 /**
725 * Record the insertion of an RTP packet from this
726 * source into the scheduled reception queue. All
727 * received packets should be registered with
728 * recordReception(), but only those actually inserted
729 * into the queue should be registered via this
730 * method.
731 *
732 * @param pl Link structure for packet inserted into the queue.
733 **/
734 void recordInsertion(const IncomingRTPPktLink& pl);
Emeric Vigier2f625822012-08-06 11:09:52 -0400735
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500736 void initStats();
Emeric Vigier2f625822012-08-06 11:09:52 -0400737
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500738 /**
739 * Compute cumulative packet lost and fraction of
740 * packets lost during the last reporting interval.
741 **/
742 void computeStats();
Emeric Vigier2f625822012-08-06 11:09:52 -0400743
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500744 MembershipBookkeeping* membership;
745 // The source this link object refers to.
746 SyncSource* source;
747 // first/last packets from this source in the queue.
748 IncomingRTPPktLink* first, * last;
749 // Links for synchronization sources located before
750 // and after this one in the list of sources.
751 SyncSourceLink* prev, * next;
752 // Prev and next inside the hash table collision list.
753 SyncSourceLink* nextCollis;
754 ConflictingTransportAddress* prevConflict;
755 unsigned char* senderInfo;
756 unsigned char* receiverInfo;
757 // time the last RTP packet from this source was
758 // received at.
759 timeval lastPacketTime;
760 // time the last RTCP packet was received.
761 timeval lastRTCPPacketTime;
762 // time the lasrt RTCP SR was received. Required for
763 // DLSR computation.
764 timeval lastRTCPSRTime;
Emeric Vigier2f625822012-08-06 11:09:52 -0400765
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500766 // for outgoing RR reports.
767 // number of packets received from this source.
768 uint32 obsPacketCount;
769 // number of octets received from this source.
770 uint32 obsOctetCount;
771 // the higher sequence number seen from this source
772 uint16 maxSeqNum;
773 uint32 extendedMaxSeqNum;
774 uint32 cumulativePacketLost;
775 uint8 fractionLost;
776 // for interarrivel jitter computation
777 uint32 lastPacketTransitTime;
778 // interarrival jitter of packets from this source.
779 float jitter;
780 uint32 initialDataTimestamp;
781 timeval initialDataTime;
Emeric Vigier2f625822012-08-06 11:09:52 -0400782
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500783 // this flag assures we only call one gotHello and one
784 // gotGoodbye for this src.
785 bool flag;
Emeric Vigier2f625822012-08-06 11:09:52 -0400786
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500787 // for source validation:
788 uint32 badSeqNum;
789 uint8 probation; // packets in sequence before valid.
790 uint16 baseSeqNum;
791 uint32 expectedPrior;
792 uint32 receivedPrior;
793 uint32 seqNumAccum;
794 };
Emeric Vigier2f625822012-08-06 11:09:52 -0400795
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500796 /**
797 * Returns whether there is already a synchronizacion source
798 * with "ssrc" SSRC identifier.
799 **/
800 bool
801 isRegistered(uint32 ssrc);
Emeric Vigier2f625822012-08-06 11:09:52 -0400802
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500803 /**
804 * Get the description of a source by its <code>ssrc</code> identifier.
805 *
806 * @param ssrc SSRC identifier, in host order.
807 * @param created whether a new source has been created.
808 * @return Pointer to the SyncSource object identified by
809 * <code>ssrc</code>.
810 */
811 SyncSourceLink*
812 getSourceBySSRC(uint32 ssrc, bool& created);
Emeric Vigier2f625822012-08-06 11:09:52 -0400813
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500814 /**
815 * Mark the source identified by <code>ssrc</code> as having
816 * sent a BYE packet. It is not deleted until a timeout
817 * expires, so that in case some packets from this source
818 * arrive a bit later the source is not inserted again in the
819 * table of known sources.
820 *
821 * @return true if the source had been previously identified.
822 * false if it was not in the table of known sources.
823 **/
824 bool
825 BYESource(uint32 ssrc);
Emeric Vigier2f625822012-08-06 11:09:52 -0400826
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500827 /**
828 * Remove the description of the source identified by
829 * <code>ssrc</code>
830 *
831 * @return whether the source has been actually removed or it
832 * did not exist.
833 */
834 bool
835 removeSource(uint32 ssrc);
Emeric Vigier2f625822012-08-06 11:09:52 -0400836
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500837 inline SyncSourceLink* getFirst()
838 { return first; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400839
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500840 inline SyncSourceLink* getLast()
841 { return last; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400842
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500843 inline uint32
844 getMembersCount()
845 { return Members::getMembersCount(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400846
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500847 inline void
848 setMembersCount(uint32 n)
849 { Members::setMembersCount(n); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400850
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500851 inline uint32
852 getSendersCount()
853 { return Members::getSendersCount(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400854
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500855 static const size_t defaultMembersHashSize;
856 static const uint32 SEQNUMMOD;
Emeric Vigier2f625822012-08-06 11:09:52 -0400857
858private:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500859 MembershipBookkeeping(const MembershipBookkeeping &o);
Emeric Vigier2f625822012-08-06 11:09:52 -0400860
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500861 MembershipBookkeeping&
862 operator=(const MembershipBookkeeping &o);
Emeric Vigier2f625822012-08-06 11:09:52 -0400863
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500864 /**
865 * Purge all RTPSource structures, the hash table and the list
866 * of sources.
867 **/
868 void
869 endMembers();
Emeric Vigier2f625822012-08-06 11:09:52 -0400870
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500871 // Hash table with sources of RTP and RTCP packets
872 uint32 sourceBucketsNum;
873 SyncSourceLink** sourceLinks;
874 // List of sources, ordered from older to newer
875 SyncSourceLink* first, * last;
Emeric Vigier2f625822012-08-06 11:09:52 -0400876};
877
878/**
879 * @class IncomingDataQueue
880 * @short Queue for incoming RTP data packets in an RTP session.
881 *
882 * @author Federico Montesino Pouzols <fedemp@altern.org>
883 **/
884class __EXPORT IncomingDataQueue: public IncomingDataQueueBase,
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500885 protected MembershipBookkeeping
Emeric Vigier2f625822012-08-06 11:09:52 -0400886{
887public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500888 /**
889 * @class SyncSourcesIterator
890 * @short iterator through the list of synchronizations
891 * sources in this session
892 **/
893 class SyncSourcesIterator
894 {
895 public:
896 typedef std::forward_iterator_tag iterator_category;
897 typedef SyncSource value_type;
898 typedef std::ptrdiff_t difference_type;
899 typedef const SyncSource* pointer;
900 typedef const SyncSource& reference;
Emeric Vigier2f625822012-08-06 11:09:52 -0400901
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500902 SyncSourcesIterator(SyncSourceLink* l = NULL) :
903 link(l)
904 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400905
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500906 SyncSourcesIterator(const SyncSourcesIterator& si) :
907 link(si.link)
908 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400909
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500910 reference operator*() const
911 { return *(link->getSource()); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400912
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500913 pointer operator->() const
914 { return link->getSource(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400915
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500916 SyncSourcesIterator& operator++() {
917 link = link->getNext();
918 return *this;
919 }
Emeric Vigier2f625822012-08-06 11:09:52 -0400920
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500921 SyncSourcesIterator operator++(int) {
922 SyncSourcesIterator result(*this);
923 ++(*this);
924 return result;
925 }
Emeric Vigier2f625822012-08-06 11:09:52 -0400926
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500927 friend bool operator==(const SyncSourcesIterator& l,
928 const SyncSourcesIterator& r)
929 { return l.link == r.link; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400930
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500931 friend bool operator!=(const SyncSourcesIterator& l,
932 const SyncSourcesIterator& r)
933 { return l.link != r.link; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400934
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500935 private:
936 SyncSourceLink *link;
937 };
Emeric Vigier2f625822012-08-06 11:09:52 -0400938
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500939 SyncSourcesIterator begin()
940 { return SyncSourcesIterator(MembershipBookkeeping::getFirst()); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400941
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500942 SyncSourcesIterator end()
943 { return SyncSourcesIterator(NULL); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400944
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500945 /**
946 * Retreive data from a specific timestamped packet if such a
947 * packet is currently available in the receive buffer.
948 *
949 * @param stamp Data unit timestamp.
950 * @param src Optional synchronization source selector.
951 * @return data retrieved from the reception buffer.
952 * @retval null pointer if no packet with such timestamp is available.
953 **/
954 const AppDataUnit*
955 getData(uint32 stamp, const SyncSource* src = NULL);
Emeric Vigier2f625822012-08-06 11:09:52 -0400956
957
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500958 /**
959 * Determine if packets are waiting in the reception queue.
960 *
961 * @param src Optional synchronization source selector.
962 * @return True if packets are waiting.
963 */
964 bool
965 isWaiting(const SyncSource* src = NULL) const;
Emeric Vigier2f625822012-08-06 11:09:52 -0400966
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500967 /**
968 * Get timestamp of first packet waiting in the queue.
969 *
970 * @param src optional source selector.
971 * @return timestamp of first arrival packet.
972 **/
973 uint32
974 getFirstTimestamp(const SyncSource* src = NULL) const;
Emeric Vigier2f625822012-08-06 11:09:52 -0400975
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500976 /**
977 * When receiving packets from a new source, it may be
978 * convenient to reject a first few packets before we are
979 * really sure the source is valid. This method sets how many
980 * data packets must be received in sequence before the source
981 * is considered valid and the stack starts to accept its
982 * packets.
983 *
984 * @note the default (see defaultMinValidPacketSequence())
985 * value for this parameter is 0, so that no packets are
986 * rejected (data packets are accepted from the first one).
987 *
988 * @note this validation is performed after the generic header
989 * validation and the additional validation done in
990 * onRTPPacketRecv().
991 *
992 * @note if any valid RTCP packet is received from this
993 * source, it will be immediatly considered valid regardless
994 * of the number of sequential data packets received.
995 *
996 * @param packets number of sequential packet required
997 **/
998 void
999 setMinValidPacketSequence(uint8 packets)
1000 { minValidPacketSequence = packets; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001001
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001002 uint8
1003 getDefaultMinValidPacketSequence() const
1004 { return defaultMinValidPacketSequence; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001005
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001006 /**
1007 * Get the minimun number of consecutive packets that must be
1008 * received from a source before accepting its data packets.
1009 **/
1010 uint8
1011 getMinValidPacketSequence() const
1012 { return minValidPacketSequence; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001013
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001014 void
1015 setMaxPacketMisorder(uint16 packets)
1016 { maxPacketMisorder = packets; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001017
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001018 uint16
1019 getDefaultMaxPacketMisorder() const
1020 { return defaultMaxPacketMisorder; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001021
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001022 uint16
1023 getMaxPacketMisorder() const
1024 { return maxPacketMisorder; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001025
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001026 /**
1027 *
1028 * It also prevents packets sent after a restart of the source
1029 * being immediately accepted.
1030 **/
1031 void
1032 setMaxPacketDropout(uint16 packets) // default: 3000.
1033 { maxPacketDropout = packets; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001034
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001035 uint16
1036 getDefaultMaxPacketDropout() const
1037 { return defaultMaxPacketDropout; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001038
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001039 uint16
1040 getMaxPacketDropout() const
1041 { return maxPacketDropout; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001042
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001043 // default value for constructors that allow to specify
1044 // members table s\ize
Emeric Vigier2f625822012-08-06 11:09:52 -04001045 inline static size_t
1046 getDefaultMembersSize()
1047 { return defaultMembersSize; }
1048
1049 /**
1050 * Set input queue CryptoContext.
1051 *
1052 * The endQueue method (provided by RTPQueue) deletes all
1053 * registered CryptoContexts.
1054 *
1055 * @param cc Pointer to initialized CryptoContext.
1056 */
1057 void
1058 setInQueueCryptoContext(CryptoContext* cc);
1059
1060 /**
1061 * Remove input queue CryptoContext.
1062 *
1063 * The endQueue method (provided by RTPQueue) also deletes all
1064 * registered CryptoContexts.
1065 *
1066 * @param cc
1067 * Pointer to initialized CryptoContext to remove. If pointer
1068 * if <code>NULL</code> then delete the whole queue
1069 */
1070 void
1071 removeInQueueCryptoContext(CryptoContext* cc);
1072
1073 /**
1074 * Get an input queue CryptoContext identified by SSRC
1075 *
1076 * @param ssrc Request CryptoContext for this incoming SSRC
1077 * @return Pointer to CryptoContext of the SSRC of NULL if no context
1078 * available for this SSRC.
1079 */
1080 CryptoContext*
1081 getInQueueCryptoContext(uint32 ssrc);
1082
1083protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001084 /**
1085 * @param size initial size of the membership table.
1086 **/
1087 IncomingDataQueue(uint32 size);
Emeric Vigier2f625822012-08-06 11:09:52 -04001088
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001089 virtual ~IncomingDataQueue()
1090 { }
Emeric Vigier2f625822012-08-06 11:09:52 -04001091
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001092 /**
1093 * Apply collision and loop detection and correction algorithm
1094 * when receiving RTP data packets. Follows section 8.2 in
1095 * draft-ietf-avt-rtp-new.
1096 *
1097 * @param sourceLink link to the source object.
1098 * @param is_new whether the source has been just recorded.
1099 * @param na data packet network address.
1100 * @param tp data packet source transport port.
1101 *
1102 * @return whether the packet must not be discarded.
1103 **/
1104 bool checkSSRCInIncomingRTPPkt(SyncSourceLink& sourceLink,
1105 bool is_new, InetAddress& na,
1106 tpport_t tp);
Emeric Vigier2f625822012-08-06 11:09:52 -04001107
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001108 /**
1109 * Set the number of RTCP intervals that the stack will wait
1110 * to change the state of a source from stateActive to
1111 * stateInactive, or to delete the source after being in
1112 * stateInactive.
1113 *
1114 * Note that this value should be uniform accross all
1115 * participants and SHOULD be fixed for a particular profile.
1116 *
1117 * @param intervals number of RTCP report intervals
1118 *
1119 * @note If RTCP is not being used, the RTCP interval is
1120 * assumed to be the default: 5 seconds.
1121 * @note The default for this value is, as RECOMMENDED, 5.
1122 **/
1123 void setSourceExpirationPeriod(uint8 intervals)
1124 { sourceExpirationPeriod = intervals; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001125
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001126 /**
1127 * This function is used by the service thread to process
1128 * the next incoming packet and place it in the receive list.
1129 *
1130 * @return number of payload bytes received. <0 if error.
1131 */
1132 virtual size_t
1133 takeInDataPacket();
Emeric Vigier2f625822012-08-06 11:09:52 -04001134
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001135 void renewLocalSSRC();
Emeric Vigier2f625822012-08-06 11:09:52 -04001136
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001137 /**
1138 * This is used to fetch a packet in the receive queue and to
1139 * expire packets older than the current timestamp.
1140 *
1141 * @return packet buffer object for current timestamp if found.
1142 * @param timestamp timestamp requested.
1143 * @param src optional source selector
1144 * @note if found, the packet is removed from the reception queue
1145 **/
1146 IncomingDataQueue::IncomingRTPPktLink*
1147 getWaiting(uint32 timestamp, const SyncSource *src = NULL);
Emeric Vigier2f625822012-08-06 11:09:52 -04001148
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001149 /**
1150 * Log reception of a new RTP packet from this source. Usually
1151 * updates data such as the packet counter, the expected
1152 * sequence number for the next packet and the time the last
1153 * packet was received at.
1154 *
1155 * @param srcLink Link structure for the synchronization
1156 * source of this packet.
1157 * @param pkt Packet just created and to be logged.
1158 * @param recvtime Reception time.
1159 *
1160 * @return whether, according to the source state and
1161 * statistics, the packet is considered valid and must be
1162 * inserted in the incoming packets queue.
1163 **/
1164 bool
1165 recordReception(SyncSourceLink& srcLink, const IncomingRTPPkt& pkt,
1166 const timeval recvtime);
Emeric Vigier2f625822012-08-06 11:09:52 -04001167
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001168 /**
1169 * Log extraction of a packet from this source from the
1170 * scheduled reception queue.
1171 *
1172 * @param pkt Packet extracted from the queue.
1173 **/
1174 void
1175 recordExtraction(const IncomingRTPPkt& pkt);
Emeric Vigier2f625822012-08-06 11:09:52 -04001176
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001177 void purgeIncomingQueue();
Emeric Vigier2f625822012-08-06 11:09:52 -04001178
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001179 /**
1180 * Virtual called when a new synchronization source has joined
1181 * the session.
1182 *
1183 * @param - new synchronization source
1184 **/
1185 inline virtual void
1186 onNewSyncSource(const SyncSource&)
1187 { }
Emeric Vigier2f625822012-08-06 11:09:52 -04001188
1189protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001190 /**
1191 * A virtual function to support parsing of arriving packets
1192 * to determine if they should be kept in the queue and to
1193 * dispatch events.
1194 *
1195 * A generic header validity check (as specified in RFC 1889)
1196 * is performed on every incoming packet. If the generic check
1197 * completes succesfully, this method is called before the
1198 * packet is actually inserted into the reception queue.
1199 *
1200 * May be used to perform additional validity checks or to do
1201 * some application specific processing.
1202 *
1203 * @param - packet just received.
1204 * @return true if packet is kept in the incoming packets queue.
1205 **/
1206 inline virtual bool
1207 onRTPPacketRecv(IncomingRTPPkt&)
1208 { return true; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001209
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001210 /**
1211 * A hook to filter packets in the receive queue that are being
1212 * expired. This hook may be used to do some application
1213 * specific processing on expired packets before they are
1214 * deleted.
1215 *
1216 * @param - packet expired from the recv queue.
1217 **/
1218 inline virtual void onExpireRecv(IncomingRTPPkt&)
1219 { return; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001220
1221 /**
1222 * A hook that gets called if the decoding of an incoming SRTP was erroneous
1223 *
1224 * @param pkt
1225 * The SRTP packet with error.
1226 * @param errorCode
1227 * The error code: -1 - SRTP authentication failure, -2 - replay
1228 * check failed
1229 * @return
1230 * True: put the packet in incoming queue for further processing
1231 * by the applications; false: dismiss packet. The default
1232 * implementation returns false.
1233 **/
1234 inline virtual bool
1235 onSRTPPacketError(IncomingRTPPkt& pkt, int32 errorCode)
1236 { return false; }
1237
1238 inline virtual bool
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001239 end2EndDelayed(IncomingRTPPktLink&)
1240 { return false; }
Emeric Vigier2f625822012-08-06 11:09:52 -04001241
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001242 /**
1243 * Insert a just received packet in the queue (both general
1244 * and source specific queues). If the packet was already in
1245 * the queue (same SSRC and sequence number), it is not
1246 * inserted but deleted.
1247 *
1248 * @param packetLink link to a packet just received and
1249 * generally validated and processed by onRTPPacketRecv.
1250 *
1251 * @return whether the packet was successfully inserted.
1252 * @retval false when the packet is duplicated (there is
1253 * already a packet from the same source with the same
1254 * timestamp).
1255 * @retval true when the packet is not duplicated.
1256 **/
1257 bool
1258 insertRecvPacket(IncomingRTPPktLink* packetLink);
Emeric Vigier2f625822012-08-06 11:09:52 -04001259
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001260 /**
1261 * This function performs the physical I/O for reading a
1262 * packet from the source. It is a virtual that is
1263 * overriden in the derived class.
1264 *
1265 * @return number of bytes read.
1266 * @param buffer of read packet.
1267 * @param length of data to read.
1268 * @param host address of source.
1269 * @param port number of source.
1270 **/
1271 virtual size_t
1272 recvData(unsigned char* buffer, size_t length,
1273 InetHostAddress& host, tpport_t& port) = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -04001274
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001275 virtual size_t
1276 getNextDataPacketSize() const = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -04001277
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001278 mutable ThreadLock recvLock;
1279 // reception queue
1280 IncomingRTPPktLink* recvFirst, * recvLast;
1281 // values for packet validation.
1282 static const uint8 defaultMinValidPacketSequence;
1283 static const uint16 defaultMaxPacketMisorder;
1284 static const uint16 defaultMaxPacketDropout;
1285 uint8 minValidPacketSequence;
1286 uint16 maxPacketMisorder;
1287 uint16 maxPacketDropout;
1288 static const size_t defaultMembersSize;
1289 uint8 sourceExpirationPeriod;
1290 mutable Mutex cryptoMutex;
Emeric Vigier2f625822012-08-06 11:09:52 -04001291 std::list<CryptoContext *> cryptoContexts;
1292};
1293
1294/** @}*/ // iqueue
1295
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001296END_NAMESPACE
Emeric Vigier2f625822012-08-06 11:09:52 -04001297
1298#endif //CCXX_RTP_IQUEUE_H_
1299
1300/** EMACS **
1301 * Local variables:
1302 * mode: c++
1303 * c-basic-offset: 8
1304 * End:
1305 */