1 /**
2  * yatertp.h
3  * Yet Another RTP Stack
4  * This file is part of the YATE Project http://YATE.null.ro
5  *
6  * Yet Another Telephony Engine - a fully featured software PBX and IVR
7  * Copyright (C) 2004-2014 Null Team
8  *
9  * This software is distributed under multiple licenses;
10  * see the COPYING file in the main directory for licensing
11  * information for this specific distribution.
12  *
13  * This use of this software may be subject to additional restrictions.
14  * See the LEGAL file in the main directory for details.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  */
20 
21 #ifndef __YATERTP_H
22 #define __YATERTP_H
23 
24 #include <yateclass.h>
25 
26 #ifdef _WINDOWS
27 
28 #ifdef LIBYRTP_EXPORTS
29 #define YRTP_API __declspec(dllexport)
30 #else
31 #ifndef LIBYRTP_STATIC
32 #define YRTP_API __declspec(dllimport)
33 #endif
34 #endif
35 
36 #endif /* _WINDOWS */
37 
38 #ifndef YRTP_API
39 #define YRTP_API
40 #endif
41 
42 /**
43  * Holds all Telephony Engine related classes.
44  */
45 namespace TelEngine {
46 
47 class RTPGroup;
48 class RTPTransport;
49 class RTPSession;
50 class RTPSender;
51 class RTPReceiver;
52 class RTPSecure;
53 
54 /**
55  * Object holding RTP debug
56  * @short RTP debug holder
57  */
58 class YRTP_API RTPDebug
59 {
60 public:
61     /**
62      * Constructor
63      * @param dbg DebugEnabler
64      * @param traceId Trace ID
65      */
RTPDebug(DebugEnabler * dbg,const char * traceId)66     inline RTPDebug(DebugEnabler* dbg, const char* traceId)
67 	: m_dbg(dbg), m_traceId(traceId)
68 	{}
69 
70     /**
71      * Constructor from RTP session
72      * @param session RTP session to take debug from
73      */
74     RTPDebug(RTPSession* session);
75 
76     /**
77      * Retrieve DebugEnabler
78      * @return DebugEnabler pointer
79      */
dbg()80     inline DebugEnabler* dbg() const
81 	{ return m_dbg; }
82 
83     /**
84      * Retrieve trace ID
85      * @return Trace ID
86      */
dbgTraceId()87     inline const String& dbgTraceId() const
88 	{ return m_traceId; }
89 
90 protected:
91     /**
92      * Setup debug data
93      * @param dbg DebugEnabler
94      * @param traceId Trace ID
95      */
setDebug(DebugEnabler * dbg,const char * traceId)96     inline void setDebug(DebugEnabler* dbg, const char* traceId) {
97 	    m_dbg = dbg;
98 	    if (!m_traceId)
99 		m_traceId = traceId;
100 	}
101 
102     DebugEnabler* m_dbg;
103     String m_traceId;
104 };
105 
106 /**
107  * A base class that contains just placeholders to process raw RTP and RTCP packets.
108  * @short Base class to ease creation of RTP forwarders
109  */
110 class YRTP_API RTPProcessor : public GenObject, public RTPDebug
111 {
112     friend class UDPSession;
113     friend class UDPTLSession;
114     friend class RTPGroup;
115     friend class RTPTransport;
116     friend class RTPSender;
117     friend class RTPReceiver;
118 
119 public:
120     /**
121      * Constructor - processor should be later inserted in a RTP group
122      * @param dbg Processor DebugEnabler
123      * @param traceId Processor trace ID
124      */
125     RTPProcessor(DebugEnabler* dbg = 0, const char* traceId = 0);
126 
127     /**
128      * Destructor - removes itself from the RTP group
129      */
130     virtual ~RTPProcessor();
131 
132     /**
133      * Get the RTP group to which this processor belongs
134      * @return Pointer to the RTP group this processor has joined
135      */
group()136     inline RTPGroup* group() const
137 	{ return m_group; }
138 
139     /**
140      * This method is called to send or process a RTP packet
141      * @param data Pointer to raw RTP data
142      * @param len Length of the data packet
143      */
144     virtual void rtpData(const void* data, int len);
145 
146     /**
147      * This method is called to send or process a RTCP packet
148      * @param data Pointer to raw RTCP data
149      * @param len Length of the data packet
150      */
151     virtual void rtcpData(const void* data, int len);
152 
153     /**
154      * Retrieve MGCP P: style comma separated session parameters
155      * @param stats String to append parameters to
156      */
157     virtual void getStats(String& stats) const;
158 
159     /**
160      * Increase the counter for number of RTP packets received from a wrong source
161      */
incWrongSrc()162     virtual inline void incWrongSrc()
163 	{  }
164 
165     /**
166      * Get the number of RTP packets that were received from a wrong source
167      * @return Number of RTP packets received from a wrong source
168      */
wrongSrc()169     inline unsigned int wrongSrc()
170 	{ return m_wrongSrc; }
171 
172 protected:
173     /**
174      * Set a new RTP group for this processor
175      * @param newgrp New group to join this processor, the old one will be left
176      */
177     void group(RTPGroup* newgrp);
178 
179     /**
180      * Method called periodically to keep the data flowing
181      * @param when Time to use as base in all computing
182      */
183     virtual void timerTick(const Time& when) = 0;
184 
185     unsigned int m_wrongSrc;
186 
187 private:
188     RTPGroup* m_group;
189 };
190 
191 /**
192  * Several possibly related RTP processors share the same RTP group which
193  *  holds the thread that keeps them running.
194  * @short A group of RTP processors handled by the same thread
195  */
196 class YRTP_API RTPGroup : public GenObject, public Mutex, public Thread
197 {
198     friend class RTPProcessor;
199 
200 public:
201     /**
202      * Constructor
203      * @param msec Minimum time to sleep in loop in milliseconds
204      * @param prio Thread priority to run this group
205      * @param affinity Comma-separated list of CPUs and/or CPU range on which the thread should run on
206      */
207     RTPGroup(int msec = 0, Priority prio = Normal, const String& affinity = String::empty());
208 
209     /**
210      * Group destructor, removes itself from all remaining processors
211      */
212     virtual ~RTPGroup();
213 
214     /**
215      * Inherited thread cleanup
216      */
217     virtual void cleanup();
218 
219     /**
220      * Inherited thread run method
221      */
222     virtual void run();
223 
224     /**
225      * Set the system global minimum time to sleep in loop
226      * @param msec Minimum time to sleep in loop in milliseconds
227      */
228     static void setMinSleep(int msec);
229 
230     /**
231      * Add a RTP processor to this group
232      * @param proc Pointer to the RTP processor to add
233      */
234     void join(RTPProcessor* proc);
235 
236     /**
237      * Remove a RTP processor from this group
238      * @param proc Pointer to the RTP processor to remove
239      */
240     void part(RTPProcessor* proc);
241 
242 private:
243     ObjList m_processors;
244     bool m_listChanged;
245     unsigned long m_sleep;
246 };
247 
248 /**
249  * Class that holds sockets and addresses for transporting RTP and RTCP packets.
250  * @short Low level transport for RTP and RTCP
251  */
252 class YRTP_API RTPTransport : public RTPProcessor
253 {
254 public:
255     /**
256      * Activation status of the transport
257      */
258     enum Activation {
259 	Inactive,
260 	Bound,
261 	Active
262     };
263 
264     /**
265      * Type of transported data
266      */
267     enum Type {
268 	Unknown,
269 	RTP,
270 	UDPTL
271     };
272 
273     /**
274      * Constructor, creates an unconnected transport
275      * @param type Type of check to apply to the data
276      * @param dbg Transport DebugEnabler
277      * @param traceId Transport trace ID
278      */
279     RTPTransport(Type type = RTP, DebugEnabler* dbg = 0, const char* traceId = 0);
280 
281     /**
282      * Destructor
283      */
284     virtual ~RTPTransport();
285 
286     /**
287      * Destroys the object, disposes the memory. Do not call delete directly.
288      */
289     virtual void destruct();
290 
291     /**
292      * Set the RTP/RTCP processor of data received by this transport
293      * @param processor A pointer to the RTPProcessor for this transport
294      */
295     void setProcessor(RTPProcessor* processor = 0);
296 
297     /**
298      * Set the RTP/RTCP monitor of data received by this transport
299      * @param monitor A pointer to a second RTPProcessor for this transport
300      */
301     void setMonitor(RTPProcessor* monitor = 0);
302 
303     /**
304      * Get the local network address of the RTP transport
305      * @return Reference to the local RTP transport address
306      */
localAddr()307     inline const SocketAddr& localAddr() const
308 	{ return m_localAddr; }
309 
310     /**
311      * Get the remote network address of the RTP transport
312      * @return Reference to the remote RTP transport address
313      */
remoteAddr()314     inline const SocketAddr& remoteAddr() const
315 	{ return m_remoteAddr; }
316 
317     /**
318      * Set the local network address of the RTP transport
319      * @param addr New local RTP transport address
320      * @param rtcp Enable RTCP transport
321      * @return True if address set, false if a failure occured
322      */
323     bool localAddr(SocketAddr& addr, bool rtcp = true);
324 
325     /**
326      * Set the remote network address of the RTP transport
327      * @param addr New remote RTP transport address
328      * @param sniff Automatically adjust the address from the first incoming packet
329      * @return True if address set, false if a failure occured
330      */
331     bool remoteAddr(SocketAddr& addr, bool sniff = false);
332 
333     /**
334      * Set the size of the operating system's buffers for the RTP and RTCP sockets
335      * @param bufLen Requested length of the buffer
336      * @return True if the buffer length was set
337      */
338     bool setBuffer(int bufLen = 4096);
339 
340     /**
341      * Set the Type Of Service for the RTP socket
342      * @param tos Type Of Service bits to set
343      * @return True if operation was successfull, false if an error occured
344      */
setTOS(int tos)345     inline bool setTOS(int tos)
346 	{ return m_rtpSock.setTOS(tos); }
347 
348     /**
349      * Get the RTP socket used by this transport
350      * @return Pointer to the RTP socket
351      */
rtpSock()352     inline Socket* rtpSock()
353 	{ return &m_rtpSock; }
354 
355     /**
356      * Get the RTCP socket used by this transport
357      * @return Pointer to the RTCP socket
358      */
rtcpSock()359     inline Socket* rtcpSock()
360 	{ return &m_rtcpSock; }
361 
362     /**
363      * Drill a hole in a firewall or NAT for the RTP and RTCP sockets
364      * @return True if at least a packet was sent for the RTP socket
365      */
366     bool drillHole();
367 
368 protected:
369     /**
370      * Method called periodically to read data out of sockets
371      * @param when Time to use as base in all computing
372      */
373     virtual void timerTick(const Time& when);
374 
375     /**
376      * This method is called to send a RTP packet
377      * @param data Pointer to raw RTP data
378      * @param len Length of the data packet
379      */
380     virtual void rtpData(const void* data, int len);
381 
382     /**
383      * This method is called to send a RTCP packet
384      * @param data Pointer to raw RTCP data
385      * @param len Length of the data packet
386      */
387     virtual void rtcpData(const void* data, int len);
388 
389 private:
390     bool sendData(Socket& sock, const SocketAddr& to, const void* data, int len,
391 	const char* what, bool& flag);
392     Type m_type;
393     RTPProcessor* m_processor;
394     RTPProcessor* m_monitor;
395     Socket m_rtpSock;
396     Socket m_rtcpSock;
397     SocketAddr m_localAddr;
398     SocketAddr m_remoteAddr;
399     SocketAddr m_remoteRTCP;
400     SocketAddr m_remotePref;
401     SocketAddr m_rxAddrRTP;
402     SocketAddr m_rxAddrRTCP;
403     bool m_autoRemote;
404     bool m_warnSendErrorRtp;
405     bool m_warnSendErrorRtcp;
406 };
407 
408 /**
409  * A dejitter buffer that can be inserted in the receive data path to
410  *  absorb variations in packet arrival time. Incoming packets are stored
411  *  and forwarded at fixed intervals.
412  * @short Dejitter buffer for incoming data packets
413  */
414 class YRTP_API RTPDejitter : public RTPProcessor
415 {
416 public:
417     /**
418      * Constructor of a new jitter attenuator
419      * @param receiver RTP receiver which gets the delayed packets
420      * @param mindelay Minimum length of the dejitter buffer in microseconds
421      * @param maxdelay Maximum length of the dejitter buffer in microseconds
422      * @param dbg Dejitter DebugEnabler
423      * @param traceId Dejitter trace ID
424      */
425     RTPDejitter(RTPReceiver* receiver, unsigned int mindelay, unsigned int maxdelay,
426 	DebugEnabler* dbg = 0, const char* traceId = 0);
427 
428     /**
429      * Destructor - drops the packets and shows statistics
430      */
431     virtual ~RTPDejitter();
432 
433     /**
434      * Process and store one RTP data packet
435      * @param marker True if the marker bit is set in data packet
436      * @param payload Payload number
437      * @param timestamp Sampling instant of the packet data
438      * @param data Pointer to data block to process
439      * @param len Length of the data block in bytes
440      * @return True if the data packet was queued
441      */
442     virtual bool rtpRecv(bool marker, int payload, unsigned int timestamp,
443 	const void* data, int len);
444 
445     /**
446      * Clear the delayed packets queue and all variables
447      */
448     void clear();
449 
450 protected:
451     /**
452      * Method called periodically to keep the data flowing
453      * @param when Time to use as base in all computing
454      */
455     virtual void timerTick(const Time& when);
456 
457 private:
458     ObjList m_packets;
459     RTPReceiver* m_receiver;
460     unsigned int m_minDelay;
461     unsigned int m_maxDelay;
462     unsigned int m_headStamp;
463     unsigned int m_tailStamp;
464     u_int64_t m_headTime;
465     u_int64_t m_sampRate;
466     unsigned char m_fastRate;
467 };
468 
469 /**
470  * Base class that holds common sender and receiver methods
471  * @short Common send/recv variables holder
472  */
473 class YRTP_API RTPBaseIO: public RTPDebug
474 {
475     friend class RTPSession;
476     friend class RTPSecure;
477 public:
478     /**
479      * Default constructor.
480      */
481     inline RTPBaseIO(RTPSession* session = 0)
RTPDebug(session)482 	: RTPDebug(session),
483 	  m_session(session), m_secure(0),
484 	  m_ssrcInit(true), m_ssrc(0), m_ts(0),
485 	  m_seq(0), m_rollover(0), m_secLen(0), m_mkiLen(0),
486 	  m_evTs(0), m_evNum(-1), m_evVol(-1), m_evSeq(0),
487 	  m_ioPackets(), m_ioOctets(0), m_tsLast(0),
488 	  m_debugDataLevel(0), m_debugData(false), m_debugEvent(false),
489 	  m_dataType(-1), m_eventType(-1), m_silenceType(-1)
490 	{ }
491 
492     /**
493      * Destructor
494      */
495     virtual ~RTPBaseIO();
496 
497     /**
498      * Get the payload type for data packets
499      * @return Payload type, -1 if not set
500      */
dataPayload()501     inline int dataPayload() const
502 	{ return m_dataType; }
503 
504     /**
505      * Set the payload type for data packets
506      * @param type Payload type, -1 to disable
507      * @return True if changed, false if invalid payload type
508      */
509     bool dataPayload(int type);
510 
511     /**
512      * Get the payload type for event packets
513      * @return Payload type, -1 if not set
514      */
eventPayload()515     inline int eventPayload() const
516 	{ return m_eventType; }
517 
518     /**
519      * Set the payload type for event packets
520      * @param type Payload type, -1 to disable
521      * @return True if changed, false if invalid payload type
522      */
523     bool eventPayload(int type);
524 
525     /**
526      * Get the payload type for Silence event packets
527      * @return Payload type, -1 if not set
528      */
silencePayload()529     inline int silencePayload() const
530 	{ return m_silenceType; }
531 
532     /**
533      * Set the payload type for Silence event packets.
534      * Thanks, Silence, for a new and incompatible way of sending events.
535      * @param type Payload type, -1 to disable
536      * @return True if changed, false if invalid payload type
537      */
538     bool silencePayload(int type);
539 
540     /**
541      * Return SSRC value, initialize to a new, random value if needed
542      * @return Current value of SSRC
543      */
544     unsigned int ssrcInit();
545 
546     /**
547      * Requesting generation/grabbing of a new SSRC
548      */
reset()549     inline void reset()
550 	{ m_ssrcInit = true; }
551 
552     /**
553      * Get the value of the current SSRC, zero if not initialized yet
554      * @return Value of SSRC, zero if not initialized
555      */
ssrc()556     inline unsigned int ssrc() const
557 	{ return m_ssrcInit ? 0 : m_ssrc; }
558 
559     /**
560      * Force a new known SSRC for all further packets
561      */
ssrc(unsigned int src)562     inline void ssrc(unsigned int src)
563 	{ m_ssrc = src; m_ssrcInit = false; }
564 
565     /**
566      * Get the current sequence number
567      * @return Sequence number
568      */
seq()569     inline u_int16_t seq() const
570 	{ return m_seq; }
571 
572     /**
573      * Get the value of the rollover counter
574      * @return How many times the seqeunce has rolled over since SSRC changed
575      */
rollover()576     inline u_int32_t rollover() const
577 	{ return m_rollover; }
578 
579     /**
580      * Get the full current sequence number including rollovers
581      * @return Full 48 bit current sequence number
582      */
fullSeq()583     inline u_int64_t fullSeq() const
584 	{ return m_seq | (((u_int64_t)m_rollover) << 16); }
585 
586     /**
587      * Retrieve the number of packets exchanged on current session
588      * @return Number of packets exchanged
589      */
ioPackets()590     inline u_int32_t ioPackets() const
591 	{ return m_ioPackets; }
592 
593     /**
594      * Retrieve the number of payload octets exchanged on current session
595      * @return Number of octets exchanged except headers and padding
596      */
ioOctets()597     inline u_int32_t ioOctets() const
598 	{ return m_ioOctets; }
599 
600     /**
601      * Get the timestamp of the last packet as transmitted over the wire
602      * @return Timestamp of last packet sent or received
603      */
tsLast()604     inline unsigned int tsLast() const
605 	{ return m_ts + m_tsLast; }
606 
607     /**
608      * Get the session this object belongs to
609      * @return Pointer to RTP session or NULL
610      */
session()611     inline RTPSession* session() const
612 	{ return m_session; }
613 
614     /**
615      * Get the security provider of this sender or receiver
616      * @return A pointer to the RTPSecure or NULL
617      */
security()618     inline RTPSecure* security() const
619 	{ return m_secure; }
620 
621     /**
622      * Set the security provider of this sender or receiver
623      * @param secure Pointer to the new RTPSecure or NULL
624      */
625     void security(RTPSecure* secure);
626 
627     /**
628      * Initialize data debug
629      * @param recv True if receiving, false if sending
630      * @param params Parameters list
631      */
632     void initDebugData(bool recv, const NamedList& params);
633 
634 protected:
635     /**
636      * Method called periodically to keep the data flowing
637      * @param when Time to use as base in all computing
638      */
639     virtual void timerTick(const Time& when) = 0;
640 
641     /**
642      * Set the length of the added / expected security info block
643      * @param len Length of security information portion
644      * @param key Length of master key identifier
645      */
646     inline void secLength(u_int32_t len, u_int32_t key = 0)
647 	{ m_secLen = len; m_mkiLen = key; }
648 
649     RTPSession* m_session;
650     RTPSecure* m_secure;
651     bool m_ssrcInit;
652     u_int32_t m_ssrc;
653     u_int32_t m_ts;
654     u_int16_t m_seq;
655     u_int32_t m_rollover;
656     u_int16_t m_secLen;
657     u_int16_t m_mkiLen;
658     u_int32_t m_evTs;
659     int m_evNum;
660     int m_evVol;
661     unsigned int m_evSeq;
662     u_int32_t m_ioPackets;
663     u_int32_t m_ioOctets;
664     unsigned int m_tsLast;
665     // Debug data
666     int m_debugDataLevel;
667     bool m_debugData;
668     bool m_debugEvent;
669 
670 private:
671     int m_dataType;
672     int m_eventType;
673     int m_silenceType;
674 };
675 
676 /**
677  * Class that handles incoming RTP and RTCP packets
678  * @short RTP/RTCP packet receiver
679  */
680 class YRTP_API RTPReceiver : public RTPBaseIO
681 {
682     friend class RTPSession;
683     friend class RTPDejitter;
684 public:
685     /**
686      * Constructor
687      */
688     inline RTPReceiver(RTPSession* session = 0)
RTPBaseIO(session)689 	: RTPBaseIO(session),
690 	  m_ioLostPkt(0), m_dejitter(0),
691 	  m_seqSync(0), m_seqCount(0), m_warn(true), m_warnSeq(1),
692 	  m_seqLost(0), m_wrongSSRC(0), m_syncLost(0)
693 	{ }
694 
695     /**
696      * Destructor - gets rid of the jitter buffer if present
697      */
698     virtual ~RTPReceiver();
699 
700     /**
701      * Retrieve the number of lost packets in current session
702      * @return Number of packets in sequence gaps
703      */
ioPacketsLost()704     inline u_int32_t ioPacketsLost() const
705 	{ return m_ioLostPkt; }
706 
707 
708     /**
709      * Set a new dejitter buffer in this receiver
710      * @param dejitter New dejitter buffer to set, NULL to remove
711      */
712     void setDejitter(RTPDejitter* dejitter);
713 
714     /**
715      * Allocate and set a new dejitter buffer in this receiver
716      * @param mindelay Minimum length of the dejitter buffer in microseconds
717      * @param maxdelay Maximum length of the dejitter buffer in microseconds
718      */
setDejitter(unsigned int mindelay,unsigned int maxdelay)719     inline void setDejitter(unsigned int mindelay, unsigned int maxdelay)
720 	{ setDejitter(new RTPDejitter(this,mindelay,maxdelay,dbg(),m_traceId)); }
721 
722     /**
723      * Process one RTP payload packet.
724      * Default behaviour is to call rtpRecvData() or rtpRecvEvent().
725      * @param marker Set to true if the marker bit is set
726      * @param payload Payload number
727      * @param timestamp Sampling instant of the packet data
728      * @param data Pointer to data block to process
729      * @param len Length of the data block in bytes
730      * @return True if data was handled
731      */
732     virtual bool rtpRecv(bool marker, int payload, unsigned int timestamp,
733 	const void* data, int len);
734 
735     /**
736      * Process one RTP data packet
737      * @param marker Set to true if the marker bit is set
738      * @param timestamp Sampling instant of the packet data
739      * @param data Pointer to data block to process
740      * @param len Length of the data block in bytes
741      * @return True if data was handled
742      */
743     virtual bool rtpRecvData(bool marker, unsigned int timestamp,
744 	const void* data, int len);
745 
746     /**
747      * Process one RTP event
748      * @param event Received event code
749      * @param key Received key (for events 0-16) or zero
750      * @param duration Duration of the event as number of samples
751      * @param volume Attenuation of the tone, zero for don't care
752      * @param timestamp Sampling instant of the initial packet data
753      * @return True if data was handled
754      */
755     virtual bool rtpRecvEvent(int event, char key, int duration,
756 	int volume, unsigned int timestamp);
757 
758     /**
759      * Method called for unknown payload types just before attempting
760      *  to call rtpRecvData(). This is a good opportunity to change the
761      *  payload type and continue.
762      * @param payload Payload number
763      * @param timestamp Sampling instant of the unexpected packet data
764      */
765     virtual void rtpNewPayload(int payload, unsigned int timestamp);
766 
767     /**
768     * Method called when a packet with an unexpected SSRC is received
769     *  just before processing further. This is a good opportunity to
770     *  change the SSRC and continue
771     * @param newSsrc SSRC received in packet
772     * @param marker True if marker bit is set in the RTP packet
773     */
774     virtual void rtpNewSSRC(u_int32_t newSsrc, bool marker);
775 
776     /**
777      * Retrieve the statistical data from this receiver in a NamedList. Reset all the data.
778      * @param stat NamedList to populate with the values for different counters
779      */
780     virtual void stats(NamedList& stat) const;
781 
782 protected:
783     /**
784      * Method called periodically to finish lingering events
785      * @param when Time to use as base in all computing
786      */
787     virtual void timerTick(const Time& when);
788 
789     /**
790      * Method called to decipher RTP data in-place.
791      * The default implementation calls session's @ref RTPSecure::rtpDecipher()
792      * @param data Pointer to data block to decipher
793      * @param len Length of data including any padding
794      * @param secData Pointer to security data if applicable
795      * @param ssrc SSRC of the packet to decipher
796      * @param seq Full (48 bit) seqence number of the packet including rollovers
797      * @return True is the packet was deciphered correctly or can't tell
798      */
799     virtual bool rtpDecipher(unsigned char* data, int len, const void* secData, u_int32_t ssrc, u_int64_t seq);
800 
801     /**
802      * Method called to check the integrity of the RTP packet.
803      * The default implementation calls session's @ref RTPSecure::rtpCheckIntegrity()
804      * @param data Pointer to RTP header and data
805      * @param len Length of header, data and padding
806      * @param authData Pointer to authentication data
807      * @param ssrc SSRC of the packet to validate
808      * @param seq Full (48 bit) seqence number of the packet including rollovers
809      * @return True is the packet passed integrity checks
810      */
811     virtual bool rtpCheckIntegrity(const unsigned char* data, int len, const void* authData, u_int32_t ssrc, u_int64_t seq);
812 
813     u_int32_t m_ioLostPkt;
814 
815 private:
816     void rtpData(const void* data, int len);
817     void rtcpData(const void* data, int len);
818     bool decodeEvent(bool marker, unsigned int timestamp, const void* data, int len);
819     bool decodeSilence(bool marker, unsigned int timestamp, const void* data, int len);
820     void finishEvent(unsigned int timestamp);
821     bool pushEvent(int event, int duration, int volume, unsigned int timestamp);
822     RTPDejitter* m_dejitter;
823     u_int16_t m_seqSync;
824     u_int16_t m_seqCount;
825     bool m_warn;
826     int m_warnSeq;                       // Warn on invalid sequence (1: DebugWarn, -1: DebugInfo)
827     unsigned int m_seqLost;
828     unsigned int m_wrongSSRC;
829     unsigned int m_syncLost;
830 };
831 
832 /**
833  * Class that builds and sends RTP and RTCP packets
834  * @short RTP/RTCP packet sender
835  */
836 class YRTP_API RTPSender : public RTPBaseIO
837 {
838 public:
839     /**
840      * Constructor
841      * @param session RTP session the sender belongs
842      * @param randomTs Initialize a random timestamp offset
843      */
844     RTPSender(RTPSession* session = 0, bool randomTs = true);
845 
846     /**
847      * Do-nothing destructor
848      */
~RTPSender()849     virtual ~RTPSender()
850 	{ }
851 
852     /**
853      * Send one RTP payload packet
854      * @param marker Set to true if the marker bit must be set
855      * @param payload Payload number
856      * @param timestamp Sampling instant of the packet data
857      * @param data Pointer to data block to send
858      * @param len Length of the data block
859      * @return True if data sending was attempted
860      */
861     bool rtpSend(bool marker, int payload, unsigned int timestamp,
862 	const void* data, int len);
863 
864     /**
865      * Send one RTP data packet
866      * @param marker Set to true if the marker bit must be set
867      * @param timestamp Sampling instant of the packet data
868      * @param data Pointer to data block to send
869      * @param len Length of the data block
870      * @return True if data sending was attempted
871      */
872     bool rtpSendData(bool marker, unsigned int timestamp,
873 	const void* data, int len);
874 
875     /**
876      * Send one RTP event
877      * @param event Event code to send
878      * @param duration Duration of the event as number of samples
879      * @param volume Attenuation of the tone, zero for don't care
880      * @param timestamp Sampling instant of the packet data, zero to use current
881      * @return True if data sending was attempted
882      */
883     bool rtpSendEvent(int event, int duration, int volume = 0, unsigned int timestamp = 0);
884 
885     /**
886      * Send one RTP key event
887      * @param key Key to send
888      * @param duration Duration of the event as number of samples
889      * @param volume Attenuation of the tone, zero for don't care
890      * @param timestamp Sampling instant of the packet data, zero to use current
891      * @return True if data sending was attempted
892      */
893     bool rtpSendKey(char key, int duration, int volume = 0, unsigned int timestamp = 0);
894 
895 
896     /**
897      * Get the payload padding size
898      * @return Chunk size to pad the payload to a multiple of
899      */
padding()900     inline int padding() const
901 	{ return m_padding; }
902 
903     /**
904      * Set the padding to a multiple of a data chunk
905      * @param chunk Size to pad the payload to a multiple of
906      * @return True if the new chunk size is valid
907      */
908     bool padding(int chunk);
909 
910     /**
911      * Retrieve the statistical data from this receiver in a NamedList. Reset all the data.
912      * @param stat NamedList to populate with the values for different counters
913      */
914     virtual void stats(NamedList& stat) const;
915 
916 protected:
917     /**
918      * Method called periodically to send events and buffered data
919      * @param when Time to use as base in all computing
920      */
921     virtual void timerTick(const Time& when);
922 
923     /**
924      * Method called to encipher RTP payload data in-place.
925      * The default implementation calls session's @ref RTPSecure::rtpEncipher()
926      * @param data Pointer to data block to encipher
927      * @param len Length of payload data to be encrypted including any padding
928      */
929     virtual void rtpEncipher(unsigned char* data, int len);
930 
931     /**
932      * Method called to add integrity information to the RTP packet.
933      * The default implementation calls session's @ref RTPSecure::rtpAddIntegrity()
934      * @param data Pointer to the RTP packet to protect
935      * @param len Length of RTP data to be encrypted including header and padding
936      * @param authData Address to write the integrity data to
937      */
938     virtual void rtpAddIntegrity(const unsigned char* data, int len, unsigned char* authData);
939 
940 
941 private:
942     int m_evTime;
943     unsigned char m_padding;
944     DataBlock m_buffer;
945     bool sendEventData(unsigned int timestamp);
946 };
947 
948 /**
949  * A base class for RTP, SRTP or UDPTL sessions
950  * @short RTP or UDPTL session
951  */
952 class YRTP_API UDPSession : public RTPProcessor
953 {
954 public:
955     /**
956      * Destructor - cleans up any remaining resources
957      */
958     virtual ~UDPSession();
959 
960     /**
961      * Create a new RTP or UDP transport for this session.
962      * Override this method to create objects derived from RTPTransport.
963      * @return Pointer to the new transport or NULL on failure
964      */
965     virtual RTPTransport* createTransport();
966 
967     /**
968      * Initialize the RTP session, attach a transport if there is none
969      * @return True if initialized, false on some failure
970      */
971     bool initTransport();
972 
973     /**
974      * Initialize the RTP session, attach a group if none is present
975      * @param msec Minimum time to sleep in group loop in milliseconds
976      * @param prio Thread priority to run the new group
977      * @param affinity Comma-separated list of CPUs and/or CPU range on which the thread should run on
978      * @return True if initialized, false on some failure
979      */
980     bool initGroup(int msec = 0, Thread::Priority prio = Thread::Normal, const String& affinity = String::empty());
981 
982     /**
983      * Set the remote network address of the RTP transport of this session
984      * @param addr New remote RTP transport address
985      * @param sniff Automatically adjust the address from the first incoming packet
986      * @return True if address set, false if a failure occured
987      */
988     inline bool remoteAddr(SocketAddr& addr, bool sniff = false)
989 	{ return m_transport && m_transport->remoteAddr(addr,sniff); }
990 
991     /**
992      * Set the size of the operating system's buffers for the RTP and RTCP transport sockets
993      * @param bufLen Requested length of the buffer
994      * @return True if the buffer length was set
995      */
996     inline bool setBuffer(int bufLen = 4096)
997 	{ return m_transport && m_transport->setBuffer(bufLen); }
998 
999     /**
1000      * Set the Type Of Service for the RTP transport socket
1001      * @param tos Type Of Service bits to set
1002      * @return True if operation was successfull, false if an error occured
1003      */
setTOS(int tos)1004     inline bool setTOS(int tos)
1005 	{ return m_transport && m_transport->setTOS(tos); }
1006 
1007     /**
1008      * Get the main transport socket used by this session
1009      * @return Pointer to the RTP or UDPTL socket, NULL if no transport exists
1010      */
rtpSock()1011     inline Socket* rtpSock()
1012 	{ return m_transport ? m_transport->rtpSock() : 0; }
1013 
1014     /**
1015      * Drill a hole in a firewall or NAT for the RTP and RTCP sockets
1016      * @return True if at least a packet was sent for the RTP socket
1017      */
drillHole()1018     inline bool drillHole()
1019 	{ return m_transport && m_transport->drillHole(); }
1020 
1021     /**
1022      * Set the interval until receiver timeout is detected
1023      * @param interval Milliseconds until receiver times out, zero to disable
1024      */
1025     void setTimeout(int interval);
1026 
1027     /**
1028      * Get the RTP/RTCP transport of data handled by this session.
1029      * @return A pointer to the RTPTransport of this session
1030      */
transport()1031     inline RTPTransport* transport() const
1032 	{ return m_transport; }
1033 
1034     /**
1035      * Set the UDP transport of data handled by this session
1036      * @param trans A pointer to the new RTPTransport for this session
1037      */
1038     virtual void transport(RTPTransport* trans);
1039 
1040 protected:
1041     /**
1042      * Default constructor
1043      * @param dbg Session DebugEnabler
1044      * @param traceId Session trace ID
1045      */
1046     UDPSession(DebugEnabler* dbg = 0, const char* traceId = 0);
1047 
1048     /**
1049      * Method called when the receiver timed out
1050      * @param initial True if no packet was ever received in this session
1051      */
1052     virtual void timeout(bool initial);
1053 
1054     RTPTransport* m_transport;
1055     u_int64_t m_timeoutTime;
1056     u_int64_t m_timeoutInterval;
1057 };
1058 
1059 /**
1060  * An unidirectional or bidirectional RTP session
1061  * @short Full RTP session
1062  */
1063 class YRTP_API RTPSession : public UDPSession, public Mutex
1064 {
1065 public:
1066     /**
1067      * Direction of the session
1068      */
1069     enum Direction {
1070 	FullStop = 0,
1071 	RecvOnly = 1,
1072 	SendOnly = 2,
1073 	SendRecv = 3
1074     };
1075 
1076     /**
1077      * Default constructor, creates a detached session
1078      * @param dbg Session DebugEnabler
1079      * @param traceId Session trace ID
1080      */
1081     RTPSession(DebugEnabler* dbg = 0, const char* traceId = 0);
1082 
1083     /**
1084      * Destructor - shuts down the session and destroys the transport
1085      */
1086     virtual ~RTPSession();
1087 
1088     /**
1089      * Retrieve MGCP P: style comma separated session parameters
1090      * @param stats String to append parameters to
1091      */
1092     virtual void getStats(String& stats) const;
1093 
1094     /**
1095      * This method is called to process a RTP packet.
1096      * @param data Pointer to raw RTP data
1097      * @param len Length of the data packet
1098      */
1099     virtual void rtpData(const void* data, int len);
1100 
1101     /**
1102      * This method is called to process a RTCP packet.
1103      * @param data Pointer to raw RTCP data
1104      * @param len Length of the data packet
1105      */
1106     virtual void rtcpData(const void* data, int len);
1107 
1108     /**
1109      * Process one RTP data packet
1110      * @param marker Set to true if the marker bit is set
1111      * @param timestamp Sampling instant of the packet data
1112      * @param data Pointer to data block to process
1113      * @param len Length of the data block in bytes
1114      * @return True if data was handled
1115      */
1116     virtual bool rtpRecvData(bool marker, unsigned int timestamp,
1117 	const void* data, int len);
1118 
1119     /**
1120      * Process one RTP event
1121      * @param event Received event code
1122      * @param key Received key (for events 0-16) or zero
1123      * @param duration Duration of the event as number of samples
1124      * @param volume Attenuation of the tone, zero for don't care
1125      * @param timestamp Sampling instant of the initial packet data
1126      * @return True if data was handled
1127      */
1128     virtual bool rtpRecvEvent(int event, char key, int duration,
1129 	int volume, unsigned int timestamp);
1130 
1131     /**
1132      * Method called for unknown payload types just before attempting
1133      *  to call rtpRecvData(). This is a good opportunity to change the
1134      *  payload type and continue.
1135      * @param payload Payload number
1136      * @param timestamp Sampling instant of the unexpected packet data
1137      */
1138     virtual void rtpNewPayload(int payload, unsigned int timestamp);
1139 
1140     /**
1141     * Method called when a packet with an unexpected SSRC is received
1142     *  just before processing further. This is a good opportunity to
1143     *  change the SSRC and continue
1144     * @param newSsrc SSRC received in packet
1145     * @param marker True if marker bit is set in the RTP packet
1146     */
1147     virtual void rtpNewSSRC(u_int32_t newSsrc, bool marker);
1148 
1149     /**
1150      * Create a new RTP sender for this session.
1151      * Override this method to create objects derived from RTPSender.
1152      * @return Pointer to the new sender or NULL on failure
1153      */
1154     virtual RTPSender* createSender();
1155 
1156     /**
1157      * Create a new RTP receiver for this session.
1158      * Override this method to create objects derived from RTPReceiver.
1159      * @return Pointer to the new receiver or NULL on failure
1160      */
1161     virtual RTPReceiver* createReceiver();
1162 
1163     /**
1164      * Create a cipher when required for SRTP
1165      * @param name Name of the cipher to create
1166      * @param dir Direction the cipher must be able to handle
1167      * @return Pointer to newly allocated Cipher or NULL
1168      */
1169     virtual Cipher* createCipher(const String& name, Cipher::Direction dir);
1170 
1171     /**
1172      * Check if a cipher is supported for SRTP
1173      * @param name Name of the cipher to check
1174      * @return True if the specified cipher is supported
1175      */
1176     virtual bool checkCipher(const String& name);
1177 
1178     /**
1179      * Send one RTP payload packet
1180      * @param marker Set to true if the marker bit must be set
1181      * @param payload Payload number
1182      * @param timestamp Sampling instant of the packet data
1183      * @param data Pointer to data block to send
1184      * @param len Length of the data block
1185      * @return True if data sending was attempted
1186      */
rtpSend(bool marker,int payload,unsigned int timestamp,const void * data,int len)1187     inline bool rtpSend(bool marker, int payload, unsigned int timestamp,
1188 	const void* data, int len)
1189 	{ Lock lck(this); return m_send && m_send->rtpSend(marker,payload,timestamp,data,len); }
1190 
1191     /**
1192      * Send one RTP data packet
1193      * @param marker Set to true if the marker bit must be set
1194      * @param timestamp Sampling instant of the packet data
1195      * @param data Pointer to data block to send
1196      * @param len Length of the data block
1197      * @return True if data sending was attempted
1198      */
rtpSendData(bool marker,unsigned int timestamp,const void * data,int len)1199     inline bool rtpSendData(bool marker, unsigned int timestamp,
1200 	const void* data, int len)
1201 	{ Lock lck(this); return m_send && m_send->rtpSendData(marker,timestamp,data,len); }
1202 
1203     /**
1204      * Send one RTP event
1205      * @param event Event code to send
1206      * @param duration Duration of the event as number of samples
1207      * @param volume Attenuation of the tone, zero for don't care
1208      * @param timestamp Sampling instant of the packet data, zero to use current
1209      * @return True if data sending was attempted
1210      */
1211     inline bool rtpSendEvent(int event, int duration, int volume = 0, unsigned int timestamp = 0)
1212 	{ Lock lck(this); return m_send && m_send->rtpSendEvent(event,duration,volume,timestamp); }
1213 
1214     /**
1215      * Send one RTP key event
1216      * @param key Key to send
1217      * @param duration Duration of the event as number of samples
1218      * @param volume Attenuation of the tone, zero for don't care
1219      * @param timestamp Sampling instant of the packet data, zero to use current
1220      * @return True if data sending was attempted
1221      */
1222     inline bool rtpSendKey(char key, int duration, int volume = 0, unsigned int timestamp = 0)
1223 	{ Lock lck(this); return m_send && m_send->rtpSendKey(key,duration,volume,timestamp); }
1224 
1225     /**
1226      * Retrieve the number of lost packets in current received
1227      * @return Number of packets in sequence gaps
1228      */
ioPacketsLost()1229     inline u_int32_t ioPacketsLost() const
1230 	{ return m_recv ? m_recv->ioPacketsLost() : 0; }
1231 
1232     /**
1233      * Get the payload padding size
1234      * @return Chunk size to pad the payload to a multiple of
1235      */
padding()1236     inline int padding() const
1237 	{ return m_send ? m_send->padding() : 0; }
1238 
1239     /**
1240      * Set the padding to a multiple of a data chunk
1241      * @param chunk Size to pad the payload to a multiple of
1242      * @return True if the new chunk size is valid
1243      */
padding(int chunk)1244     inline bool padding(int chunk)
1245 	{ return m_send && m_send->padding(chunk); }
1246 
1247     /**
1248      * Allocate and set a new dejitter buffer for the receiver in the session
1249      * @param mindelay Minimum length of the dejitter buffer in microseconds
1250      * @param maxdelay Maximum length of the dejitter buffer in microseconds
1251      */
1252     inline void setDejitter(unsigned int mindelay = 20, unsigned int maxdelay = 50)
1253 	{ if (m_recv) m_recv->setDejitter(mindelay,maxdelay); }
1254 
1255     /**
1256      * Set the RTP/RTCP transport of data handled by this session
1257      * @param trans A pointer to the new RTPTransport for this session
1258      */
1259     virtual void transport(RTPTransport* trans);
1260 
1261     /**
1262      * Get the RTP/RTCP sender of this session
1263      * @return A pointer to the RTPSender of this session
1264      */
sender()1265     inline RTPSender* sender() const
1266 	{ return m_send; }
1267 
1268     /**
1269      * Set the RTP/RTCP sender of this session
1270      * @param send A pointer to the new RTPSender of this session or NULL
1271      */
1272     void sender(RTPSender* send);
1273 
1274     /**
1275      * Get the RTP/RTCP receiver of this session
1276      * @return A pointer to the RTPReceiver of this session
1277      */
receiver()1278     inline RTPReceiver* receiver() const
1279 	{ return m_recv; }
1280 
1281     /**
1282      * Set the RTP/RTCP receiver of this session
1283      * @param recv A pointer to the new RTPReceiver of this session or NULL
1284      */
1285     void receiver(RTPReceiver* recv);
1286 
1287     /**
1288      * Get the direction of this session
1289      * @return Session's direction as a Direction enum
1290      */
direction()1291     inline Direction direction() const
1292 	{ return m_direction; }
1293 
1294     /**
1295      * Set the direction of this session. A transport must exist for this
1296      *  method to succeed.
1297      * @param dir New Direction for this session
1298      * @return True if direction was set, false if a failure occured
1299      */
1300     bool direction(Direction dir);
1301 
1302     /**
1303      * Add a direction of this session. A transport must exist for this
1304      *  method to succeed.
1305      * @param dir New Direction to add for this session
1306      * @return True if direction was set, false if a failure occured
1307      */
addDirection(Direction dir)1308     inline bool addDirection(Direction dir)
1309 	{ return direction((Direction)(m_direction | dir)); }
1310 
1311     /**
1312      * Delete a direction of this session. A transport must exist for this
1313      *  method to succeed.
1314      * @param dir Direction to remove for this session
1315      * @return True if direction was set, false if a failure occured
1316      */
delDirection(Direction dir)1317     inline bool delDirection(Direction dir)
1318 	{ return direction((Direction)(m_direction & ~dir)); }
1319 
1320     /**
1321      * Set the data payload type for both receiver and sender.
1322      * @param type Payload type, -1 to disable
1323      * @return True if changed, false if invalid payload type
1324      */
1325     bool dataPayload(int type);
1326 
1327     /**
1328      * Set the event payload type for both receiver and sender.
1329      * @param type Payload type, -1 to disable
1330      * @return True if changed, false if invalid payload type
1331      */
1332     bool eventPayload(int type);
1333 
1334     /**
1335      * Set the silence payload type for both receiver and sender.
1336      * @param type Payload type, -1 to disable
1337      * @return True if changed, false if invalid payload type
1338      */
1339     bool silencePayload(int type);
1340 
1341     /**
1342      * Set the local network address of the RTP transport of this session
1343      * @param addr New local RTP transport address
1344      * @param rtcp Enable RTCP in this session
1345      * @return True if address set, false if a failure occured
1346      */
1347     inline bool localAddr(SocketAddr& addr, bool rtcp = true)
1348 	{ Lock lck(this); return m_transport && m_transport->localAddr(addr,rtcp); }
1349 
1350     /**
1351      * Get the stored security provider or of the sender
1352      * @return A pointer to the RTPSecure or NULL
1353      */
security()1354     inline RTPSecure* security() const
1355 	{ return m_send ? m_send->security() : m_secure; }
1356 
1357     /**
1358      * Store a security provider for the sender
1359      * @param secure Pointer to the new RTPSecure or NULL
1360      */
1361     void security(RTPSecure* secure);
1362 
1363     /**
1364      * Set the RTCP report interval
1365      * @param interval Average interval between reports in msec, zero to disable
1366      */
1367     void setReports(int interval);
1368 
1369     /**
1370      * Put the collected statistical data
1371      * @param stats NamedList to populate with the data
1372      */
1373     virtual void getStats(NamedList& stats) const;
1374 
1375     /**
1376      * Increase the counter for number of RTP packets received from a wrong source
1377      */
1378     virtual void incWrongSrc();
1379 
1380     /**
1381      * Set the packet with invalid sequence warn mode
1382      * @param on True to show a message at DebugWarn level,
1383      *  false to show at DebugInfo level
1384      */
setWarnSeq(bool on)1385     inline void setWarnSeq(bool on)
1386 	{ m_warnSeq = on ? 1 : -1; }
1387 
1388     /**
1389      * Initialize data debug
1390      * @param params Parameters list
1391      */
initDebugData(const NamedList & params)1392     inline void initDebugData(const NamedList& params) {
1393 	if (m_recv)
1394 		m_recv->initDebugData(true,params);
1395 	    if (m_send)
1396 		m_send->initDebugData(false,params);
1397 	}
1398 
1399 protected:
1400     /**
1401      * Method called periodically to push any asynchronous data or statistics
1402      * @param when Time to use as base in all computing
1403      */
1404     virtual void timerTick(const Time& when);
1405 
1406     /**
1407      * Send a RTCP report
1408      * @param when Time to use as base for timestamps
1409      */
1410     void sendRtcpReport(const Time& when);
1411 
1412     /**
1413      * Send a RTCP BYE when the sender is stopped or replaced
1414      */
1415     void sendRtcpBye();
1416 
1417 private:
1418     Direction m_direction;
1419     RTPSender* m_send;
1420     RTPReceiver* m_recv;
1421     RTPSecure* m_secure;
1422     u_int64_t m_reportTime;
1423     u_int64_t m_reportInterval;
1424     int m_warnSeq;                       // Warn on invalid sequence (1: DebugWarn, -1: DebugInfo)
1425 };
1426 
1427 /**
1428  * A bidirectional UDPTL session usable for T.38
1429  * @short UDPTL session
1430  */
1431 class YRTP_API UDPTLSession : public UDPSession, public Mutex
1432 {
1433 public:
1434     /**
1435      * Destructor
1436      */
1437     ~UDPTLSession();
1438 
1439     /**
1440      * Set the local network address of the RTP transport of this session
1441      * @param addr New local RTP transport address
1442      * @return True if address set, false if a failure occured
1443      */
localAddr(SocketAddr & addr)1444     inline bool localAddr(SocketAddr& addr)
1445 	{ Lock lck(this); return m_transport && m_transport->localAddr(addr,false); }
1446 
1447     /**
1448      * Get the maximum UDPTL packet length
1449      * @return Maximum length of UDPTL packet length in bytes
1450      */
maxLen()1451     inline u_int16_t maxLen() const
1452 	{ return m_maxLen; }
1453 
1454     /**
1455      * Get the maximum number of UDPTL secondary IFPs
1456      * @return Maximum number of secondary IFPs, zero if disabled
1457      */
maxSec()1458     inline u_int8_t maxSec() const
1459 	{ return m_maxSec; }
1460 
1461     /**
1462      * This method is called to send or process an UDPTL packet
1463      * @param data Pointer to raw UDPTL data
1464      * @param len Length of the data packet
1465      */
1466     virtual void rtpData(const void* data, int len);
1467 
1468     /**
1469      * Send UDPTL data over the transport, add older blocks for error recovery
1470      * @param data Pointer to IFP block to send as primary
1471      * @param len Length of primary IFP block
1472      * @param seq Sequence number to incorporate in message
1473      * @return True if data block was sent, false if an error occured
1474      */
1475     bool udptlSend(const void* data, int len, u_int16_t seq);
1476 
1477 protected:
1478     /**
1479      * UDPTL Session constructor
1480      * @param maxLen Maximum length of UDPTL packet, at least longest primary IFP + 5 bytes
1481      * @param maxSec Maximum number of secondary IFPs, set to zero to disable
1482      * @param dbg Session DebugEnabler
1483      * @param traceId Session trace ID
1484      */
1485     UDPTLSession(u_int16_t maxLen = 250, u_int8_t maxSec = 2,
1486 	DebugEnabler* dbg = 0, const char* traceId = 0);
1487 
1488     /**
1489      * Method called periodically to push any asynchronous data or statistics
1490      * @param when Time to use as base in all computing
1491      */
1492     virtual void timerTick(const Time& when);
1493 
1494     /**
1495      * Create a new UDPTL transport for this session.
1496      * Override this method to create objects derived from RTPTransport.
1497      * @return Pointer to the new transport or NULL on failure
1498      */
1499     virtual RTPTransport* createTransport();
1500 
1501     /**
1502      * Method called when UDPTL data is received
1503      * @param data Pointer to IFP block
1504      * @param len Length of the IFP block
1505      * @param seq Sequence number of the block
1506      * @param recovered True if the IFP block was recovered after data loss
1507      */
1508     virtual void udptlRecv(const void* data, int len, u_int16_t seq, bool recovered) = 0;
1509 
1510 private:
1511     void recoverSec(const unsigned char* data, int len, u_int16_t seq, int nSec);
1512     u_int16_t m_rxSeq;
1513     u_int16_t m_txSeq;
1514     u_int16_t m_maxLen;
1515     u_int8_t m_maxSec;
1516     bool m_warn;
1517     ObjList m_txQueue;
1518 };
1519 
1520 /**
1521  * Security and integrity implementation
1522  * @short SRTP implementation
1523  */
1524 class YRTP_API RTPSecure : public GenObject, public RTPDebug
1525 {
1526     friend class RTPReceiver;
1527     friend class RTPSender;
1528     friend class RTPSession;
1529 public:
1530     /**
1531      * Default constructor, builds an inactive implementation
1532      * @param dbg DebugEnabler
1533      * @param traceId Trace ID
1534      */
1535     RTPSecure(DebugEnabler* dbg = 0, const char* traceId = 0);
1536 
1537     /**
1538      * Constructor that creates an active implementation
1539      * @param suite Cryptographic suite to use by default
1540      * @param dbg DebugEnabler
1541      * @param traceId Trace ID
1542      */
1543     RTPSecure(const String& suite, DebugEnabler* dbg = 0, const char* traceId = 0);
1544 
1545     /**
1546      * Constructor that copies the basic crypto lengths
1547      * @param other Security provider to copy parameters from
1548      */
1549     RTPSecure(const RTPSecure& other);
1550 
1551     /**
1552      * Destructor
1553      */
1554     virtual ~RTPSecure();
1555 
1556     /**
1557      * Get the owner of this security instance
1558      * @return Pointer to RTPBaseIO or NULL
1559      */
owner()1560     inline RTPBaseIO* owner() const
1561 	{ return m_owner; }
1562 
1563     /**
1564      * Set the owner of this security instance
1565      * @param newOwner Pointer to new RTPBaseIO owning this security instance
1566      */
1567     void owner(RTPBaseIO* newOwner);
1568 
1569     /**
1570      * Get the current RTP cipher if set
1571      * @return Pointer to current RTP cipher or NULL
1572      */
rtpCipher()1573     inline Cipher* rtpCipher() const
1574 	{ return m_rtpCipher; }
1575 
1576     /**
1577      * Check if the systems supports requirements for activating SRTP
1578      * @param session RTP session to use for cipher checking, NULL to use owner session
1579      * @return True if it looks like SRTP can be activated later
1580      */
1581     virtual bool supported(RTPSession* session = 0) const;
1582 
1583     /**
1584      * Set up the cryptographic parameters
1585      * @param suite Descriptor of the encryption and authentication algorithms
1586      * @param keyParams Keying material and related parameters
1587      * @param paramList Optional session parameters as list of Strings
1588      * @return True if the session parameters were applied successfully
1589      */
1590     virtual bool setup(const String& suite, const String& keyParams, const ObjList* paramList = 0);
1591 
1592     /**
1593      * Create a set of cryptographic parameters
1594      * @param suite Reference of returned cryptographic suite description
1595      * @param keyParams Reference to returned keying material
1596      * @param buildMaster Create random master key and salt if not already set
1597      * @return True if security instance is valid and ready
1598      */
1599     virtual bool create(String& suite, String& keyParams, bool buildMaster = true);
1600 
1601 protected:
1602     /**
1603      * Initialize security related variables in the RTP session
1604      */
1605     virtual void init();
1606 
1607     /**
1608      * Method called to encipher RTP payload data in-place
1609      * @param data Pointer to data block to encipher
1610      * @param len Length of payload data to be encrypted including any padding
1611      */
1612     virtual void rtpEncipher(unsigned char* data, int len);
1613 
1614     /**
1615      * Method called to add integrity information to the RTP packet
1616      * @param data Pointer to the RTP packet to protect
1617      * @param len Length of RTP data to be encrypted including header and padding
1618      * @param authData Address to write the integrity data to
1619      */
1620     virtual void rtpAddIntegrity(const unsigned char* data, int len, unsigned char* authData);
1621 
1622     /**
1623      * Method called to decipher RTP data in-place
1624      * @param data Pointer to data block to decipher
1625      * @param len Length of data including any padding
1626      * @param secData Pointer to security data if applicable
1627      * @param ssrc SSRC of the packet to decipher
1628      * @param seq Full (48 bit) seqence number of the packet including rollovers
1629      * @return True is the packet was deciphered correctly or can't tell
1630      */
1631     virtual bool rtpDecipher(unsigned char* data, int len, const void* secData, u_int32_t ssrc, u_int64_t seq);
1632 
1633     /**
1634      * Method called to check the integrity of the RTP packet
1635      * @param data Pointer to RTP header and data
1636      * @param len Length of header, data and padding
1637      * @param authData Pointer to authentication data
1638      * @param ssrc SSRC of the packet to validate
1639      * @param seq Full (48 bit) seqence number of the packet including rollovers
1640      * @return True is the packet passed integrity checks
1641      */
1642     virtual bool rtpCheckIntegrity(const unsigned char* data, int len, const void* authData, u_int32_t ssrc, u_int64_t seq);
1643 
1644     /**
1645      * Internal method implementing key derivation
1646      * @param cipher Cipher used for key derivation
1647      * @param key Reference to derived key output
1648      * @param len Desired length of the key, should be at most cipher block length
1649      * @param label Derived key type
1650      * @param index Packet index after being divided by KDR
1651      * @return True if success, false if invalid parameters or missing cipher
1652      */
1653     bool deriveKey(Cipher& cipher, DataBlock& key, unsigned int len, unsigned char label, u_int64_t index = 0);
1654 
1655 private:
1656     RTPBaseIO* m_owner;
1657     Cipher* m_rtpCipher;
1658     DataBlock m_masterKey;
1659     DataBlock m_masterSalt;
1660     DataBlock m_cipherKey;
1661     DataBlock m_cipherSalt;
1662     SHA1 m_authIpad;
1663     SHA1 m_authOpad;
1664     u_int32_t m_rtpAuthLen;
1665     bool m_rtpEncrypted;
1666 };
1667 
1668 }
1669 
1670 #endif /* __YATERTP_H */
1671 
1672 /* vi: set ts=8 sw=4 sts=4 noet: */
1673