OPAL Version 3.10.2
rtp.h
Go to the documentation of this file.
00001 /*
00002  * rtp.h
00003  *
00004  * RTP protocol handler
00005  *
00006  * Open H323 Library
00007  *
00008  * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Open H323 Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Portions of this code were written with the assisance of funding from
00025  * Vovida Networks, Inc. http://www.vovida.com.
00026  *
00027  * Contributor(s): ______________________________________.
00028  *
00029  * $Revision: 26293 $
00030  * $Author: rjongbloed $
00031  * $Date: 2011-08-08 21:25:33 -0500 (Mon, 08 Aug 2011) $
00032  */
00033 
00034 #ifndef OPAL_RTP_RTP_H
00035 #define OPAL_RTP_RTP_H
00036 
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040 
00041 #include <opal/buildopts.h>
00042 
00043 #include <ptlib/sockets.h>
00044 #include <ptlib/safecoll.h>
00045 
00046 #include <list>
00047 
00048 #include <rtp/metrics.h>
00049 
00050 class RTP_JitterBuffer;
00051 class PNatMethod;
00052 class OpalSecurityMode;
00053 
00055 // 
00056 // class to hold the QoS definitions for an RTP channel
00057 
00058 class RTP_QOS : public PObject
00059 {
00060   PCLASSINFO(RTP_QOS,PObject);
00061   public:
00062     PQoS dataQoS;
00063     PQoS ctrlQoS;
00064 };
00065 
00067 // Real Time Protocol - IETF RFC1889 and RFC1890
00068 
00071 class RTP_DataFrame : public PBYTEArray
00072 {
00073   PCLASSINFO(RTP_DataFrame, PBYTEArray);
00074 
00075   public:
00076     RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
00077     RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = true);
00078 
00079     enum {
00080       ProtocolVersion = 2,
00081       MinHeaderSize = 12,
00082       // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
00083       MaxMtuPayloadSize = (576-20-16-12)
00084     };
00085 
00086     enum PayloadTypes {
00087       PCMU,         // G.711 u-Law
00088       FS1016,       // Federal Standard 1016 CELP
00089       G721,         // ADPCM - Subsumed by G.726
00090       G726 = G721,
00091       GSM,          // GSM 06.10
00092       G7231,        // G.723.1 at 6.3kbps or 5.3 kbps
00093       DVI4_8k,      // DVI4 at 8kHz sample rate
00094       DVI4_16k,     // DVI4 at 16kHz sample rate
00095       LPC,          // LPC-10 Linear Predictive CELP
00096       PCMA,         // G.711 A-Law
00097       G722,         // G.722
00098       L16_Stereo,   // 16 bit linear PCM
00099       L16_Mono,     // 16 bit linear PCM
00100       G723,         // G.723
00101       CN,           // Confort Noise
00102       MPA,          // MPEG1 or MPEG2 audio
00103       G728,         // G.728 16kbps CELP
00104       DVI4_11k,     // DVI4 at 11kHz sample rate
00105       DVI4_22k,     // DVI4 at 22kHz sample rate
00106       G729,         // G.729 8kbps
00107       Cisco_CN,     // Cisco systems comfort noise (unofficial)
00108 
00109       CelB = 25,    // Sun Systems Cell-B video
00110       JPEG,         // Motion JPEG
00111       H261 = 31,    // H.261
00112       MPV,          // MPEG1 or MPEG2 video
00113       MP2T,         // MPEG2 transport system
00114       H263,         // H.263
00115 
00116       T38 = 38,     // T.38 (internal)
00117 
00118       LastKnownPayloadType,
00119 
00120       DynamicBase = 96,
00121       MaxPayloadType = 127,
00122       IllegalPayloadType
00123     };
00124 
00125     unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00126 
00127     PBoolean GetExtension() const   { return (theArray[0]&0x10) != 0; }
00128     void SetExtension(PBoolean ext);
00129 
00130     PBoolean GetMarker() const { return (theArray[1]&0x80) != 0; }
00131     void SetMarker(PBoolean m);
00132 
00133     bool GetPadding() const { return (theArray[0]&0x20) != 0; }
00134     void SetPadding(bool v)  { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
00135     BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
00136 
00137     unsigned GetPaddingSize() const { return m_paddingSize; }
00138     bool     SetPaddingSize(PINDEX sz);
00139 
00140     PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00141     void         SetPayloadType(PayloadTypes t);
00142 
00143     WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00144     void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00145 
00146     DWORD GetTimestamp() const  { return *(PUInt32b *)&theArray[4]; }
00147     void  SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00148 
00149     DWORD GetSyncSource() const  { return *(PUInt32b *)&theArray[8]; }
00150     void  SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00151 
00152     PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00153     DWORD  GetContribSource(PINDEX idx) const;
00154     void   SetContribSource(PINDEX idx, DWORD src);
00155 
00156     PINDEX GetHeaderSize() const { return m_headerSize; }
00157 
00158     int GetExtensionType() const; // -1 is no extension
00159     void   SetExtensionType(int type);
00160     PINDEX GetExtensionSizeDWORDs() const;      // get the number of 32 bit words in the extension (excluding the header).
00161     bool   SetExtensionSizeDWORDs(PINDEX sz);   // set the number of 32 bit words in the extension (excluding the header)
00162     BYTE * GetExtensionPtr() const;
00163 
00164     PINDEX GetPayloadSize() const { return m_payloadSize; }
00165     bool   SetPayloadSize(PINDEX sz);
00166     BYTE * GetPayloadPtr()     const { return (BYTE *)(theArray+m_headerSize); }
00167 
00168     virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
00169     virtual void PrintOn(ostream & strm) const;
00170 
00171     // Note this sets the whole packet length, and calculates the various
00172     // sub-section sizes: header payload and padding.
00173     bool SetPacketSize(PINDEX sz);
00174 
00175   protected:
00176     PINDEX m_headerSize;
00177     PINDEX m_payloadSize;
00178     PINDEX m_paddingSize;
00179 
00180 #if PTRACING
00181     friend ostream & operator<<(ostream & o, PayloadTypes t);
00182 #endif
00183 };
00184 
00185 PLIST(RTP_DataFrameList, RTP_DataFrame);
00186 
00187 
00190 class RTP_ControlFrame : public PBYTEArray
00191 {
00192   PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00193 
00194   public:
00195     RTP_ControlFrame(PINDEX compoundSize = 2048);
00196 
00197     unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00198 
00199     unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00200     void     SetCount(unsigned count);
00201 
00202     enum PayloadTypes {
00203       e_IntraFrameRequest       = 192,
00204       e_SenderReport            = 200,
00205       e_ReceiverReport          = 201,
00206       e_SourceDescription       = 202,
00207       e_Goodbye                 = 203,
00208       e_ApplDefined             = 204,
00209       e_TransportLayerFeedBack  = 205, // RFC4585
00210       e_PayloadSpecificFeedBack = 206,
00211       e_ExtendedReport          = 207  // RFC3611
00212     };
00213 
00214     unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00215     void     SetPayloadType(unsigned t);
00216 
00217     PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00218     void   SetPayloadSize(PINDEX sz);
00219 
00220     BYTE * GetPayloadPtr() const;
00221 
00222     PBoolean ReadNextPacket();
00223     PBoolean StartNewPacket();
00224     void EndPacket();
00225 
00226     PINDEX GetCompoundSize() const;
00227 
00228     void Reset(PINDEX size);
00229 
00230 #pragma pack(1)
00231     struct ReceiverReport {
00232       PUInt32b ssrc;      /* data source being reported */
00233       BYTE fraction;      /* fraction lost since last SR/RR */
00234       BYTE lost[3];       /* cumulative number of packets lost (signed!) */
00235       PUInt32b last_seq;  /* extended last sequence number received */
00236       PUInt32b jitter;    /* interarrival jitter */
00237       PUInt32b lsr;       /* last SR packet from this source */
00238       PUInt32b dlsr;      /* delay since last SR packet */
00239 
00240       unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00241       void SetLostPackets(unsigned lost);
00242     };
00243 
00244     struct SenderReport {
00245       PUInt32b ntp_sec;   /* NTP timestamp */
00246       PUInt32b ntp_frac;
00247       PUInt32b rtp_ts;    /* RTP timestamp */
00248       PUInt32b psent;     /* packets sent */
00249       PUInt32b osent;     /* octets sent */ 
00250     };
00251 
00252     struct ExtendedReport {
00253       /* VoIP Metrics Report Block */
00254       BYTE bt;                     /* block type */
00255       BYTE type_specific;          /* determined by the block definition */
00256       PUInt16b length;             /* length of the report block */
00257       PUInt32b ssrc;               /* data source being reported */
00258       BYTE loss_rate;              /* fraction of RTP data packets lost */ 
00259       BYTE discard_rate;           /* fraction of RTP data packets discarded */
00260       BYTE burst_density;          /* fraction of RTP data packets within burst periods */
00261       BYTE gap_density;            /* fraction of RTP data packets within inter-burst gaps */
00262       PUInt16b burst_duration;     /* the mean duration, in ms, of burst periods */
00263       PUInt16b gap_duration;       /* the mean duration, in ms, of gap periods */
00264       PUInt16b round_trip_delay;   /* the most recently calculated round trip time */    
00265       PUInt16b end_system_delay;   /* the most recently estimates end system delay */
00266       BYTE signal_level;           /* voice signal level related to 0 dBm */
00267       BYTE noise_level;            /* ratio of the silent background level to 0 dBm */
00268       BYTE rerl;                   /* residual echo return loss */
00269       BYTE gmin;                   /* gap threshold */
00270       BYTE r_factor;               /* voice quality metric of the call */
00271       BYTE ext_r_factor;           /* external R factor */
00272       BYTE mos_lq;                 /* MOS for listen quality */
00273       BYTE mos_cq;                 /* MOS for conversational quality */
00274       BYTE rx_config;              /* receiver configuration byte */
00275       BYTE reserved;               /* reserved for future definition */
00276       PUInt16b jb_nominal;         /* current nominal jitter buffer delay, in ms */ 
00277       PUInt16b jb_maximum;         /* current maximum jitter buffer delay, in ms */
00278       PUInt16b jb_absolute;        /* current absolute maximum jitter buffer delay, in ms */
00279     };
00280 
00281     enum DescriptionTypes {
00282       e_END,
00283       e_CNAME,
00284       e_NAME,
00285       e_EMAIL,
00286       e_PHONE,
00287       e_LOC,
00288       e_TOOL,
00289       e_NOTE,
00290       e_PRIV,
00291       NumDescriptionTypes
00292     };
00293 
00294     struct SourceDescription {
00295       PUInt32b src;       /* first SSRC/CSRC */
00296       struct Item {
00297         BYTE type;        /* type of SDES item (enum DescriptionTypes) */
00298         BYTE length;      /* length of SDES item (in octets) */
00299         char data[1];     /* text, not zero-terminated */
00300 
00301         /* WARNING, SourceDescription may not be big enough to contain length and data, for 
00302            instance, when type == RTP_ControlFrame::e_END.
00303            Be careful whan calling the following function of it may read to over to 
00304            memory allocated*/
00305         unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);} 
00306         const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00307         Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00308       } item[1];          /* list of SDES items */
00309     };
00310 
00311     void StartSourceDescription(
00312       DWORD src   
00313     );
00314 
00315     void AddSourceDescriptionItem(
00316       unsigned type,            
00317       const PString & data      
00318     );
00319 
00320     // RFC4585 Feedback Message Type (FMT)
00321     unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00322     void     SetFbType(unsigned type, PINDEX fciSize);
00323 
00324     enum PayloadSpecificFbTypes {
00325       e_PictureLossIndication = 1,
00326       e_SliceLostIndication,
00327       e_ReferencePictureSelectionIndication,
00328       e_FullIntraRequest,                     //RFC5104
00329       e_TemporalSpatialTradeOffRequest,
00330       e_TemporalSpatialTradeOffNotification,
00331       e_VideoBackChannelMessage,
00332       e_ApplicationLayerFbMessage = 15
00333     };
00334 
00335     struct FbFCI {
00336       PUInt32b senderSSRC;  /* data source of sender of message */
00337       PUInt32b mediaSSRC;   /* data source of media */
00338     };
00339 
00340     struct FbFIR {
00341       FbFCI    fci;
00342       PUInt32b requestSSRC;
00343       BYTE     sequenceNUmber;
00344     };
00345 
00346     struct FbTSTO {
00347       FbFCI    fci;
00348       PUInt32b requestSSRC;
00349       BYTE     sequenceNUmber;
00350       BYTE     reserver[2];
00351       BYTE     tradeOff;
00352     };
00353 
00354 #pragma pack()
00355 
00356   protected:
00357     PINDEX compoundOffset;
00358     PINDEX payloadSize;
00359 };
00360 
00361 
00362 class RTP_Session;
00363 
00365 
00366 #if OPAL_STATISTICS
00367 
00370 class OpalMediaStatistics : public PObject
00371 {
00372     PCLASSINFO(OpalMediaStatistics, PObject);
00373   public:
00374     OpalMediaStatistics();
00375 
00376     // General info (typicallly from RTP)
00377     PUInt64  m_totalBytes;
00378     unsigned m_totalPackets;
00379     unsigned m_packetsLost;
00380     unsigned m_packetsOutOfOrder;
00381     unsigned m_packetsTooLate;
00382     unsigned m_packetOverruns;
00383     unsigned m_minimumPacketTime;
00384     unsigned m_averagePacketTime;
00385     unsigned m_maximumPacketTime;
00386 
00387     // Audio
00388     unsigned m_averageJitter;
00389     unsigned m_maximumJitter;
00390     unsigned m_jitterBufferDelay;
00391 
00392     // Video
00393     unsigned m_totalFrames;
00394     unsigned m_keyFrames;
00395 
00396     // Fax
00397 #if OPAL_FAX
00398     enum {
00399       FaxNotStarted = -2,
00400       FaxInProgress = -1,
00401       FaxSuccessful = 0,
00402       FaxErrorBase  = 1
00403     };
00404     enum FaxCompression {
00405       FaxCompressionUnknown,
00406       FaxCompressionT4_1d,
00407       FaxCompressionT4_2d,
00408       FaxCompressionT6,
00409     };
00410     friend ostream & operator<<(ostream & strm, FaxCompression compression);
00411     struct Fax {
00412       Fax();
00413 
00414       int  m_result;      // -2=not started, -1=progress, 0=success, >0=ended with error
00415       char m_phase;       // 'A', 'B', 'D'
00416       int  m_bitRate;     // e.g. 14400, 9600
00417       FaxCompression m_compression; // 0=N/A, 1=T.4 1d, 2=T.4 2d, 3=T.6
00418       bool m_errorCorrection;
00419       int  m_txPages;
00420       int  m_rxPages;
00421       int  m_totalPages;
00422       int  m_imageSize;   // In bytes
00423       int  m_resolutionX; // Pixels per inch
00424       int  m_resolutionY; // Pixels per inch
00425       int  m_pageWidth;
00426       int  m_pageHeight;
00427       int  m_badRows;     // Total number of bad rows
00428       int  m_mostBadRows; // Longest run of bad rows
00429       int  m_errorCorrectionRetries;
00430 
00431       PString m_stationId; // Remote station identifier
00432       PString m_errorText;
00433     } m_fax;
00434 #endif
00435 };
00436 
00437 #endif
00438 
00439 
00444 class RTP_UserData : public PObject
00445 {
00446   PCLASSINFO(RTP_UserData, PObject);
00447 
00448   public:
00455     virtual void OnTxStatistics(
00456       const RTP_Session & session   
00457     ) const;
00458 
00465     virtual void OnRxStatistics(
00466       const RTP_Session & session   
00467     ) const;
00468 
00469 #if OPAL_VIDEO
00470 
00475     virtual void OnTxIntraFrameRequest(
00476       const RTP_Session & session   
00477     ) const;
00478 
00484     virtual void OnRxIntraFrameRequest(
00485       const RTP_Session & session   
00486     ) const;
00487 #endif
00488 
00492     virtual void SessionFailing(
00493       RTP_Session & session   
00494     );
00495 };
00496 
00497 class RTP_Encoding;
00498 
00499 
00502 class RTP_Session : public PObject
00503 {
00504   PCLASSINFO(RTP_Session, PObject);
00505 
00506   public:
00509     struct Params {
00510       Params()
00511         : id(0)
00512         , userData(NULL)
00513         , autoDelete(true)
00514         , isAudio(false)
00515         , remoteIsNAT(false)
00516       { }
00517 
00518       PString             encoding;    
00519       unsigned            id;          
00520       RTP_UserData      * userData;    
00521       bool                autoDelete;  
00522       bool                isAudio;     
00523       bool                remoteIsNAT; 
00524     };
00525 
00528     RTP_Session(
00529       const Params & options 
00530     );
00531 
00535     ~RTP_Session();
00537 
00547     void SetJitterBufferSize(
00548       unsigned minJitterDelay, 
00549       unsigned maxJitterDelay, 
00550       unsigned timeUnits = 0,  
00551       PINDEX packetSize = 2048 
00552     );
00553 
00559     unsigned GetJitterBufferSize() const;
00560     unsigned GetJitterBufferDelay() const { return GetJitterBufferSize()/GetJitterTimeUnits(); }
00561     
00564     unsigned GetJitterTimeUnits() const { return m_timeUnits; }
00565 
00567     virtual PBoolean ModifyQOS(RTP_QOS * )
00568     { return false; }
00569 
00575     virtual PBoolean ReadBufferedData(
00576       RTP_DataFrame & frame   
00577     );
00578 
00584     virtual PBoolean ReadData(
00585       RTP_DataFrame & frame   
00586     ) = 0;
00587 
00590     virtual PBoolean WriteData(
00591       RTP_DataFrame & frame   
00592     ) = 0;
00593 
00597     virtual PBoolean WriteOOBData(
00598       RTP_DataFrame & frame,
00599       bool rewriteTimeStamp = true
00600     );
00601 
00604     virtual PBoolean WriteControl(
00605       RTP_ControlFrame & frame    
00606     ) = 0;
00607 
00610     virtual PBoolean SendReport();
00611 
00614     virtual bool Close(
00615       PBoolean reading    
00616     ) = 0;
00617 
00620     virtual void Reopen(
00621       PBoolean isReading
00622     ) = 0;
00623 
00626     virtual PString GetLocalHostName() = 0;
00627 
00628 #if OPAL_STATISTICS
00629     virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
00630 #endif
00631 
00632 
00635     enum SendReceiveStatus {
00636       e_ProcessPacket,
00637       e_IgnorePacket,
00638       e_AbortTransport
00639     };
00640     virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00641     virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame);
00642 
00643     virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00644     virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00645 
00646     virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
00647     virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame);
00648 
00649     virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00650 
00651     class ReceiverReport : public PObject  {
00652         PCLASSINFO(ReceiverReport, PObject);
00653       public:
00654         void PrintOn(ostream &) const;
00655 
00656         DWORD sourceIdentifier;
00657         DWORD fractionLost;         /* fraction lost since last SR/RR */
00658         DWORD totalLost;            /* cumulative number of packets lost (signed!) */
00659         DWORD lastSequenceNumber;   /* extended last sequence number received */
00660         DWORD jitter;               /* interarrival jitter */
00661         PTimeInterval lastTimestamp;/* last SR packet from this source */
00662         PTimeInterval delay;        /* delay since last SR packet */
00663     };
00664     PARRAY(ReceiverReportArray, ReceiverReport);
00665 
00666     class SenderReport : public PObject  {
00667         PCLASSINFO(SenderReport, PObject);
00668       public:
00669         void PrintOn(ostream &) const;
00670 
00671         DWORD sourceIdentifier;
00672         PTime realTimestamp;
00673         DWORD rtpTimestamp;
00674         DWORD packetsSent;
00675         DWORD octetsSent;
00676     };
00677 
00678     virtual void OnRxSenderReport(const SenderReport & sender,
00679                                   const ReceiverReportArray & reports);
00680     virtual void OnRxReceiverReport(DWORD src,
00681                                     const ReceiverReportArray & reports);
00682     virtual void OnReceiverReports(const ReceiverReportArray & reports);
00683 
00684     class SourceDescription : public PObject  {
00685         PCLASSINFO(SourceDescription, PObject);
00686       public:
00687         SourceDescription(DWORD src) { sourceIdentifier = src; }
00688         void PrintOn(ostream &) const;
00689 
00690         DWORD            sourceIdentifier;
00691         POrdinalToString items;
00692     };
00693     PARRAY(SourceDescriptionArray, SourceDescription);
00694     virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00695 
00696     virtual void OnRxGoodbye(const PDWORDArray & sources,
00697                              const PString & reason);
00698 
00699     virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00700                                  const BYTE * data, PINDEX size);
00701 
00702 #if OPAL_RTCP_XR
00703     class ExtendedReport : public PObject  {
00704         PCLASSINFO(ExtendedReport, PObject);
00705       public:
00706         void PrintOn(ostream &) const;
00707 
00708         DWORD sourceIdentifier;
00709         DWORD lossRate;            /* fraction of RTP data packets lost */ 
00710         DWORD discardRate;         /* fraction of RTP data packets discarded */
00711         DWORD burstDensity;        /* fraction of RTP data packets within burst periods */
00712         DWORD gapDensity;          /* fraction of RTP data packets within inter-burst gaps */
00713         DWORD roundTripDelay;  /* the most recently calculated round trip time */    
00714         DWORD RFactor;            /* voice quality metric of the call */
00715         DWORD mosLQ;               /* MOS for listen quality */
00716         DWORD mosCQ;               /* MOS for conversational quality */
00717         DWORD jbNominal;      /* current nominal jitter buffer delay, in ms */ 
00718         DWORD jbMaximum;      /* current maximum jitter buffer delay, in ms */
00719         DWORD jbAbsolute;     /* current absolute maximum jitter buffer delay, in ms */
00720     };
00721     PARRAY(ExtendedReportArray, ExtendedReport);
00722 
00723     virtual void OnRxExtendedReport(DWORD src,
00724                                     const ExtendedReportArray & reports);                             
00725 #endif
00726 
00727 
00732     unsigned GetSessionID() const { return sessionID; }
00733 
00736     void SetSessionID(unsigned id) { sessionID = id; }
00737 
00740     bool IsAudio() const { return isAudio; }
00741 
00744     void SetAudio(
00745       bool aud    
00746     ) { isAudio = aud; }
00747 
00750     PString GetCanonicalName() const;
00751 
00754     void SetCanonicalName(const PString & name);
00755 
00758     PString GetToolName() const;
00759 
00762     void SetToolName(const PString & name);
00763 
00766     RTP_UserData * GetUserData() const { return userData; }
00767 
00770     void SetUserData(
00771       RTP_UserData * data,            
00772       PBoolean autoDeleteUserData = true  
00773     );
00774 
00777     DWORD GetSyncSourceOut() const { return syncSourceOut; }
00778 
00781     bool AllowAnySyncSource() const { return allowAnySyncSource; }
00782 
00785     void SetAnySyncSource(
00786       bool allow    
00787     ) { allowAnySyncSource = allow; }
00788 
00791     void SetIgnorePayloadTypeChanges(
00792       PBoolean ignore   
00793     ) { ignorePayloadTypeChanges = ignore; }
00794 
00797     const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00798 
00801     void SetReportTimeInterval(
00802       const PTimeInterval & interval 
00803     )  { reportTimeInterval = interval; }
00804 
00807     PTimeInterval GetReportTimer()
00808     { return reportTimer; }
00809 
00812     unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00813 
00816     void SetTxStatisticsInterval(
00817       unsigned packets   
00818     );
00819 
00822     unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00823 
00826     void SetRxStatisticsInterval(
00827       unsigned packets   
00828     );
00829 
00832     void ClearStatistics();
00833 
00836     DWORD GetPacketsSent() const { return packetsSent; }
00837 
00840     DWORD GetOctetsSent() const { return octetsSent; }
00841 
00844     DWORD GetPacketsReceived() const { return packetsReceived; }
00845 
00848     DWORD GetOctetsReceived() const { return octetsReceived; }
00849 
00852     DWORD GetPacketsLost() const { return packetsLost; }
00853 
00857     DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
00858 
00861     DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00862 
00865     DWORD GetPacketsTooLate() const;
00866 
00869     DWORD GetPacketOverruns() const;
00870 
00875     DWORD GetAverageSendTime() const { return averageSendTime; }
00876 
00881     DWORD GetMarkerRecvCount() const { return markerRecvCount; }
00882 
00887     DWORD GetMarkerSendCount() const { return markerSendCount; }
00888 
00893     DWORD GetMaximumSendTime() const { return maximumSendTime; }
00894 
00899     DWORD GetMinimumSendTime() const { return minimumSendTime; }
00900 
00905     DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00906 
00911     DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00912 
00917     DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00918 
00919     enum { JitterRoundingGuardBits = 4 };
00924     DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
00925 
00929     DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
00930 
00935     DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); }
00937 
00938     virtual void SetCloseOnBYE(PBoolean v)  { closeOnBye = v; }
00939 
00944     virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
00945 
00950     virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
00951 
00952     void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
00953 
00954     virtual PString GetEncoding() const { return m_encoding; }
00955     virtual void SetEncoding(const PString & newEncoding);
00956 
00957     DWORD GetSyncSourceIn() const { return syncSourceIn; }
00958 
00959     class EncodingLock
00960     {
00961       public:
00962         EncodingLock(RTP_Session & _session);
00963         ~EncodingLock();
00964 
00965         __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
00966 
00967       protected:
00968         RTP_Session  & session;
00969         RTP_Encoding * m_encodingHandler;
00970     };
00971 
00972     friend class EncodingLock; 
00973 
00974     void SetFailed(bool v)
00975     { failed = v; }
00976 
00977     bool HasFailed() const
00978     { return failed; }
00979 
00980     typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
00981     #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, RTP_Session::SendReceiveStatus &)
00982     #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, RTP_Session::SendReceiveStatus &)
00983 
00984     void AddFilter(const FilterNotifier & filter);
00985 
00986 #if OPAL_RTCP_XR
00987     const RTCP_XR_Metrics & GetMetrics() const { return m_metrics; }
00988 #endif
00989 
00990     virtual void SendBYE();
00991 
00992   protected:
00993     void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00994 
00995     PBoolean InsertReportPacket(RTP_ControlFrame & report);
00996     
00997 #if OPAL_RTCP_XR
00998     void InsertExtendedReportPacket(RTP_ControlFrame & report);
00999     void OnRxSenderReportToMetrics(const RTP_ControlFrame & frame, PINDEX offset);    
01000 #endif
01001 
01002     PString             m_encoding;
01003     PMutex              m_encodingMutex;
01004     RTP_Encoding      * m_encodingHandler;
01005 
01006     unsigned           sessionID;
01007     bool               isAudio;
01008     unsigned           m_timeUnits;
01009     PString            canonicalName;
01010     PString            toolName;
01011     RTP_UserData     * userData;
01012     PBoolean           autoDeleteUserData;
01013 
01014     typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
01015     JitterBufferPtr m_jitterBuffer;
01016 
01017     DWORD         syncSourceOut;
01018     DWORD         syncSourceIn;
01019     DWORD         lastSentTimestamp;
01020     bool          allowAnySyncSource;
01021     bool          allowOneSyncSourceChange;
01022     PBoolean      allowRemoteTransmitAddressChange;
01023     PBoolean      allowSequenceChange;
01024     PTimeInterval reportTimeInterval;
01025     unsigned      txStatisticsInterval;
01026     unsigned      rxStatisticsInterval;
01027     WORD          lastSentSequenceNumber;
01028     WORD          expectedSequenceNumber;
01029     PTimeInterval lastSentPacketTime;
01030     PTimeInterval lastReceivedPacketTime;
01031     PTime         lastSRTimestamp;
01032     PTime         lastSRReceiveTime;
01033     PTimeInterval delaySinceLastSR;
01034     WORD          lastRRSequenceNumber;
01035     bool          resequenceOutOfOrderPackets;
01036     unsigned      consecutiveOutOfOrderPackets;
01037     PTimeInterval outOfOrderPacketTime;
01038 
01039     std::list<RTP_DataFrame> m_outOfOrderPackets;
01040     void SaveOutOfOrderPacket(RTP_DataFrame & frame);
01041 
01042     PMutex        dataMutex;
01043     DWORD         timeStampOffs;               // offset between incoming media timestamp and timeStampOut
01044     PBoolean      oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
01045     DWORD         oobTimeStampOutBase;         // base timestamp value for oob data
01046     PTimeInterval oobTimeStampBase;            // base time for oob timestamp
01047 
01048     // Statistics
01049     PTime firstPacketSent;
01050     DWORD packetsSent;
01051     DWORD rtcpPacketsSent;
01052     DWORD octetsSent;
01053     PTime firstPacketReceived;
01054     DWORD packetsReceived;
01055     DWORD senderReportsReceived;
01056     DWORD octetsReceived;
01057     DWORD packetsLost;
01058     DWORD packetsLostByRemote;
01059     DWORD packetsOutOfOrder;
01060     DWORD averageSendTime;
01061     DWORD maximumSendTime;
01062     DWORD minimumSendTime;
01063     DWORD averageReceiveTime;
01064     DWORD maximumReceiveTime;
01065     DWORD minimumReceiveTime;
01066     DWORD jitterLevel;
01067     DWORD jitterLevelOnRemote;
01068     DWORD maximumJitterLevel;
01069 
01070     DWORD markerSendCount;
01071     DWORD markerRecvCount;
01072 
01073     unsigned txStatisticsCount;
01074     unsigned rxStatisticsCount;
01075     
01076 #if OPAL_RTCP_XR
01077     // Calculate the VoIP Metrics for RTCP-XR
01078     RTCP_XR_Metrics m_metrics;
01079 #endif
01080 
01081     DWORD    averageSendTimeAccum;
01082     DWORD    maximumSendTimeAccum;
01083     DWORD    minimumSendTimeAccum;
01084     DWORD    averageReceiveTimeAccum;
01085     DWORD    maximumReceiveTimeAccum;
01086     DWORD    minimumReceiveTimeAccum;
01087     DWORD    packetsLostSinceLastRR;
01088     DWORD    lastTransitTime;
01089     
01090     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
01091     PBoolean ignorePayloadTypeChanges;
01092 
01093     PMutex reportMutex;
01094     PTimer reportTimer;
01095 
01096     PBoolean closeOnBye;
01097     PBoolean byeSent;
01098     bool                failed;      
01099 
01100     list<FilterNotifier> m_filters;
01101 };
01102 
01105 class RTP_UDP : public RTP_Session
01106 {
01107   PCLASSINFO(RTP_UDP, RTP_Session);
01108 
01109   public:
01114     RTP_UDP(
01115       const Params & options 
01116     );
01117 
01119     ~RTP_UDP();
01121 
01129     virtual PBoolean ReadData(RTP_DataFrame & frame);
01130     virtual PBoolean Internal_ReadData(RTP_DataFrame & frame);
01131 
01134     virtual PBoolean WriteData(RTP_DataFrame & frame);
01135     virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
01136 
01140     virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
01141 
01144     virtual PBoolean WriteControl(RTP_ControlFrame & frame);
01145 
01148     virtual bool Close(
01149       PBoolean reading    
01150     );
01151 
01154     virtual PString GetLocalHostName();
01156 
01159     virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
01160 
01165     virtual PBoolean Open(
01166       PIPSocket::Address localAddress,  
01167       WORD portBase,                    
01168       WORD portMax,                     
01169       BYTE ipTypeOfService,             
01170       PNatMethod * natMethod = NULL,    
01171       RTP_QOS * rtpqos = NULL           
01172     );
01174 
01177     virtual void Reopen(PBoolean isReading);
01179 
01184     virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
01185 
01188     virtual void SetLocalAddress(
01189       const PIPSocket::Address & addr
01190     ) { localAddress = addr; }
01191 
01194     PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01195 
01198     virtual WORD GetLocalDataPort() const { return localDataPort; }
01199 
01202     virtual WORD GetLocalControlPort() const { return localControlPort; }
01203 
01206     virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
01207 
01210     virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
01211 
01214     virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
01215 
01218     virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
01219 
01222     virtual PBoolean SetRemoteSocketInfo(
01223       PIPSocket::Address address,   
01224       WORD port,                    
01225       PBoolean isDataPort               
01226     );
01227 
01230     virtual void ApplyQOS(
01231       const PIPSocket::Address & addr
01232     );
01234 
01235     virtual int GetDataSocketHandle() const
01236     { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01237 
01238     virtual int GetControlSocketHandle() const
01239     { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01240 
01241     friend class RTP_Encoding;
01242 
01243     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01244     virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01245 
01246     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01247     virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
01248 
01249     virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01250     virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
01251 
01252     virtual SendReceiveStatus ReadControlPDU();
01253     virtual SendReceiveStatus ReadDataOrControlPDU(
01254       BYTE * framePtr,
01255       PINDEX frameSize,
01256       PBoolean fromDataChannel
01257     );
01258 
01259     virtual bool WriteDataPDU(RTP_DataFrame & frame);
01260     virtual bool WriteDataOrControlPDU(
01261       const BYTE * framePtr,
01262       PINDEX frameSize,
01263       bool toDataChannel
01264     );
01265 
01266     virtual void SetEncoding(const PString & newEncoding);
01267 
01268 
01269   protected:
01270     PIPSocket::Address localAddress;
01271     WORD               localDataPort;
01272     WORD               localControlPort;
01273 
01274     PIPSocket::Address remoteAddress;
01275     WORD               remoteDataPort;
01276     WORD               remoteControlPort;
01277 
01278     PIPSocket::Address remoteTransmitAddress;
01279 
01280     PUDPSocket * dataSocket;
01281     PUDPSocket * controlSocket;
01282 
01283     bool shutdownRead;
01284     bool shutdownWrite;
01285     bool appliedQOS;
01286     bool remoteIsNAT;
01287     bool localHasNAT;
01288     bool m_firstData;
01289     bool m_firstControl;
01290     int  badTransmitCounter;
01291     PTime badTransmitStart;
01292 
01293     PTimer timerWriteDataIdle;
01294     PDECLARE_NOTIFIER(PTimer,  RTP_UDP, OnWriteDataIdle);
01295 };
01296 
01298 
01299 class RTP_UDP;
01300 
01301 class RTP_Encoding
01302 {
01303   public:
01304     RTP_Encoding();
01305     virtual ~RTP_Encoding();
01306     virtual void ApplyStringOptions(const PStringToString & /*stringOptions*/) {}
01307     virtual void OnStart(RTP_Session & _rtpSession);
01308     virtual void OnFinish();
01309     virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
01310     virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob);
01311     virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
01312     virtual void OnWriteDataIdle() {}
01313     virtual void SetWriteDataIdleTimer(PTimer &) {}
01314     virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
01315     virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01316     virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
01317     virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01318     virtual PBoolean ReadData(RTP_DataFrame & frame);
01319     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
01320 
01321     PMutex      mutex;
01322     unsigned    refCount;
01323 
01324   protected:
01325     RTP_UDP     * rtpUDP;
01326 };
01327 
01328 PFACTORY_LOAD(RTP_Encoding);
01329 
01330 
01332 
01333 class SecureRTP_UDP : public RTP_UDP
01334 {
01335   PCLASSINFO(SecureRTP_UDP, RTP_UDP);
01336 
01337   public:
01342     SecureRTP_UDP(
01343       const Params & options 
01344     );
01345 
01347     ~SecureRTP_UDP();
01348 
01349     virtual void SetSecurityMode(OpalSecurityMode * srtpParms);  
01350     virtual OpalSecurityMode * GetSecurityParms() const;
01351 
01352   protected:
01353     OpalSecurityMode * securityParms;
01354 };
01355 
01356 #endif // OPAL_RTP_RTP_H
01357