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  * $Log: rtp.h,v $
00030  * Revision 2.44  2007/09/05 13:06:44  csoutheren
00031  * Applied 1720918 - Track marker packets sent/received
00032  * Thanks to Josh Mahonin
00033  *
00034  * Revision 2.43  2007/07/26 00:38:56  csoutheren
00035  * Make transmission of RFC2833 independent of the media stream
00036  *
00037  * Revision 2.42  2007/05/29 06:26:00  csoutheren
00038  * Add Reset function so we can reload used control frames
00039  *
00040  * Revision 2.41  2007/05/14 10:44:09  rjongbloed
00041  * Added PrintOn function to RTP_DataFrame
00042  *
00043  * Revision 2.40  2007/04/19 06:34:12  csoutheren
00044  * Applied 1703206 - OpalVideoFastUpdatePicture over SIP
00045  * Thanks to Josh Mahonin
00046  *
00047  * Revision 2.39  2007/04/05 02:41:05  rjongbloed
00048  * Added ability to have non-dynamic allocation of memory in RTP data frames.
00049  *
00050  * Revision 2.38  2007/03/28 05:25:56  csoutheren
00051  * Add virtual function to wait for incoming data
00052  * Swallow RTP packets that arrive on the socket before session starts
00053  *
00054  * Revision 2.37  2007/03/20 02:31:56  csoutheren
00055  * Don't send BYE twice or when channel is closed
00056  *
00057  * Revision 2.36  2007/03/12 23:33:18  csoutheren
00058  * Added virtual to functions
00059  *
00060  * Revision 2.35  2007/03/08 04:36:05  csoutheren
00061  * Add flag to close RTP session when RTCP BYE received
00062  *
00063  * Revision 2.34  2007/03/01 03:31:02  csoutheren
00064  * Remove spurious zero bytes from the end of RTCP SDES packets
00065  * Fix format of RTCP BYE packets
00066  *
00067  * Revision 2.33  2007/02/23 08:06:04  csoutheren
00068  * More implementation of ZRTP (not yet complete)
00069  *
00070  * Revision 2.32  2007/02/12 02:44:27  csoutheren
00071  * Start of support for ZRTP
00072  *
00073  * Revision 2.32  2007/02/10 07:08:41  craigs
00074  * Start of support for ZRTP
00075  *
00076  * Revision 2.31  2007/02/01 06:43:19  csoutheren
00077  * Added virtual to functions
00078  *
00079  * Revision 2.30  2006/12/08 04:12:12  csoutheren
00080  * Applied 1589274 - better rtp error handling of malformed rtcp packet
00081  * Thanks to frederich
00082  *
00083  * Revision 2.29  2006/11/29 06:31:59  csoutheren
00084  * Add support fort RTP BYE
00085  *
00086  * Revision 2.28  2006/11/20 03:37:12  csoutheren
00087  * Allow optional inclusion of RTP aggregation
00088  *
00089  * Revision 2.27  2006/10/28 16:40:28  dsandras
00090  * Fixed SIP reinvite without breaking H.323 calls.
00091  *
00092  * Revision 2.26  2006/10/24 04:18:28  csoutheren
00093  * Added support for encrypted RTCP
00094  *
00095  * Revision 2.25  2006/09/05 06:18:22  csoutheren
00096  * Start bringing in SRTP code for libSRTP
00097  *
00098  * Revision 2.24  2006/08/29 18:39:21  dsandras
00099  * Added function to better deal with reinvites.
00100  *
00101  * Revision 2.23  2006/08/03 04:57:12  csoutheren
00102  * Port additional NAT handling logic from OpenH323 and extend into OpalConnection class
00103  *
00104  * Revision 2.22  2006/02/02 07:02:57  csoutheren
00105  * Added RTP payload map to transcoders and connections to allow remote SIP endpoints
00106  * to change the payload type used for outgoing RTP.
00107  *
00108  * Revision 2.21  2005/12/30 14:29:15  dsandras
00109  * Removed the assumption that the jitter will contain a 8 kHz signal.
00110  *
00111  * Revision 2.20  2005/11/30 13:35:26  csoutheren
00112  * Changed tags for Doxygen
00113  *
00114  * Revision 2.19  2005/04/11 17:34:57  dsandras
00115  * Added support for dynamic sequence changes in case of Re-INVITE.
00116  *
00117  * Revision 2.18  2005/04/10 20:50:16  dsandras
00118  * Allow changes of remote transmit address and SyncSource in an established RTP connection.
00119  *
00120  * Revision 2.17  2004/10/02 11:50:54  rjongbloed
00121  * Fixed RTP media stream so assures RTP session is open before starting.
00122  *
00123  * Revision 2.16  2004/04/26 05:37:13  rjongbloed
00124  * Allowed for selectable auto deletion of RTP user data attached to an RTP session.
00125  *
00126  * Revision 2.15  2004/02/19 10:47:01  rjongbloed
00127  * Merged OpenH323 version 1.13.1 changes.
00128  *
00129  * Revision 2.14  2004/01/18 15:35:20  rjongbloed
00130  * More work on video support
00131  *
00132  * Revision 2.13  2003/01/07 04:39:53  robertj
00133  * Updated to OpenH323 v1.11.2
00134  *
00135  * Revision 2.12  2002/11/10 11:33:17  robertj
00136  * Updated to OpenH323 v1.10.3
00137  *
00138  * Revision 2.11  2002/09/16 02:52:35  robertj
00139  * Added #define so can select if #pragma interface/implementation is used on
00140  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00141  *
00142  * Revision 2.10  2002/09/04 06:01:47  robertj
00143  * Updated to OpenH323 v1.9.6
00144  *
00145  * Revision 2.9  2002/07/01 04:56:31  robertj
00146  * Updated to OpenH323 v1.9.1
00147  *
00148  * Revision 2.8  2002/04/10 03:10:13  robertj
00149  * Added referential (container) copy functions to session manager class.
00150  *
00151  * Revision 2.7  2002/02/13 02:30:06  robertj
00152  * Added ability for media patch (and transcoders) to handle multiple RTP frames.
00153  *
00154  * Revision 2.6  2002/02/11 09:32:12  robertj
00155  * Updated to openH323 v1.8.0
00156  *
00157  * Revision 2.5  2002/01/22 05:58:55  robertj
00158  * Put MaxPayloadType back in for backward compatibility
00159  *
00160  * Revision 2.4  2002/01/22 05:03:06  robertj
00161  * Added enum for illegal payload type value.
00162  *
00163  * Revision 2.3  2001/11/14 06:20:40  robertj
00164  * Changed sending of control channel reports to be timer based.
00165  *
00166  * Revision 2.2  2001/10/05 00:22:13  robertj
00167  * Updated to PWLib 1.2.0 and OpenH323 1.7.0
00168  *
00169  * Revision 2.1  2001/08/01 05:08:43  robertj
00170  * Moved default session ID's to OpalMediaFormat class.
00171  *
00172  * Revision 2.0  2001/07/27 15:48:24  robertj
00173  * Conversion of OpenH323 to Open Phone Abstraction Library (OPAL)
00174  *
00175  * Revision 1.51  2003/10/27 06:03:39  csoutheren
00176  * Added support for QoS
00177  *   Thanks to Henry Harrison of AliceStreet
00178  *
00179  * Revision 1.50  2003/10/09 09:47:45  csoutheren
00180  * Fixed problem with re-opening RTP half-channels under unusual
00181  * circumstances. Thanks to Damien Sandras
00182  *
00183  * Revision 1.49  2003/05/14 13:46:39  rjongbloed
00184  * Removed hack of using special payload type for H.263 for a method which
00185  *   would be less prone to failure in the future.
00186  *
00187  * Revision 1.48  2003/05/02 04:57:43  robertj
00188  * Added header extension support to RTP data frame class.
00189  *
00190  * Revision 1.47  2003/05/02 04:21:53  craigs
00191  * Added hacked OpalH263 codec
00192  *
00193  * Revision 1.46  2003/02/07 00:30:41  robertj
00194  * Changes for bizarre usage of RTP code outside of scope of H.323 specs.
00195  *
00196  * Revision 1.45  2003/02/05 06:32:08  robertj
00197  * Fixed non-stun symmetric NAT support recently broken.
00198  *
00199  * Revision 1.44  2003/02/04 07:06:41  robertj
00200  * Added STUN support.
00201  *
00202  * Revision 1.43  2002/11/19 01:48:15  robertj
00203  * Allowed get/set of canonical anme and tool name.
00204  *
00205  * Revision 1.42  2002/11/12 22:10:48  robertj
00206  * Updated documentation.
00207  *
00208  * Revision 1.41  2002/10/31 00:33:29  robertj
00209  * Enhanced jitter buffer system so operates dynamically between minimum and
00210  *   maximum values. Altered API to assure app writers note the change!
00211  *
00212  * Revision 1.40  2002/09/26 04:01:58  robertj
00213  * Fixed calculation of fraction of packets lost in RR, thanks Awais Ali
00214  *
00215  * Revision 1.39  2002/09/16 01:14:15  robertj
00216  * Added #define so can select if #pragma interface/implementation is used on
00217  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00218  *
00219  * Revision 1.38  2002/09/03 05:47:02  robertj
00220  * Normalised the multi-include header prevention ifdef/define symbol.
00221  * Added copy constructor/operator for session manager.
00222  *
00223  * Revision 1.37  2002/08/05 10:03:47  robertj
00224  * Cosmetic changes to normalise the usage of pragma interface/implementation.
00225  *
00226  * Revision 1.36  2002/05/28 02:37:37  robertj
00227  * Fixed reading data out of RTCP compound statements.
00228  *
00229  * Revision 1.35  2002/05/02 05:58:24  robertj
00230  * Changed the mechanism for sending RTCP reports so that they will continue
00231  *   to be sent regardless of if there is any actual data traffic.
00232  * Added support for compound RTCP statements for sender and receiver reports.
00233  *
00234  * Revision 1.34  2002/02/09 02:33:37  robertj
00235  * Improved payload type docuemntation and added Cisco CN.
00236  *
00237  * Revision 1.33  2002/01/22 07:08:26  robertj
00238  * Added IllegalPayloadType enum as need marker for none set
00239  *   and MaxPayloadType is a legal value.
00240  *
00241  * Revision 1.32  2001/11/09 05:39:54  craigs
00242  * Added initial T.38 support thanks to Adam Lazur
00243  *
00244  * Revision 1.31  2001/09/11 00:21:21  robertj
00245  * Fixed missing stack sizes in endpoint for cleaner thread and jitter thread.
00246  *
00247  * Revision 1.30  2001/07/06 06:32:22  robertj
00248  * Added flag and checks for RTP data having specific SSRC.
00249  * Changed transmitter IP address check so is based on first received
00250  *    PDU instead of expecting it to come from the host we are sending to.
00251  *
00252  * Revision 1.29  2001/06/04 11:37:48  robertj
00253  * Added thread safe enumeration functions of RTP sessions.
00254  * Added member access functions to UDP based RTP sessions.
00255  *
00256  * Revision 1.28  2001/04/24 06:15:50  robertj
00257  * Added work around for strange Cisco bug which suddenly starts sending
00258  *   RTP packets beginning at a difference sequence number base.
00259  *
00260  * Revision 1.27  2001/04/02 23:58:23  robertj
00261  * Added jitter calculation to RTP session.
00262  * Added trace of statistics.
00263  *
00264  * Revision 1.26  2001/02/09 05:16:24  robertj
00265  * Added #pragma interface for GNU C++.
00266  *
00267  * Revision 1.25  2000/12/18 08:58:30  craigs
00268  * Added ability set ports
00269  *
00270  * Revision 1.24  2000/09/25 01:44:31  robertj
00271  * Fixed possible race condition on shutdown of RTP session with jitter buffer.
00272  *
00273  * Revision 1.23  2000/09/21 02:06:06  craigs
00274  * Added handling for endpoints that return conformant, but useless, RTP address
00275  * and port numbers
00276  *
00277  * Revision 1.22  2000/05/23 12:57:28  robertj
00278  * Added ability to change IP Type Of Service code from applications.
00279  *
00280  * Revision 1.21  2000/05/18 11:53:34  robertj
00281  * Changes to support doc++ documentation generation.
00282  *
00283  * Revision 1.20  2000/05/04 11:49:21  robertj
00284  * Added Packets Too Late statistics, requiring major rearrangement of jitter buffer code.
00285  *
00286  * Revision 1.19  2000/05/02 04:32:25  robertj
00287  * Fixed copyright notice comment.
00288  *
00289  * Revision 1.18  2000/05/01 01:01:24  robertj
00290  * Added flag for what to do with out of orer packets (use if jitter, don't if not).
00291  *
00292  * Revision 1.17  2000/04/30 03:55:18  robertj
00293  * Improved the RTCP messages, epecially reports
00294  *
00295  * Revision 1.16  2000/04/10 17:39:21  robertj
00296  * Fixed debug output of RTP payload types to allow for unknown numbers.
00297  *
00298  * Revision 1.15  2000/04/05 03:17:31  robertj
00299  * Added more RTP statistics gathering and H.245 round trip delay calculation.
00300  *
00301  * Revision 1.14  2000/03/23 02:55:18  robertj
00302  * Added sending of SDES control packets.
00303  *
00304  * Revision 1.13  2000/03/20 20:54:04  robertj
00305  * Fixed problem with being able to reopen for reading an RTP_Session (Cisco compatibilty)
00306  *
00307  * Revision 1.12  2000/02/29 13:00:13  robertj
00308  * Added extra statistic display for RTP packets out of order.
00309  *
00310  * Revision 1.11  1999/12/30 09:14:31  robertj
00311  * Changed payload type functions to use enum.
00312  *
00313  * Revision 1.10  1999/12/23 23:02:35  robertj
00314  * File reorganision for separating RTP from H.323 and creation of LID for VPB support.
00315  *
00316  * Revision 1.9  1999/11/20 05:35:57  robertj
00317  * Fixed possibly I/O block in RTP read loops.
00318  *
00319  * Revision 1.8  1999/11/19 09:17:15  robertj
00320  * Fixed problems with aycnhronous shut down of logical channels.
00321  *
00322  * Revision 1.7  1999/11/14 11:41:18  robertj
00323  * Added access functions to RTP statistics.
00324  *
00325  * Revision 1.6  1999/09/08 04:05:48  robertj
00326  * Added support for video capabilities & codec, still needs the actual codec itself!
00327  *
00328  * Revision 1.5  1999/08/31 12:34:18  robertj
00329  * Added gatekeeper support.
00330  *
00331  * Revision 1.4  1999/07/13 09:53:24  robertj
00332  * Fixed some problems with jitter buffer and added more debugging.
00333  *
00334  * Revision 1.3  1999/07/09 06:09:49  robertj
00335  * Major implementation. An ENORMOUS amount of stuff added everywhere.
00336  *
00337  * Revision 1.2  1999/06/22 13:49:40  robertj
00338  * Added GSM support and further RTP protocol enhancements.
00339  *
00340  * Revision 1.1  1999/06/14 06:12:25  robertj
00341  * Changes for using RTP sessions correctly in H323 Logical Channel context
00342  *
00343  */
00344 
00345 #ifndef __OPAL_RTP_H
00346 #define __OPAL_RTP_H
00347 
00348 #ifdef P_USE_PRAGMA
00349 #pragma interface
00350 #endif
00351 
00352 #include <opal/buildopts.h>
00353 #include <ptlib/sockets.h>
00354 
00355 
00356 class RTP_JitterBuffer;
00357 class PSTUNClient;
00358 class OpalSecurityMode;
00359 
00360 #if OPAL_RTP_AGGREGATE
00361 #include <ptclib/sockagg.h>
00362 #else
00363 typedef void * PHandleAggregator;
00364 typedef void * RTP_AggregatedHandle;
00365 #endif
00366 
00368 // 
00369 // class to hold the QoS definitions for an RTP channel
00370 
00371 class RTP_QOS : public PObject
00372 {
00373   PCLASSINFO(RTP_QOS,PObject);
00374   public:
00375     PQoS dataQoS;
00376     PQoS ctrlQoS;
00377 };
00378 
00380 // Real Time Protocol - IETF RFC1889 and RFC1890
00381 
00384 class RTP_DataFrame : public PBYTEArray
00385 {
00386   PCLASSINFO(RTP_DataFrame, PBYTEArray);
00387 
00388   public:
00389     RTP_DataFrame(PINDEX payloadSize = 2048);
00390     RTP_DataFrame(const BYTE * data, PINDEX len, BOOL dynamic = TRUE);
00391 
00392     enum {
00393       ProtocolVersion = 2,
00394       MinHeaderSize = 12,
00395       // Max Ethernet packet (1518 bytes) minus 802.3/CRC, 802.3, IP, UDP an RTP headers
00396       MaxEthernetPayloadSize = (1518-14-4-8-20-16-12)
00397     };
00398 
00399     enum PayloadTypes {
00400       PCMU,         // G.711 u-Law
00401       FS1016,       // Federal Standard 1016 CELP
00402       G721,         // ADPCM - Subsumed by G.726
00403       G726 = G721,
00404       GSM,          // GSM 06.10
00405       G7231,        // G.723.1 at 6.3kbps or 5.3 kbps
00406       DVI4_8k,      // DVI4 at 8kHz sample rate
00407       DVI4_16k,     // DVI4 at 16kHz sample rate
00408       LPC,          // LPC-10 Linear Predictive CELP
00409       PCMA,         // G.711 A-Law
00410       G722,         // G.722
00411       L16_Stereo,   // 16 bit linear PCM
00412       L16_Mono,     // 16 bit linear PCM
00413       G723,         // G.723
00414       CN,           // Confort Noise
00415       MPA,          // MPEG1 or MPEG2 audio
00416       G728,         // G.728 16kbps CELP
00417       DVI4_11k,     // DVI4 at 11kHz sample rate
00418       DVI4_22k,     // DVI4 at 22kHz sample rate
00419       G729,         // G.729 8kbps
00420       Cisco_CN,     // Cisco systems comfort noise (unofficial)
00421 
00422       CelB = 25,    // Sun Systems Cell-B video
00423       JPEG,         // Motion JPEG
00424       H261 = 31,    // H.261
00425       MPV,          // MPEG1 or MPEG2 video
00426       MP2T,         // MPEG2 transport system
00427       H263,         // H.263
00428 
00429       LastKnownPayloadType,
00430 
00431       DynamicBase = 96,
00432       MaxPayloadType = 127,
00433       IllegalPayloadType
00434     };
00435 
00436     typedef std::map<PayloadTypes, PayloadTypes> PayloadMapType;
00437 
00438     unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00439 
00440     BOOL GetExtension() const   { return (theArray[0]&0x10) != 0; }
00441     void SetExtension(BOOL ext);
00442 
00443     BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
00444     void SetMarker(BOOL m);
00445 
00446     PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00447     void         SetPayloadType(PayloadTypes t);
00448 
00449     WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00450     void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00451 
00452     DWORD GetTimestamp() const  { return *(PUInt32b *)&theArray[4]; }
00453     void  SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00454 
00455     DWORD GetSyncSource() const  { return *(PUInt32b *)&theArray[8]; }
00456     void  SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00457 
00458     PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00459     DWORD  GetContribSource(PINDEX idx) const;
00460     void   SetContribSource(PINDEX idx, DWORD src);
00461 
00462     PINDEX GetHeaderSize() const;
00463 
00464     int GetExtensionType() const; // -1 is no extension
00465     void   SetExtensionType(int type);
00466     PINDEX GetExtensionSize() const;
00467     BOOL   SetExtensionSize(PINDEX sz);
00468     BYTE * GetExtensionPtr() const;
00469 
00470     PINDEX GetPayloadSize() const { return payloadSize; }
00471     BOOL   SetPayloadSize(PINDEX sz);
00472     BYTE * GetPayloadPtr()     const { return (BYTE *)(theArray+GetHeaderSize()); }
00473 
00474     virtual void PrintOn(ostream & strm) const;
00475 
00476   protected:
00477     PINDEX payloadSize;
00478 
00479 #if PTRACING
00480     friend ostream & operator<<(ostream & o, PayloadTypes t);
00481 #endif
00482 };
00483 
00484 PLIST(RTP_DataFrameList, RTP_DataFrame);
00485 
00486 
00489 class RTP_ControlFrame : public PBYTEArray
00490 {
00491   PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00492 
00493   public:
00494     RTP_ControlFrame(PINDEX compoundSize = 2048);
00495 
00496     unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00497 
00498     unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00499     void     SetCount(unsigned count);
00500 
00501     enum PayloadTypes {
00502       e_IntraFrameRequest = 192,
00503       e_SenderReport = 200,
00504       e_ReceiverReport,
00505       e_SourceDescription,
00506       e_Goodbye,
00507       e_ApplDefined
00508     };
00509 
00510     unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00511     void     SetPayloadType(unsigned t);
00512 
00513     PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00514     void   SetPayloadSize(PINDEX sz);
00515 
00516     BYTE * GetPayloadPtr() const;
00517 
00518     BOOL ReadNextPacket();
00519     BOOL StartNewPacket();
00520     void EndPacket();
00521 
00522     PINDEX GetCompoundSize() const;
00523 
00524     BOOL GetPadding() const { return theArray[compoundOffset & 0x20] != 0; }
00525     void SetPadding(BOOL v) { if (v) theArray[compoundOffset] |= 0x20; else theArray[compoundOffset] &= 0xdf; }
00526 
00527     void Reset(PINDEX size);
00528 
00529 #pragma pack(1)
00530     struct ReceiverReport {
00531       PUInt32b ssrc;      /* data source being reported */
00532       BYTE fraction;      /* fraction lost since last SR/RR */
00533       BYTE lost[3];       /* cumulative number of packets lost (signed!) */
00534       PUInt32b last_seq;  /* extended last sequence number received */
00535       PUInt32b jitter;    /* interarrival jitter */
00536       PUInt32b lsr;       /* last SR packet from this source */
00537       PUInt32b dlsr;      /* delay since last SR packet */
00538 
00539       unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00540       void SetLostPackets(unsigned lost);
00541     };
00542 
00543     struct SenderReport {
00544       PUInt32b ntp_sec;   /* NTP timestamp */
00545       PUInt32b ntp_frac;
00546       PUInt32b rtp_ts;    /* RTP timestamp */
00547       PUInt32b psent;     /* packets sent */
00548       PUInt32b osent;     /* octets sent */ 
00549     };
00550 
00551     enum DescriptionTypes {
00552       e_END,
00553       e_CNAME,
00554       e_NAME,
00555       e_EMAIL,
00556       e_PHONE,
00557       e_LOC,
00558       e_TOOL,
00559       e_NOTE,
00560       e_PRIV,
00561       NumDescriptionTypes
00562     };
00563 
00564     struct SourceDescription {
00565       PUInt32b src;       /* first SSRC/CSRC */
00566       struct Item {
00567         BYTE type;        /* type of SDES item (enum DescriptionTypes) */
00568         BYTE length;      /* length of SDES item (in octets) */
00569         char data[1];     /* text, not zero-terminated */
00570 
00571         /* WARNING, SourceDescription may not be big enough to contain length and data, for 
00572            instance, when type == RTP_ControlFrame::e_END.
00573            Be careful whan calling the following function of it may read to over to 
00574            memory allocated*/
00575         unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);} 
00576         const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00577         Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00578       } item[1];          /* list of SDES items */
00579     };
00580 
00581     void StartSourceDescription(
00582       DWORD src   
00583     );
00584 
00585     void AddSourceDescriptionItem(
00586       unsigned type,            
00587       const PString & data      
00588     );
00589 #pragma pack()
00590 
00591   protected:
00592     PINDEX compoundOffset;
00593     PINDEX payloadSize;
00594 };
00595 
00596 
00597 class RTP_Session;
00598 
00603 class RTP_UserData : public PObject
00604 {
00605   PCLASSINFO(RTP_UserData, PObject);
00606 
00607   public:
00614     virtual void OnTxStatistics(
00615       const RTP_Session & session   
00616     ) const;
00617 
00624     virtual void OnRxStatistics(
00625       const RTP_Session & session   
00626     ) const;
00627 
00628 #if OPAL_VIDEO
00629 
00634     virtual void OnTxIntraFrameRequest(
00635       const RTP_Session & session   
00636     ) const;
00637 
00643     virtual void OnRxIntraFrameRequest(
00644       const RTP_Session & session   
00645     ) const;
00646 #endif
00647 };
00648 
00649 
00652 class RTP_Session : public PObject
00653 {
00654   PCLASSINFO(RTP_Session, PObject);
00655 
00656   public:
00661     RTP_Session(
00662       PHandleAggregator * aggregator, 
00663       unsigned id,                    
00664       RTP_UserData * userData = NULL, 
00665       BOOL autoDeleteUserData = TRUE  
00666     );
00667 
00671     ~RTP_Session();
00673 
00685     void SetJitterBufferSize(
00686       unsigned minJitterDelay, 
00687       unsigned maxJitterDelay, 
00688       unsigned timeUnits = 8,  
00689       PINDEX stackSize = 30000 
00690     );
00691 
00697     unsigned GetJitterBufferSize() const;
00698     
00701     unsigned GetJitterTimeUnits() const;
00702 
00704     virtual BOOL ModifyQOS(RTP_QOS * )
00705     { return FALSE; }
00706 
00712     virtual BOOL ReadBufferedData(
00713       DWORD timestamp,        
00714       RTP_DataFrame & frame   
00715     );
00716 
00722     virtual BOOL ReadData(
00723       RTP_DataFrame & frame,  
00724       BOOL loop               
00725     ) = 0;
00726 
00729     virtual BOOL WriteData(
00730       RTP_DataFrame & frame   
00731     ) = 0;
00732 
00736     virtual BOOL WriteOOBData(
00737       RTP_DataFrame & frame
00738     );
00739 
00742     virtual BOOL WriteControl(
00743       RTP_ControlFrame & frame    
00744     ) = 0;
00745 
00748     virtual BOOL SendReport();
00749 
00752     virtual void Close(
00753       BOOL reading    
00754     ) = 0;
00755 
00758     virtual void Reopen(
00759       BOOL isReading
00760     ) = 0;
00761 
00764     virtual PString GetLocalHostName() = 0;
00766 
00769     enum SendReceiveStatus {
00770       e_ProcessPacket,
00771       e_IgnorePacket,
00772       e_AbortTransport
00773     };
00774     virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00775     virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00776     virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
00777     virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00778 
00779     class ReceiverReport : public PObject  {
00780         PCLASSINFO(ReceiverReport, PObject);
00781       public:
00782         void PrintOn(ostream &) const;
00783 
00784         DWORD sourceIdentifier;
00785         DWORD fractionLost;         /* fraction lost since last SR/RR */
00786         DWORD totalLost;            /* cumulative number of packets lost (signed!) */
00787         DWORD lastSequenceNumber;   /* extended last sequence number received */
00788         DWORD jitter;               /* interarrival jitter */
00789         PTimeInterval lastTimestamp;/* last SR packet from this source */
00790         PTimeInterval delay;        /* delay since last SR packet */
00791     };
00792     PARRAY(ReceiverReportArray, ReceiverReport);
00793 
00794     class SenderReport : public PObject  {
00795         PCLASSINFO(SenderReport, PObject);
00796       public:
00797         void PrintOn(ostream &) const;
00798 
00799         DWORD sourceIdentifier;
00800         PTime realTimestamp;
00801         DWORD rtpTimestamp;
00802         DWORD packetsSent;
00803         DWORD octetsSent;
00804     };
00805     virtual void OnRxSenderReport(const SenderReport & sender,
00806                                   const ReceiverReportArray & reports);
00807     virtual void OnRxReceiverReport(DWORD src,
00808                                     const ReceiverReportArray & reports);
00809 
00810     class SourceDescription : public PObject  {
00811         PCLASSINFO(SourceDescription, PObject);
00812       public:
00813         SourceDescription(DWORD src) { sourceIdentifier = src; }
00814         void PrintOn(ostream &) const;
00815 
00816         DWORD            sourceIdentifier;
00817         POrdinalToString items;
00818     };
00819     PARRAY(SourceDescriptionArray, SourceDescription);
00820     virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00821 
00822     virtual void OnRxGoodbye(const PDWORDArray & sources,
00823                              const PString & reason);
00824 
00825     virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00826                                  const BYTE * data, PINDEX size);
00828 
00833     unsigned GetSessionID() const { return sessionID; }
00834 
00837     PString GetCanonicalName() const;
00838 
00841     void SetCanonicalName(const PString & name);
00842 
00845     PString GetToolName() const;
00846 
00849     void SetToolName(const PString & name);
00850 
00853     RTP_UserData * GetUserData() const { return userData; }
00854 
00857     void SetUserData(
00858       RTP_UserData * data,            
00859       BOOL autoDeleteUserData = TRUE  
00860     );
00861 
00864     DWORD GetSyncSourceOut() const { return syncSourceOut; }
00865 
00868     void IncrementReference() { referenceCount++; }
00869 
00872     BOOL DecrementReference() { return --referenceCount == 0; }
00873 
00876     BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
00877 
00880     void SetIgnoreOtherSources(
00881       BOOL ignore   
00882     ) { ignoreOtherSources = ignore; }
00883 
00886     BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00887 
00890     void SetIgnoreOutOfOrderPackets(
00891       BOOL ignore   
00892     ) { ignoreOutOfOrderPackets = ignore; }
00893 
00896     void SetIgnorePayloadTypeChanges(
00897       BOOL ignore   
00898     ) { ignorePayloadTypeChanges = ignore; }
00899 
00902     const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00903 
00906     void SetReportTimeInterval(
00907       const PTimeInterval & interval 
00908     )  { reportTimeInterval = interval; }
00909 
00912     PTimeInterval GetReportTimer()
00913     { return reportTimer; }
00914 
00917     unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00918 
00921     void SetTxStatisticsInterval(
00922       unsigned packets   
00923     );
00924 
00927     unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00928 
00931     void SetRxStatisticsInterval(
00932       unsigned packets   
00933     );
00934 
00937     DWORD GetPacketsSent() const { return packetsSent; }
00938 
00941     DWORD GetOctetsSent() const { return octetsSent; }
00942 
00945     DWORD GetPacketsReceived() const { return packetsReceived; }
00946 
00949     DWORD GetOctetsReceived() const { return octetsReceived; }
00950 
00953     DWORD GetPacketsLost() const { return packetsLost; }
00954 
00957     DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00958 
00961     DWORD GetPacketsTooLate() const;
00962 
00967     DWORD GetAverageSendTime() const { return averageSendTime; }
00968 
00973     DWORD GetMarkerRecvCount() const { return markerRecvCount; }
00974 
00979     DWORD GetMarkerSendCount() const { return markerSendCount; }
00980 
00985     DWORD GetMaximumSendTime() const { return maximumSendTime; }
00986 
00991     DWORD GetMinimumSendTime() const { return minimumSendTime; }
00992 
00997     DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00998 
01003     DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
01004 
01009     DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
01010 
01015     DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
01016 
01020     DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
01022 
01025     virtual int GetDataSocketHandle() const
01026     { return -1; }
01027     virtual int GetControlSocketHandle() const
01028     { return -1; }
01030 
01031     virtual void SendBYE();
01032     virtual void SetCloseOnBYE(BOOL v)  { closeOnBye = v; }
01033 #if OPAL_VIDEO
01034 
01038     virtual void SendIntraFrameRequest();
01039 #endif    
01040   protected:
01041     void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
01042     BOOL InsertReportPacket(RTP_ControlFrame & report);
01043 
01044     unsigned           sessionID;
01045     PString            canonicalName;
01046     PString            toolName;
01047     unsigned           referenceCount;
01048     RTP_UserData     * userData;
01049     BOOL               autoDeleteUserData;
01050     RTP_JitterBuffer * jitter;
01051 
01052     BOOL          ignoreOtherSources;
01053     BOOL          ignoreOutOfOrderPackets;
01054     DWORD         syncSourceOut;
01055     DWORD         syncSourceIn;
01056     DWORD         lastSentTimestamp;
01057     BOOL                allowSyncSourceInChange;
01058     BOOL                allowRemoteTransmitAddressChange;
01059     BOOL                allowSequenceChange;
01060     PTimeInterval reportTimeInterval;
01061     unsigned      txStatisticsInterval;
01062     unsigned      rxStatisticsInterval;
01063     WORD          lastSentSequenceNumber;
01064     WORD          expectedSequenceNumber;
01065     PTimeInterval lastSentPacketTime;
01066     PTimeInterval lastReceivedPacketTime;
01067     WORD          lastRRSequenceNumber;
01068     PINDEX        consecutiveOutOfOrderPackets;
01069 
01070     PMutex        sendDataMutex;
01071     DWORD         timeStampOut;               // current timestamp for this session
01072     DWORD         timeStampOffs;              // offset between incoming media timestamp and timeStampOut
01073     BOOL          timeStampOffsetEstablished; // TRUE if timeStampOffs has been established by media
01074     BOOL          timeStampIsPremedia;        // TRUE if timeStampOutTick has been initialised
01075 
01076     // Statistics
01077     DWORD packetsSent;
01078     DWORD rtcpPacketsSent;
01079     DWORD octetsSent;
01080     DWORD packetsReceived;
01081     DWORD octetsReceived;
01082     DWORD packetsLost;
01083     DWORD packetsOutOfOrder;
01084     DWORD averageSendTime;
01085     DWORD maximumSendTime;
01086     DWORD minimumSendTime;
01087     DWORD averageReceiveTime;
01088     DWORD maximumReceiveTime;
01089     DWORD minimumReceiveTime;
01090     DWORD jitterLevel;
01091     DWORD maximumJitterLevel;
01092 
01093     DWORD markerSendCount;
01094     DWORD markerRecvCount;
01095 
01096     unsigned txStatisticsCount;
01097     unsigned rxStatisticsCount;
01098 
01099     DWORD    averageSendTimeAccum;
01100     DWORD    maximumSendTimeAccum;
01101     DWORD    minimumSendTimeAccum;
01102     DWORD    averageReceiveTimeAccum;
01103     DWORD    maximumReceiveTimeAccum;
01104     DWORD    minimumReceiveTimeAccum;
01105     DWORD    packetsLostSinceLastRR;
01106     DWORD    lastTransitTime;
01107     
01108     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
01109     BOOL ignorePayloadTypeChanges;
01110 
01111     PMutex reportMutex;
01112     PTimer reportTimer;
01113 
01114     PHandleAggregator * aggregator;
01115 
01116     BOOL closeOnBye;
01117     BOOL byeSent;
01118 };
01119 
01120 
01123 class RTP_SessionManager : public PObject
01124 {
01125   PCLASSINFO(RTP_SessionManager, PObject);
01126 
01127   public:
01132     RTP_SessionManager();
01133     RTP_SessionManager(const RTP_SessionManager & sm);
01134     RTP_SessionManager & operator=(const RTP_SessionManager & sm);
01136 
01137 
01151     RTP_Session * UseSession(
01152       unsigned sessionID    
01153     );
01154 
01161     void AddSession(
01162       RTP_Session * session    
01163     );
01164 
01168     void ReleaseSession(
01169       unsigned sessionID,    
01170       BOOL clearAll = FALSE  
01171     );
01172 
01177     RTP_Session * GetSession(
01178       unsigned sessionID    
01179     ) const;
01180 
01197     RTP_Session * First();
01198 
01205     RTP_Session * Next();
01206 
01214     void Exit();
01216 
01217 
01218   protected:
01219     PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
01220     SessionDict sessions;
01221     PMutex      mutex;
01222     PINDEX      enumerationIndex;
01223 };
01224 
01225 
01226 
01229 class RTP_UDP : public RTP_Session
01230 {
01231   PCLASSINFO(RTP_UDP, RTP_Session);
01232 
01233   public:
01238     RTP_UDP(
01239       PHandleAggregator * aggregator, 
01240       unsigned id,                    
01241       BOOL remoteIsNAT                
01242     );
01243 
01245     ~RTP_UDP();
01247 
01255     virtual BOOL ReadData(RTP_DataFrame & frame, BOOL loop);
01256 
01259     virtual BOOL WriteData(RTP_DataFrame & frame);
01260 
01264     virtual BOOL WriteOOBData(RTP_DataFrame & frame);
01265 
01268     virtual BOOL WriteControl(RTP_ControlFrame & frame);
01269 
01272     virtual void Close(
01273       BOOL reading    
01274     );
01275 
01278     virtual PString GetLocalHostName();
01280 
01283     virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
01284 
01289     virtual BOOL Open(
01290       PIPSocket::Address localAddress,  
01291       WORD portBase,                    
01292       WORD portMax,                     
01293       BYTE ipTypeOfService,             
01294       PSTUNClient * stun = NULL,        
01295       RTP_QOS * rtpqos = NULL           
01296     );
01298 
01301     virtual void Reopen(BOOL isReading);
01303 
01308     virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
01309 
01312     virtual void SetLocalAddress(
01313       const PIPSocket::Address & addr
01314     ) { localAddress = addr; }
01315 
01318     PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01319 
01322     virtual WORD GetLocalDataPort() const { return localDataPort; }
01323 
01326     virtual WORD GetLocalControlPort() const { return localControlPort; }
01327 
01330     virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
01331 
01334     virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
01335 
01338     virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
01339 
01342     virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
01343 
01346     virtual BOOL SetRemoteSocketInfo(
01347       PIPSocket::Address address,   
01348       WORD port,                    
01349       BOOL isDataPort               
01350     );
01351 
01354     virtual void ApplyQOS(
01355       const PIPSocket::Address & addr
01356     );
01358 
01359     virtual int GetDataSocketHandle() const
01360     { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01361 
01362     virtual int GetControlSocketHandle() const
01363     { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01364 
01365   protected:
01366     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01367     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01368     virtual SendReceiveStatus ReadControlPDU();
01369     virtual SendReceiveStatus ReadDataOrControlPDU(
01370       PUDPSocket & socket,
01371       PBYTEArray & frame,
01372       BOOL fromDataChannel
01373     );
01374 
01375     PIPSocket::Address localAddress;
01376     WORD               localDataPort;
01377     WORD               localControlPort;
01378 
01379     PIPSocket::Address remoteAddress;
01380     WORD               remoteDataPort;
01381     WORD               remoteControlPort;
01382 
01383     PIPSocket::Address remoteTransmitAddress;
01384 
01385     BOOL shutdownRead;
01386     BOOL shutdownWrite;
01387 
01388     PUDPSocket * dataSocket;
01389     PUDPSocket * controlSocket;
01390 
01391     BOOL appliedQOS;
01392     BOOL remoteIsNAT;
01393     BOOL first;
01394 };
01395 
01397 
01398 class SecureRTP_UDP : public RTP_UDP
01399 {
01400   PCLASSINFO(SecureRTP_UDP, RTP_UDP);
01401 
01402   public:
01407     SecureRTP_UDP(
01408       PHandleAggregator * aggregator, 
01409       unsigned id,                    
01410       BOOL remoteIsNAT                
01411     );
01412 
01414     ~SecureRTP_UDP();
01415 
01416     virtual void SetSecurityMode(OpalSecurityMode * srtpParms);  
01417     virtual OpalSecurityMode * GetSecurityParms() const;
01418 
01419   protected:
01420     OpalSecurityMode * securityParms;
01421 };
01422 
01423 #endif // __OPAL_RTP_H
01424 

Generated on Fri Mar 7 06:33:41 2008 for OPAL by  doxygen 1.5.1