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
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 #ifndef __OPAL_RTP_H
00275 #define __OPAL_RTP_H
00276
00277 #ifdef P_USE_PRAGMA
00278 #pragma interface
00279 #endif
00280
00281
00282 #include <ptlib/sockets.h>
00283
00284
00285 class RTP_JitterBuffer;
00286 class PSTUNClient;
00287
00288
00289
00291
00292
00293
00294 class RTP_QOS : public PObject
00295 {
00296 PCLASSINFO(RTP_QOS,PObject);
00297 public:
00298 PQoS dataQoS;
00299 PQoS ctrlQoS;
00300 };
00301
00303
00304
00307 class RTP_DataFrame : public PBYTEArray
00308 {
00309 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00310
00311 public:
00312 RTP_DataFrame(PINDEX payloadSize = 2048);
00313
00314 enum {
00315 ProtocolVersion = 2,
00316 MinHeaderSize = 12,
00317
00318 MaxEthernetPayloadSize = (1518-14-4-8-20-16-12)
00319 };
00320
00321 enum PayloadTypes {
00322 PCMU,
00323 FS1016,
00324 G721,
00325 G726 = G721,
00326 GSM,
00327 G7231,
00328 DVI4_8k,
00329 DVI4_16k,
00330 LPC,
00331 PCMA,
00332 G722,
00333 L16_Stereo,
00334 L16_Mono,
00335 G723,
00336 CN,
00337 MPA,
00338 G728,
00339 DVI4_11k,
00340 DVI4_22k,
00341 G729,
00342 Cisco_CN,
00343
00344 CelB = 25,
00345 JPEG,
00346 H261 = 31,
00347 MPV,
00348 MP2T,
00349 H263,
00350
00351 LastKnownPayloadType,
00352
00353 DynamicBase = 96,
00354 MaxPayloadType = 127,
00355 IllegalPayloadType
00356 };
00357
00358 typedef std::map<PayloadTypes, PayloadTypes> PayloadMapType;
00359
00360 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00361
00362 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; }
00363 void SetExtension(BOOL ext);
00364
00365 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
00366 void SetMarker(BOOL m);
00367
00368 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00369 void SetPayloadType(PayloadTypes t);
00370
00371 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00372 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00373
00374 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00375 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00376
00377 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00378 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00379
00380 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00381 DWORD GetContribSource(PINDEX idx) const;
00382 void SetContribSource(PINDEX idx, DWORD src);
00383
00384 PINDEX GetHeaderSize() const;
00385
00386 int GetExtensionType() const;
00387 void SetExtensionType(int type);
00388 PINDEX GetExtensionSize() const;
00389 BOOL SetExtensionSize(PINDEX sz);
00390 BYTE * GetExtensionPtr() const;
00391
00392 PINDEX GetPayloadSize() const { return payloadSize; }
00393 BOOL SetPayloadSize(PINDEX sz);
00394 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); }
00395
00396 protected:
00397 PINDEX payloadSize;
00398
00399 #if PTRACING
00400 friend ostream & operator<<(ostream & o, PayloadTypes t);
00401 #endif
00402 };
00403
00404 PLIST(RTP_DataFrameList, RTP_DataFrame);
00405
00406
00409 class RTP_ControlFrame : public PBYTEArray
00410 {
00411 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00412
00413 public:
00414 RTP_ControlFrame(PINDEX compoundSize = 2048);
00415
00416 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00417
00418 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00419 void SetCount(unsigned count);
00420
00421 enum PayloadTypes {
00422 e_SenderReport = 200,
00423 e_ReceiverReport,
00424 e_SourceDescription,
00425 e_Goodbye,
00426 e_ApplDefined
00427 };
00428
00429 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00430 void SetPayloadType(unsigned t);
00431
00432 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00433 void SetPayloadSize(PINDEX sz);
00434
00435 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); }
00436
00437 BOOL ReadNextCompound();
00438 BOOL WriteNextCompound();
00439
00440 PINDEX GetCompoundSize() const { return compoundSize; }
00441
00442 #pragma pack(1)
00443 struct ReceiverReport {
00444 PUInt32b ssrc;
00445 BYTE fraction;
00446 BYTE lost[3];
00447 PUInt32b last_seq;
00448 PUInt32b jitter;
00449 PUInt32b lsr;
00450 PUInt32b dlsr;
00451
00452 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00453 void SetLostPackets(unsigned lost);
00454 };
00455
00456 struct SenderReport {
00457 PUInt32b ssrc;
00458 PUInt32b ntp_sec;
00459 PUInt32b ntp_frac;
00460 PUInt32b rtp_ts;
00461 PUInt32b psent;
00462 PUInt32b osent;
00463 };
00464
00465 enum DescriptionTypes {
00466 e_END,
00467 e_CNAME,
00468 e_NAME,
00469 e_EMAIL,
00470 e_PHONE,
00471 e_LOC,
00472 e_TOOL,
00473 e_NOTE,
00474 e_PRIV,
00475 NumDescriptionTypes
00476 };
00477
00478 struct SourceDescription {
00479 PUInt32b src;
00480 struct Item {
00481 BYTE type;
00482 BYTE length;
00483 char data[1];
00484
00485 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00486 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00487 } item[1];
00488 };
00489
00490 SourceDescription & AddSourceDescription(
00491 DWORD src
00492 );
00493
00494 SourceDescription::Item & AddSourceDescriptionItem(
00495 SourceDescription & sdes,
00496 unsigned type,
00497 const PString & data
00498 );
00499 #pragma pack()
00500
00501 protected:
00502 PINDEX compoundOffset;
00503 PINDEX compoundSize;
00504 };
00505
00506
00507 class RTP_Session;
00508
00513 class RTP_UserData : public PObject
00514 {
00515 PCLASSINFO(RTP_UserData, PObject);
00516
00517 public:
00524 virtual void OnTxStatistics(
00525 const RTP_Session & session
00526 ) const;
00527
00534 virtual void OnRxStatistics(
00535 const RTP_Session & session
00536 ) const;
00537 };
00538
00539
00542 class RTP_Session : public PObject
00543 {
00544 PCLASSINFO(RTP_Session, PObject);
00545
00546 public:
00551 RTP_Session(
00552 unsigned id,
00553 RTP_UserData * userData = NULL,
00554 BOOL autoDeleteUserData = TRUE
00555 );
00556
00560 ~RTP_Session();
00562
00574 void SetJitterBufferSize(
00575 unsigned minJitterDelay,
00576 unsigned maxJitterDelay,
00577 unsigned timeUnits = 8,
00578 PINDEX stackSize = 30000
00579 );
00580
00586 unsigned GetJitterBufferSize() const;
00587
00590 unsigned GetJitterTimeUnits() const;
00591
00593 virtual BOOL ModifyQOS(RTP_QOS * )
00594 { return FALSE; }
00595
00601 BOOL ReadBufferedData(
00602 DWORD timestamp,
00603 RTP_DataFrame & frame
00604 );
00605
00611 virtual BOOL ReadData(
00612 RTP_DataFrame & frame
00613 ) = 0;
00614
00617 virtual BOOL WriteData(
00618 RTP_DataFrame & frame
00619 ) = 0;
00620
00623 virtual BOOL WriteControl(
00624 RTP_ControlFrame & frame
00625 ) = 0;
00626
00629 virtual BOOL SendReport();
00630
00633 virtual void Close(
00634 BOOL reading
00635 ) = 0;
00636
00639 virtual void Reopen(
00640 BOOL isReading
00641 ) = 0;
00642
00645 virtual PString GetLocalHostName() = 0;
00647
00650 enum SendReceiveStatus {
00651 e_ProcessPacket,
00652 e_IgnorePacket,
00653 e_AbortTransport
00654 };
00655 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00656 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame);
00657 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00658
00659 class ReceiverReport : public PObject {
00660 PCLASSINFO(ReceiverReport, PObject);
00661 public:
00662 void PrintOn(ostream &) const;
00663
00664 DWORD sourceIdentifier;
00665 DWORD fractionLost;
00666 DWORD totalLost;
00667 DWORD lastSequenceNumber;
00668 DWORD jitter;
00669 PTimeInterval lastTimestamp;
00670 PTimeInterval delay;
00671 };
00672 PARRAY(ReceiverReportArray, ReceiverReport);
00673
00674 class SenderReport : public PObject {
00675 PCLASSINFO(SenderReport, PObject);
00676 public:
00677 void PrintOn(ostream &) const;
00678
00679 DWORD sourceIdentifier;
00680 PTime realTimestamp;
00681 DWORD rtpTimestamp;
00682 DWORD packetsSent;
00683 DWORD octetsSent;
00684 };
00685 virtual void OnRxSenderReport(const SenderReport & sender,
00686 const ReceiverReportArray & reports);
00687 virtual void OnRxReceiverReport(DWORD src,
00688 const ReceiverReportArray & reports);
00689
00690 class SourceDescription : public PObject {
00691 PCLASSINFO(SourceDescription, PObject);
00692 public:
00693 SourceDescription(DWORD src) { sourceIdentifier = src; }
00694 void PrintOn(ostream &) const;
00695
00696 DWORD sourceIdentifier;
00697 POrdinalToString items;
00698 };
00699 PARRAY(SourceDescriptionArray, SourceDescription);
00700 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00701
00702 virtual void OnRxGoodbye(const PDWORDArray & sources,
00703 const PString & reason);
00704
00705 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00706 const BYTE * data, PINDEX size);
00708
00713 unsigned GetSessionID() const { return sessionID; }
00714
00717 PString GetCanonicalName() const;
00718
00721 void SetCanonicalName(const PString & name);
00722
00725 PString GetToolName() const;
00726
00729 void SetToolName(const PString & name);
00730
00733 RTP_UserData * GetUserData() const { return userData; }
00734
00737 void SetUserData(
00738 RTP_UserData * data,
00739 BOOL autoDeleteUserData = TRUE
00740 );
00741
00744 DWORD GetSyncSourceOut() const { return syncSourceOut; }
00745
00748 void IncrementReference() { referenceCount++; }
00749
00752 BOOL DecrementReference() { return --referenceCount == 0; }
00753
00756 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
00757
00760 void SetIgnoreOtherSources(
00761 BOOL ignore
00762 ) { ignoreOtherSources = ignore; }
00763
00766 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00767
00770 void SetIgnoreOutOfOrderPackets(
00771 BOOL ignore
00772 ) { ignoreOutOfOrderPackets = ignore; }
00773
00776 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00777
00780 void SetReportTimeInterval(
00781 const PTimeInterval & interval
00782 ) { reportTimeInterval = interval; }
00783
00786 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00787
00790 void SetTxStatisticsInterval(
00791 unsigned packets
00792 );
00793
00796 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00797
00800 void SetRxStatisticsInterval(
00801 unsigned packets
00802 );
00803
00806 DWORD GetPacketsSent() const { return packetsSent; }
00807
00810 DWORD GetOctetsSent() const { return octetsSent; }
00811
00814 DWORD GetPacketsReceived() const { return packetsReceived; }
00815
00818 DWORD GetOctetsReceived() const { return octetsReceived; }
00819
00822 DWORD GetPacketsLost() const { return packetsLost; }
00823
00826 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00827
00830 DWORD GetPacketsTooLate() const;
00831
00836 DWORD GetAverageSendTime() const { return averageSendTime; }
00837
00842 DWORD GetMaximumSendTime() const { return maximumSendTime; }
00843
00848 DWORD GetMinimumSendTime() const { return minimumSendTime; }
00849
00854 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00855
00860 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00861
00866 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00867
00872 DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00873
00877 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00879
00880 protected:
00881 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00882
00883 unsigned sessionID;
00884 PString canonicalName;
00885 PString toolName;
00886 unsigned referenceCount;
00887 RTP_UserData * userData;
00888 BOOL autoDeleteUserData;
00889 RTP_JitterBuffer * jitter;
00890
00891 BOOL ignoreOtherSources;
00892 BOOL ignoreOutOfOrderPackets;
00893 DWORD syncSourceOut;
00894 DWORD syncSourceIn;
00895 BOOL allowSyncSourceInChange;
00896 BOOL allowRemoteTransmitAddressChange;
00897 BOOL allowSequenceChange;
00898 PTimeInterval reportTimeInterval;
00899 unsigned txStatisticsInterval;
00900 unsigned rxStatisticsInterval;
00901 WORD lastSentSequenceNumber;
00902 WORD expectedSequenceNumber;
00903 DWORD lastSentTimestamp;
00904 PTimeInterval lastSentPacketTime;
00905 PTimeInterval lastReceivedPacketTime;
00906 WORD lastRRSequenceNumber;
00907 PINDEX consecutiveOutOfOrderPackets;
00908
00909
00910 DWORD packetsSent;
00911 DWORD octetsSent;
00912 DWORD packetsReceived;
00913 DWORD octetsReceived;
00914 DWORD packetsLost;
00915 DWORD packetsOutOfOrder;
00916 DWORD averageSendTime;
00917 DWORD maximumSendTime;
00918 DWORD minimumSendTime;
00919 DWORD averageReceiveTime;
00920 DWORD maximumReceiveTime;
00921 DWORD minimumReceiveTime;
00922 DWORD jitterLevel;
00923 DWORD maximumJitterLevel;
00924
00925 unsigned txStatisticsCount;
00926 unsigned rxStatisticsCount;
00927
00928 DWORD averageSendTimeAccum;
00929 DWORD maximumSendTimeAccum;
00930 DWORD minimumSendTimeAccum;
00931 DWORD averageReceiveTimeAccum;
00932 DWORD maximumReceiveTimeAccum;
00933 DWORD minimumReceiveTimeAccum;
00934 DWORD packetsLostSinceLastRR;
00935 DWORD lastTransitTime;
00936
00937 PMutex reportMutex;
00938 PTimer reportTimer;
00939 };
00940
00941
00944 class RTP_SessionManager : public PObject
00945 {
00946 PCLASSINFO(RTP_SessionManager, PObject);
00947
00948 public:
00953 RTP_SessionManager();
00954 RTP_SessionManager(const RTP_SessionManager & sm);
00955 RTP_SessionManager & operator=(const RTP_SessionManager & sm);
00957
00958
00972 RTP_Session * UseSession(
00973 unsigned sessionID
00974 );
00975
00982 void AddSession(
00983 RTP_Session * session
00984 );
00985
00989 void ReleaseSession(
00990 unsigned sessionID
00991 );
00992
00997 RTP_Session * GetSession(
00998 unsigned sessionID
00999 ) const;
01000
01017 RTP_Session * First();
01018
01025 RTP_Session * Next();
01026
01034 void Exit();
01036
01037
01038 protected:
01039 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
01040 SessionDict sessions;
01041 PMutex mutex;
01042 PINDEX enumerationIndex;
01043 };
01044
01045
01046
01049 class RTP_UDP : public RTP_Session
01050 {
01051 PCLASSINFO(RTP_UDP, RTP_Session);
01052
01053 public:
01058 RTP_UDP(
01059 unsigned id
01060 );
01061
01063 ~RTP_UDP();
01065
01073 virtual BOOL ReadData(RTP_DataFrame & frame);
01074
01077 virtual BOOL WriteData(RTP_DataFrame & frame);
01078
01081 virtual BOOL WriteControl(RTP_ControlFrame & frame);
01082
01085 virtual void Close(
01086 BOOL reading
01087 );
01088
01091 virtual PString GetLocalHostName();
01093
01096 virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
01097
01102 BOOL Open(
01103 PIPSocket::Address localAddress,
01104 WORD portBase,
01105 WORD portMax,
01106 BYTE ipTypeOfService,
01107 PSTUNClient * stun = NULL,
01108 RTP_QOS * rtpqos = NULL
01109 );
01111
01114 virtual void Reopen(BOOL isReading);
01116
01121 PIPSocket::Address GetLocalAddress() const { return localAddress; }
01122
01125 void SetLocalAddress(
01126 const PIPSocket::Address & addr
01127 ) { localAddress = addr; }
01128
01131 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01132
01135 WORD GetLocalDataPort() const { return localDataPort; }
01136
01139 WORD GetLocalControlPort() const { return localControlPort; }
01140
01143 WORD GetRemoteDataPort() const { return remoteDataPort; }
01144
01147 WORD GetRemoteControlPort() const { return remoteControlPort; }
01148
01151 PUDPSocket & GetDataSocket() { return *dataSocket; }
01152
01155 PUDPSocket & GetControlSocket() { return *controlSocket; }
01156
01159 BOOL SetRemoteSocketInfo(
01160 PIPSocket::Address address,
01161 WORD port,
01162 BOOL isDataPort
01163 );
01164
01167 void ApplyQOS(
01168 const PIPSocket::Address & addr
01169 );
01171
01172 protected:
01173 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01174 SendReceiveStatus ReadControlPDU();
01175 SendReceiveStatus ReadDataOrControlPDU(
01176 PUDPSocket & socket,
01177 PBYTEArray & frame,
01178 BOOL fromDataChannel
01179 );
01180
01181 PIPSocket::Address localAddress;
01182 WORD localDataPort;
01183 WORD localControlPort;
01184
01185 PIPSocket::Address remoteAddress;
01186 WORD remoteDataPort;
01187 WORD remoteControlPort;
01188
01189 PIPSocket::Address remoteTransmitAddress;
01190
01191 BOOL shutdownRead;
01192 BOOL shutdownWrite;
01193
01194 PUDPSocket * dataSocket;
01195 PUDPSocket * controlSocket;
01196
01197 BOOL appliedQOS;
01198 };
01199
01200
01201 #endif // __OPAL_RTP_H
01202
01203