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 #ifndef __OPAL_RTP_H
00208 #define __OPAL_RTP_H
00209
00210 #ifdef P_USE_PRAGMA
00211 #pragma interface
00212 #endif
00213
00214
00215 #include <ptlib/sockets.h>
00216
00217
00218 class RTP_JitterBuffer;
00219 class PSTUNClient;
00220
00221
00222
00224
00225
00226
00227 #if P_HAS_QOS
00228
00229 class RTP_QOS : public PObject
00230 {
00231 PCLASSINFO(RTP_QOS,PObject);
00232 public:
00233 PQoS dataQoS;
00234 PQoS ctrlQoS;
00235 };
00236
00237 #else
00238
00239 class RTP_QOS;
00240
00241 #endif
00242
00244
00245
00248 class RTP_DataFrame : public PBYTEArray
00249 {
00250 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00251
00252 public:
00253 RTP_DataFrame(PINDEX payloadSize = 2048);
00254
00255 enum {
00256 ProtocolVersion = 2,
00257 MinHeaderSize = 12
00258 };
00259
00260 enum PayloadTypes {
00261 PCMU,
00262 FS1016,
00263 G721,
00264 G726 = G721,
00265 GSM,
00266 G7231,
00267 DVI4_8k,
00268 DVI4_16k,
00269 LPC,
00270 PCMA,
00271 G722,
00272 L16_Stereo,
00273 L16_Mono,
00274 G723,
00275 CN,
00276 MPA,
00277 G728,
00278 DVI4_11k,
00279 DVI4_22k,
00280 G729,
00281 Cisco_CN,
00282
00283 CelB = 25,
00284 JPEG,
00285 H261 = 31,
00286 MPV,
00287 MP2T,
00288 H263,
00289
00290 LastKnownPayloadType,
00291
00292 DynamicBase = 96,
00293 MaxPayloadType = 127,
00294 IllegalPayloadType
00295 };
00296
00297 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00298
00299 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; }
00300 void SetExtension(BOOL ext);
00301
00302 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
00303 void SetMarker(BOOL m);
00304
00305 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00306 void SetPayloadType(PayloadTypes t);
00307
00308 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00309 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00310
00311 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00312 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00313
00314 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00315 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00316
00317 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00318 DWORD GetContribSource(PINDEX idx) const;
00319 void SetContribSource(PINDEX idx, DWORD src);
00320
00321 PINDEX GetHeaderSize() const;
00322
00323 int GetExtensionType() const;
00324 void SetExtensionType(int type);
00325 PINDEX GetExtensionSize() const;
00326 BOOL SetExtensionSize(PINDEX sz);
00327 BYTE * GetExtensionPtr() const;
00328
00329 PINDEX GetPayloadSize() const { return payloadSize; }
00330 BOOL SetPayloadSize(PINDEX sz);
00331 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); }
00332
00333 protected:
00334 PINDEX payloadSize;
00335
00336 #if PTRACING
00337 friend ostream & operator<<(ostream & o, PayloadTypes t);
00338 #endif
00339 };
00340
00341 PLIST(RTP_DataFrameList, RTP_DataFrame);
00342
00343
00346 class RTP_ControlFrame : public PBYTEArray
00347 {
00348 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00349
00350 public:
00351 RTP_ControlFrame(PINDEX compoundSize = 2048);
00352
00353 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00354
00355 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00356 void SetCount(unsigned count);
00357
00358 enum PayloadTypes {
00359 e_SenderReport = 200,
00360 e_ReceiverReport,
00361 e_SourceDescription,
00362 e_Goodbye,
00363 e_ApplDefined
00364 };
00365
00366 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00367 void SetPayloadType(unsigned t);
00368
00369 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00370 void SetPayloadSize(PINDEX sz);
00371
00372 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); }
00373
00374 BOOL ReadNextCompound();
00375 BOOL WriteNextCompound();
00376
00377 PINDEX GetCompoundSize() const { return compoundSize; }
00378
00379 #pragma pack(1)
00380 struct ReceiverReport {
00381 PUInt32b ssrc;
00382 BYTE fraction;
00383 BYTE lost[3];
00384 PUInt32b last_seq;
00385 PUInt32b jitter;
00386 PUInt32b lsr;
00387 PUInt32b dlsr;
00388
00389 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00390 void SetLostPackets(unsigned lost);
00391 };
00392
00393 struct SenderReport {
00394 PUInt32b ssrc;
00395 PUInt32b ntp_sec;
00396 PUInt32b ntp_frac;
00397 PUInt32b rtp_ts;
00398 PUInt32b psent;
00399 PUInt32b osent;
00400 };
00401
00402 enum DescriptionTypes {
00403 e_END,
00404 e_CNAME,
00405 e_NAME,
00406 e_EMAIL,
00407 e_PHONE,
00408 e_LOC,
00409 e_TOOL,
00410 e_NOTE,
00411 e_PRIV,
00412 NumDescriptionTypes
00413 };
00414
00415 struct SourceDescription {
00416 PUInt32b src;
00417 struct Item {
00418 BYTE type;
00419 BYTE length;
00420 char data[1];
00421
00422 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00423 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00424 } item[1];
00425 };
00426
00427 SourceDescription & AddSourceDescription(
00428 DWORD src
00429 );
00430
00431 SourceDescription::Item & AddSourceDescriptionItem(
00432 SourceDescription & sdes,
00433 unsigned type,
00434 const PString & data
00435 );
00436 #pragma pack()
00437
00438 protected:
00439 PINDEX compoundOffset;
00440 PINDEX compoundSize;
00441 };
00442
00443
00444 class RTP_Session;
00445
00450 class RTP_UserData : public PObject
00451 {
00452 PCLASSINFO(RTP_UserData, PObject);
00453
00454 public:
00461 virtual void OnTxStatistics(
00462 const RTP_Session & session
00463 ) const;
00464
00471 virtual void OnRxStatistics(
00472 const RTP_Session & session
00473 ) const;
00474 };
00475
00476
00479 class RTP_Session : public PObject
00480 {
00481 PCLASSINFO(RTP_Session, PObject);
00482
00483 public:
00484 enum {
00485 DefaultAudioSessionID = 1,
00486 DefaultVideoSessionID = 2,
00487 DefaultFaxSessionID = 3
00488 };
00489
00494 RTP_Session(
00495 unsigned id,
00496 RTP_UserData * userData = NULL
00497 );
00498
00502 ~RTP_Session();
00504
00516 void SetJitterBufferSize(
00517 unsigned minJitterDelay,
00518 unsigned maxJitterDelay,
00519 PINDEX stackSize = 30000
00520 );
00521
00527 unsigned GetJitterBufferSize() const;
00528
00530 virtual BOOL ModifyQOS(RTP_QOS * )
00531 { return FALSE; }
00532
00538 BOOL ReadBufferedData(
00539 DWORD timestamp,
00540 RTP_DataFrame & frame
00541 );
00542
00548 virtual BOOL ReadData(
00549 RTP_DataFrame & frame
00550 ) = 0;
00551
00554 virtual BOOL WriteData(
00555 RTP_DataFrame & frame
00556 ) = 0;
00557
00560 virtual BOOL WriteControl(
00561 RTP_ControlFrame & frame
00562 ) = 0;
00563
00566 virtual BOOL SendReport();
00567
00570 virtual void Close(
00571 BOOL reading
00572 ) = 0;
00573
00576 virtual PString GetLocalHostName() = 0;
00578
00581 enum SendReceiveStatus {
00582 e_ProcessPacket,
00583 e_IgnorePacket,
00584 e_AbortTransport
00585 };
00586 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00587 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame);
00588 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00589
00590 class ReceiverReport : public PObject {
00591 PCLASSINFO(ReceiverReport, PObject);
00592 public:
00593 void PrintOn(ostream &) const;
00594
00595 DWORD sourceIdentifier;
00596 DWORD fractionLost;
00597 DWORD totalLost;
00598 DWORD lastSequenceNumber;
00599 DWORD jitter;
00600 PTimeInterval lastTimestamp;
00601 PTimeInterval delay;
00602 };
00603 PARRAY(ReceiverReportArray, ReceiverReport);
00604
00605 class SenderReport : public PObject {
00606 PCLASSINFO(SenderReport, PObject);
00607 public:
00608 void PrintOn(ostream &) const;
00609
00610 DWORD sourceIdentifier;
00611 PTime realTimestamp;
00612 DWORD rtpTimestamp;
00613 DWORD packetsSent;
00614 DWORD octetsSent;
00615 };
00616 virtual void OnRxSenderReport(const SenderReport & sender,
00617 const ReceiverReportArray & reports);
00618 virtual void OnRxReceiverReport(DWORD src,
00619 const ReceiverReportArray & reports);
00620
00621 class SourceDescription : public PObject {
00622 PCLASSINFO(SourceDescription, PObject);
00623 public:
00624 SourceDescription(DWORD src) { sourceIdentifier = src; }
00625 void PrintOn(ostream &) const;
00626
00627 DWORD sourceIdentifier;
00628 POrdinalToString items;
00629 };
00630 PARRAY(SourceDescriptionArray, SourceDescription);
00631 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00632
00633 virtual void OnRxGoodbye(const PDWORDArray & sources,
00634 const PString & reason);
00635
00636 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00637 const BYTE * data, PINDEX size);
00639
00644 unsigned GetSessionID() const { return sessionID; }
00645
00648 PString GetCanonicalName() const;
00649
00652 void SetCanonicalName(const PString & name);
00653
00656 PString GetToolName() const;
00657
00660 void SetToolName(const PString & name);
00661
00664 RTP_UserData * GetUserData() const { return userData; }
00665
00668 void SetUserData(
00669 RTP_UserData * data
00670 );
00671
00674 DWORD GetSyncSourceOut() const { return syncSourceOut; }
00675
00678 void IncrementReference() { referenceCount++; }
00679
00682 BOOL DecrementReference() { return --referenceCount == 0; }
00683
00686 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
00687
00690 void SetIgnoreOtherSources(
00691 BOOL ignore
00692 ) { ignoreOtherSources = ignore; }
00693
00696 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00697
00700 void SetIgnoreOutOfOrderPackets(
00701 BOOL ignore
00702 ) { ignoreOutOfOrderPackets = ignore; }
00703
00706 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00707
00710 void SetReportTimeInterval(
00711 const PTimeInterval & interval
00712 ) { reportTimeInterval = interval; }
00713
00716 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00717
00720 void SetTxStatisticsInterval(
00721 unsigned packets
00722 );
00723
00726 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00727
00730 void SetRxStatisticsInterval(
00731 unsigned packets
00732 );
00733
00736 DWORD GetPacketsSent() const { return packetsSent; }
00737
00740 DWORD GetOctetsSent() const { return octetsSent; }
00741
00744 DWORD GetPacketsReceived() const { return packetsReceived; }
00745
00748 DWORD GetOctetsReceived() const { return octetsReceived; }
00749
00752 DWORD GetPacketsLost() const { return packetsLost; }
00753
00756 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00757
00760 DWORD GetPacketsTooLate() const;
00761
00766 DWORD GetAverageSendTime() const { return averageSendTime; }
00767
00772 DWORD GetMaximumSendTime() const { return maximumSendTime; }
00773
00778 DWORD GetMinimumSendTime() const { return minimumSendTime; }
00779
00784 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00785
00790 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00791
00796 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00797
00802 DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00803
00807 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00809
00810 protected:
00811 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00812
00813 unsigned sessionID;
00814 PString canonicalName;
00815 PString toolName;
00816 unsigned referenceCount;
00817 RTP_UserData * userData;
00818 RTP_JitterBuffer * jitter;
00819
00820 BOOL ignoreOtherSources;
00821 BOOL ignoreOutOfOrderPackets;
00822 DWORD syncSourceOut;
00823 DWORD syncSourceIn;
00824 PTimeInterval reportTimeInterval;
00825 unsigned txStatisticsInterval;
00826 unsigned rxStatisticsInterval;
00827 WORD lastSentSequenceNumber;
00828 WORD expectedSequenceNumber;
00829 DWORD lastSentTimestamp;
00830 PTimeInterval lastSentPacketTime;
00831 PTimeInterval lastReceivedPacketTime;
00832 WORD lastRRSequenceNumber;
00833 PINDEX consecutiveOutOfOrderPackets;
00834
00835
00836 DWORD packetsSent;
00837 DWORD octetsSent;
00838 DWORD packetsReceived;
00839 DWORD octetsReceived;
00840 DWORD packetsLost;
00841 DWORD packetsOutOfOrder;
00842 DWORD averageSendTime;
00843 DWORD maximumSendTime;
00844 DWORD minimumSendTime;
00845 DWORD averageReceiveTime;
00846 DWORD maximumReceiveTime;
00847 DWORD minimumReceiveTime;
00848 DWORD jitterLevel;
00849 DWORD maximumJitterLevel;
00850
00851 unsigned txStatisticsCount;
00852 unsigned rxStatisticsCount;
00853
00854 DWORD averageSendTimeAccum;
00855 DWORD maximumSendTimeAccum;
00856 DWORD minimumSendTimeAccum;
00857 DWORD averageReceiveTimeAccum;
00858 DWORD maximumReceiveTimeAccum;
00859 DWORD minimumReceiveTimeAccum;
00860 DWORD packetsLostSinceLastRR;
00861 DWORD lastTransitTime;
00862
00863 PMutex reportMutex;
00864 PTimer reportTimer;
00865 };
00866
00867
00870 class RTP_SessionManager : public PObject
00871 {
00872 PCLASSINFO(RTP_SessionManager, PObject);
00873
00874 public:
00879 RTP_SessionManager();
00880 RTP_SessionManager(const RTP_SessionManager & sm);
00881 RTP_SessionManager & operator=(const RTP_SessionManager & sm);
00883
00884
00898 RTP_Session * UseSession(
00899 unsigned sessionID
00900 );
00901
00908 void AddSession(
00909 RTP_Session * session
00910 );
00911
00915 void ReleaseSession(
00916 unsigned sessionID
00917 );
00918
00923 RTP_Session * GetSession(
00924 unsigned sessionID
00925 ) const;
00926
00943 RTP_Session * First();
00944
00951 RTP_Session * Next();
00952
00960 void Exit();
00962
00963
00964 protected:
00965 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
00966 SessionDict sessions;
00967 PMutex mutex;
00968 PINDEX enumerationIndex;
00969 };
00970
00971
00972
00975 class RTP_UDP : public RTP_Session
00976 {
00977 PCLASSINFO(RTP_UDP, RTP_Session);
00978
00979 public:
00984 RTP_UDP(
00985 unsigned id,
00986 BOOL remoteIsNat = FALSE
00987 );
00988
00990 ~RTP_UDP();
00992
01000 virtual BOOL ReadData(RTP_DataFrame & frame);
01001
01004 virtual BOOL WriteData(RTP_DataFrame & frame);
01005
01008 virtual BOOL WriteControl(RTP_ControlFrame & frame);
01009
01012 virtual void Close(
01013 BOOL reading
01014 );
01015
01018 virtual PString GetLocalHostName();
01020
01023 virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
01024
01029 BOOL Open(
01030 PIPSocket::Address localAddress,
01031 WORD portBase,
01032 WORD portMax,
01033 BYTE ipTypeOfService,
01034 PSTUNClient * stun = NULL,
01035 RTP_QOS * rtpqos = NULL
01036 );
01038
01041 void Reopen(BOOL isReading);
01043
01048 PIPSocket::Address GetLocalAddress() const { return localAddress; }
01049
01052 void SetLocalAddress(
01053 const PIPSocket::Address & addr
01054 ) { localAddress = addr; }
01055
01058 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01059
01062 WORD GetLocalDataPort() const { return localDataPort; }
01063
01066 WORD GetLocalControlPort() const { return localControlPort; }
01067
01070 WORD GetRemoteDataPort() const { return remoteDataPort; }
01071
01074 WORD GetRemoteControlPort() const { return remoteControlPort; }
01075
01078 PUDPSocket & GetDataSocket() { return *dataSocket; }
01079
01082 PUDPSocket & GetControlSocket() { return *controlSocket; }
01083
01086 BOOL SetRemoteSocketInfo(
01087 PIPSocket::Address address,
01088 WORD port,
01089 BOOL isDataPort
01090 );
01091
01094 void ApplyQOS(
01095 const PIPSocket::Address & addr
01096 );
01098
01099 protected:
01100 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01101 SendReceiveStatus ReadControlPDU();
01102 SendReceiveStatus ReadDataOrControlPDU(
01103 PUDPSocket & socket,
01104 PBYTEArray & frame,
01105 BOOL fromDataChannel
01106 );
01107
01108 PIPSocket::Address localAddress;
01109 WORD localDataPort;
01110 WORD localControlPort;
01111
01112 PIPSocket::Address remoteAddress;
01113 WORD remoteDataPort;
01114 WORD remoteControlPort;
01115
01116 PIPSocket::Address remoteTransmitAddress;
01117
01118 BOOL shutdownRead;
01119 BOOL shutdownWrite;
01120
01121 PUDPSocket * dataSocket;
01122 PUDPSocket * controlSocket;
01123
01124 BOOL appliedQOS;
01125
01126 BOOL remoteIsNAT;
01127 };
01128
01129
01130 #endif // __OPAL_RTP_H
01131
01132