OpenH323 1.18.0
|
00001 /* 00002 * rtp.h 00003 * 00004 * RTP protocol handler 00005 * 00006 * Open H323 Library 00007 * 00008 * Copyright (c) 1998-2000 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 * $Log: rtp.h,v $ 00030 * Revision 1.58 2005/11/30 13:05:01 csoutheren 00031 * Changed tags for Doxygen 00032 * 00033 * Revision 1.57 2005/11/21 21:06:23 shorne 00034 * Added GQoS switches 00035 * 00036 * Revision 1.56 2005/08/27 02:06:00 csoutheren 00037 * Keep track of time first RTP packet is received 00038 * 00039 * Revision 1.55 2005/01/03 14:03:20 csoutheren 00040 * Added new configure options and ability to disable/enable modules 00041 * 00042 * Revision 1.54 2005/01/03 06:25:52 csoutheren 00043 * Added extensive support for disabling code modules at compile time 00044 * 00045 * Revision 1.53 2004/04/22 12:38:02 rjongbloed 00046 * Removed the RTP QoS class if there is no QoS support in build, 00047 * thanks Nick Hoath, ISDN Communications Ltd. 00048 * 00049 * Revision 1.52 2004/04/07 05:31:42 csoutheren 00050 * Added ability to receive calls from endpoints behind NAT firewalls 00051 * 00052 * Revision 1.51 2003/10/27 06:03:39 csoutheren 00053 * Added support for QoS 00054 * Thanks to Henry Harrison of AliceStreet 00055 * 00056 * Revision 1.50 2003/10/09 09:47:45 csoutheren 00057 * Fixed problem with re-opening RTP half-channels under unusual 00058 * circumstances. Thanks to Damien Sandras 00059 * 00060 * Revision 1.49 2003/05/14 13:46:39 rjongbloed 00061 * Removed hack of using special payload type for H.263 for a method which 00062 * would be less prone to failure in the future. 00063 * 00064 * Revision 1.48 2003/05/02 04:57:43 robertj 00065 * Added header extension support to RTP data frame class. 00066 * 00067 * Revision 1.47 2003/05/02 04:21:53 craigs 00068 * Added hacked OpalH263 codec 00069 * 00070 * Revision 1.46 2003/02/07 00:30:41 robertj 00071 * Changes for bizarre usage of RTP code outside of scope of H.323 specs. 00072 * 00073 * Revision 1.45 2003/02/05 06:32:08 robertj 00074 * Fixed non-stun symmetric NAT support recently broken. 00075 * 00076 * Revision 1.44 2003/02/04 07:06:41 robertj 00077 * Added STUN support. 00078 * 00079 * Revision 1.43 2002/11/19 01:48:15 robertj 00080 * Allowed get/set of canonical anme and tool name. 00081 * 00082 * Revision 1.42 2002/11/12 22:10:48 robertj 00083 * Updated documentation. 00084 * 00085 * Revision 1.41 2002/10/31 00:33:29 robertj 00086 * Enhanced jitter buffer system so operates dynamically between minimum and 00087 * maximum values. Altered API to assure app writers note the change! 00088 * 00089 * Revision 1.40 2002/09/26 04:01:58 robertj 00090 * Fixed calculation of fraction of packets lost in RR, thanks Awais Ali 00091 * 00092 * Revision 1.39 2002/09/16 01:14:15 robertj 00093 * Added #define so can select if #pragma interface/implementation is used on 00094 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00095 * 00096 * Revision 1.38 2002/09/03 05:47:02 robertj 00097 * Normalised the multi-include header prevention ifdef/define symbol. 00098 * Added copy constructor/operator for session manager. 00099 * 00100 * Revision 1.37 2002/08/05 10:03:47 robertj 00101 * Cosmetic changes to normalise the usage of pragma interface/implementation. 00102 * 00103 * Revision 1.36 2002/05/28 02:37:37 robertj 00104 * Fixed reading data out of RTCP compound statements. 00105 * 00106 * Revision 1.35 2002/05/02 05:58:24 robertj 00107 * Changed the mechanism for sending RTCP reports so that they will continue 00108 * to be sent regardless of if there is any actual data traffic. 00109 * Added support for compound RTCP statements for sender and receiver reports. 00110 * 00111 * Revision 1.34 2002/02/09 02:33:37 robertj 00112 * Improved payload type docuemntation and added Cisco CN. 00113 * 00114 * Revision 1.33 2002/01/22 07:08:26 robertj 00115 * Added IllegalPayloadType enum as need marker for none set 00116 * and MaxPayloadType is a legal value. 00117 * 00118 * Revision 1.32 2001/11/09 05:39:54 craigs 00119 * Added initial T.38 support thanks to Adam Lazur 00120 * 00121 * Revision 1.31 2001/09/11 00:21:21 robertj 00122 * Fixed missing stack sizes in endpoint for cleaner thread and jitter thread. 00123 * 00124 * Revision 1.30 2001/07/06 06:32:22 robertj 00125 * Added flag and checks for RTP data having specific SSRC. 00126 * Changed transmitter IP address check so is based on first received 00127 * PDU instead of expecting it to come from the host we are sending to. 00128 * 00129 * Revision 1.29 2001/06/04 11:37:48 robertj 00130 * Added thread safe enumeration functions of RTP sessions. 00131 * Added member access functions to UDP based RTP sessions. 00132 * 00133 * Revision 1.28 2001/04/24 06:15:50 robertj 00134 * Added work around for strange Cisco bug which suddenly starts sending 00135 * RTP packets beginning at a difference sequence number base. 00136 * 00137 * Revision 1.27 2001/04/02 23:58:23 robertj 00138 * Added jitter calculation to RTP session. 00139 * Added trace of statistics. 00140 * 00141 * Revision 1.26 2001/02/09 05:16:24 robertj 00142 * Added #pragma interface for GNU C++. 00143 * 00144 * Revision 1.25 2000/12/18 08:58:30 craigs 00145 * Added ability set ports 00146 * 00147 * Revision 1.24 2000/09/25 01:44:31 robertj 00148 * Fixed possible race condition on shutdown of RTP session with jitter buffer. 00149 * 00150 * Revision 1.23 2000/09/21 02:06:06 craigs 00151 * Added handling for endpoints that return conformant, but useless, RTP address 00152 * and port numbers 00153 * 00154 * Revision 1.22 2000/05/23 12:57:28 robertj 00155 * Added ability to change IP Type Of Service code from applications. 00156 * 00157 * Revision 1.21 2000/05/18 11:53:34 robertj 00158 * Changes to support doc++ documentation generation. 00159 * 00160 * Revision 1.20 2000/05/04 11:49:21 robertj 00161 * Added Packets Too Late statistics, requiring major rearrangement of jitter buffer code. 00162 * 00163 * Revision 1.19 2000/05/02 04:32:25 robertj 00164 * Fixed copyright notice comment. 00165 * 00166 * Revision 1.18 2000/05/01 01:01:24 robertj 00167 * Added flag for what to do with out of orer packets (use if jitter, don't if not). 00168 * 00169 * Revision 1.17 2000/04/30 03:55:18 robertj 00170 * Improved the RTCP messages, epecially reports 00171 * 00172 * Revision 1.16 2000/04/10 17:39:21 robertj 00173 * Fixed debug output of RTP payload types to allow for unknown numbers. 00174 * 00175 * Revision 1.15 2000/04/05 03:17:31 robertj 00176 * Added more RTP statistics gathering and H.245 round trip delay calculation. 00177 * 00178 * Revision 1.14 2000/03/23 02:55:18 robertj 00179 * Added sending of SDES control packets. 00180 * 00181 * Revision 1.13 2000/03/20 20:54:04 robertj 00182 * Fixed problem with being able to reopen for reading an RTP_Session (Cisco compatibilty) 00183 * 00184 * Revision 1.12 2000/02/29 13:00:13 robertj 00185 * Added extra statistic display for RTP packets out of order. 00186 * 00187 * Revision 1.11 1999/12/30 09:14:31 robertj 00188 * Changed payload type functions to use enum. 00189 * 00190 * Revision 1.10 1999/12/23 23:02:35 robertj 00191 * File reorganision for separating RTP from H.323 and creation of LID for VPB support. 00192 * 00193 * Revision 1.9 1999/11/20 05:35:57 robertj 00194 * Fixed possibly I/O block in RTP read loops. 00195 * 00196 * Revision 1.8 1999/11/19 09:17:15 robertj 00197 * Fixed problems with aycnhronous shut down of logical channels. 00198 * 00199 * Revision 1.7 1999/11/14 11:41:18 robertj 00200 * Added access functions to RTP statistics. 00201 * 00202 * Revision 1.6 1999/09/08 04:05:48 robertj 00203 * Added support for video capabilities & codec, still needs the actual codec itself! 00204 * 00205 * Revision 1.5 1999/08/31 12:34:18 robertj 00206 * Added gatekeeper support. 00207 * 00208 * Revision 1.4 1999/07/13 09:53:24 robertj 00209 * Fixed some problems with jitter buffer and added more debugging. 00210 * 00211 * Revision 1.3 1999/07/09 06:09:49 robertj 00212 * Major implementation. An ENORMOUS amount of stuff added everywhere. 00213 * 00214 * Revision 1.2 1999/06/22 13:49:40 robertj 00215 * Added GSM support and further RTP protocol enhancements. 00216 * 00217 * Revision 1.1 1999/06/14 06:12:25 robertj 00218 * Changes for using RTP sessions correctly in H323 Logical Channel context 00219 * 00220 */ 00221 00222 #ifndef __OPAL_RTP_H 00223 #define __OPAL_RTP_H 00224 00225 #ifdef P_USE_PRAGMA 00226 #pragma interface 00227 #endif 00228 00229 00230 #include <ptlib/sockets.h> 00231 00232 class RTP_JitterBuffer; 00233 00234 #ifdef P_STUN 00235 class PSTUNClient; 00236 #endif 00237 00239 // 00240 // class to hold the QoS definitions for an RTP channel 00241 00242 #if P_HAS_QOS 00243 00244 class RTP_QOS : public PObject 00245 { 00246 PCLASSINFO(RTP_QOS,PObject); 00247 public: 00248 PQoS dataQoS; 00249 PQoS ctrlQoS; 00250 }; 00251 00252 #else 00253 00254 class RTP_QOS; 00255 00256 #endif 00257 00259 // Real Time Protocol - IETF RFC1889 and RFC1890 00260 00263 class RTP_DataFrame : public PBYTEArray 00264 { 00265 PCLASSINFO(RTP_DataFrame, PBYTEArray); 00266 00267 public: 00268 RTP_DataFrame(PINDEX payloadSize = 2048); 00269 00270 enum { 00271 ProtocolVersion = 2, 00272 MinHeaderSize = 12 00273 }; 00274 00275 enum PayloadTypes { 00276 PCMU, // G.711 u-Law 00277 FS1016, // Federal Standard 1016 CELP 00278 G721, // ADPCM - Subsumed by G.726 00279 G726 = G721, 00280 GSM, // GSM 06.10 00281 G7231, // G.723.1 at 6.3kbps or 5.3 kbps 00282 DVI4_8k, // DVI4 at 8kHz sample rate 00283 DVI4_16k, // DVI4 at 16kHz sample rate 00284 LPC, // LPC-10 Linear Predictive CELP 00285 PCMA, // G.711 A-Law 00286 G722, // G.722 00287 L16_Stereo, // 16 bit linear PCM 00288 L16_Mono, // 16 bit linear PCM 00289 G723, // G.723 00290 CN, // Confort Noise 00291 MPA, // MPEG1 or MPEG2 audio 00292 G728, // G.728 16kbps CELP 00293 DVI4_11k, // DVI4 at 11kHz sample rate 00294 DVI4_22k, // DVI4 at 22kHz sample rate 00295 G729, // G.729 8kbps 00296 Cisco_CN, // Cisco systems comfort noise (unofficial) 00297 00298 CelB = 25, // Sun Systems Cell-B video 00299 JPEG, // Motion JPEG 00300 H261 = 31, // H.261 00301 MPV, // MPEG1 or MPEG2 video 00302 MP2T, // MPEG2 transport system 00303 H263, // H.263 00304 00305 LastKnownPayloadType, 00306 00307 DynamicBase = 96, 00308 MaxPayloadType = 127, 00309 IllegalPayloadType 00310 }; 00311 00312 unsigned GetVersion() const { return (theArray[0]>>6)&3; } 00313 00314 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; } 00315 void SetExtension(BOOL ext); 00316 00317 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; } 00318 void SetMarker(BOOL m); 00319 00320 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); } 00321 void SetPayloadType(PayloadTypes t); 00322 00323 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; } 00324 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; } 00325 00326 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; } 00327 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; } 00328 00329 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; } 00330 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; } 00331 00332 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; } 00333 DWORD GetContribSource(PINDEX idx) const; 00334 void SetContribSource(PINDEX idx, DWORD src); 00335 00336 PINDEX GetHeaderSize() const; 00337 00338 int GetExtensionType() const; // -1 is no extension 00339 void SetExtensionType(int type); 00340 PINDEX GetExtensionSize() const; 00341 BOOL SetExtensionSize(PINDEX sz); 00342 BYTE * GetExtensionPtr() const; 00343 00344 PINDEX GetPayloadSize() const { return payloadSize; } 00345 BOOL SetPayloadSize(PINDEX sz); 00346 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); } 00347 00348 protected: 00349 PINDEX payloadSize; 00350 00351 #if PTRACING 00352 friend ostream & operator<<(ostream & o, PayloadTypes t); 00353 #endif 00354 }; 00355 00356 PLIST(RTP_DataFrameList, RTP_DataFrame); 00357 00358 00361 class RTP_ControlFrame : public PBYTEArray 00362 { 00363 PCLASSINFO(RTP_ControlFrame, PBYTEArray); 00364 00365 public: 00366 RTP_ControlFrame(PINDEX compoundSize = 2048); 00367 00368 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; } 00369 00370 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; } 00371 void SetCount(unsigned count); 00372 00373 enum PayloadTypes { 00374 e_SenderReport = 200, 00375 e_ReceiverReport, 00376 e_SourceDescription, 00377 e_Goodbye, 00378 e_ApplDefined 00379 }; 00380 00381 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; } 00382 void SetPayloadType(unsigned t); 00383 00384 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); } 00385 void SetPayloadSize(PINDEX sz); 00386 00387 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); } 00388 00389 BOOL ReadNextCompound(); 00390 BOOL WriteNextCompound(); 00391 00392 PINDEX GetCompoundSize() const { return compoundSize; } 00393 00394 #pragma pack(1) 00395 struct ReceiverReport { 00396 PUInt32b ssrc; /* data source being reported */ 00397 BYTE fraction; /* fraction lost since last SR/RR */ 00398 BYTE lost[3]; /* cumulative number of packets lost (signed!) */ 00399 PUInt32b last_seq; /* extended last sequence number received */ 00400 PUInt32b jitter; /* interarrival jitter */ 00401 PUInt32b lsr; /* last SR packet from this source */ 00402 PUInt32b dlsr; /* delay since last SR packet */ 00403 00404 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; } 00405 void SetLostPackets(unsigned lost); 00406 }; 00407 00408 struct SenderReport { 00409 PUInt32b ssrc; /* source this RTCP packet refers to */ 00410 PUInt32b ntp_sec; /* NTP timestamp */ 00411 PUInt32b ntp_frac; 00412 PUInt32b rtp_ts; /* RTP timestamp */ 00413 PUInt32b psent; /* packets sent */ 00414 PUInt32b osent; /* octets sent */ 00415 }; 00416 00417 enum DescriptionTypes { 00418 e_END, 00419 e_CNAME, 00420 e_NAME, 00421 e_EMAIL, 00422 e_PHONE, 00423 e_LOC, 00424 e_TOOL, 00425 e_NOTE, 00426 e_PRIV, 00427 NumDescriptionTypes 00428 }; 00429 00430 struct SourceDescription { 00431 PUInt32b src; /* first SSRC/CSRC */ 00432 struct Item { 00433 BYTE type; /* type of SDES item (enum DescriptionTypes) */ 00434 BYTE length; /* length of SDES item (in octets) */ 00435 char data[1]; /* text, not zero-terminated */ 00436 00437 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); } 00438 Item * GetNextItem() { return (Item *)((char *)this + length + 2); } 00439 } item[1]; /* list of SDES items */ 00440 }; 00441 00442 SourceDescription & AddSourceDescription( 00443 DWORD src 00444 ); 00445 00446 SourceDescription::Item & AddSourceDescriptionItem( 00447 SourceDescription & sdes, 00448 unsigned type, 00449 const PString & data 00450 ); 00451 #pragma pack() 00452 00453 protected: 00454 PINDEX compoundOffset; 00455 PINDEX compoundSize; 00456 }; 00457 00458 00459 class RTP_Session; 00460 00465 class RTP_UserData : public PObject 00466 { 00467 PCLASSINFO(RTP_UserData, PObject); 00468 00469 public: 00476 virtual void OnTxStatistics( 00477 const RTP_Session & session 00478 ) const; 00479 00486 virtual void OnRxStatistics( 00487 const RTP_Session & session 00488 ) const; 00489 }; 00490 00491 00494 class RTP_Session : public PObject 00495 { 00496 PCLASSINFO(RTP_Session, PObject); 00497 00498 public: 00499 enum { 00500 DefaultAudioSessionID = 1, 00501 DefaultVideoSessionID = 2, 00502 DefaultFaxSessionID = 3 00503 }; 00504 00509 RTP_Session( 00510 unsigned id, 00511 RTP_UserData * userData = NULL 00512 ); 00513 00517 ~RTP_Session(); 00519 00531 void SetJitterBufferSize( 00532 unsigned minJitterDelay, 00533 unsigned maxJitterDelay, 00534 PINDEX stackSize = 30000 00535 ); 00536 00542 unsigned GetJitterBufferSize() const; 00543 00545 virtual BOOL ModifyQOS(RTP_QOS * ) 00546 { return FALSE; } 00547 00553 BOOL ReadBufferedData( 00554 DWORD timestamp, 00555 RTP_DataFrame & frame 00556 ); 00557 00563 virtual BOOL ReadData( 00564 RTP_DataFrame & frame 00565 ) = 0; 00566 00569 virtual BOOL WriteData( 00570 RTP_DataFrame & frame 00571 ) = 0; 00572 00575 virtual BOOL WriteControl( 00576 RTP_ControlFrame & frame 00577 ) = 0; 00578 00581 virtual BOOL SendReport(); 00582 00585 virtual void Close( 00586 BOOL reading 00587 ) = 0; 00588 00591 virtual PString GetLocalHostName() = 0; 00593 00596 enum SendReceiveStatus { 00597 e_ProcessPacket, 00598 e_IgnorePacket, 00599 e_AbortTransport 00600 }; 00601 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame); 00602 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame); 00603 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame); 00604 00605 class ReceiverReport : public PObject { 00606 PCLASSINFO(ReceiverReport, PObject); 00607 public: 00608 void PrintOn(ostream &) const; 00609 00610 DWORD sourceIdentifier; 00611 DWORD fractionLost; /* fraction lost since last SR/RR */ 00612 DWORD totalLost; /* cumulative number of packets lost (signed!) */ 00613 DWORD lastSequenceNumber; /* extended last sequence number received */ 00614 DWORD jitter; /* interarrival jitter */ 00615 PTimeInterval lastTimestamp;/* last SR packet from this source */ 00616 PTimeInterval delay; /* delay since last SR packet */ 00617 }; 00618 PARRAY(ReceiverReportArray, ReceiverReport); 00619 00620 class SenderReport : public PObject { 00621 PCLASSINFO(SenderReport, PObject); 00622 public: 00623 void PrintOn(ostream &) const; 00624 00625 DWORD sourceIdentifier; 00626 PTime realTimestamp; 00627 DWORD rtpTimestamp; 00628 DWORD packetsSent; 00629 DWORD octetsSent; 00630 }; 00631 virtual void OnRxSenderReport(const SenderReport & sender, 00632 const ReceiverReportArray & reports); 00633 virtual void OnRxReceiverReport(DWORD src, 00634 const ReceiverReportArray & reports); 00635 00636 class SourceDescription : public PObject { 00637 PCLASSINFO(SourceDescription, PObject); 00638 public: 00639 SourceDescription(DWORD src) { sourceIdentifier = src; } 00640 void PrintOn(ostream &) const; 00641 00642 DWORD sourceIdentifier; 00643 POrdinalToString items; 00644 }; 00645 PARRAY(SourceDescriptionArray, SourceDescription); 00646 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions); 00647 00648 virtual void OnRxGoodbye(const PDWORDArray & sources, 00649 const PString & reason); 00650 00651 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src, 00652 const BYTE * data, PINDEX size); 00654 00659 unsigned GetSessionID() const { return sessionID; } 00660 00663 PString GetCanonicalName() const; 00664 00667 void SetCanonicalName(const PString & name); 00668 00671 PString GetToolName() const; 00672 00675 void SetToolName(const PString & name); 00676 00679 RTP_UserData * GetUserData() const { return userData; } 00680 00683 void SetUserData( 00684 RTP_UserData * data 00685 ); 00686 00689 DWORD GetSyncSourceOut() const { return syncSourceOut; } 00690 00693 void IncrementReference() { referenceCount++; } 00694 00697 BOOL DecrementReference() { return --referenceCount == 0; } 00698 00701 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; } 00702 00705 void SetIgnoreOtherSources( 00706 BOOL ignore 00707 ) { ignoreOtherSources = ignore; } 00708 00711 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; } 00712 00715 void SetIgnoreOutOfOrderPackets( 00716 BOOL ignore 00717 ) { ignoreOutOfOrderPackets = ignore; } 00718 00721 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; } 00722 00725 void SetReportTimeInterval( 00726 const PTimeInterval & interval 00727 ) { reportTimeInterval = interval; } 00728 00731 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; } 00732 00735 void SetTxStatisticsInterval( 00736 unsigned packets 00737 ); 00738 00741 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; } 00742 00745 void SetRxStatisticsInterval( 00746 unsigned packets 00747 ); 00748 00751 DWORD GetPacketsSent() const { return packetsSent; } 00752 00755 DWORD GetOctetsSent() const { return octetsSent; } 00756 00759 DWORD GetPacketsReceived() const { return packetsReceived; } 00760 00763 DWORD GetOctetsReceived() const { return octetsReceived; } 00764 00767 DWORD GetPacketsLost() const { return packetsLost; } 00768 00771 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; } 00772 00775 DWORD GetPacketsTooLate() const; 00776 00781 DWORD GetAverageSendTime() const { return averageSendTime; } 00782 00787 DWORD GetMaximumSendTime() const { return maximumSendTime; } 00788 00793 DWORD GetMinimumSendTime() const { return minimumSendTime; } 00794 00799 DWORD GetAverageReceiveTime() const { return averageReceiveTime; } 00800 00805 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; } 00806 00811 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; } 00812 00817 DWORD GetAvgJitterTime() const { return jitterLevel>>7; } 00818 00822 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; } 00823 00827 PTime GetFirstDataReceivedTime() const { return firstDataReceivedTime; } 00829 00830 protected: 00831 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver); 00832 00833 unsigned sessionID; 00834 PString canonicalName; 00835 PString toolName; 00836 unsigned referenceCount; 00837 RTP_UserData * userData; 00838 00839 #ifndef NO_H323_AUDIO_CODECS 00840 RTP_JitterBuffer * jitter; 00841 #endif 00842 00843 BOOL ignoreOtherSources; 00844 BOOL ignoreOutOfOrderPackets; 00845 DWORD syncSourceOut; 00846 DWORD syncSourceIn; 00847 PTimeInterval reportTimeInterval; 00848 unsigned txStatisticsInterval; 00849 unsigned rxStatisticsInterval; 00850 WORD lastSentSequenceNumber; 00851 WORD expectedSequenceNumber; 00852 DWORD lastSentTimestamp; 00853 PTimeInterval lastSentPacketTime; 00854 PTimeInterval lastReceivedPacketTime; 00855 WORD lastRRSequenceNumber; 00856 PINDEX consecutiveOutOfOrderPackets; 00857 00858 // Statistics 00859 DWORD packetsSent; 00860 DWORD octetsSent; 00861 DWORD packetsReceived; 00862 DWORD octetsReceived; 00863 DWORD packetsLost; 00864 DWORD packetsOutOfOrder; 00865 DWORD averageSendTime; 00866 DWORD maximumSendTime; 00867 DWORD minimumSendTime; 00868 DWORD averageReceiveTime; 00869 DWORD maximumReceiveTime; 00870 DWORD minimumReceiveTime; 00871 DWORD jitterLevel; 00872 DWORD maximumJitterLevel; 00873 00874 unsigned txStatisticsCount; 00875 unsigned rxStatisticsCount; 00876 00877 DWORD averageSendTimeAccum; 00878 DWORD maximumSendTimeAccum; 00879 DWORD minimumSendTimeAccum; 00880 DWORD averageReceiveTimeAccum; 00881 DWORD maximumReceiveTimeAccum; 00882 DWORD minimumReceiveTimeAccum; 00883 DWORD packetsLostSinceLastRR; 00884 DWORD lastTransitTime; 00885 PTime firstDataReceivedTime; 00886 00887 PMutex reportMutex; 00888 PTimer reportTimer; 00889 }; 00890 00891 00894 class RTP_SessionManager : public PObject 00895 { 00896 PCLASSINFO(RTP_SessionManager, PObject); 00897 00898 public: 00903 RTP_SessionManager(); 00904 RTP_SessionManager(const RTP_SessionManager & sm); 00905 RTP_SessionManager & operator=(const RTP_SessionManager & sm); 00907 00908 00922 RTP_Session * UseSession( 00923 unsigned sessionID 00924 ); 00925 00932 void AddSession( 00933 RTP_Session * session 00934 ); 00935 00939 void ReleaseSession( 00940 unsigned sessionID 00941 ); 00942 00947 RTP_Session * GetSession( 00948 unsigned sessionID 00949 ) const; 00950 00967 RTP_Session * First(); 00968 00975 RTP_Session * Next(); 00976 00984 void Exit(); 00986 00987 00988 protected: 00989 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session); 00990 SessionDict sessions; 00991 PMutex mutex; 00992 PINDEX enumerationIndex; 00993 }; 00994 00995 00996 00999 class RTP_UDP : public RTP_Session 01000 { 01001 PCLASSINFO(RTP_UDP, RTP_Session); 01002 01003 public: 01008 RTP_UDP( 01009 unsigned id, 01010 BOOL remoteIsNat = FALSE 01011 ); 01012 01014 ~RTP_UDP(); 01016 01024 virtual BOOL ReadData(RTP_DataFrame & frame); 01025 01028 virtual BOOL WriteData(RTP_DataFrame & frame); 01029 01032 virtual BOOL WriteControl(RTP_ControlFrame & frame); 01033 01036 virtual void Close( 01037 BOOL reading 01038 ); 01039 01042 virtual PString GetLocalHostName(); 01044 01049 virtual BOOL ModifyQOS(RTP_QOS * rtpqos); 01050 01053 virtual void EnableGQoS(); 01054 01055 #if P_HAS_QOS 01056 01058 PQoS & GetQOS(); 01059 #endif 01060 01061 01066 BOOL Open( 01067 PIPSocket::Address localAddress, 01068 WORD portBase, 01069 WORD portMax, 01070 BYTE ipTypeOfService, 01071 #ifdef P_STUN 01072 PSTUNClient * stun = NULL, 01073 #else 01074 void * = NULL, 01075 #endif 01076 RTP_QOS * rtpqos = NULL 01077 ); 01079 01082 void Reopen(BOOL isReading); 01084 01089 PIPSocket::Address GetLocalAddress() const { return localAddress; } 01090 01093 void SetLocalAddress( 01094 const PIPSocket::Address & addr 01095 ) { localAddress = addr; } 01096 01099 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; } 01100 01103 WORD GetLocalDataPort() const { return localDataPort; } 01104 01107 WORD GetLocalControlPort() const { return localControlPort; } 01108 01111 WORD GetRemoteDataPort() const { return remoteDataPort; } 01112 01115 WORD GetRemoteControlPort() const { return remoteControlPort; } 01116 01119 PUDPSocket & GetDataSocket() { return *dataSocket; } 01120 01123 PUDPSocket & GetControlSocket() { return *controlSocket; } 01124 01127 BOOL SetRemoteSocketInfo( 01128 PIPSocket::Address address, 01129 WORD port, 01130 BOOL isDataPort 01131 ); 01132 01135 void ApplyQOS( 01136 const PIPSocket::Address & addr 01137 ); 01139 01140 protected: 01141 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame); 01142 SendReceiveStatus ReadControlPDU(); 01143 SendReceiveStatus ReadDataOrControlPDU( 01144 PUDPSocket & socket, 01145 PBYTEArray & frame, 01146 BOOL fromDataChannel 01147 ); 01148 01149 PIPSocket::Address localAddress; 01150 WORD localDataPort; 01151 WORD localControlPort; 01152 01153 PIPSocket::Address remoteAddress; 01154 WORD remoteDataPort; 01155 WORD remoteControlPort; 01156 01157 PIPSocket::Address remoteTransmitAddress; 01158 01159 BOOL shutdownRead; 01160 BOOL shutdownWrite; 01161 01162 PUDPSocket * dataSocket; 01163 PUDPSocket * controlSocket; 01164 01165 BOOL appliedQOS; 01166 BOOL enableGQOS; 01167 01168 BOOL remoteIsNAT; 01169 }; 01170 01171 01172 #endif // __OPAL_RTP_H 01173 01174