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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 #ifndef __OPAL_RTP_H
00247 #define __OPAL_RTP_H
00248
00249 #ifdef P_USE_PRAGMA
00250 #pragma interface
00251 #endif
00252
00253 #include <openh323buildopts.h>
00254 #include <ptlib/sockets.h>
00255
00256 class RTP_JitterBuffer;
00257 class PHandleAggregator;
00258
00259 #ifdef P_STUN
00260 class PNatMethod;
00261 #endif
00262
00264
00265
00266
00267 #if P_HAS_QOS
00268
00269 class RTP_QOS : public PObject
00270 {
00271 PCLASSINFO(RTP_QOS,PObject);
00272 public:
00273 PQoS dataQoS;
00274 PQoS ctrlQoS;
00275 };
00276
00277 #else
00278
00279 class RTP_QOS;
00280
00281 #endif
00282
00284
00285
00288 class RTP_DataFrame : public PBYTEArray
00289 {
00290 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00291
00292 public:
00293 RTP_DataFrame(PINDEX payloadSize = 2048, BOOL dynamicAllocation = TRUE);
00294
00295 enum {
00296 ProtocolVersion = 2,
00297 MinHeaderSize = 12
00298 };
00299
00300 enum PayloadTypes {
00301 PCMU,
00302 FS1016,
00303 G721,
00304 G726 = G721,
00305 GSM,
00306 G7231,
00307 DVI4_8k,
00308 DVI4_16k,
00309 LPC,
00310 PCMA,
00311 G722,
00312 L16_Stereo,
00313 L16_Mono,
00314 G723,
00315 CN,
00316 MPA,
00317 G728,
00318 DVI4_11k,
00319 DVI4_22k,
00320 G729,
00321 Cisco_CN,
00322
00323 CelB = 25,
00324 JPEG,
00325 H261 = 31,
00326 MPV,
00327 MP2T,
00328 H263,
00329
00330 LastKnownPayloadType,
00331
00332 DynamicBase = 96,
00333 MaxPayloadType = 127,
00334 IllegalPayloadType
00335 };
00336
00337 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00338
00339 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; }
00340 void SetExtension(BOOL ext);
00341
00342 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
00343 void SetMarker(BOOL m);
00344
00345 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00346 void SetPayloadType(PayloadTypes t);
00347
00348 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00349 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00350
00351 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00352 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00353
00354 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00355 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00356
00357 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00358 DWORD GetContribSource(PINDEX idx) const;
00359 void SetContribSource(PINDEX idx, DWORD src);
00360
00361 PINDEX GetHeaderSize() const;
00362
00363 int GetExtensionType() const;
00364 void SetExtensionType(int type);
00365 PINDEX GetExtensionSize() const;
00366 BOOL SetExtensionSize(PINDEX sz);
00367 BYTE * GetExtensionPtr() const;
00368
00369 PINDEX GetPayloadSize() const { return payloadSize; }
00370 BOOL SetPayloadSize(PINDEX sz);
00371 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); }
00372
00373 protected:
00374 PINDEX payloadSize;
00375
00376 #if PTRACING
00377 friend ostream & operator<<(ostream & o, PayloadTypes t);
00378 #endif
00379 };
00380
00381 PLIST(RTP_DataFrameList, RTP_DataFrame);
00382
00383
00386 class RTP_ControlFrame : public PBYTEArray
00387 {
00388 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00389
00390 public:
00391 RTP_ControlFrame(PINDEX compoundSize = 2048);
00392
00393 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00394
00395 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00396 void SetCount(unsigned count);
00397
00398 enum PayloadTypes {
00399 e_SenderReport = 200,
00400 e_ReceiverReport,
00401 e_SourceDescription,
00402 e_Goodbye,
00403 e_ApplDefined
00404 };
00405
00406 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00407 void SetPayloadType(unsigned t);
00408
00409 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00410 void SetPayloadSize(PINDEX sz);
00411
00412 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); }
00413
00414 BOOL ReadNextCompound();
00415 BOOL WriteNextCompound();
00416
00417 PINDEX GetCompoundSize() const { return compoundSize; }
00418
00419 #pragma pack(1)
00420 struct ReceiverReport {
00421 PUInt32b ssrc;
00422 BYTE fraction;
00423 BYTE lost[3];
00424 PUInt32b last_seq;
00425 PUInt32b jitter;
00426 PUInt32b lsr;
00427 PUInt32b dlsr;
00428
00429 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00430 void SetLostPackets(unsigned lost);
00431 };
00432
00433 struct SenderReport {
00434 PUInt32b ssrc;
00435 PUInt32b ntp_sec;
00436 PUInt32b ntp_frac;
00437 PUInt32b rtp_ts;
00438 PUInt32b psent;
00439 PUInt32b osent;
00440 };
00441
00442 enum DescriptionTypes {
00443 e_END,
00444 e_CNAME,
00445 e_NAME,
00446 e_EMAIL,
00447 e_PHONE,
00448 e_LOC,
00449 e_TOOL,
00450 e_NOTE,
00451 e_PRIV,
00452 NumDescriptionTypes
00453 };
00454
00455 struct SourceDescription {
00456 PUInt32b src;
00457 struct Item {
00458 BYTE type;
00459 BYTE length;
00460 char data[1];
00461
00462 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00463 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00464 } item[1];
00465 };
00466
00467 SourceDescription & AddSourceDescription(
00468 DWORD src
00469 );
00470
00471 SourceDescription::Item & AddSourceDescriptionItem(
00472 SourceDescription & sdes,
00473 unsigned type,
00474 const PString & data
00475 );
00476 #pragma pack()
00477
00478 protected:
00479 PINDEX compoundOffset;
00480 PINDEX compoundSize;
00481 };
00482
00483
00484 class RTP_Session;
00485
00490 class RTP_UserData : public PObject
00491 {
00492 PCLASSINFO(RTP_UserData, PObject);
00493
00494 public:
00501 virtual void OnTxStatistics(
00502 const RTP_Session & session
00503 ) const;
00504
00511 virtual void OnRxStatistics(
00512 const RTP_Session & session
00513 ) const;
00514
00521 virtual void OnFinalStatistics(
00522 const RTP_Session & session
00523 ) const;
00524 };
00525
00526
00529 class RTP_UDP;
00530 class RTP_Session : public PObject
00531 {
00532 PCLASSINFO(RTP_Session, PObject);
00533
00534 public:
00535 enum {
00536 DefaultAudioSessionID = 1,
00537 DefaultVideoSessionID = 2,
00538 DefaultFaxSessionID = 3,
00539 DefaultExtVideoSessionID = 5
00540 };
00541
00546 RTP_Session(
00547 #ifdef H323_RTP_AGGREGATE
00548 PHandleAggregator * aggregator,
00549 #endif
00550 unsigned id,
00551 RTP_UserData * userData = NULL
00552 );
00553
00557 ~RTP_Session();
00559
00571 void SetJitterBufferSize(
00572 unsigned minJitterDelay,
00573 unsigned maxJitterDelay,
00574 PINDEX stackSize = 30000
00575 );
00576
00582 unsigned GetJitterBufferSize() const;
00583
00585 virtual BOOL ModifyQOS(RTP_QOS * )
00586 { return FALSE; }
00587
00593 BOOL ReadBufferedData(
00594 DWORD timestamp,
00595 RTP_DataFrame & frame
00596 );
00597
00603 virtual BOOL ReadData(
00604 RTP_DataFrame & frame,
00605 BOOL loop
00606 ) = 0;
00607
00610 virtual BOOL WriteData(
00611 RTP_DataFrame & frame
00612 ) = 0;
00613
00616 virtual BOOL WriteControl(
00617 RTP_ControlFrame & frame
00618 ) = 0;
00619
00622 virtual BOOL SendReport();
00623
00626 virtual void Close(
00627 BOOL reading
00628 ) = 0;
00629
00632 virtual PString GetLocalHostName() = 0;
00634
00637 enum SendReceiveStatus {
00638 e_ProcessPacket,
00639 e_IgnorePacket,
00640 e_AbortTransport
00641 };
00642 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00643 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame, const RTP_UDP & rtp);
00644 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00645
00646 class ReceiverReport : public PObject {
00647 PCLASSINFO(ReceiverReport, PObject);
00648 public:
00649 void PrintOn(ostream &) const;
00650
00651 DWORD sourceIdentifier;
00652 DWORD fractionLost;
00653 DWORD totalLost;
00654 DWORD lastSequenceNumber;
00655 DWORD jitter;
00656 PTimeInterval lastTimestamp;
00657 PTimeInterval delay;
00658 };
00659 PARRAY(ReceiverReportArray, ReceiverReport);
00660
00661 class SenderReport : public PObject {
00662 PCLASSINFO(SenderReport, PObject);
00663 public:
00664 void PrintOn(ostream &) const;
00665
00666 DWORD sourceIdentifier;
00667 PTime realTimestamp;
00668 DWORD rtpTimestamp;
00669 DWORD packetsSent;
00670 DWORD octetsSent;
00671 };
00672 virtual void OnRxSenderReport(const SenderReport & sender,
00673 const ReceiverReportArray & reports);
00674 virtual void OnRxReceiverReport(DWORD src,
00675 const ReceiverReportArray & reports);
00676
00677 class SourceDescription : public PObject {
00678 PCLASSINFO(SourceDescription, PObject);
00679 public:
00680 SourceDescription(DWORD src) { sourceIdentifier = src; }
00681 void PrintOn(ostream &) const;
00682
00683 DWORD sourceIdentifier;
00684 POrdinalToString items;
00685 };
00686 PARRAY(SourceDescriptionArray, SourceDescription);
00687 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00688
00689 virtual void OnRxGoodbye(const PDWORDArray & sources,
00690 const PString & reason);
00691
00692 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00693 const BYTE * data, PINDEX size);
00695
00700 unsigned GetSessionID() const { return sessionID; }
00701
00704 PString GetCanonicalName() const;
00705
00708 void SetCanonicalName(const PString & name);
00709
00712 PString GetToolName() const;
00713
00716 void SetToolName(const PString & name);
00717
00720 RTP_UserData * GetUserData() const { return userData; }
00721
00724 void SetUserData(
00725 RTP_UserData * data
00726 );
00727
00730 DWORD GetSyncSourceOut() const { return syncSourceOut; }
00731
00734 void IncrementReference() { referenceCount++; }
00735
00738 BOOL DecrementReference() { return --referenceCount == 0; }
00739
00742 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
00743
00746 void SetIgnoreOtherSources(
00747 BOOL ignore
00748 ) { ignoreOtherSources = ignore; }
00749
00752 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00753
00756 void SetIgnoreOutOfOrderPackets(
00757 BOOL ignore
00758 ) { ignoreOutOfOrderPackets = ignore; }
00759
00762 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00763
00766 void SetReportTimeInterval(
00767 const PTimeInterval & interval
00768 ) { reportTimeInterval = interval; }
00769
00772 PTimeInterval GetReportTimer()
00773 { return reportTimer; }
00774
00777 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00778
00781 void SetTxStatisticsInterval(
00782 unsigned packets
00783 );
00784
00787 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00788
00791 void SetRxStatisticsInterval(
00792 unsigned packets
00793 );
00794
00797 DWORD GetPacketsSent() const { return packetsSent; }
00798
00801 DWORD GetOctetsSent() const { return octetsSent; }
00802
00805 DWORD GetPacketsReceived() const { return packetsReceived; }
00806
00809 DWORD GetOctetsReceived() const { return octetsReceived; }
00810
00813 DWORD GetPacketsLost() const { return packetsLost; }
00814
00817 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00818
00821 DWORD GetPacketsTooLate() const;
00822
00827 DWORD GetAverageSendTime() const { return averageSendTime; }
00828
00833 DWORD GetMaximumSendTime() const { return maximumSendTime; }
00834
00839 DWORD GetMinimumSendTime() const { return minimumSendTime; }
00840
00845 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00846
00851 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00852
00857 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00858
00863 DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00864
00868 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00869
00873 PTime GetFirstDataReceivedTime() const { return firstDataReceivedTime; }
00874
00878 PString GetLocalTransportAddress() const { return localAddress; };
00879
00883 PString GetRemoteTransportAddress() const { return remoteAddress; };
00884
00886
00889 virtual int GetDataSocketHandle() const
00890 { return -1; }
00891 virtual int GetControlSocketHandle() const
00892 { return -1; }
00894
00895 protected:
00896 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00897
00898 unsigned sessionID;
00899 PString canonicalName;
00900 PString toolName;
00901 unsigned referenceCount;
00902 RTP_UserData * userData;
00903
00904 #ifndef NO_H323_AUDIO_CODECS
00905 RTP_JitterBuffer * jitter;
00906 #endif
00907
00908 BOOL ignoreOtherSources;
00909 BOOL ignoreOutOfOrderPackets;
00910 DWORD syncSourceOut;
00911 DWORD syncSourceIn;
00912 PTimeInterval reportTimeInterval;
00913 unsigned txStatisticsInterval;
00914 unsigned rxStatisticsInterval;
00915 WORD lastSentSequenceNumber;
00916 WORD expectedSequenceNumber;
00917 DWORD lastSentTimestamp;
00918 PTimeInterval lastSentPacketTime;
00919 PTimeInterval lastReceivedPacketTime;
00920 WORD lastRRSequenceNumber;
00921 PINDEX consecutiveOutOfOrderPackets;
00922
00923
00924 DWORD packetsSent;
00925 DWORD octetsSent;
00926 DWORD packetsReceived;
00927 DWORD octetsReceived;
00928 DWORD packetsLost;
00929 DWORD packetsOutOfOrder;
00930 DWORD averageSendTime;
00931 DWORD maximumSendTime;
00932 DWORD minimumSendTime;
00933 DWORD averageReceiveTime;
00934 DWORD maximumReceiveTime;
00935 DWORD minimumReceiveTime;
00936 DWORD jitterLevel;
00937 DWORD maximumJitterLevel;
00938
00939
00940 PString localAddress;
00941 PString remoteAddress;
00942
00943 unsigned txStatisticsCount;
00944 unsigned rxStatisticsCount;
00945
00946 DWORD averageSendTimeAccum;
00947 DWORD maximumSendTimeAccum;
00948 DWORD minimumSendTimeAccum;
00949 DWORD averageReceiveTimeAccum;
00950 DWORD maximumReceiveTimeAccum;
00951 DWORD minimumReceiveTimeAccum;
00952 DWORD packetsLostSinceLastRR;
00953 DWORD lastTransitTime;
00954 PTime firstDataReceivedTime;
00955
00956 PMutex reportMutex;
00957 PTimer reportTimer;
00958
00959 #ifdef H323_RTP_AGGREGATE
00960 PHandleAggregator * aggregator;
00961 #endif
00962 };
00963
00964
00967 class RTP_SessionManager : public PObject
00968 {
00969 PCLASSINFO(RTP_SessionManager, PObject);
00970
00971 public:
00976 RTP_SessionManager();
00977 RTP_SessionManager(const RTP_SessionManager & sm);
00978 RTP_SessionManager & operator=(const RTP_SessionManager & sm);
00980
00981
00995 RTP_Session * UseSession(
00996 unsigned sessionID
00997 );
00998
01005 void AddSession(
01006 RTP_Session * session
01007 );
01008
01012 void ReleaseSession(
01013 unsigned sessionID
01014 );
01015
01020 RTP_Session * GetSession(
01021 unsigned sessionID
01022 ) const;
01023
01040 RTP_Session * First();
01041
01048 RTP_Session * Next();
01049
01057 void Exit();
01059
01060
01061 protected:
01062 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
01063 SessionDict sessions;
01064 PMutex mutex;
01065 PINDEX enumerationIndex;
01066 };
01067
01068
01069
01072 class RTP_UDP : public RTP_Session
01073 {
01074 PCLASSINFO(RTP_UDP, RTP_Session);
01075
01076 public:
01081 RTP_UDP(
01082 #ifdef H323_RTP_AGGREGATE
01083 PHandleAggregator * aggregator,
01084 #endif
01085 unsigned id,
01086 BOOL remoteIsNat = FALSE
01087 );
01088
01090 ~RTP_UDP();
01092
01100 virtual BOOL ReadData(RTP_DataFrame & frame, BOOL loop);
01101
01104 virtual BOOL WriteData(RTP_DataFrame & frame);
01105
01108 virtual BOOL WriteControl(RTP_ControlFrame & frame);
01109
01112 virtual void Close(
01113 BOOL reading
01114 );
01115
01118 virtual PString GetLocalHostName();
01120
01125 virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
01126
01129 virtual void EnableGQoS(BOOL success = TRUE);
01130
01131 #if P_HAS_QOS
01132
01134 PQoS & GetQOS();
01135 #endif
01136
01137
01142 BOOL Open(
01143 PIPSocket::Address localAddress,
01144 WORD portBase,
01145 WORD portMax,
01146 BYTE ipTypeOfService,
01147 #ifdef P_STUN
01148 PNatMethod * meth = NULL,
01149 #else
01150 void * = NULL,
01151 #endif
01152 RTP_QOS * rtpqos = NULL
01153 );
01155
01158 void Reopen(BOOL isReading);
01160
01165 PIPSocket::Address GetLocalAddress() const { return localAddress; }
01166
01169 void SetLocalAddress(
01170 const PIPSocket::Address & addr
01171 ) { localAddress = addr; }
01172
01175 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01176
01179 WORD GetLocalDataPort() const { return localDataPort; }
01180
01183 WORD GetLocalControlPort() const { return localControlPort; }
01184
01187 WORD GetRemoteDataPort() const { return remoteDataPort; }
01188
01191 WORD GetRemoteControlPort() const { return remoteControlPort; }
01192
01195 PUDPSocket & GetDataSocket() { return *dataSocket; }
01196
01199 PUDPSocket & GetControlSocket() { return *controlSocket; }
01200
01203 BOOL SetRemoteSocketInfo(
01204 PIPSocket::Address address,
01205 WORD port,
01206 BOOL isDataPort
01207 );
01208
01211 void ApplyQOS(
01212 const PIPSocket::Address & addr
01213 );
01215
01216 int GetDataSocketHandle() const
01217 { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01218
01219 int GetControlSocketHandle() const
01220 { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01221
01222 protected:
01223 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01224 SendReceiveStatus ReadControlPDU();
01225 SendReceiveStatus ReadDataOrControlPDU(
01226 PUDPSocket & socket,
01227 PBYTEArray & frame,
01228 BOOL fromDataChannel
01229 );
01230
01231 PIPSocket::Address localAddress;
01232 WORD localDataPort;
01233 WORD localControlPort;
01234
01235 PIPSocket::Address remoteAddress;
01236 WORD remoteDataPort;
01237 WORD remoteControlPort;
01238
01239 PIPSocket::Address remoteTransmitAddress;
01240
01241 BOOL shutdownRead;
01242 BOOL shutdownWrite;
01243
01244 PUDPSocket * dataSocket;
01245 PUDPSocket * controlSocket;
01246
01247 BOOL appliedQOS;
01248 BOOL enableGQOS;
01249
01250 BOOL remoteIsNAT;
01251 };
01252
01253
01254 #endif // __OPAL_RTP_H
01255
01256