1 /*
2  * rtp.h
3  *
4  * RTP protocol handler
5  *
6  * Open H323 Library
7  *
8  * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Open H323 Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions of this code were written with the assisance of funding from
25  * Vovida Networks, Inc. http://www.vovida.com.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 27699 $
30  * $Author: rjongbloed $
31  * $Date: 2012-05-24 20:35:37 -0500 (Thu, 24 May 2012) $
32  */
33 
34 #ifndef OPAL_RTP_RTP_H
35 #define OPAL_RTP_RTP_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #include <opal/buildopts.h>
42 
43 #include <ptlib/sockets.h>
44 #include <ptlib/safecoll.h>
45 
46 #include <list>
47 
48 
49 class RTP_JitterBuffer;
50 class PNatMethod;
51 class OpalSecurityMode;
52 class RTCP_XR_Metrics;
53 
54 ///////////////////////////////////////////////////////////////////////////////
55 //
56 // class to hold the QoS definitions for an RTP channel
57 
58 class RTP_QOS : public PObject
59 {
60   PCLASSINFO(RTP_QOS,PObject);
61   public:
62     PQoS dataQoS;
63     PQoS ctrlQoS;
64 };
65 
66 ///////////////////////////////////////////////////////////////////////////////
67 // Real Time Protocol - IETF RFC1889 and RFC1890
68 
69 /**An RTP data frame encapsulation.
70   */
71 class RTP_DataFrame : public PBYTEArray
72 {
73   PCLASSINFO(RTP_DataFrame, PBYTEArray);
74 
75   public:
76     RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
77     RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = true);
78 
79     enum {
80       ProtocolVersion = 2,
81       MinHeaderSize = 12,
82       // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
83       MaxMtuPayloadSize = (576-20-16-12)
84     };
85 
86     enum PayloadTypes {
87       PCMU,         // G.711 u-Law
88       FS1016,       // Federal Standard 1016 CELP
89       G721,         // ADPCM - Subsumed by G.726
90       G726 = G721,
91       GSM,          // GSM 06.10
92       G7231,        // G.723.1 at 6.3kbps or 5.3 kbps
93       DVI4_8k,      // DVI4 at 8kHz sample rate
94       DVI4_16k,     // DVI4 at 16kHz sample rate
95       LPC,          // LPC-10 Linear Predictive CELP
96       PCMA,         // G.711 A-Law
97       G722,         // G.722
98       L16_Stereo,   // 16 bit linear PCM
99       L16_Mono,     // 16 bit linear PCM
100       G723,         // G.723
101       CN,           // Confort Noise
102       MPA,          // MPEG1 or MPEG2 audio
103       G728,         // G.728 16kbps CELP
104       DVI4_11k,     // DVI4 at 11kHz sample rate
105       DVI4_22k,     // DVI4 at 22kHz sample rate
106       G729,         // G.729 8kbps
107       Cisco_CN,     // Cisco systems comfort noise (unofficial)
108 
109       CelB = 25,    // Sun Systems Cell-B video
110       JPEG,         // Motion JPEG
111       H261 = 31,    // H.261
112       MPV,          // MPEG1 or MPEG2 video
113       MP2T,         // MPEG2 transport system
114       H263,         // H.263
115 
116       T38 = 38,     // T.38 (internal)
117 
118       LastKnownPayloadType,
119 
120       DynamicBase = 96,
121       MaxPayloadType = 127,
122       IllegalPayloadType
123     };
124 
GetVersion()125     unsigned GetVersion() const { return (theArray[0]>>6)&3; }
126 
GetExtension()127     PBoolean GetExtension() const   { return (theArray[0]&0x10) != 0; }
128     void SetExtension(PBoolean ext);
129 
GetMarker()130     PBoolean GetMarker() const { return (theArray[1]&0x80) != 0; }
131     void SetMarker(PBoolean m);
132 
GetPadding()133     bool GetPadding() const { return (theArray[0]&0x20) != 0; }
SetPadding(bool v)134     void SetPadding(bool v)  { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
GetPaddingPtr()135     BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
136 
GetPaddingSize()137     unsigned GetPaddingSize() const { return m_paddingSize; }
138     bool     SetPaddingSize(PINDEX sz);
139 
GetPayloadType()140     PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
141     void         SetPayloadType(PayloadTypes t);
142 
GetSequenceNumber()143     WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
SetSequenceNumber(WORD n)144     void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
145 
GetTimestamp()146     DWORD GetTimestamp() const  { return *(PUInt32b *)&theArray[4]; }
SetTimestamp(DWORD t)147     void  SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
148 
GetSyncSource()149     DWORD GetSyncSource() const  { return *(PUInt32b *)&theArray[8]; }
SetSyncSource(DWORD s)150     void  SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
151 
GetContribSrcCount()152     PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
153     DWORD  GetContribSource(PINDEX idx) const;
154     void   SetContribSource(PINDEX idx, DWORD src);
155 
GetHeaderSize()156     PINDEX GetHeaderSize() const { return m_headerSize; }
157 
158     int GetExtensionType() const; // -1 is no extension
159     void   SetExtensionType(int type);
160     PINDEX GetExtensionSizeDWORDs() const;      // get the number of 32 bit words in the extension (excluding the header).
161     bool   SetExtensionSizeDWORDs(PINDEX sz);   // set the number of 32 bit words in the extension (excluding the header)
162     BYTE * GetExtensionPtr() const;
163 
GetPayloadSize()164     PINDEX GetPayloadSize() const { return m_payloadSize; }
165     bool   SetPayloadSize(PINDEX sz);
GetPayloadPtr()166     BYTE * GetPayloadPtr()     const { return (BYTE *)(theArray+m_headerSize); }
167 
Clone()168     virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
169     virtual void PrintOn(ostream & strm) const;
170 
171     // Note this sets the whole packet length, and calculates the various
172     // sub-section sizes: header payload and padding.
173     bool SetPacketSize(PINDEX sz);
174 
175   protected:
176     PINDEX m_headerSize;
177     PINDEX m_payloadSize;
178     PINDEX m_paddingSize;
179 
180 #if PTRACING
181     friend ostream & operator<<(ostream & o, PayloadTypes t);
182 #endif
183 };
184 
185 PLIST(RTP_DataFrameList, RTP_DataFrame);
186 
187 
188 /**An RTP control frame encapsulation.
189   */
190 class RTP_ControlFrame : public PBYTEArray
191 {
192   PCLASSINFO(RTP_ControlFrame, PBYTEArray);
193 
194   public:
195     RTP_ControlFrame(PINDEX compoundSize = 2048);
196 
GetVersion()197     unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
198 
GetCount()199     unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
200     void     SetCount(unsigned count);
201 
202     enum PayloadTypes {
203       e_IntraFrameRequest       = 192,
204       e_SenderReport            = 200,
205       e_ReceiverReport          = 201,
206       e_SourceDescription       = 202,
207       e_Goodbye                 = 203,
208       e_ApplDefined             = 204,
209       e_TransportLayerFeedBack  = 205, // RFC4585
210       e_PayloadSpecificFeedBack = 206,
211       e_ExtendedReport          = 207  // RFC3611
212     };
213 
GetPayloadType()214     unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
215     void     SetPayloadType(unsigned t);
216 
GetPayloadSize()217     PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
218     void   SetPayloadSize(PINDEX sz);
219 
220     BYTE * GetPayloadPtr() const;
221 
222     PBoolean ReadNextPacket();
223     PBoolean StartNewPacket();
224     void EndPacket();
225 
226     PINDEX GetCompoundSize() const;
227 
228     void Reset(PINDEX size);
229 
230 #pragma pack(1)
231     struct ReceiverReport {
232       PUInt32b ssrc;      /* data source being reported */
233       BYTE fraction;      /* fraction lost since last SR/RR */
234       BYTE lost[3];	  /* cumulative number of packets lost (signed!) */
235       PUInt32b last_seq;  /* extended last sequence number received */
236       PUInt32b jitter;    /* interarrival jitter */
237       PUInt32b lsr;       /* last SR packet from this source */
238       PUInt32b dlsr;      /* delay since last SR packet */
239 
GetLostPacketsReceiverReport240       unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
241       void SetLostPackets(unsigned lost);
242     };
243 
244     struct SenderReport {
245       PUInt32b ntp_sec;   /* NTP timestamp */
246       PUInt32b ntp_frac;
247       PUInt32b rtp_ts;    /* RTP timestamp */
248       PUInt32b psent;     /* packets sent */
249       PUInt32b osent;     /* octets sent */
250     };
251 
252     struct ExtendedReport {
253       /* VoIP Metrics Report Block */
254       BYTE bt;                     /* block type */
255       BYTE type_specific;          /* determined by the block definition */
256       PUInt16b length;             /* length of the report block */
257       PUInt32b ssrc;               /* data source being reported */
258       BYTE loss_rate;              /* fraction of RTP data packets lost */
259       BYTE discard_rate;           /* fraction of RTP data packets discarded */
260       BYTE burst_density;          /* fraction of RTP data packets within burst periods */
261       BYTE gap_density;            /* fraction of RTP data packets within inter-burst gaps */
262       PUInt16b burst_duration;     /* the mean duration, in ms, of burst periods */
263       PUInt16b gap_duration;       /* the mean duration, in ms, of gap periods */
264       PUInt16b round_trip_delay;   /* the most recently calculated round trip time */
265       PUInt16b end_system_delay;   /* the most recently estimates end system delay */
266       BYTE signal_level;           /* voice signal level related to 0 dBm */
267       BYTE noise_level;            /* ratio of the silent background level to 0 dBm */
268       BYTE rerl;                   /* residual echo return loss */
269       BYTE gmin;                   /* gap threshold */
270       BYTE r_factor;               /* voice quality metric of the call */
271       BYTE ext_r_factor;           /* external R factor */
272       BYTE mos_lq;                 /* MOS for listen quality */
273       BYTE mos_cq;                 /* MOS for conversational quality */
274       BYTE rx_config;              /* receiver configuration byte */
275       BYTE reserved;               /* reserved for future definition */
276       PUInt16b jb_nominal;         /* current nominal jitter buffer delay, in ms */
277       PUInt16b jb_maximum;         /* current maximum jitter buffer delay, in ms */
278       PUInt16b jb_absolute;        /* current absolute maximum jitter buffer delay, in ms */
279     };
280 
281     enum DescriptionTypes {
282       e_END,
283       e_CNAME,
284       e_NAME,
285       e_EMAIL,
286       e_PHONE,
287       e_LOC,
288       e_TOOL,
289       e_NOTE,
290       e_PRIV,
291       NumDescriptionTypes
292     };
293 
294     struct SourceDescription {
295       PUInt32b src;       /* first SSRC/CSRC */
296       struct Item {
297         BYTE type;        /* type of SDES item (enum DescriptionTypes) */
298         BYTE length;      /* length of SDES item (in octets) */
299         char data[1];     /* text, not zero-terminated */
300 
301         /* WARNING, SourceDescription may not be big enough to contain length and data, for
302            instance, when type == RTP_ControlFrame::e_END.
303            Be careful whan calling the following function of it may read to over to
304            memory allocated*/
GetLengthTotalSourceDescription::Item305         unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
GetNextItemSourceDescription::Item306         const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
GetNextItemSourceDescription::Item307         Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
308       } item[1];          /* list of SDES items */
309     };
310 
311     void StartSourceDescription(
312       DWORD src   ///<  SSRC/CSRC identifier
313     );
314 
315     void AddSourceDescriptionItem(
316       unsigned type,            ///<  Description type
317       const PString & data      ///<  Data for description
318     );
319 
320     // RFC4585 Feedback Message Type (FMT)
GetFbType()321     unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
322     void     SetFbType(unsigned type, PINDEX fciSize);
323 
324     enum PayloadSpecificFbTypes {
325       e_PictureLossIndication = 1,
326       e_SliceLostIndication,
327       e_ReferencePictureSelectionIndication,
328       e_FullIntraRequest,                     //RFC5104
329       e_TemporalSpatialTradeOffRequest,
330       e_TemporalSpatialTradeOffNotification,
331       e_VideoBackChannelMessage,
332       e_ApplicationLayerFbMessage = 15
333     };
334 
335     struct FbFCI {
336       PUInt32b senderSSRC;  /* data source of sender of message */
337       PUInt32b mediaSSRC;   /* data source of media */
338     };
339 
340     struct FbFIR {
341       FbFCI    fci;
342       PUInt32b requestSSRC;
343       BYTE     sequenceNUmber;
344     };
345 
346     struct FbTSTO {
347       FbFCI    fci;
348       PUInt32b requestSSRC;
349       BYTE     sequenceNUmber;
350       BYTE     reserver[2];
351       BYTE     tradeOff;
352     };
353 
354 #pragma pack()
355 
356   protected:
357     PINDEX compoundOffset;
358     PINDEX payloadSize;
359 };
360 
361 
362 class RTP_Session;
363 
364 ///////////////////////////////////////////////////////////////////////////////
365 
366 #if OPAL_STATISTICS
367 
368 /**This class carries statistics on the media stream.
369   */
370 class OpalMediaStatistics : public PObject
371 {
372     PCLASSINFO(OpalMediaStatistics, PObject);
373   public:
374     OpalMediaStatistics();
375 
376     // General info (typicallly from RTP)
377     PUInt64  m_totalBytes;
378     unsigned m_totalPackets;
379     unsigned m_packetsLost;
380     unsigned m_packetsOutOfOrder;
381     unsigned m_packetsTooLate;
382     unsigned m_packetOverruns;
383     unsigned m_minimumPacketTime;
384     unsigned m_averagePacketTime;
385     unsigned m_maximumPacketTime;
386 
387     // Audio
388     unsigned m_averageJitter;
389     unsigned m_maximumJitter;
390     unsigned m_jitterBufferDelay;
391 
392     // Video
393     unsigned m_totalFrames;
394     unsigned m_keyFrames;
395 
396     // Fax
397 #if OPAL_FAX
398     enum {
399       FaxNotStarted = -2,
400       FaxInProgress = -1,
401       FaxSuccessful = 0,
402       FaxErrorBase  = 1
403     };
404     enum FaxCompression {
405       FaxCompressionUnknown,
406       FaxCompressionT4_1d,
407       FaxCompressionT4_2d,
408       FaxCompressionT6,
409     };
410     friend ostream & operator<<(ostream & strm, FaxCompression compression);
411     struct Fax {
412       Fax();
413 
414       int  m_result;      // -2=not started, -1=progress, 0=success, >0=ended with error
415       char m_phase;       // 'A', 'B', 'D'
416       int  m_bitRate;     // e.g. 14400, 9600
417       FaxCompression m_compression; // 0=N/A, 1=T.4 1d, 2=T.4 2d, 3=T.6
418       bool m_errorCorrection;
419       int  m_txPages;
420       int  m_rxPages;
421       int  m_totalPages;
422       int  m_imageSize;   // In bytes
423       int  m_resolutionX; // Pixels per inch
424       int  m_resolutionY; // Pixels per inch
425       int  m_pageWidth;
426       int  m_pageHeight;
427       int  m_badRows;     // Total number of bad rows
428       int  m_mostBadRows; // Longest run of bad rows
429       int  m_errorCorrectionRetries;
430 
431       PString m_stationId; // Remote station identifier
432       PString m_errorText;
433     } m_fax;
434 #endif
435 };
436 
437 #endif
438 
439 
440 /**This class is the base for user data that may be attached to the RTP_session
441    allowing callbacks for statistics and progress monitoring to be passed to an
442    arbitrary object that an RTP consumer may require.
443   */
444 class RTP_UserData : public PObject
445 {
446   PCLASSINFO(RTP_UserData, PObject);
447 
448   public:
449     /**Callback from the RTP session for transmit statistics monitoring.
450        This is called every RTP_Session::txStatisticsInterval packets on the
451        transmitter indicating that the statistics have been updated.
452 
453        The default behaviour does nothing.
454       */
455     virtual void OnTxStatistics(
456       const RTP_Session & session   ///<  Session with statistics
457     ) const;
458 
459     /**Callback from the RTP session for receive statistics monitoring.
460        This is called every RTP_Session::receiverReportInterval packets on the
461        receiver indicating that the statistics have been updated.
462 
463        The default behaviour does nothing.
464       */
465     virtual void OnRxStatistics(
466       const RTP_Session & session   ///<  Session with statistics
467     ) const;
468 
469 #if OPAL_VIDEO
470     /**Callback from the RTP session when an intra frame request control
471        packet is sent.
472 
473        The default behaviour does nothing.
474       */
475     virtual void OnTxIntraFrameRequest(
476       const RTP_Session & session   ///<  Session with statistics
477     ) const;
478 
479     /**Callback from the RTP session when an intra frame request control
480        packet is received.
481 
482        The default behaviour does nothing.
483       */
484     virtual void OnRxIntraFrameRequest(
485       const RTP_Session & session   ///<  Session with statistics
486     ) const;
487 #endif
488 
489     /**Callback from the RTP session when RTP session is failing due to the remote being unavailable
490        The default behaviour does nothing.
491       */
492     virtual void SessionFailing(
493       RTP_Session & session   ///<  Session with statistics
494     );
495 };
496 
497 class RTP_Encoding;
498 
499 
500 /**This class is for encpsulating the IETF Real Time Protocol interface.
501  */
502 class RTP_Session : public PObject
503 {
504   PCLASSINFO(RTP_Session, PObject);
505 
506   public:
507   /**@name Construction */
508   //@{
509     struct Params {
ParamsParams510       Params()
511         : id(0)
512         , userData(NULL)
513         , autoDelete(true)
514         , isAudio(false)
515         , remoteIsNAT(false)
516       { }
517 
518       PString             encoding;    ///<  identifies initial RTP encoding (RTP/AVP, UDPTL etc)
519       unsigned            id;          ///<  Session ID for RTP channel
520       RTP_UserData      * userData;    ///<  Optional data for session.
521       bool                autoDelete;  ///<  Delete optional data with session.
522       bool                isAudio;     ///<  is audio RTP data
523       bool                remoteIsNAT; ///<  Remote is behid NAT
524     };
525 
526     /**Create a new RTP session.
527      */
528     RTP_Session(
529       const Params & options ///< Parameters to construct with session.
530     );
531 
532     /**Delete a session.
533        This deletes the userData field if autoDeleteUserData is true.
534      */
535     ~RTP_Session();
536   //@}
537 
538   /**@name Operations */
539   //@{
540     /**Sets the size of the jitter buffer to be used by this RTP session.
541        A session defaults to not having any jitter buffer enabled for reading
542        and the ReadBufferedData() function simply calls ReadData().
543 
544        If either jitter delay parameter is zero, it destroys the jitter buffer
545        attached to this RTP session.
546       */
547     void SetJitterBufferSize(
548       unsigned minJitterDelay, ///<  Minimum jitter buffer delay in RTP timestamp units
549       unsigned maxJitterDelay, ///<  Maximum jitter buffer delay in RTP timestamp units
550       unsigned timeUnits = 0,  ///<  Time Units, zero uses default
551       PINDEX packetSize = 2048 ///<  Receive RTP packet size
552     );
553 
554     /**Get current size of the jitter buffer.
555        This returns the currently used jitter buffer delay in RTP timestamp
556        units. It will be some value between the minimum and maximum set in
557        the SetJitterBufferSize() function.
558       */
559     unsigned GetJitterBufferSize() const;
GetJitterBufferDelay()560     unsigned GetJitterBufferDelay() const { return GetJitterBufferSize()/GetJitterTimeUnits(); }
561 
562     /**Get current time units of the jitter buffer.
563      */
GetJitterTimeUnits()564     unsigned GetJitterTimeUnits() const { return m_timeUnits; }
565 
566     /**Modifies the QOS specifications for this RTP session*/
ModifyQOS(RTP_QOS *)567     virtual PBoolean ModifyQOS(RTP_QOS * )
568     { return false; }
569 
570     /**Read a data frame from the RTP channel.
571        This function will conditionally read data from the jitter buffer or
572        directly if there is no jitter buffer enabled. An application should
573        generally use this in preference to directly calling ReadData().
574       */
575     virtual PBoolean ReadBufferedData(
576       RTP_DataFrame & frame   ///<  Frame read from the RTP session
577     );
578 
579     /**Read a data frame from the RTP channel.
580        Any control frames received are dispatched to callbacks and are not
581        returned by this function. It will block until a data frame is
582        available or an error occurs.
583       */
584     virtual PBoolean ReadData(
585       RTP_DataFrame & frame   ///<  Frame read from the RTP session
586     ) = 0;
587 
588     /**Flush incoming data.
589       */
590     virtual void FlushData();
591 
592     /**Write a data frame from the RTP channel.
593       */
594     virtual PBoolean WriteData(
595       RTP_DataFrame & frame   ///<  Frame to write to the RTP session
596     ) = 0;
597 
598     /** Write data frame to the RTP channel outside the normal stream of media
599       * Used for RFC2833 packets
600       */
601     virtual PBoolean WriteOOBData(
602       RTP_DataFrame & frame,
603       bool rewriteTimeStamp = true
604     );
605 
606     /**Write a control frame from the RTP channel.
607       */
608     virtual PBoolean WriteControl(
609       RTP_ControlFrame & frame    ///<  Frame to write to the RTP session
610     ) = 0;
611 
612     /**Close down the RTP session.
613       */
614     virtual bool Close(
615       PBoolean reading    ///<  Closing the read side of the session
616     ) = 0;
617 
618    /**Reopens an existing session in the given direction.
619       */
620     virtual void Reopen(
621       PBoolean isReading
622     ) = 0;
623 
624     /**Get the local host name as used in SDES packes.
625       */
626     virtual PString GetLocalHostName() = 0;
627 
628 #if OPAL_STATISTICS
629     virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
630 #endif
631   //@}
632 
633   /**@name Call back functions */
634   //@{
635     enum SendReceiveStatus {
636       e_ProcessPacket,
637       e_IgnorePacket,
638       e_AbortTransport
639     };
640     virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
641     virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame);
642 
643     virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
644     virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
645 
646     virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
647     virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame);
648 
649     virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
650 
651     class ReceiverReport : public PObject  {
652         PCLASSINFO(ReceiverReport, PObject);
653       public:
654         void PrintOn(ostream &) const;
655 
656         DWORD sourceIdentifier;
657         DWORD fractionLost;         /* fraction lost since last SR/RR */
658         DWORD totalLost;	    /* cumulative number of packets lost (signed!) */
659         DWORD lastSequenceNumber;   /* extended last sequence number received */
660         DWORD jitter;               /* interarrival jitter */
661         PTimeInterval lastTimestamp;/* last SR packet from this source */
662         PTimeInterval delay;        /* delay since last SR packet */
663     };
664     PARRAY(ReceiverReportArray, ReceiverReport);
665 
666     class SenderReport : public PObject  {
667         PCLASSINFO(SenderReport, PObject);
668       public:
669         void PrintOn(ostream &) const;
670 
671         DWORD sourceIdentifier;
672         PTime realTimestamp;
673         DWORD rtpTimestamp;
674         DWORD packetsSent;
675         DWORD octetsSent;
676     };
677 
678     virtual void OnRxSenderReport(const SenderReport & sender,
679                                   const ReceiverReportArray & reports);
680     virtual void OnRxReceiverReport(DWORD src,
681                                     const ReceiverReportArray & reports);
682     virtual void OnReceiverReports(const ReceiverReportArray & reports);
683 
684     class SourceDescription : public PObject  {
685         PCLASSINFO(SourceDescription, PObject);
686       public:
SourceDescription(DWORD src)687         SourceDescription(DWORD src) { sourceIdentifier = src; }
688         void PrintOn(ostream &) const;
689 
690         DWORD            sourceIdentifier;
691         POrdinalToString items;
692     };
693     PARRAY(SourceDescriptionArray, SourceDescription);
694     virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
695 
696     virtual void OnRxGoodbye(const PDWORDArray & sources,
697                              const PString & reason);
698 
699     virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
700                                  const BYTE * data, PINDEX size);
701 
702 #if OPAL_RTCP_XR
703     class ExtendedReport : public PObject  {
704         PCLASSINFO(ExtendedReport, PObject);
705       public:
706         void PrintOn(ostream &) const;
707 
708         DWORD sourceIdentifier;
709         DWORD lossRate;            /* fraction of RTP data packets lost */
710         DWORD discardRate;         /* fraction of RTP data packets discarded */
711         DWORD burstDensity;        /* fraction of RTP data packets within burst periods */
712         DWORD gapDensity;          /* fraction of RTP data packets within inter-burst gaps */
713         DWORD roundTripDelay;  /* the most recently calculated round trip time */
714         DWORD RFactor;            /* voice quality metric of the call */
715         DWORD mosLQ;               /* MOS for listen quality */
716         DWORD mosCQ;               /* MOS for conversational quality */
717         DWORD jbNominal;      /* current nominal jitter buffer delay, in ms */
718         DWORD jbMaximum;      /* current maximum jitter buffer delay, in ms */
719         DWORD jbAbsolute;     /* current absolute maximum jitter buffer delay, in ms */
720     };
721     PARRAY(ExtendedReportArray, ExtendedReport);
722 
723     virtual void OnRxExtendedReport(
724       DWORD src,
725       const ExtendedReportArray & reports
726     );
727 
GetExtendedMetrics()728     RTCP_XR_Metrics * GetExtendedMetrics() const { return m_metrics; }
729 #endif // OPAL_RTCP_XR
730   //@}
731 
732   /**@name Member variable access */
733   //@{
734     /**Get the ID for the RTP session.
735       */
GetSessionID()736     unsigned GetSessionID() const { return sessionID; }
737 
738     /**Set the ID for the RTP session.
739       */
SetSessionID(unsigned id)740     void SetSessionID(unsigned id) { sessionID = id; }
741 
742     /**Get flag for is audio RTP.
743       */
IsAudio()744     bool IsAudio() const { return isAudio; }
745 
746     /**Set flag for RTP session is audio.
747      */
SetAudio(bool aud)748     void SetAudio(
749       bool aud    /// New audio indication flag
750     ) { isAudio = aud; }
751 
752     /**Get the canonical name for the RTP session.
753       */
754     PString GetCanonicalName() const;
755 
756     /**Set the canonical name for the RTP session.
757       */
758     void SetCanonicalName(const PString & name);
759 
760     /**Get the tool name for the RTP session.
761       */
762     PString GetToolName() const;
763 
764     /**Set the tool name for the RTP session.
765       */
766     void SetToolName(const PString & name);
767 
768     /**Get the user data for the session.
769       */
GetUserData()770     RTP_UserData * GetUserData() const { return userData; }
771 
772     /**Set the user data for the session.
773       */
774     void SetUserData(
775       RTP_UserData * data,            ///<  New user data to be used
776       PBoolean autoDeleteUserData = true  ///<  Delete optional data with session.
777     );
778 
779     /**Get the source output identifier.
780       */
GetSyncSourceOut()781     DWORD GetSyncSourceOut() const { return syncSourceOut; }
782 
783     /**Indicate if will ignore all but first received SSRC value.
784       */
AllowAnySyncSource()785     bool AllowAnySyncSource() const { return allowAnySyncSource; }
786 
787     /**Indicate if will ignore all but first received SSRC value.
788       */
SetAnySyncSource(bool allow)789     void SetAnySyncSource(
790       bool allow    ///<  Flag for allow any SSRC values
791     ) { allowAnySyncSource = allow; }
792 
793     /**Indicate if will ignore rtp payload type changes in received packets.
794      */
SetIgnorePayloadTypeChanges(PBoolean ignore)795     void SetIgnorePayloadTypeChanges(
796       PBoolean ignore   ///<  Flag to ignore payload type changes
797     ) { ignorePayloadTypeChanges = ignore; }
798 
799     /**Get the time interval for sending RTCP reports in the session.
800       */
GetReportTimeInterval()801     const PTimeInterval & GetReportTimeInterval() { return m_reportTimer.GetResetTime(); }
802 
803     /**Set the time interval for sending RTCP reports in the session.
804       */
SetReportTimeInterval(const PTimeInterval & interval)805     void SetReportTimeInterval(
806       const PTimeInterval & interval ///<  New time interval for reports.
807     )  { m_reportTimer.RunContinuous(interval); }
808 
809     /**Get the interval for transmitter statistics in the session.
810       */
GetTxStatisticsInterval()811     unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
812 
813     /**Set the interval for transmitter statistics in the session.
814       */
815     void SetTxStatisticsInterval(
816       unsigned packets   ///<  Number of packets between callbacks
817     );
818 
819     /**Get the interval for receiver statistics in the session.
820       */
GetRxStatisticsInterval()821     unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
822 
823     /**Set the interval for receiver statistics in the session.
824       */
825     void SetRxStatisticsInterval(
826       unsigned packets   ///<  Number of packets between callbacks
827     );
828 
829     /**Clear statistics
830       */
831     void ClearStatistics();
832 
833     /**Get total number of packets sent in session.
834       */
GetPacketsSent()835     DWORD GetPacketsSent() const { return packetsSent; }
836 
837     /**Get total number of octets sent in session.
838       */
GetOctetsSent()839     DWORD GetOctetsSent() const { return octetsSent; }
840 
841     /**Get total number of packets received in session.
842       */
GetPacketsReceived()843     DWORD GetPacketsReceived() const { return packetsReceived; }
844 
845     /**Get total number of octets received in session.
846       */
GetOctetsReceived()847     DWORD GetOctetsReceived() const { return octetsReceived; }
848 
849     /**Get total number received packets lost in session.
850       */
GetPacketsLost()851     DWORD GetPacketsLost() const { return packetsLost; }
852 
853     /**Get total number transmitted packets lost by remote in session.
854        Determined via RTCP.
855       */
GetPacketsLostByRemote()856     DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
857 
858     /**Get total number of packets received out of order in session.
859       */
GetPacketsOutOfOrder()860     DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
861 
862     /**Get total number received packets too late to go into jitter buffer.
863       */
864     DWORD GetPacketsTooLate() const;
865 
866     /**Get total number received packets that could not fit into the jitter buffer.
867       */
868     DWORD GetPacketOverruns() const;
869 
870     /**Get average time between sent packets.
871        This is averaged over the last txStatisticsInterval packets and is in
872        milliseconds.
873       */
GetAverageSendTime()874     DWORD GetAverageSendTime() const { return averageSendTime; }
875 
876     /**Get the number of marker packets received this session.
877        This can be used to find out the number of frames received in a video
878        RTP stream.
879       */
GetMarkerRecvCount()880     DWORD GetMarkerRecvCount() const { return markerRecvCount; }
881 
882     /**Get the number of marker packets sent this session.
883        This can be used to find out the number of frames sent in a video
884        RTP stream.
885       */
GetMarkerSendCount()886     DWORD GetMarkerSendCount() const { return markerSendCount; }
887 
888     /**Get maximum time between sent packets.
889        This is over the last txStatisticsInterval packets and is in
890        milliseconds.
891       */
GetMaximumSendTime()892     DWORD GetMaximumSendTime() const { return maximumSendTime; }
893 
894     /**Get minimum time between sent packets.
895        This is over the last txStatisticsInterval packets and is in
896        milliseconds.
897       */
GetMinimumSendTime()898     DWORD GetMinimumSendTime() const { return minimumSendTime; }
899 
900     /**Get average time between received packets.
901        This is averaged over the last rxStatisticsInterval packets and is in
902        milliseconds.
903       */
GetAverageReceiveTime()904     DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
905 
906     /**Get maximum time between received packets.
907        This is over the last rxStatisticsInterval packets and is in
908        milliseconds.
909       */
GetMaximumReceiveTime()910     DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
911 
912     /**Get minimum time between received packets.
913        This is over the last rxStatisticsInterval packets and is in
914        milliseconds.
915       */
GetMinimumReceiveTime()916     DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
917 
918     enum { JitterRoundingGuardBits = 4 };
919     /**Get averaged jitter time for received packets.
920        This is the calculated statistical variance of the interarrival
921        time of received packets in milliseconds.
922       */
GetAvgJitterTime()923     DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
924 
925     /**Get averaged jitter time for received packets.
926        This is the maximum value of jitterLevel for the session.
927       */
GetMaxJitterTime()928     DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
929 
930     /**Get jitter time for received packets on remote.
931        This is the calculated statistical variance of the interarrival
932        time of received packets in milliseconds.
933       */
GetJitterTimeOnRemote()934     DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); }
935   //@}
936 
SetCloseOnBYE(PBoolean v)937     virtual void SetCloseOnBYE(PBoolean v)  { closeOnBye = v; }
938 
939     /** Tell the rtp session to send out an intra frame request control packet.
940         This is called when the media stream receives an OpalVideoUpdatePicture
941         media command.
942       */
943     virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
944 
945     /** Tell the rtp session to send out an temporal spatial trade off request
946         control packet. This is called when the media stream receives an
947         OpalTemporalSpatialTradeOff media command.
948       */
949     virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
950 
SetNextSentSequenceNumber(WORD num)951     void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
952 
GetEncoding()953     virtual PString GetEncoding() const { return m_encoding; }
954     virtual void SetEncoding(const PString & newEncoding);
955 
GetSyncSourceIn()956     DWORD GetSyncSourceIn() const { return syncSourceIn; }
957 
958     class EncodingLock
959     {
960       public:
961         EncodingLock(RTP_Session & _session);
962         ~EncodingLock();
963 
964         __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
965 
966       protected:
967         RTP_Session  & session;
968         RTP_Encoding * m_encodingHandler;
969     };
970 
971     friend class EncodingLock;
972 
SetFailed(bool v)973     void SetFailed(bool v)
974     { failed = v; }
975 
HasFailed()976     bool HasFailed() const
977     { return failed; }
978 
979     typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
980     #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, RTP_Session::SendReceiveStatus &)
981     #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, RTP_Session::SendReceiveStatus &)
982 
983     void AddFilter(const FilterNotifier & filter);
984 
985     virtual void SendBYE();
986 
987   protected:
988     RTP_Session::ReceiverReportArray BuildReceiverReportArray(const RTP_ControlFrame & frame, PINDEX offset);
989     void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
990 
991     PBoolean InsertReportPacket(RTP_ControlFrame & report);
992 
993     PString             m_encoding;
994     PMutex              m_encodingMutex;
995     RTP_Encoding      * m_encodingHandler;
996 
997     unsigned           sessionID;
998     bool               isAudio;
999     unsigned           m_timeUnits;
1000     PString            canonicalName;
1001     PString            toolName;
1002     RTP_UserData     * userData;
1003     PBoolean           autoDeleteUserData;
1004 
1005     typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
1006     JitterBufferPtr m_jitterBuffer;
1007 
1008     DWORD         syncSourceOut;
1009     DWORD         syncSourceIn;
1010     DWORD         lastSentTimestamp;
1011     bool          allowAnySyncSource;
1012     bool          allowOneSyncSourceChange;
1013     PBoolean      allowRemoteTransmitAddressChange;
1014     PBoolean      allowSequenceChange;
1015     unsigned      txStatisticsInterval;
1016     unsigned      rxStatisticsInterval;
1017     WORD          lastSentSequenceNumber;
1018     WORD          expectedSequenceNumber;
1019     PTimeInterval lastSentPacketTime;
1020     PTimeInterval lastReceivedPacketTime;
1021     PTime         lastSRTimestamp;
1022     PTime         lastSRReceiveTime;
1023     PTimeInterval delaySinceLastSR;
1024     WORD          lastRRSequenceNumber;
1025     bool          resequenceOutOfOrderPackets;
1026     unsigned      consecutiveOutOfOrderPackets;
1027     PTimeInterval outOfOrderWaitTime;
1028     PTimeInterval outOfOrderPacketTime;
1029 
1030     std::list<RTP_DataFrame> m_outOfOrderPackets;
1031     void SaveOutOfOrderPacket(RTP_DataFrame & frame);
1032 
1033     PMutex        dataMutex;
1034     DWORD         timeStampOffs;               // offset between incoming media timestamp and timeStampOut
1035     PBoolean      oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
1036     DWORD         oobTimeStampOutBase;         // base timestamp value for oob data
1037     PTimeInterval oobTimeStampBase;            // base time for oob timestamp
1038 
1039     // Statistics
1040     PTime firstPacketSent;
1041     DWORD packetsSent;
1042     DWORD rtcpPacketsSent;
1043     DWORD octetsSent;
1044     PTime firstPacketReceived;
1045     DWORD packetsReceived;
1046     DWORD senderReportsReceived;
1047     DWORD octetsReceived;
1048     DWORD packetsLost;
1049     DWORD packetsLostByRemote;
1050     DWORD packetsOutOfOrder;
1051     DWORD averageSendTime;
1052     DWORD maximumSendTime;
1053     DWORD minimumSendTime;
1054     DWORD averageReceiveTime;
1055     DWORD maximumReceiveTime;
1056     DWORD minimumReceiveTime;
1057     DWORD jitterLevel;
1058     DWORD jitterLevelOnRemote;
1059     DWORD maximumJitterLevel;
1060 
1061     DWORD markerSendCount;
1062     DWORD markerRecvCount;
1063 
1064     unsigned txStatisticsCount;
1065     unsigned rxStatisticsCount;
1066 
1067 #if OPAL_RTCP_XR
1068     // Calculate the VoIP Metrics for RTCP-XR
1069     RTCP_XR_Metrics * m_metrics;
1070     friend class RTCP_XR_Metrics;
1071 #endif
1072 
1073     DWORD    averageSendTimeAccum;
1074     DWORD    maximumSendTimeAccum;
1075     DWORD    minimumSendTimeAccum;
1076     DWORD    averageReceiveTimeAccum;
1077     DWORD    maximumReceiveTimeAccum;
1078     DWORD    minimumReceiveTimeAccum;
1079     DWORD    packetsLostSinceLastRR;
1080     DWORD    lastTransitTime;
1081 
1082     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
1083     PBoolean ignorePayloadTypeChanges;
1084 
1085     PMutex m_reportMutex;
1086     PTimer m_reportTimer;
1087     PDECLARE_NOTIFIER(PTimer, RTP_Session, SendReport);
1088 
1089     PBoolean closeOnBye;
1090     PBoolean byeSent;
1091     bool                failed;      ///<  set to true if session has received too many ICMP destination unreachable
1092 
1093     list<FilterNotifier> m_filters;
1094 };
1095 
1096 /**This class is for the IETF Real Time Protocol interface on UDP/IP.
1097  */
1098 class RTP_UDP : public RTP_Session
1099 {
1100   PCLASSINFO(RTP_UDP, RTP_Session);
1101 
1102   public:
1103   /**@name Construction */
1104   //@{
1105     /**Create a new RTP channel.
1106      */
1107     RTP_UDP(
1108       const Params & options ///< Parameters to construct with session.
1109     );
1110 
1111     /// Destroy the RTP
1112     ~RTP_UDP();
1113   //@}
1114 
1115   /**@name Overrides from class RTP_Session */
1116   //@{
1117     /**Read a data frame from the RTP channel.
1118        Any control frames received are dispatched to callbacks and are not
1119        returned by this function. It will block until a data frame is
1120        available or an error occurs.
1121       */
1122     virtual PBoolean ReadData(RTP_DataFrame & frame);
1123     virtual PBoolean Internal_ReadData(RTP_DataFrame & frame);
1124 
1125     /**Flush incoming data.
1126       */
1127     virtual void FlushData();
1128 
1129     /** Write a data frame to the RTP channel.
1130       */
1131     virtual PBoolean WriteData(RTP_DataFrame & frame);
1132     virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
1133 
1134     /** Write data frame to the RTP channel outside the normal stream of media
1135       * Used for RFC2833 packets
1136       */
1137     virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
1138 
1139     /**Write a control frame from the RTP channel.
1140       */
1141     virtual PBoolean WriteControl(RTP_ControlFrame & frame);
1142 
1143     /**Close down the RTP session.
1144       */
1145     virtual bool Close(
1146       PBoolean reading    ///<  Closing the read side of the session
1147     );
1148 
1149     /**Get the session description name.
1150       */
1151     virtual PString GetLocalHostName();
1152   //@}
1153 
1154     /**Change the QoS settings
1155       */
1156     virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
1157 
1158   /**@name New functions for class */
1159   //@{
1160     /**Open the UDP ports for the RTP session.
1161       */
1162     virtual PBoolean Open(
1163       PIPSocket::Address localAddress,  ///<  Local interface to bind to
1164       WORD portBase,                    ///<  Base of ports to search
1165       WORD portMax,                     ///<  end of ports to search (inclusive)
1166       BYTE ipTypeOfService,             ///<  Type of Service byte
1167       PNatMethod * natMethod = NULL,    ///<  NAT traversal method to use createing sockets
1168       RTP_QOS * rtpqos = NULL           ///<  QOS spec (or NULL if no QoS)
1169     );
1170   //@}
1171 
1172    /**Reopens an existing session in the given direction.
1173       */
1174     virtual void Reopen(PBoolean isReading);
1175   //@}
1176 
1177   /**@name Member variable access */
1178   //@{
1179     /**Get local address of session.
1180       */
GetLocalAddress()1181     virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
1182 
1183     /**Set local address of session.
1184       */
SetLocalAddress(const PIPSocket::Address & addr)1185     virtual void SetLocalAddress(
1186       const PIPSocket::Address & addr
1187     ) { localAddress = addr; }
1188 
1189     /**Get remote address of session.
1190       */
GetRemoteAddress()1191     PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
1192 
1193     /**Get local data port of session.
1194       */
GetLocalDataPort()1195     virtual WORD GetLocalDataPort() const { return localDataPort; }
1196 
1197     /**Get local control port of session.
1198       */
GetLocalControlPort()1199     virtual WORD GetLocalControlPort() const { return localControlPort; }
1200 
1201     /**Get remote data port of session.
1202       */
GetRemoteDataPort()1203     virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
1204 
1205     /**Get remote control port of session.
1206       */
GetRemoteControlPort()1207     virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
1208 
1209     /**Get data UDP socket of session.
1210       */
GetDataSocket()1211     virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
1212 
1213     /**Get control UDP socket of session.
1214       */
GetControlSocket()1215     virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
1216 
1217     /**Set the remote address and port information for session.
1218       */
1219     virtual PBoolean SetRemoteSocketInfo(
1220       PIPSocket::Address address,   ///<  Addre ss of remote
1221       WORD port,                    ///<  Port on remote
1222       PBoolean isDataPort               ///<  Flag for data or control channel
1223     );
1224 
1225     /**Apply QOS - requires address to connect the socket on Windows platforms
1226      */
1227     virtual void ApplyQOS(
1228       const PIPSocket::Address & addr
1229     );
1230   //@}
1231 
GetDataSocketHandle()1232     virtual int GetDataSocketHandle() const
1233     { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
1234 
GetControlSocketHandle()1235     virtual int GetControlSocketHandle() const
1236     { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
1237 
1238     friend class RTP_Encoding;
1239 
1240     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
1241     virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
1242 
1243     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
1244     virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
1245 
1246     virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
1247     virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
1248 
1249     virtual SendReceiveStatus ReadControlPDU();
1250     virtual SendReceiveStatus ReadDataOrControlPDU(
1251       BYTE * framePtr,
1252       PINDEX frameSize,
1253       PBoolean fromDataChannel
1254     );
1255 
1256     virtual bool WriteDataPDU(RTP_DataFrame & frame);
1257     virtual bool WriteDataOrControlPDU(
1258       const BYTE * framePtr,
1259       PINDEX frameSize,
1260       bool toDataChannel
1261     );
1262 
1263     virtual void SetEncoding(const PString & newEncoding);
1264 
1265 
1266   protected:
1267     PIPSocket::Address localAddress;
1268     WORD               localDataPort;
1269     WORD               localControlPort;
1270 
1271     PIPSocket::Address remoteAddress;
1272     WORD               remoteDataPort;
1273     WORD               remoteControlPort;
1274 
1275     PIPSocket::Address remoteTransmitAddress;
1276 
1277     PUDPSocket * dataSocket;
1278     PUDPSocket * controlSocket;
1279 
1280     bool shutdownRead;
1281     bool shutdownWrite;
1282     bool appliedQOS;
1283     bool remoteIsNAT;
1284     bool localHasNAT;
1285     bool m_firstControl;
1286     int  badTransmitCounter;
1287     PTime badTransmitStart;
1288 
1289     PTimer timerWriteDataIdle;
1290     PDECLARE_NOTIFIER(PTimer,  RTP_UDP, OnWriteDataIdle);
1291 };
1292 
1293 /////////////////////////////////////////////////////////////////////////////
1294 
1295 class RTP_UDP;
1296 
1297 class RTP_Encoding
1298 {
1299   public:
1300     RTP_Encoding();
1301     virtual ~RTP_Encoding();
ApplyStringOptions(const PStringToString &)1302     virtual void ApplyStringOptions(const PStringToString & /*stringOptions*/) {}
1303     virtual void OnStart(RTP_Session & _rtpSession);
1304     virtual void OnFinish();
1305     virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
1306     virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob);
1307     virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
OnWriteDataIdle()1308     virtual void OnWriteDataIdle() {}
SetWriteDataIdleTimer(PTimer &)1309     virtual void SetWriteDataIdleTimer(PTimer &) {}
1310     virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
1311     virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
1312     virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
1313     virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
1314     virtual PBoolean ReadData(RTP_DataFrame & frame);
1315     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
1316 
1317     PMutex      mutex;
1318     unsigned    refCount;
1319 
1320   protected:
1321     RTP_UDP     * rtpUDP;
1322 };
1323 
1324 PFACTORY_LOAD(RTP_Encoding);
1325 
1326 
1327 /////////////////////////////////////////////////////////////////////////////
1328 
1329 class SecureRTP_UDP : public RTP_UDP
1330 {
1331   PCLASSINFO(SecureRTP_UDP, RTP_UDP);
1332 
1333   public:
1334   /**@name Construction */
1335   //@{
1336     /**Create a new RTP channel.
1337      */
1338     SecureRTP_UDP(
1339       const Params & options ///< Parameters to construct with session.
1340     );
1341 
1342     /// Destroy the RTP
1343     ~SecureRTP_UDP();
1344 
1345     virtual void SetSecurityMode(OpalSecurityMode * srtpParms);
1346     virtual OpalSecurityMode * GetSecurityParms() const;
1347 
1348   protected:
1349     OpalSecurityMode * securityParms;
1350 };
1351 
1352 #endif // OPAL_RTP_RTP_H
1353 
1354 /////////////////////////////////////////////////////////////////////////////
1355