blob: 86852e1031a7a42d90e79434b52f28c7df577ae7 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001,2002,2003,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 sources.h
40 *
41 * @short Sources of synchronization and participants related clases.
42 **/
43
44#ifndef CCXX_RTP_SOURCES_H_
45#define CCXX_RTP_SOURCES_H_
46
47#include <string>
48#include <ccrtp/rtcppkt.h>
49
50#ifdef CCXX_NAMESPACES
51namespace ost {
52#endif
53
54/**
55 * @defgroup sources Participants and synchronization sources.
56 * @{
57 **/
58
59/**
60 * @class SDESItemsHolder
61 *
62 * Holds the SDES items and related information from a participant in
63 * an RTP application. This is a base class for participant classes.
64 *
65 * @author Federico Montesino Pouzols <fedemp@altern.org>
66 **/
67class __EXPORT SDESItemsHolder
68{
69public:
70 const std::string&
71 getItem(SDESItemType type) const;
72
73 inline const std::string&
74 getPRIVPrefix() const
75 { return sdesItems[SDESItemTypeEND]; }
76
77 void
78 setItem(SDESItemType item, const std::string& val);
79
80 inline void
81 setPRIVPrefix(const std::string& val)
82 { sdesItems[SDESItemTypeEND] = val; }
83
84protected:
85 SDESItemsHolder()
86 { }
87
88 inline virtual ~SDESItemsHolder()
89 { }
90
91private:
92 // SDES items for a participant.
93 // sdesItems[0] (== sdesItems[SDESItemTypeEND]) holds the prefix
94 // value for the PRIV item. The rest of entries hold the
95 // correponding SDES item value.
96 std::string sdesItems[SDESItemTypeLast + 1];
97};
98
99/**
100 * @class Participant
101 * @short A class of objects representing remote participants (RTP
102 * applications) in a multimedia session.
103 *
104 * Any RTP socket/queue class that directly or indirectly inherits
105 * from QueueRTCPManager (and hence has RTCP support) will represent
106 * participants from which any RTP or RTCP packet has been received
107 * through a Participant object. These Participant objects are
108 * entities such as end systems (user applications, monitors, etc),
109 * RTP mixers and RTP translators.
110 *
111 * Participant objects are identified by a CNAME and provide access to
112 * all known data about the source of RTP/RTCP packets, such as the
113 * CNAME and any other SDES item. Each participant object is related
114 * to one or more synchronization objects (@see SyncSource).
115 *
116 * If an RTP application based on ccRTP receives packets from itself
117 * (for instance, it is included in the destination list), there will
118 * be a Participant object that corresponds to the "local participant"
119 * (RTPApplication) object.
120 *
121 * @author Federico Montesino Pouzols <fedemp@altern.org>
122 *
123 * @todo implement reference counting from sources, so that when a
124 * source is destroyed, we know if the Participant should be
125 * destroyed.
126 **/
127class __EXPORT Participant : private SDESItemsHolder
128{
129public:
130 /**
131 * Get the value of an SDES item. For instance,
132 * getSDESItem(SDESItemTypeCNAME), return the CNAME of this
133 * Participant.
134 *
135 * @param type type of SDES item to get value of.
136 *
137 * @return value of the SDES item as a string.
138 * @retval empty string when the value is not known (no RTCP
139 * packet with the requested SDES item has been received from this
140 * source).
141 **/
142 const std::string&
143 getSDESItem(SDESItemType type) const
144 { return SDESItemsHolder::getItem(type); }
145
146 /**
147 * Get the prefix value for the PRIV SDES item.
148 *
149 * @return PRIV SDES item prefix as a string.
150 * @retval empty string when no PRIV SDES item has been
151 * received from this source.
152 **/
153 inline const std::string&
154 getPRIVPrefix() const
155 { return SDESItemsHolder::getPRIVPrefix(); }
156
157 /**
158 * Construct a new participant.
159 *
160 * @param cname Unique CNAME identifier.
161 **/
162 Participant(const std::string& cname);
163
164 ~Participant();
165
166private:
167 friend class ParticipantHandler;
168
169 /**
170 * Set the value of a SDES item.
171 **/
172 inline void
173 setSDESItem(SDESItemType item, const std::string& val)
174 { SDESItemsHolder::setItem(item,val); }
175
176 /**
177 * Set prefix value for the PRIV SDES item.
178 **/
179 inline void
180 setPRIVPrefix(const std::string val)
181 { SDESItemsHolder::setPRIVPrefix(val); }
182};
183
184/**
185 * @class SyncSource
186 * @short Synchronization source in an RTP session
187 *
188 * Each synchronization source in an RTP session is identified by a
189 * 32-bit numeric SSRC identifier. Each SyncSource object is related
190 * to a Participant object, which can be retrieved through the
191 * getParticipant() method.
192 *
193 * @author Federico Montesino Pouzols <fedemp@altern.org>
194 **/
195class __EXPORT SyncSource
196{
197public:
198 /**
199 * @enum State
200 *
201 * @short Synchronization source states during an RTP session.
202 *
203 * In general, new synchronization sources are not considered
204 * valid until multiple valid data packets or a valid RTCP
205 * compound packet has been received from the new source (@see
206 * IncomingDataQueue::setMinValidPacketSequence()). Thus, the
207 * source will probably be in statePrevalid before reaching
208 * one of the two states that indicate a valid source:
209 * stateActive and stateInactive.
210 *
211 * A valid participant is in stateActive state if RTP and/or
212 * RTCP packets are currently being received from it. If,
213 * after a small number of RTCP report intervals (see
214 * IncomingDataQueue::setSourceExpirationPeriod() ), no
215 * packets are received, it will reach the stateInactive
216 * state. If, after a small number of RTCP report intervals,
217 * no packet is received from an inactive source, it will be
218 * deleted.
219 *
220 * If RTCP is being used, after receiving a BYE RTCP packet
221 * from a synchronization source, it will reach the
222 * stateLeaving state and will be deleted after a delay (see
223 * QueueRTCPManager::setLeavingDelay()).
224 *
225 * Sources in statePrevalid and stateLeaving are not counted
226 * for the number of session members estimation.
227 **/
228 typedef enum {
229 stateUnknown, ///< No valid packet has been received.
230 statePrevalid, ///< Some packets have been
231 ///received, but source validity not
232 ///yet guaranteed.
233 stateActive, ///< We currently receive packets
234 ///(data or control) from this source.
235 stateInactive, ///< Was active in the near past but
236 ///no packet from this source has
237 ///been received lately.
238 stateLeaving ///< An RTCP BYE has been received
239 ///from the source.
240 } State;
241
242 /**
243 * @param ssrc SSRC identifier of the source, unique in each
244 * session.
245 */
246 SyncSource(uint32 ssrc);
247
248 ~SyncSource();
249
250 State
251 getState() const
252 { return state; }
253
254 /**
255 * Whether this source sends RTP data packets.
256 **/
257 bool isSender() const
258 { return activeSender; }
259
260 uint32 getID() const
261 { return SSRC; }
262
263 /**
264 * Get the participant this synchronization source is
265 * asociated to.
266 *
267 * @retval NULL if the stack has not been yet able to identify
268 * the participant this source is associated to.
269 **/
270 inline Participant*
271 getParticipant() const
272 { return participant; }
273
274 tpport_t getDataTransportPort() const
275 { return dataTransportPort; }
276
277 tpport_t getControlTransportPort() const
278 { return controlTransportPort; }
279
280 const InetAddress& getNetworkAddress() const
281 { return networkAddress; }
282
283protected:
284 /**
285 * @param source The RTPSource object being copied
286 */
287 SyncSource(const SyncSource& source);
288
289 SyncSource&
290 operator=(const SyncSource& source);
291
292private:
293 friend class SyncSourceHandler;
294
295 inline void
296 setState(State st)
297 { state = st; }
298
299 /**
300 * Mark this source as an active sender.
301 **/
302 inline void
303 setSender(bool active)
304 { activeSender = active; }
305
306 inline void
307 setParticipant(Participant& p)
308 { participant = &p; }
309
310 void setDataTransportPort(tpport_t p)
311 { dataTransportPort = p; }
312
313 void setControlTransportPort(tpport_t p)
314 { controlTransportPort = p; }
315
316 void setNetworkAddress(InetAddress addr)
317 { networkAddress = addr; }
318
319 inline void
320 setLink(void *l)
321 { link = l; }
322
323 void *getLink() const
324 { return link; }
325
326 // validity state of this source
327 State state;
328 // 32-bit SSRC identifier.
329 uint32 SSRC;
330 // A valid source not always is active
331 bool activeSender;
332 // The corresponding participant.
333 Participant* participant;
334
335 // Network protocol address for data and control connection
336 // (both are assumed to be the same).
337 InetAddress networkAddress;
338 tpport_t dataTransportPort;
339 tpport_t controlTransportPort;
340
341 // Pointer to the SyncSourceLink or similar object in the
342 // service queue. Saves a lot of searches in the membership
343 // table.
344 void* link;
345};
346
347/**
348 * @class RTPApplication
349 * @short An RTP application, holding identifying RTCP SDES item
350 * values. Represents local participants.
351 *
352 * An application in the context of RTP: an entity that has a CNAME
353 * (unique identifier in the form of user\@host.domain) as well as
354 * other RTCP SDES items (such as NAME or TOOL), and may open a number
355 * of RTP sessions. Each application is a different source of
356 * synchronization (with a potentially diferent SSRC identifier) in
357 * each RTP session it participates. All the sources of
358 * synchronization from a participant are tied together by means of
359 * the CNAME.
360 *
361 * The definition of this class allows applications based on ccRTP to
362 * implement several "RTP applications" in the same process. Each
363 * object of this class represents a local participant.
364 *
365 * @author Federico Montesino Pouzols <fedemp@altern.org>
366 **/
367class __EXPORT RTPApplication : private SDESItemsHolder
368{
369private:
370 struct ParticipantLink;
371
372public:
373 /**
374 * Create a new RTP application. If the CNAME string provided
375 * has zero length, it is guessed from the user and machine
376 * name.
377 *
378 * @param cname Local participant canonical name.
379 **/
380 RTPApplication(const std::string& cname);
381
382 ~RTPApplication();
383
384 inline void
385 setSDESItem(SDESItemType item, const std::string& val)
386 { SDESItemsHolder::setItem(item,val); }
387
388 inline void
389 setPRIVPrefix(const std::string& val)
390 { SDESItemsHolder::setPRIVPrefix(val); }
391
392 const std::string&
393 getSDESItem(SDESItemType item) const
394 { return SDESItemsHolder::getItem(item); }
395
396 inline const std::string&
397 getPRIVPrefix() const
398 { return SDESItemsHolder::getPRIVPrefix(); }
399
400 /**
401 * Iterator through the list of participants in this
402 * session. Somehow resembles and standard const_iterator
403 **/
404 class ParticipantsIterator
405 {
406 public:
407 typedef std::forward_iterator_tag iterator_category;
408 typedef Participant value_type;
409 typedef ptrdiff_t difference_type;
410 typedef const Participant* pointer;
411 typedef const Participant& reference;
412
413 ParticipantsIterator(ParticipantLink* p = NULL) :
414 link(p)
415 { }
416
417 ParticipantsIterator(const ParticipantsIterator& pi) :
418 link(pi.link)
419 { }
420
421 reference operator*() const
422 { return *(link->getParticipant()); }
423
424 pointer operator->() const
425 { return link->getParticipant(); }
426
427 ParticipantsIterator& operator++() {
428 link = link->getNext();
429 return *this;
430 }
431
432 ParticipantsIterator operator++(int) {
433 ParticipantsIterator result(*this);
434 ++(*this);
435 return result;
436 }
437 friend bool operator==(const ParticipantsIterator& l,
438 const ParticipantsIterator& r)
439 { return l.link == r.link; }
440
441 friend bool operator!=(const ParticipantsIterator& l,
442 const ParticipantsIterator& r)
443 { return l.link != r.link; }
444 private:
445 ParticipantLink *link;
446 };
447
448 ParticipantsIterator begin()
449 { return ParticipantsIterator(firstPart); }
450
451 ParticipantsIterator end()
452 { return ParticipantsIterator(NULL); }
453
454 const Participant*
455 getParticipant(const std::string& cname) const;
456
457private:
458 friend class ApplicationHandler;
459
460 struct ParticipantLink {
461 ParticipantLink(Participant& p,
462 ParticipantLink* l) :
463 participant(&p), next(l)
464 { }
465 inline ~ParticipantLink() { delete participant; }
466 inline Participant* getParticipant() { return participant; }
467 inline ParticipantLink* getPrev() { return prev; }
468 inline ParticipantLink* getNext() { return next; }
469 inline void setPrev(ParticipantLink* l) { prev = l; }
470 inline void setNext(ParticipantLink* l) { next = l; }
471 Participant* participant;
472 ParticipantLink* next, *prev;
473 };
474
475 void
476 addParticipant(Participant& part);
477
478 void
479 removeParticipant(ParticipantLink* part);
480
481 /**
482 * Find out the local CNAME as user\@host and store it as part
483 * of the internal state of this class.
484 */
485 void
486 findCNAME();
487
488 /// Hash table with sources of RTP and RTCP packets.
489 static const size_t defaultParticipantsNum;
490 Participant** participants;
491 /// List of participants, ordered from older to newer.
492 ParticipantLink* firstPart, * lastPart;
493};
494
495/**
496 * Get the RTPApplication object for the "default" application (the
497 * only one used by common applications -those that only implement one
498 * "RTP application"). Note that this application object differs from
499 * all the others that may be defined in that it is automatically
500 * constructed by the ccRTP stack and its CNAME is automatically
501 * assigned (as user\@host), whereas the other application objects'
502 * CNAME is provided to its constructor.
503 **/
504__EXPORT RTPApplication& defaultApplication();
505
506/** @}*/ // sources
507
508#ifdef CCXX_NAMESPACES
509}
510#endif
511
512#endif //CCXX_RTP_SOURCES_H_
513
514/** EMACS **
515 * Local variables:
516 * mode: c++
517 * c-basic-offset: 8
518 * End:
519 */