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