00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
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 
00047 class RTP_JitterBuffer;
00048 class PNatMethod;
00049 class OpalSecurityMode;
00050 
00052 
00053 
00054 
00055 class RTP_QOS : public PObject
00056 {
00057   PCLASSINFO(RTP_QOS,PObject);
00058   public:
00059     PQoS dataQoS;
00060     PQoS ctrlQoS;
00061 };
00062 
00064 
00065 
00068 class RTP_DataFrame : public PBYTEArray
00069 {
00070   PCLASSINFO(RTP_DataFrame, PBYTEArray);
00071 
00072   public:
00073     RTP_DataFrame(PINDEX payloadSize, PINDEX bufferSize = 0);
00074     RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = PTrue);
00075 
00076     enum {
00077       ProtocolVersion = 2,
00078       MinHeaderSize = 12,
00079       
00080       MaxMtuPayloadSize = (576-20-16-12)
00081     };
00082 
00083     enum PayloadTypes {
00084       PCMU,         
00085       FS1016,       
00086       G721,         
00087       G726 = G721,
00088       GSM,          
00089       G7231,        
00090       DVI4_8k,      
00091       DVI4_16k,     
00092       LPC,          
00093       PCMA,         
00094       G722,         
00095       L16_Stereo,   
00096       L16_Mono,     
00097       G723,         
00098       CN,           
00099       MPA,          
00100       G728,         
00101       DVI4_11k,     
00102       DVI4_22k,     
00103       G729,         
00104       Cisco_CN,     
00105 
00106       CelB = 25,    
00107       JPEG,         
00108       H261 = 31,    
00109       MPV,          
00110       MP2T,         
00111       H263,         
00112 
00113       LastKnownPayloadType,
00114 
00115       DynamicBase = 96,
00116       MaxPayloadType = 127,
00117       IllegalPayloadType
00118     };
00119 
00120     unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00121 
00122     PBoolean GetExtension() const   { return (theArray[0]&0x10) != 0; }
00123     void SetExtension(PBoolean ext);
00124 
00125     PBoolean GetMarker() const { return (theArray[1]&0x80) != 0; }
00126     void SetMarker(PBoolean m);
00127 
00128     bool GetPadding() const { return (theArray[0]&0x20) != 0; }
00129     void SetPadding(bool v)  { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
00130 
00131     unsigned GetPaddingSize() const;
00132 
00133     PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00134     void         SetPayloadType(PayloadTypes t);
00135 
00136     WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00137     void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00138 
00139     DWORD GetTimestamp() const  { return *(PUInt32b *)&theArray[4]; }
00140     void  SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00141 
00142     DWORD GetSyncSource() const  { return *(PUInt32b *)&theArray[8]; }
00143     void  SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00144 
00145     PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00146     DWORD  GetContribSource(PINDEX idx) const;
00147     void   SetContribSource(PINDEX idx, DWORD src);
00148 
00149     PINDEX GetHeaderSize() const;
00150 
00151     int GetExtensionType() const; 
00152     void   SetExtensionType(int type);
00153     PINDEX GetExtensionSize() const;
00154     PBoolean   SetExtensionSize(PINDEX sz);
00155     BYTE * GetExtensionPtr() const;
00156 
00157     PINDEX GetPayloadSize() const { return payloadSize - GetPaddingSize(); }
00158     PBoolean   SetPayloadSize(PINDEX sz);
00159     BYTE * GetPayloadPtr()     const { return (BYTE *)(theArray+GetHeaderSize()); }
00160 
00161     virtual void PrintOn(ostream & strm) const;
00162 
00163   protected:
00164     PINDEX payloadSize;
00165 
00166 #if PTRACING
00167     friend ostream & operator<<(ostream & o, PayloadTypes t);
00168 #endif
00169 };
00170 
00171 PLIST(RTP_DataFrameList, RTP_DataFrame);
00172 
00173 
00176 class RTP_ControlFrame : public PBYTEArray
00177 {
00178   PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00179 
00180   public:
00181     RTP_ControlFrame(PINDEX compoundSize = 2048);
00182 
00183     unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00184 
00185     unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00186     void     SetCount(unsigned count);
00187 
00188     enum PayloadTypes {
00189       e_IntraFrameRequest = 192,
00190       e_SenderReport = 200,
00191       e_ReceiverReport,
00192       e_SourceDescription,
00193       e_Goodbye,
00194       e_ApplDefined
00195     };
00196 
00197     unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00198     void     SetPayloadType(unsigned t);
00199 
00200     PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00201     void   SetPayloadSize(PINDEX sz);
00202 
00203     BYTE * GetPayloadPtr() const;
00204 
00205     PBoolean ReadNextPacket();
00206     PBoolean StartNewPacket();
00207     void EndPacket();
00208 
00209     PINDEX GetCompoundSize() const;
00210 
00211     void Reset(PINDEX size);
00212 
00213 #pragma pack(1)
00214     struct ReceiverReport {
00215       PUInt32b ssrc;      
00216       BYTE fraction;      
00217       BYTE lost[3];       
00218       PUInt32b last_seq;  
00219       PUInt32b jitter;    
00220       PUInt32b lsr;       
00221       PUInt32b dlsr;      
00222 
00223       unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00224       void SetLostPackets(unsigned lost);
00225     };
00226 
00227     struct SenderReport {
00228       PUInt32b ntp_sec;   
00229       PUInt32b ntp_frac;
00230       PUInt32b rtp_ts;    
00231       PUInt32b psent;     
00232       PUInt32b osent;      
00233     };
00234 
00235     enum DescriptionTypes {
00236       e_END,
00237       e_CNAME,
00238       e_NAME,
00239       e_EMAIL,
00240       e_PHONE,
00241       e_LOC,
00242       e_TOOL,
00243       e_NOTE,
00244       e_PRIV,
00245       NumDescriptionTypes
00246     };
00247 
00248     struct SourceDescription {
00249       PUInt32b src;       
00250       struct Item {
00251         BYTE type;        
00252         BYTE length;      
00253         char data[1];     
00254 
00255         
00256 
00257 
00258 
00259         unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);} 
00260         const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00261         Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00262       } item[1];          
00263     };
00264 
00265     void StartSourceDescription(
00266       DWORD src   
00267     );
00268 
00269     void AddSourceDescriptionItem(
00270       unsigned type,            
00271       const PString & data      
00272     );
00273 #pragma pack()
00274 
00275   protected:
00276     PINDEX compoundOffset;
00277     PINDEX payloadSize;
00278 };
00279 
00280 
00281 class RTP_Session;
00282 
00284 
00285 #if OPAL_STATISTICS
00286 
00289 class OpalMediaStatistics : public PObject
00290 {
00291     PCLASSINFO(OpalMediaStatistics, PObject);
00292   public:
00293     OpalMediaStatistics();
00294 
00295     
00296     PUInt64  m_totalBytes;
00297     unsigned m_totalPackets;
00298     unsigned m_packetsLost;
00299     unsigned m_packetsOutOfOrder;
00300     unsigned m_packetsTooLate;
00301     unsigned m_packetOverruns;
00302     unsigned m_minimumPacketTime;
00303     unsigned m_averagePacketTime;
00304     unsigned m_maximumPacketTime;
00305 
00306     
00307     unsigned m_averageJitter;
00308     unsigned m_maximumJitter;
00309 
00310     
00311     unsigned m_totalFrames;
00312     unsigned m_keyFrames;
00313 
00314     
00315 #if OPAL_FAX
00316     struct Fax {
00317       Fax();
00318 
00319       int  m_result;      
00320       int  m_bitRate;     
00321       int  m_compression; 
00322       bool m_errorCorrection;
00323       int  m_txPages;
00324       int  m_rxPages;
00325       int  m_totalPages;
00326       int  m_imageSize;   
00327       int  m_resolutionX; 
00328       int  m_resolutionY; 
00329       int  m_pageWidth;
00330       int  m_pageHeight;
00331       int  m_badRows;     
00332       int  m_mostBadRows; 
00333       int  m_errorCorrectionRetries;
00334     } m_fax;
00335 #endif
00336 };
00337 
00338 #endif
00339 
00340 
00345 class RTP_UserData : public PObject
00346 {
00347   PCLASSINFO(RTP_UserData, PObject);
00348 
00349   public:
00356     virtual void OnTxStatistics(
00357       const RTP_Session & session   
00358     ) const;
00359 
00366     virtual void OnRxStatistics(
00367       const RTP_Session & session   
00368     ) const;
00369 
00370 #if OPAL_VIDEO
00371 
00376     virtual void OnTxIntraFrameRequest(
00377       const RTP_Session & session   
00378     ) const;
00379 
00385     virtual void OnRxIntraFrameRequest(
00386       const RTP_Session & session   
00387     ) const;
00388 #endif
00389 
00393     virtual void SessionFailing(
00394       RTP_Session & session   
00395     );
00396 };
00397 
00398 class RTP_Encoding;
00399 
00400 
00403 class RTP_Session : public PObject
00404 {
00405   PCLASSINFO(RTP_Session, PObject);
00406 
00407   public:
00410     struct Params {
00411       Params()
00412         : id(0)
00413         , userData(NULL)
00414         , autoDelete(true)
00415         , isAudio(false)
00416         , remoteIsNAT(false)
00417       { }
00418 
00419       PString             encoding;    
00420       unsigned            id;          
00421       RTP_UserData      * userData;    
00422       bool                autoDelete;  
00423       bool                isAudio;     
00424       bool                remoteIsNAT; 
00425     };
00426 
00429     RTP_Session(
00430       const Params & options 
00431     );
00432 
00436     ~RTP_Session();
00438 
00450     void SetJitterBufferSize(
00451       unsigned minJitterDelay, 
00452       unsigned maxJitterDelay, 
00453       unsigned timeUnits = 8,  
00454       PINDEX stackSize = 30000 
00455     );
00456 
00462     unsigned GetJitterBufferSize() const;
00463     
00466     unsigned GetJitterTimeUnits() const;
00467 
00469     virtual PBoolean ModifyQOS(RTP_QOS * )
00470     { return PFalse; }
00471 
00477     virtual PBoolean ReadBufferedData(
00478       RTP_DataFrame & frame   
00479     );
00480 
00486     virtual PBoolean ReadData(
00487       RTP_DataFrame & frame,  
00488       PBoolean loop               
00489     ) = 0;
00490 
00493     virtual PBoolean WriteData(
00494       RTP_DataFrame & frame   
00495     ) = 0;
00496 
00500     virtual PBoolean WriteOOBData(
00501       RTP_DataFrame & frame,
00502       bool rewriteTimeStamp = true
00503     );
00504 
00507     virtual PBoolean WriteControl(
00508       RTP_ControlFrame & frame    
00509     ) = 0;
00510 
00513     virtual PBoolean SendReport();
00514 
00517     virtual void Close(
00518       PBoolean reading    
00519     ) = 0;
00520 
00523     virtual void Reopen(
00524       PBoolean isReading
00525     ) = 0;
00526 
00529     virtual PString GetLocalHostName() = 0;
00530 
00531 #if OPAL_STATISTICS
00532     virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
00533 #endif
00534 
00535 
00538     enum SendReceiveStatus {
00539       e_ProcessPacket,
00540       e_IgnorePacket,
00541       e_AbortTransport
00542     };
00543     virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00544     virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame);
00545 
00546     virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00547     virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00548 
00549     virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
00550     virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame);
00551 
00552     virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00553 
00554     class ReceiverReport : public PObject  {
00555         PCLASSINFO(ReceiverReport, PObject);
00556       public:
00557         void PrintOn(ostream &) const;
00558 
00559         DWORD sourceIdentifier;
00560         DWORD fractionLost;         
00561         DWORD totalLost;            
00562         DWORD lastSequenceNumber;   
00563         DWORD jitter;               
00564         PTimeInterval lastTimestamp;
00565         PTimeInterval delay;        
00566     };
00567     PARRAY(ReceiverReportArray, ReceiverReport);
00568 
00569     class SenderReport : public PObject  {
00570         PCLASSINFO(SenderReport, PObject);
00571       public:
00572         void PrintOn(ostream &) const;
00573 
00574         DWORD sourceIdentifier;
00575         PTime realTimestamp;
00576         DWORD rtpTimestamp;
00577         DWORD packetsSent;
00578         DWORD octetsSent;
00579     };
00580     virtual void OnRxSenderReport(const SenderReport & sender,
00581                                   const ReceiverReportArray & reports);
00582     virtual void OnRxReceiverReport(DWORD src,
00583                                     const ReceiverReportArray & reports);
00584 
00585     class SourceDescription : public PObject  {
00586         PCLASSINFO(SourceDescription, PObject);
00587       public:
00588         SourceDescription(DWORD src) { sourceIdentifier = src; }
00589         void PrintOn(ostream &) const;
00590 
00591         DWORD            sourceIdentifier;
00592         POrdinalToString items;
00593     };
00594     PARRAY(SourceDescriptionArray, SourceDescription);
00595     virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00596 
00597     virtual void OnRxGoodbye(const PDWORDArray & sources,
00598                              const PString & reason);
00599 
00600     virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00601                                  const BYTE * data, PINDEX size);
00603 
00608     unsigned GetSessionID() const { return sessionID; }
00609 
00612     bool IsAudio() const { return isAudio; }
00613 
00616     void SetAudio(
00617       bool aud    
00618     ) { isAudio = aud; }
00619 
00622     PString GetCanonicalName() const;
00623 
00626     void SetCanonicalName(const PString & name);
00627 
00630     PString GetToolName() const;
00631 
00634     void SetToolName(const PString & name);
00635 
00638     RTP_UserData * GetUserData() const { return userData; }
00639 
00642     void SetUserData(
00643       RTP_UserData * data,            
00644       PBoolean autoDeleteUserData = PTrue  
00645     );
00646 
00649     DWORD GetSyncSourceOut() const { return syncSourceOut; }
00650 
00653     bool AllowAnySyncSource() const { return allowAnySyncSource; }
00654 
00657     void SetAnySyncSource(
00658       bool allow    
00659     ) { allowAnySyncSource = allow; }
00660 
00663     PBoolean WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00664 
00667     void SetIgnoreOutOfOrderPackets(
00668       PBoolean ignore   
00669     ) { ignoreOutOfOrderPackets = ignore; }
00670 
00673     void SetIgnorePayloadTypeChanges(
00674       PBoolean ignore   
00675     ) { ignorePayloadTypeChanges = ignore; }
00676 
00679     const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00680 
00683     void SetReportTimeInterval(
00684       const PTimeInterval & interval 
00685     )  { reportTimeInterval = interval; }
00686 
00689     PTimeInterval GetReportTimer()
00690     { return reportTimer; }
00691 
00694     unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00695 
00698     void SetTxStatisticsInterval(
00699       unsigned packets   
00700     );
00701 
00704     unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00705 
00708     void SetRxStatisticsInterval(
00709       unsigned packets   
00710     );
00711 
00714     void ClearStatistics();
00715 
00718     DWORD GetPacketsSent() const { return packetsSent; }
00719 
00722     DWORD GetOctetsSent() const { return octetsSent; }
00723 
00726     DWORD GetPacketsReceived() const { return packetsReceived; }
00727 
00730     DWORD GetOctetsReceived() const { return octetsReceived; }
00731 
00734     DWORD GetPacketsLost() const { return packetsLost; }
00735 
00738     DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00739 
00742     DWORD GetPacketsTooLate() const;
00743 
00746     DWORD GetPacketOverruns() const;
00747 
00752     DWORD GetAverageSendTime() const { return averageSendTime; }
00753 
00758     DWORD GetMarkerRecvCount() const { return markerRecvCount; }
00759 
00764     DWORD GetMarkerSendCount() const { return markerSendCount; }
00765 
00770     DWORD GetMaximumSendTime() const { return maximumSendTime; }
00771 
00776     DWORD GetMinimumSendTime() const { return minimumSendTime; }
00777 
00782     DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00783 
00788     DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00789 
00794     DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00795 
00800     DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00801 
00805     DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00807 
00810     virtual int GetDataSocketHandle() const
00811     { return -1; }
00812     virtual int GetControlSocketHandle() const
00813     { return -1; }
00815 
00816     virtual void SetCloseOnBYE(PBoolean v)  { closeOnBye = v; }
00817 
00822     virtual void SendIntraFrameRequest();
00823 
00824     void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
00825 
00826     virtual PString GetEncoding() const { return m_encoding; }
00827     virtual void SetEncoding(const PString & newEncoding);
00828 
00829     DWORD GetSyncSourceIn() const { return syncSourceIn; }
00830 
00831     class EncodingLock
00832     {
00833       public:
00834         EncodingLock(RTP_Session & _session);
00835         ~EncodingLock();
00836 
00837         __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
00838 
00839       protected:
00840         RTP_Session  & session;
00841         RTP_Encoding * m_encodingHandler;
00842     };
00843 
00844     friend class EncodingLock; 
00845 
00846     void SetFailed(bool v)
00847     { failed = v; }
00848 
00849     bool HasFailed() const
00850     { return failed; }
00851 
00852     void AddFilter(const PNotifier & filter);
00853 
00854   protected:
00855     virtual void SendBYE();
00856     void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00857     PBoolean InsertReportPacket(RTP_ControlFrame & report);
00858 
00859     PString             m_encoding;
00860     PMutex              m_encodingMutex;
00861     RTP_Encoding      * m_encodingHandler;
00862 
00863     unsigned           sessionID;
00864     bool               isAudio;
00865     PString            canonicalName;
00866     PString            toolName;
00867     RTP_UserData     * userData;
00868     PBoolean           autoDeleteUserData;
00869 
00870     typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
00871     JitterBufferPtr m_jitterBuffer;
00872 
00873     PBoolean      ignoreOutOfOrderPackets;
00874     DWORD         syncSourceOut;
00875     DWORD         syncSourceIn;
00876     DWORD         lastSentTimestamp;
00877     bool          allowAnySyncSource;
00878     bool          allowOneSyncSourceChange;
00879     PBoolean      allowRemoteTransmitAddressChange;
00880     PBoolean      allowSequenceChange;
00881     PTimeInterval reportTimeInterval;
00882     unsigned      txStatisticsInterval;
00883     unsigned      rxStatisticsInterval;
00884     WORD          lastSentSequenceNumber;
00885     WORD          expectedSequenceNumber;
00886     PTimeInterval lastSentPacketTime;
00887     PTimeInterval lastReceivedPacketTime;
00888     WORD          lastRRSequenceNumber;
00889     PINDEX        consecutiveOutOfOrderPackets;
00890 
00891     PMutex        dataMutex;
00892     DWORD         timeStampOffs;               
00893     PBoolean      oobTimeStampBaseEstablished; 
00894     DWORD         oobTimeStampOutBase;         
00895     PTimeInterval oobTimeStampBase;            
00896 
00897     
00898     DWORD packetsSent;
00899     DWORD rtcpPacketsSent;
00900     DWORD octetsSent;
00901     DWORD packetsReceived;
00902     DWORD octetsReceived;
00903     DWORD packetsLost;
00904     DWORD packetsOutOfOrder;
00905     DWORD averageSendTime;
00906     DWORD maximumSendTime;
00907     DWORD minimumSendTime;
00908     DWORD averageReceiveTime;
00909     DWORD maximumReceiveTime;
00910     DWORD minimumReceiveTime;
00911     DWORD jitterLevel;
00912     DWORD maximumJitterLevel;
00913 
00914     DWORD markerSendCount;
00915     DWORD markerRecvCount;
00916 
00917     unsigned txStatisticsCount;
00918     unsigned rxStatisticsCount;
00919 
00920     DWORD    averageSendTimeAccum;
00921     DWORD    maximumSendTimeAccum;
00922     DWORD    minimumSendTimeAccum;
00923     DWORD    averageReceiveTimeAccum;
00924     DWORD    maximumReceiveTimeAccum;
00925     DWORD    minimumReceiveTimeAccum;
00926     DWORD    packetsLostSinceLastRR;
00927     DWORD    lastTransitTime;
00928     
00929     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
00930     PBoolean ignorePayloadTypeChanges;
00931 
00932     PMutex reportMutex;
00933     PTimer reportTimer;
00934 
00935     PBoolean closeOnBye;
00936     PBoolean byeSent;
00937     bool                failed;      
00938 
00939     class Filter : public PObject {
00940         PCLASSINFO(Filter, PObject);
00941       public:
00942         Filter(const PNotifier & n) : notifier(n) { }
00943         PNotifier notifier;
00944     };
00945     PList<Filter> filters;
00946 };
00947 
00950 class RTP_UDP : public RTP_Session
00951 {
00952   PCLASSINFO(RTP_UDP, RTP_Session);
00953 
00954   public:
00959     RTP_UDP(
00960       const Params & options 
00961     );
00962 
00964     ~RTP_UDP();
00966 
00974     virtual PBoolean ReadData(RTP_DataFrame & frame, PBoolean loop);
00975     virtual PBoolean Internal_ReadData(RTP_DataFrame & frame, PBoolean loop);
00976 
00979     virtual PBoolean WriteData(RTP_DataFrame & frame);
00980     virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
00981 
00985     virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
00986 
00989     virtual PBoolean WriteControl(RTP_ControlFrame & frame);
00990 
00993     virtual void Close(
00994       PBoolean reading    
00995     );
00996 
00999     virtual PString GetLocalHostName();
01001 
01004     virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
01005 
01010     virtual PBoolean Open(
01011       PIPSocket::Address localAddress,  
01012       WORD portBase,                    
01013       WORD portMax,                     
01014       BYTE ipTypeOfService,             
01015       PNatMethod * natMethod = NULL,    
01016       RTP_QOS * rtpqos = NULL           
01017     );
01019 
01022     virtual void Reopen(PBoolean isReading);
01024 
01029     virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
01030 
01033     virtual void SetLocalAddress(
01034       const PIPSocket::Address & addr
01035     ) { localAddress = addr; }
01036 
01039     PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01040 
01043     virtual WORD GetLocalDataPort() const { return localDataPort; }
01044 
01047     virtual WORD GetLocalControlPort() const { return localControlPort; }
01048 
01051     virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
01052 
01055     virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
01056 
01059     virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
01060 
01063     virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
01064 
01067     virtual PBoolean SetRemoteSocketInfo(
01068       PIPSocket::Address address,   
01069       WORD port,                    
01070       PBoolean isDataPort               
01071     );
01072 
01075     virtual void ApplyQOS(
01076       const PIPSocket::Address & addr
01077     );
01079 
01080     virtual int GetDataSocketHandle() const
01081     { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01082 
01083     virtual int GetControlSocketHandle() const
01084     { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01085 
01086     friend class RTP_Encoding;
01087 
01088     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01089     virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01090 
01091     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01092     virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
01093 
01094     virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01095     virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
01096 
01097     virtual SendReceiveStatus ReadControlPDU();
01098     virtual SendReceiveStatus ReadDataOrControlPDU(
01099       BYTE * framePtr,
01100       PINDEX frameSize,
01101       PBoolean fromDataChannel
01102     );
01103     
01104     virtual bool WriteDataPDU(RTP_DataFrame & frame);
01105     virtual bool WriteDataOrControlPDU(
01106       const BYTE * framePtr,
01107       PINDEX frameSize,
01108       bool toDataChannel
01109     );
01110 
01111 
01112   protected:
01113     PIPSocket::Address localAddress;
01114     WORD               localDataPort;
01115     WORD               localControlPort;
01116 
01117     PIPSocket::Address remoteAddress;
01118     WORD               remoteDataPort;
01119     WORD               remoteControlPort;
01120 
01121     PIPSocket::Address remoteTransmitAddress;
01122 
01123     PUDPSocket * dataSocket;
01124     PUDPSocket * controlSocket;
01125 
01126     bool shutdownRead;
01127     bool shutdownWrite;
01128     bool appliedQOS;
01129     bool remoteIsNAT;
01130     bool localHasNAT;
01131     bool first;
01132     int  badTransmitCounter;
01133     PTime badTransmitStart;
01134 };
01135 
01137 
01138 class RTP_UDP;
01139 
01140 class RTP_Encoding
01141 {
01142   public:
01143     RTP_Encoding();
01144     virtual ~RTP_Encoding();
01145     virtual void OnStart(RTP_Session & _rtpSession);
01146     virtual void OnFinish();
01147     virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
01148     virtual PBoolean WriteData(RTP_DataFrame & frame);
01149     virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
01150     virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
01151     virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01152     virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
01153     virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01154     virtual PBoolean ReadData(RTP_DataFrame & frame, PBoolean loop);
01155     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
01156 
01157     PMutex      mutex;
01158     unsigned    refCount;
01159 
01160   protected:
01161     RTP_UDP     * rtpUDP;
01162 };
01163 
01165 
01166 class SecureRTP_UDP : public RTP_UDP
01167 {
01168   PCLASSINFO(SecureRTP_UDP, RTP_UDP);
01169 
01170   public:
01175     SecureRTP_UDP(
01176       const Params & options 
01177     );
01178 
01180     ~SecureRTP_UDP();
01181 
01182     virtual void SetSecurityMode(OpalSecurityMode * srtpParms);  
01183     virtual OpalSecurityMode * GetSecurityParms() const;
01184 
01185   protected:
01186     OpalSecurityMode * securityParms;
01187 };
01188 
01189 #endif // OPAL_RTP_RTP_H
01190