OPAL  Version 3.10.4
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: 26716 $
00030  * $Author: rjongbloed $
00031  * $Date: 2011-11-30 17:51:43 -0600 (Wed, 30 Nov 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 outOfOrderWaitTime;
01038     PTimeInterval outOfOrderPacketTime;
01039 
01040     std::list<RTP_DataFrame> m_outOfOrderPackets;
01041     void SaveOutOfOrderPacket(RTP_DataFrame & frame);
01042 
01043     PMutex        dataMutex;
01044     DWORD         timeStampOffs;               // offset between incoming media timestamp and timeStampOut
01045     PBoolean      oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
01046     DWORD         oobTimeStampOutBase;         // base timestamp value for oob data
01047     PTimeInterval oobTimeStampBase;            // base time for oob timestamp
01048 
01049     // Statistics
01050     PTime firstPacketSent;
01051     DWORD packetsSent;
01052     DWORD rtcpPacketsSent;
01053     DWORD octetsSent;
01054     PTime firstPacketReceived;
01055     DWORD packetsReceived;
01056     DWORD senderReportsReceived;
01057     DWORD octetsReceived;
01058     DWORD packetsLost;
01059     DWORD packetsLostByRemote;
01060     DWORD packetsOutOfOrder;
01061     DWORD averageSendTime;
01062     DWORD maximumSendTime;
01063     DWORD minimumSendTime;
01064     DWORD averageReceiveTime;
01065     DWORD maximumReceiveTime;
01066     DWORD minimumReceiveTime;
01067     DWORD jitterLevel;
01068     DWORD jitterLevelOnRemote;
01069     DWORD maximumJitterLevel;
01070 
01071     DWORD markerSendCount;
01072     DWORD markerRecvCount;
01073 
01074     unsigned txStatisticsCount;
01075     unsigned rxStatisticsCount;
01076     
01077 #if OPAL_RTCP_XR
01078     // Calculate the VoIP Metrics for RTCP-XR
01079     RTCP_XR_Metrics m_metrics;
01080 #endif
01081 
01082     DWORD    averageSendTimeAccum;
01083     DWORD    maximumSendTimeAccum;
01084     DWORD    minimumSendTimeAccum;
01085     DWORD    averageReceiveTimeAccum;
01086     DWORD    maximumReceiveTimeAccum;
01087     DWORD    minimumReceiveTimeAccum;
01088     DWORD    packetsLostSinceLastRR;
01089     DWORD    lastTransitTime;
01090     
01091     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
01092     PBoolean ignorePayloadTypeChanges;
01093 
01094     PMutex reportMutex;
01095     PTimer reportTimer;
01096 
01097     PBoolean closeOnBye;
01098     PBoolean byeSent;
01099     bool                failed;      
01100 
01101     list<FilterNotifier> m_filters;
01102 };
01103 
01106 class RTP_UDP : public RTP_Session
01107 {
01108   PCLASSINFO(RTP_UDP, RTP_Session);
01109 
01110   public:
01115     RTP_UDP(
01116       const Params & options 
01117     );
01118 
01120     ~RTP_UDP();
01122 
01130     virtual PBoolean ReadData(RTP_DataFrame & frame);
01131     virtual PBoolean Internal_ReadData(RTP_DataFrame & frame);
01132 
01135     virtual PBoolean WriteData(RTP_DataFrame & frame);
01136     virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
01137 
01141     virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
01142 
01145     virtual PBoolean WriteControl(RTP_ControlFrame & frame);
01146 
01149     virtual bool Close(
01150       PBoolean reading    
01151     );
01152 
01155     virtual PString GetLocalHostName();
01157 
01160     virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
01161 
01166     virtual PBoolean Open(
01167       PIPSocket::Address localAddress,  
01168       WORD portBase,                    
01169       WORD portMax,                     
01170       BYTE ipTypeOfService,             
01171       PNatMethod * natMethod = NULL,    
01172       RTP_QOS * rtpqos = NULL           
01173     );
01175 
01178     virtual void Reopen(PBoolean isReading);
01180 
01185     virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
01186 
01189     virtual void SetLocalAddress(
01190       const PIPSocket::Address & addr
01191     ) { localAddress = addr; }
01192 
01195     PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01196 
01199     virtual WORD GetLocalDataPort() const { return localDataPort; }
01200 
01203     virtual WORD GetLocalControlPort() const { return localControlPort; }
01204 
01207     virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
01208 
01211     virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
01212 
01215     virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
01216 
01219     virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
01220 
01223     virtual PBoolean SetRemoteSocketInfo(
01224       PIPSocket::Address address,   
01225       WORD port,                    
01226       PBoolean isDataPort               
01227     );
01228 
01231     virtual void ApplyQOS(
01232       const PIPSocket::Address & addr
01233     );
01235 
01236     virtual int GetDataSocketHandle() const
01237     { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01238 
01239     virtual int GetControlSocketHandle() const
01240     { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01241 
01242     friend class RTP_Encoding;
01243 
01244     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01245     virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01246 
01247     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01248     virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
01249 
01250     virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01251     virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
01252 
01253     virtual SendReceiveStatus ReadControlPDU();
01254     virtual SendReceiveStatus ReadDataOrControlPDU(
01255       BYTE * framePtr,
01256       PINDEX frameSize,
01257       PBoolean fromDataChannel
01258     );
01259 
01260     virtual bool WriteDataPDU(RTP_DataFrame & frame);
01261     virtual bool WriteDataOrControlPDU(
01262       const BYTE * framePtr,
01263       PINDEX frameSize,
01264       bool toDataChannel
01265     );
01266 
01267     virtual void SetEncoding(const PString & newEncoding);
01268 
01269 
01270   protected:
01271     PIPSocket::Address localAddress;
01272     WORD               localDataPort;
01273     WORD               localControlPort;
01274 
01275     PIPSocket::Address remoteAddress;
01276     WORD               remoteDataPort;
01277     WORD               remoteControlPort;
01278 
01279     PIPSocket::Address remoteTransmitAddress;
01280 
01281     PUDPSocket * dataSocket;
01282     PUDPSocket * controlSocket;
01283 
01284     bool shutdownRead;
01285     bool shutdownWrite;
01286     bool appliedQOS;
01287     bool remoteIsNAT;
01288     bool localHasNAT;
01289     bool m_firstData;
01290     bool m_firstControl;
01291     int  badTransmitCounter;
01292     PTime badTransmitStart;
01293 
01294     PTimer timerWriteDataIdle;
01295     PDECLARE_NOTIFIER(PTimer,  RTP_UDP, OnWriteDataIdle);
01296 };
01297 
01299 
01300 class RTP_UDP;
01301 
01302 class RTP_Encoding
01303 {
01304   public:
01305     RTP_Encoding();
01306     virtual ~RTP_Encoding();
01307     virtual void ApplyStringOptions(const PStringToString & /*stringOptions*/) {}
01308     virtual void OnStart(RTP_Session & _rtpSession);
01309     virtual void OnFinish();
01310     virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
01311     virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob);
01312     virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
01313     virtual void OnWriteDataIdle() {}
01314     virtual void SetWriteDataIdleTimer(PTimer &) {}
01315     virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
01316     virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01317     virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
01318     virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01319     virtual PBoolean ReadData(RTP_DataFrame & frame);
01320     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
01321 
01322     PMutex      mutex;
01323     unsigned    refCount;
01324 
01325   protected:
01326     RTP_UDP     * rtpUDP;
01327 };
01328 
01329 PFACTORY_LOAD(RTP_Encoding);
01330 
01331 
01333 
01334 class SecureRTP_UDP : public RTP_UDP
01335 {
01336   PCLASSINFO(SecureRTP_UDP, RTP_UDP);
01337 
01338   public:
01343     SecureRTP_UDP(
01344       const Params & options 
01345     );
01346 
01348     ~SecureRTP_UDP();
01349 
01350     virtual void SetSecurityMode(OpalSecurityMode * srtpParms);  
01351     virtual OpalSecurityMode * GetSecurityParms() const;
01352 
01353   protected:
01354     OpalSecurityMode * securityParms;
01355 };
01356 
01357 #endif // OPAL_RTP_RTP_H
01358