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 #ifndef __OPAL_RTP_H
00229 #define __OPAL_RTP_H
00230
00231 #ifdef P_USE_PRAGMA
00232 #pragma interface
00233 #endif
00234
00235 #include <openh323buildopts.h>
00236 #include <ptlib/sockets.h>
00237
00238 class RTP_JitterBuffer;
00239 class PHandleAggregator;
00240
00241 #ifdef P_STUN
00242 class PNatMethod;
00243 #endif
00244
00246
00247
00248
00249 #if P_HAS_QOS
00250
00251 class RTP_QOS : public PObject
00252 {
00253 PCLASSINFO(RTP_QOS,PObject);
00254 public:
00255 PQoS dataQoS;
00256 PQoS ctrlQoS;
00257 };
00258
00259 #else
00260
00261 class RTP_QOS;
00262
00263 #endif
00264
00266
00267
00270 class RTP_DataFrame : public PBYTEArray
00271 {
00272 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00273
00274 public:
00275 RTP_DataFrame(PINDEX payloadSize = 2048);
00276
00277 enum {
00278 ProtocolVersion = 2,
00279 MinHeaderSize = 12
00280 };
00281
00282 enum PayloadTypes {
00283 PCMU,
00284 FS1016,
00285 G721,
00286 G726 = G721,
00287 GSM,
00288 G7231,
00289 DVI4_8k,
00290 DVI4_16k,
00291 LPC,
00292 PCMA,
00293 G722,
00294 L16_Stereo,
00295 L16_Mono,
00296 G723,
00297 CN,
00298 MPA,
00299 G728,
00300 DVI4_11k,
00301 DVI4_22k,
00302 G729,
00303 Cisco_CN,
00304
00305 CelB = 25,
00306 JPEG,
00307 H261 = 31,
00308 MPV,
00309 MP2T,
00310 H263,
00311
00312 LastKnownPayloadType,
00313
00314 DynamicBase = 96,
00315 MaxPayloadType = 127,
00316 IllegalPayloadType
00317 };
00318
00319 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00320
00321 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; }
00322 void SetExtension(BOOL ext);
00323
00324 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
00325 void SetMarker(BOOL m);
00326
00327 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00328 void SetPayloadType(PayloadTypes t);
00329
00330 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00331 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00332
00333 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00334 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00335
00336 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00337 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00338
00339 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00340 DWORD GetContribSource(PINDEX idx) const;
00341 void SetContribSource(PINDEX idx, DWORD src);
00342
00343 PINDEX GetHeaderSize() const;
00344
00345 int GetExtensionType() const;
00346 void SetExtensionType(int type);
00347 PINDEX GetExtensionSize() const;
00348 BOOL SetExtensionSize(PINDEX sz);
00349 BYTE * GetExtensionPtr() const;
00350
00351 PINDEX GetPayloadSize() const { return payloadSize; }
00352 BOOL SetPayloadSize(PINDEX sz);
00353 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); }
00354
00355 protected:
00356 PINDEX payloadSize;
00357
00358 #if PTRACING
00359 friend ostream & operator<<(ostream & o, PayloadTypes t);
00360 #endif
00361 };
00362
00363 PLIST(RTP_DataFrameList, RTP_DataFrame);
00364
00365
00368 class RTP_ControlFrame : public PBYTEArray
00369 {
00370 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00371
00372 public:
00373 RTP_ControlFrame(PINDEX compoundSize = 2048);
00374
00375 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00376
00377 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00378 void SetCount(unsigned count);
00379
00380 enum PayloadTypes {
00381 e_SenderReport = 200,
00382 e_ReceiverReport,
00383 e_SourceDescription,
00384 e_Goodbye,
00385 e_ApplDefined
00386 };
00387
00388 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00389 void SetPayloadType(unsigned t);
00390
00391 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00392 void SetPayloadSize(PINDEX sz);
00393
00394 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); }
00395
00396 BOOL ReadNextCompound();
00397 BOOL WriteNextCompound();
00398
00399 PINDEX GetCompoundSize() const { return compoundSize; }
00400
00401 #pragma pack(1)
00402 struct ReceiverReport {
00403 PUInt32b ssrc;
00404 BYTE fraction;
00405 BYTE lost[3];
00406 PUInt32b last_seq;
00407 PUInt32b jitter;
00408 PUInt32b lsr;
00409 PUInt32b dlsr;
00410
00411 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00412 void SetLostPackets(unsigned lost);
00413 };
00414
00415 struct SenderReport {
00416 PUInt32b ssrc;
00417 PUInt32b ntp_sec;
00418 PUInt32b ntp_frac;
00419 PUInt32b rtp_ts;
00420 PUInt32b psent;
00421 PUInt32b osent;
00422 };
00423
00424 enum DescriptionTypes {
00425 e_END,
00426 e_CNAME,
00427 e_NAME,
00428 e_EMAIL,
00429 e_PHONE,
00430 e_LOC,
00431 e_TOOL,
00432 e_NOTE,
00433 e_PRIV,
00434 NumDescriptionTypes
00435 };
00436
00437 struct SourceDescription {
00438 PUInt32b src;
00439 struct Item {
00440 BYTE type;
00441 BYTE length;
00442 char data[1];
00443
00444 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00445 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00446 } item[1];
00447 };
00448
00449 SourceDescription & AddSourceDescription(
00450 DWORD src
00451 );
00452
00453 SourceDescription::Item & AddSourceDescriptionItem(
00454 SourceDescription & sdes,
00455 unsigned type,
00456 const PString & data
00457 );
00458 #pragma pack()
00459
00460 protected:
00461 PINDEX compoundOffset;
00462 PINDEX compoundSize;
00463 };
00464
00465
00466 class RTP_Session;
00467
00472 class RTP_UserData : public PObject
00473 {
00474 PCLASSINFO(RTP_UserData, PObject);
00475
00476 public:
00483 virtual void OnTxStatistics(
00484 const RTP_Session & session
00485 ) const;
00486
00493 virtual void OnRxStatistics(
00494 const RTP_Session & session
00495 ) const;
00496 };
00497
00498
00501 class RTP_Session : public PObject
00502 {
00503 PCLASSINFO(RTP_Session, PObject);
00504
00505 public:
00506 enum {
00507 DefaultAudioSessionID = 1,
00508 DefaultVideoSessionID = 2,
00509 DefaultFaxSessionID = 3
00510 };
00511
00516 RTP_Session(
00517 #ifdef H323_RTP_AGGREGATE
00518 PHandleAggregator * aggregator,
00519 #endif
00520 unsigned id,
00521 RTP_UserData * userData = NULL
00522 );
00523
00527 ~RTP_Session();
00529
00541 void SetJitterBufferSize(
00542 unsigned minJitterDelay,
00543 unsigned maxJitterDelay,
00544 PINDEX stackSize = 30000
00545 );
00546
00552 unsigned GetJitterBufferSize() const;
00553
00555 virtual BOOL ModifyQOS(RTP_QOS * )
00556 { return FALSE; }
00557
00563 BOOL ReadBufferedData(
00564 DWORD timestamp,
00565 RTP_DataFrame & frame
00566 );
00567
00573 virtual BOOL ReadData(
00574 RTP_DataFrame & frame,
00575 BOOL loop
00576 ) = 0;
00577
00580 virtual BOOL WriteData(
00581 RTP_DataFrame & frame
00582 ) = 0;
00583
00586 virtual BOOL WriteControl(
00587 RTP_ControlFrame & frame
00588 ) = 0;
00589
00592 virtual BOOL SendReport();
00593
00596 virtual void Close(
00597 BOOL reading
00598 ) = 0;
00599
00602 virtual PString GetLocalHostName() = 0;
00604
00607 enum SendReceiveStatus {
00608 e_ProcessPacket,
00609 e_IgnorePacket,
00610 e_AbortTransport
00611 };
00612 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00613 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame);
00614 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00615
00616 class ReceiverReport : public PObject {
00617 PCLASSINFO(ReceiverReport, PObject);
00618 public:
00619 void PrintOn(ostream &) const;
00620
00621 DWORD sourceIdentifier;
00622 DWORD fractionLost;
00623 DWORD totalLost;
00624 DWORD lastSequenceNumber;
00625 DWORD jitter;
00626 PTimeInterval lastTimestamp;
00627 PTimeInterval delay;
00628 };
00629 PARRAY(ReceiverReportArray, ReceiverReport);
00630
00631 class SenderReport : public PObject {
00632 PCLASSINFO(SenderReport, PObject);
00633 public:
00634 void PrintOn(ostream &) const;
00635
00636 DWORD sourceIdentifier;
00637 PTime realTimestamp;
00638 DWORD rtpTimestamp;
00639 DWORD packetsSent;
00640 DWORD octetsSent;
00641 };
00642 virtual void OnRxSenderReport(const SenderReport & sender,
00643 const ReceiverReportArray & reports);
00644 virtual void OnRxReceiverReport(DWORD src,
00645 const ReceiverReportArray & reports);
00646
00647 class SourceDescription : public PObject {
00648 PCLASSINFO(SourceDescription, PObject);
00649 public:
00650 SourceDescription(DWORD src) { sourceIdentifier = src; }
00651 void PrintOn(ostream &) const;
00652
00653 DWORD sourceIdentifier;
00654 POrdinalToString items;
00655 };
00656 PARRAY(SourceDescriptionArray, SourceDescription);
00657 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00658
00659 virtual void OnRxGoodbye(const PDWORDArray & sources,
00660 const PString & reason);
00661
00662 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00663 const BYTE * data, PINDEX size);
00665
00670 unsigned GetSessionID() const { return sessionID; }
00671
00674 PString GetCanonicalName() const;
00675
00678 void SetCanonicalName(const PString & name);
00679
00682 PString GetToolName() const;
00683
00686 void SetToolName(const PString & name);
00687
00690 RTP_UserData * GetUserData() const { return userData; }
00691
00694 void SetUserData(
00695 RTP_UserData * data
00696 );
00697
00700 DWORD GetSyncSourceOut() const { return syncSourceOut; }
00701
00704 void IncrementReference() { referenceCount++; }
00705
00708 BOOL DecrementReference() { return --referenceCount == 0; }
00709
00712 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
00713
00716 void SetIgnoreOtherSources(
00717 BOOL ignore
00718 ) { ignoreOtherSources = ignore; }
00719
00722 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00723
00726 void SetIgnoreOutOfOrderPackets(
00727 BOOL ignore
00728 ) { ignoreOutOfOrderPackets = ignore; }
00729
00732 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00733
00736 void SetReportTimeInterval(
00737 const PTimeInterval & interval
00738 ) { reportTimeInterval = interval; }
00739
00742 PTimeInterval GetReportTimer()
00743 { return reportTimer; }
00744
00747 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00748
00751 void SetTxStatisticsInterval(
00752 unsigned packets
00753 );
00754
00757 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00758
00761 void SetRxStatisticsInterval(
00762 unsigned packets
00763 );
00764
00767 DWORD GetPacketsSent() const { return packetsSent; }
00768
00771 DWORD GetOctetsSent() const { return octetsSent; }
00772
00775 DWORD GetPacketsReceived() const { return packetsReceived; }
00776
00779 DWORD GetOctetsReceived() const { return octetsReceived; }
00780
00783 DWORD GetPacketsLost() const { return packetsLost; }
00784
00787 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00788
00791 DWORD GetPacketsTooLate() const;
00792
00797 DWORD GetAverageSendTime() const { return averageSendTime; }
00798
00803 DWORD GetMaximumSendTime() const { return maximumSendTime; }
00804
00809 DWORD GetMinimumSendTime() const { return minimumSendTime; }
00810
00815 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00816
00821 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00822
00827 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00828
00833 DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00834
00838 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00839
00843 PTime GetFirstDataReceivedTime() const { return firstDataReceivedTime; }
00845
00848 virtual int GetDataSocketHandle() const
00849 { return -1; }
00850 virtual int GetControlSocketHandle() const
00851 { return -1; }
00853
00854 protected:
00855 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00856
00857 unsigned sessionID;
00858 PString canonicalName;
00859 PString toolName;
00860 unsigned referenceCount;
00861 RTP_UserData * userData;
00862
00863 #ifndef NO_H323_AUDIO_CODECS
00864 RTP_JitterBuffer * jitter;
00865 #endif
00866
00867 BOOL ignoreOtherSources;
00868 BOOL ignoreOutOfOrderPackets;
00869 DWORD syncSourceOut;
00870 DWORD syncSourceIn;
00871 PTimeInterval reportTimeInterval;
00872 unsigned txStatisticsInterval;
00873 unsigned rxStatisticsInterval;
00874 WORD lastSentSequenceNumber;
00875 WORD expectedSequenceNumber;
00876 DWORD lastSentTimestamp;
00877 PTimeInterval lastSentPacketTime;
00878 PTimeInterval lastReceivedPacketTime;
00879 WORD lastRRSequenceNumber;
00880 PINDEX consecutiveOutOfOrderPackets;
00881
00882
00883 DWORD packetsSent;
00884 DWORD octetsSent;
00885 DWORD packetsReceived;
00886 DWORD octetsReceived;
00887 DWORD packetsLost;
00888 DWORD packetsOutOfOrder;
00889 DWORD averageSendTime;
00890 DWORD maximumSendTime;
00891 DWORD minimumSendTime;
00892 DWORD averageReceiveTime;
00893 DWORD maximumReceiveTime;
00894 DWORD minimumReceiveTime;
00895 DWORD jitterLevel;
00896 DWORD maximumJitterLevel;
00897
00898 unsigned txStatisticsCount;
00899 unsigned rxStatisticsCount;
00900
00901 DWORD averageSendTimeAccum;
00902 DWORD maximumSendTimeAccum;
00903 DWORD minimumSendTimeAccum;
00904 DWORD averageReceiveTimeAccum;
00905 DWORD maximumReceiveTimeAccum;
00906 DWORD minimumReceiveTimeAccum;
00907 DWORD packetsLostSinceLastRR;
00908 DWORD lastTransitTime;
00909 PTime firstDataReceivedTime;
00910
00911 PMutex reportMutex;
00912 PTimer reportTimer;
00913
00914 #ifdef H323_RTP_AGGREGATE
00915 PHandleAggregator * aggregator;
00916 #endif
00917 };
00918
00919
00922 class RTP_SessionManager : public PObject
00923 {
00924 PCLASSINFO(RTP_SessionManager, PObject);
00925
00926 public:
00931 RTP_SessionManager();
00932 RTP_SessionManager(const RTP_SessionManager & sm);
00933 RTP_SessionManager & operator=(const RTP_SessionManager & sm);
00935
00936
00950 RTP_Session * UseSession(
00951 unsigned sessionID
00952 );
00953
00960 void AddSession(
00961 RTP_Session * session
00962 );
00963
00967 void ReleaseSession(
00968 unsigned sessionID
00969 );
00970
00975 RTP_Session * GetSession(
00976 unsigned sessionID
00977 ) const;
00978
00995 RTP_Session * First();
00996
01003 RTP_Session * Next();
01004
01012 void Exit();
01014
01015
01016 protected:
01017 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
01018 SessionDict sessions;
01019 PMutex mutex;
01020 PINDEX enumerationIndex;
01021 };
01022
01023
01024
01027 class RTP_UDP : public RTP_Session
01028 {
01029 PCLASSINFO(RTP_UDP, RTP_Session);
01030
01031 public:
01036 RTP_UDP(
01037 #ifdef H323_RTP_AGGREGATE
01038 PHandleAggregator * aggregator,
01039 #endif
01040 unsigned id,
01041 BOOL remoteIsNat = FALSE
01042 );
01043
01045 ~RTP_UDP();
01047
01055 virtual BOOL ReadData(RTP_DataFrame & frame, BOOL loop);
01056
01059 virtual BOOL WriteData(RTP_DataFrame & frame);
01060
01063 virtual BOOL WriteControl(RTP_ControlFrame & frame);
01064
01067 virtual void Close(
01068 BOOL reading
01069 );
01070
01073 virtual PString GetLocalHostName();
01075
01080 virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
01081
01084 virtual void EnableGQoS();
01085
01086 #if P_HAS_QOS
01087
01089 PQoS & GetQOS();
01090 #endif
01091
01092
01097 BOOL Open(
01098 PIPSocket::Address localAddress,
01099 WORD portBase,
01100 WORD portMax,
01101 BYTE ipTypeOfService,
01102 #ifdef P_STUN
01103 PNatMethod * meth = NULL,
01104 #else
01105 void * = NULL,
01106 #endif
01107 RTP_QOS * rtpqos = NULL
01108 );
01110
01113 void Reopen(BOOL isReading);
01115
01120 PIPSocket::Address GetLocalAddress() const { return localAddress; }
01121
01124 void SetLocalAddress(
01125 const PIPSocket::Address & addr
01126 ) { localAddress = addr; }
01127
01130 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01131
01134 WORD GetLocalDataPort() const { return localDataPort; }
01135
01138 WORD GetLocalControlPort() const { return localControlPort; }
01139
01142 WORD GetRemoteDataPort() const { return remoteDataPort; }
01143
01146 WORD GetRemoteControlPort() const { return remoteControlPort; }
01147
01150 PUDPSocket & GetDataSocket() { return *dataSocket; }
01151
01154 PUDPSocket & GetControlSocket() { return *controlSocket; }
01155
01158 BOOL SetRemoteSocketInfo(
01159 PIPSocket::Address address,
01160 WORD port,
01161 BOOL isDataPort
01162 );
01163
01166 void ApplyQOS(
01167 const PIPSocket::Address & addr
01168 );
01170
01171 int GetDataSocketHandle() const
01172 { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01173
01174 int GetControlSocketHandle() const
01175 { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01176
01177 protected:
01178 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01179 SendReceiveStatus ReadControlPDU();
01180 SendReceiveStatus ReadDataOrControlPDU(
01181 PUDPSocket & socket,
01182 PBYTEArray & frame,
01183 BOOL fromDataChannel
01184 );
01185
01186 PIPSocket::Address localAddress;
01187 WORD localDataPort;
01188 WORD localControlPort;
01189
01190 PIPSocket::Address remoteAddress;
01191 WORD remoteDataPort;
01192 WORD remoteControlPort;
01193
01194 PIPSocket::Address remoteTransmitAddress;
01195
01196 BOOL shutdownRead;
01197 BOOL shutdownWrite;
01198
01199 PUDPSocket * dataSocket;
01200 PUDPSocket * controlSocket;
01201
01202 BOOL appliedQOS;
01203 BOOL enableGQOS;
01204
01205 BOOL remoteIsNAT;
01206 };
01207
01208
01209 #endif // __OPAL_RTP_H
01210
01211