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
00275
00276
00277
00278
00279
00280
00281 #ifndef __OPAL_RTP_H
00282 #define __OPAL_RTP_H
00283
00284 #ifdef P_USE_PRAGMA
00285 #pragma interface
00286 #endif
00287
00288
00289 #include <ptlib/sockets.h>
00290
00291
00292 class RTP_JitterBuffer;
00293 class PSTUNClient;
00294
00295
00296
00298
00299
00300
00301 class RTP_QOS : public PObject
00302 {
00303 PCLASSINFO(RTP_QOS,PObject);
00304 public:
00305 PQoS dataQoS;
00306 PQoS ctrlQoS;
00307 };
00308
00310
00311
00314 class RTP_DataFrame : public PBYTEArray
00315 {
00316 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00317
00318 public:
00319 RTP_DataFrame(PINDEX payloadSize = 2048);
00320
00321 enum {
00322 ProtocolVersion = 2,
00323 MinHeaderSize = 12,
00324
00325 MaxEthernetPayloadSize = (1518-14-4-8-20-16-12)
00326 };
00327
00328 enum PayloadTypes {
00329 PCMU,
00330 FS1016,
00331 G721,
00332 G726 = G721,
00333 GSM,
00334 G7231,
00335 DVI4_8k,
00336 DVI4_16k,
00337 LPC,
00338 PCMA,
00339 G722,
00340 L16_Stereo,
00341 L16_Mono,
00342 G723,
00343 CN,
00344 MPA,
00345 G728,
00346 DVI4_11k,
00347 DVI4_22k,
00348 G729,
00349 Cisco_CN,
00350
00351 CelB = 25,
00352 JPEG,
00353 H261 = 31,
00354 MPV,
00355 MP2T,
00356 H263,
00357
00358 LastKnownPayloadType,
00359
00360 DynamicBase = 96,
00361 MaxPayloadType = 127,
00362 IllegalPayloadType
00363 };
00364
00365 typedef std::map<PayloadTypes, PayloadTypes> PayloadMapType;
00366
00367 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00368
00369 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; }
00370 void SetExtension(BOOL ext);
00371
00372 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
00373 void SetMarker(BOOL m);
00374
00375 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00376 void SetPayloadType(PayloadTypes t);
00377
00378 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00379 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00380
00381 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00382 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00383
00384 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00385 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00386
00387 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00388 DWORD GetContribSource(PINDEX idx) const;
00389 void SetContribSource(PINDEX idx, DWORD src);
00390
00391 PINDEX GetHeaderSize() const;
00392
00393 int GetExtensionType() const;
00394 void SetExtensionType(int type);
00395 PINDEX GetExtensionSize() const;
00396 BOOL SetExtensionSize(PINDEX sz);
00397 BYTE * GetExtensionPtr() const;
00398
00399 PINDEX GetPayloadSize() const { return payloadSize; }
00400 BOOL SetPayloadSize(PINDEX sz);
00401 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); }
00402
00403 protected:
00404 PINDEX payloadSize;
00405
00406 #if PTRACING
00407 friend ostream & operator<<(ostream & o, PayloadTypes t);
00408 #endif
00409 };
00410
00411 PLIST(RTP_DataFrameList, RTP_DataFrame);
00412
00413
00416 class RTP_ControlFrame : public PBYTEArray
00417 {
00418 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00419
00420 public:
00421 RTP_ControlFrame(PINDEX compoundSize = 2048);
00422
00423 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00424
00425 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00426 void SetCount(unsigned count);
00427
00428 enum PayloadTypes {
00429 e_SenderReport = 200,
00430 e_ReceiverReport,
00431 e_SourceDescription,
00432 e_Goodbye,
00433 e_ApplDefined
00434 };
00435
00436 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00437 void SetPayloadType(unsigned t);
00438
00439 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00440 void SetPayloadSize(PINDEX sz);
00441
00442 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); }
00443
00444 BOOL ReadNextCompound();
00445 BOOL WriteNextCompound();
00446
00447 PINDEX GetCompoundSize() const { return compoundSize; }
00448
00449 #pragma pack(1)
00450 struct ReceiverReport {
00451 PUInt32b ssrc;
00452 BYTE fraction;
00453 BYTE lost[3];
00454 PUInt32b last_seq;
00455 PUInt32b jitter;
00456 PUInt32b lsr;
00457 PUInt32b dlsr;
00458
00459 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00460 void SetLostPackets(unsigned lost);
00461 };
00462
00463 struct SenderReport {
00464 PUInt32b ssrc;
00465 PUInt32b ntp_sec;
00466 PUInt32b ntp_frac;
00467 PUInt32b rtp_ts;
00468 PUInt32b psent;
00469 PUInt32b osent;
00470 };
00471
00472 enum DescriptionTypes {
00473 e_END,
00474 e_CNAME,
00475 e_NAME,
00476 e_EMAIL,
00477 e_PHONE,
00478 e_LOC,
00479 e_TOOL,
00480 e_NOTE,
00481 e_PRIV,
00482 NumDescriptionTypes
00483 };
00484
00485 struct SourceDescription {
00486 PUInt32b src;
00487 struct Item {
00488 BYTE type;
00489 BYTE length;
00490 char data[1];
00491
00492 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00493 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00494 } item[1];
00495 };
00496
00497 SourceDescription & AddSourceDescription(
00498 DWORD src
00499 );
00500
00501 SourceDescription::Item & AddSourceDescriptionItem(
00502 SourceDescription & sdes,
00503 unsigned type,
00504 const PString & data
00505 );
00506 #pragma pack()
00507
00508 protected:
00509 PINDEX compoundOffset;
00510 PINDEX compoundSize;
00511 };
00512
00513
00514 class RTP_Session;
00515
00520 class RTP_UserData : public PObject
00521 {
00522 PCLASSINFO(RTP_UserData, PObject);
00523
00524 public:
00531 virtual void OnTxStatistics(
00532 const RTP_Session & session
00533 ) const;
00534
00541 virtual void OnRxStatistics(
00542 const RTP_Session & session
00543 ) const;
00544 };
00545
00546
00549 class RTP_Session : public PObject
00550 {
00551 PCLASSINFO(RTP_Session, PObject);
00552
00553 public:
00558 RTP_Session(
00559 unsigned id,
00560 RTP_UserData * userData = NULL,
00561 BOOL autoDeleteUserData = TRUE
00562 );
00563
00567 ~RTP_Session();
00569
00581 void SetJitterBufferSize(
00582 unsigned minJitterDelay,
00583 unsigned maxJitterDelay,
00584 unsigned timeUnits = 8,
00585 PINDEX stackSize = 30000
00586 );
00587
00593 unsigned GetJitterBufferSize() const;
00594
00597 unsigned GetJitterTimeUnits() const;
00598
00600 virtual BOOL ModifyQOS(RTP_QOS * )
00601 { return FALSE; }
00602
00608 BOOL ReadBufferedData(
00609 DWORD timestamp,
00610 RTP_DataFrame & frame
00611 );
00612
00618 virtual BOOL ReadData(
00619 RTP_DataFrame & frame
00620 ) = 0;
00621
00624 virtual BOOL WriteData(
00625 RTP_DataFrame & frame
00626 ) = 0;
00627
00630 virtual BOOL WriteControl(
00631 RTP_ControlFrame & frame
00632 ) = 0;
00633
00636 virtual BOOL SendReport();
00637
00640 virtual void Close(
00641 BOOL reading
00642 ) = 0;
00643
00646 virtual void Reopen(
00647 BOOL isReading
00648 ) = 0;
00649
00652 virtual PString GetLocalHostName() = 0;
00654
00657 enum SendReceiveStatus {
00658 e_ProcessPacket,
00659 e_IgnorePacket,
00660 e_AbortTransport
00661 };
00662 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00663 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame);
00664 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00665
00666 class ReceiverReport : public PObject {
00667 PCLASSINFO(ReceiverReport, PObject);
00668 public:
00669 void PrintOn(ostream &) const;
00670
00671 DWORD sourceIdentifier;
00672 DWORD fractionLost;
00673 DWORD totalLost;
00674 DWORD lastSequenceNumber;
00675 DWORD jitter;
00676 PTimeInterval lastTimestamp;
00677 PTimeInterval delay;
00678 };
00679 PARRAY(ReceiverReportArray, ReceiverReport);
00680
00681 class SenderReport : public PObject {
00682 PCLASSINFO(SenderReport, PObject);
00683 public:
00684 void PrintOn(ostream &) const;
00685
00686 DWORD sourceIdentifier;
00687 PTime realTimestamp;
00688 DWORD rtpTimestamp;
00689 DWORD packetsSent;
00690 DWORD octetsSent;
00691 };
00692 virtual void OnRxSenderReport(const SenderReport & sender,
00693 const ReceiverReportArray & reports);
00694 virtual void OnRxReceiverReport(DWORD src,
00695 const ReceiverReportArray & reports);
00696
00697 class SourceDescription : public PObject {
00698 PCLASSINFO(SourceDescription, PObject);
00699 public:
00700 SourceDescription(DWORD src) { sourceIdentifier = src; }
00701 void PrintOn(ostream &) const;
00702
00703 DWORD sourceIdentifier;
00704 POrdinalToString items;
00705 };
00706 PARRAY(SourceDescriptionArray, SourceDescription);
00707 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00708
00709 virtual void OnRxGoodbye(const PDWORDArray & sources,
00710 const PString & reason);
00711
00712 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00713 const BYTE * data, PINDEX size);
00715
00720 unsigned GetSessionID() const { return sessionID; }
00721
00724 PString GetCanonicalName() const;
00725
00728 void SetCanonicalName(const PString & name);
00729
00732 PString GetToolName() const;
00733
00736 void SetToolName(const PString & name);
00737
00740 RTP_UserData * GetUserData() const { return userData; }
00741
00744 void SetUserData(
00745 RTP_UserData * data,
00746 BOOL autoDeleteUserData = TRUE
00747 );
00748
00751 DWORD GetSyncSourceOut() const { return syncSourceOut; }
00752
00755 void IncrementReference() { referenceCount++; }
00756
00759 BOOL DecrementReference() { return --referenceCount == 0; }
00760
00763 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
00764
00767 void SetIgnoreOtherSources(
00768 BOOL ignore
00769 ) { ignoreOtherSources = ignore; }
00770
00773 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00774
00777 void SetIgnoreOutOfOrderPackets(
00778 BOOL ignore
00779 ) { ignoreOutOfOrderPackets = ignore; }
00780
00783 void SetIgnorePayloadTypeChanges(
00784 BOOL ignore
00785 ) { ignorePayloadTypeChanges = ignore; }
00786
00789 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00790
00793 void SetReportTimeInterval(
00794 const PTimeInterval & interval
00795 ) { reportTimeInterval = interval; }
00796
00799 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00800
00803 void SetTxStatisticsInterval(
00804 unsigned packets
00805 );
00806
00809 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00810
00813 void SetRxStatisticsInterval(
00814 unsigned packets
00815 );
00816
00819 DWORD GetPacketsSent() const { return packetsSent; }
00820
00823 DWORD GetOctetsSent() const { return octetsSent; }
00824
00827 DWORD GetPacketsReceived() const { return packetsReceived; }
00828
00831 DWORD GetOctetsReceived() const { return octetsReceived; }
00832
00835 DWORD GetPacketsLost() const { return packetsLost; }
00836
00839 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00840
00843 DWORD GetPacketsTooLate() const;
00844
00849 DWORD GetAverageSendTime() const { return averageSendTime; }
00850
00855 DWORD GetMaximumSendTime() const { return maximumSendTime; }
00856
00861 DWORD GetMinimumSendTime() const { return minimumSendTime; }
00862
00867 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00868
00873 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00874
00879 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00880
00885 DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00886
00890 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00892
00893 protected:
00894 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00895
00896 unsigned sessionID;
00897 PString canonicalName;
00898 PString toolName;
00899 unsigned referenceCount;
00900 RTP_UserData * userData;
00901 BOOL autoDeleteUserData;
00902 RTP_JitterBuffer * jitter;
00903
00904 BOOL ignoreOtherSources;
00905 BOOL ignoreOutOfOrderPackets;
00906 DWORD syncSourceOut;
00907 DWORD syncSourceIn;
00908 BOOL allowSyncSourceInChange;
00909 BOOL allowRemoteTransmitAddressChange;
00910 BOOL allowSequenceChange;
00911 PTimeInterval reportTimeInterval;
00912 unsigned txStatisticsInterval;
00913 unsigned rxStatisticsInterval;
00914 WORD lastSentSequenceNumber;
00915 WORD expectedSequenceNumber;
00916 DWORD lastSentTimestamp;
00917 PTimeInterval lastSentPacketTime;
00918 PTimeInterval lastReceivedPacketTime;
00919 WORD lastRRSequenceNumber;
00920 PINDEX consecutiveOutOfOrderPackets;
00921
00922
00923 DWORD packetsSent;
00924 DWORD octetsSent;
00925 DWORD packetsReceived;
00926 DWORD octetsReceived;
00927 DWORD packetsLost;
00928 DWORD packetsOutOfOrder;
00929 DWORD averageSendTime;
00930 DWORD maximumSendTime;
00931 DWORD minimumSendTime;
00932 DWORD averageReceiveTime;
00933 DWORD maximumReceiveTime;
00934 DWORD minimumReceiveTime;
00935 DWORD jitterLevel;
00936 DWORD maximumJitterLevel;
00937
00938 unsigned txStatisticsCount;
00939 unsigned rxStatisticsCount;
00940
00941 DWORD averageSendTimeAccum;
00942 DWORD maximumSendTimeAccum;
00943 DWORD minimumSendTimeAccum;
00944 DWORD averageReceiveTimeAccum;
00945 DWORD maximumReceiveTimeAccum;
00946 DWORD minimumReceiveTimeAccum;
00947 DWORD packetsLostSinceLastRR;
00948 DWORD lastTransitTime;
00949
00950 RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
00951 BOOL ignorePayloadTypeChanges;
00952
00953 PMutex reportMutex;
00954 PTimer reportTimer;
00955 };
00956
00957
00960 class RTP_SessionManager : public PObject
00961 {
00962 PCLASSINFO(RTP_SessionManager, PObject);
00963
00964 public:
00969 RTP_SessionManager();
00970 RTP_SessionManager(const RTP_SessionManager & sm);
00971 RTP_SessionManager & operator=(const RTP_SessionManager & sm);
00973
00974
00988 RTP_Session * UseSession(
00989 unsigned sessionID
00990 );
00991
00998 void AddSession(
00999 RTP_Session * session
01000 );
01001
01005 void ReleaseSession(
01006 unsigned sessionID,
01007 BOOL clearAll = FALSE
01008 );
01009
01014 RTP_Session * GetSession(
01015 unsigned sessionID
01016 ) const;
01017
01034 RTP_Session * First();
01035
01042 RTP_Session * Next();
01043
01051 void Exit();
01053
01054
01055 protected:
01056 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
01057 SessionDict sessions;
01058 PMutex mutex;
01059 PINDEX enumerationIndex;
01060 };
01061
01062
01063
01066 class RTP_UDP : public RTP_Session
01067 {
01068 PCLASSINFO(RTP_UDP, RTP_Session);
01069
01070 public:
01075 RTP_UDP(
01076 unsigned id
01077 );
01078
01080 ~RTP_UDP();
01082
01090 virtual BOOL ReadData(RTP_DataFrame & frame);
01091
01094 virtual BOOL WriteData(RTP_DataFrame & frame);
01095
01098 virtual BOOL WriteControl(RTP_ControlFrame & frame);
01099
01102 virtual void Close(
01103 BOOL reading
01104 );
01105
01108 virtual PString GetLocalHostName();
01110
01113 virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
01114
01119 BOOL Open(
01120 PIPSocket::Address localAddress,
01121 WORD portBase,
01122 WORD portMax,
01123 BYTE ipTypeOfService,
01124 PSTUNClient * stun = NULL,
01125 RTP_QOS * rtpqos = NULL
01126 );
01128
01131 virtual void Reopen(BOOL isReading);
01133
01138 PIPSocket::Address GetLocalAddress() const { return localAddress; }
01139
01142 void SetLocalAddress(
01143 const PIPSocket::Address & addr
01144 ) { localAddress = addr; }
01145
01148 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01149
01152 WORD GetLocalDataPort() const { return localDataPort; }
01153
01156 WORD GetLocalControlPort() const { return localControlPort; }
01157
01160 WORD GetRemoteDataPort() const { return remoteDataPort; }
01161
01164 WORD GetRemoteControlPort() const { return remoteControlPort; }
01165
01168 PUDPSocket & GetDataSocket() { return *dataSocket; }
01169
01172 PUDPSocket & GetControlSocket() { return *controlSocket; }
01173
01176 BOOL SetRemoteSocketInfo(
01177 PIPSocket::Address address,
01178 WORD port,
01179 BOOL isDataPort
01180 );
01181
01184 void ApplyQOS(
01185 const PIPSocket::Address & addr
01186 );
01188
01189 protected:
01190 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01191 SendReceiveStatus ReadControlPDU();
01192 SendReceiveStatus ReadDataOrControlPDU(
01193 PUDPSocket & socket,
01194 PBYTEArray & frame,
01195 BOOL fromDataChannel
01196 );
01197
01198 PIPSocket::Address localAddress;
01199 WORD localDataPort;
01200 WORD localControlPort;
01201
01202 PIPSocket::Address remoteAddress;
01203 WORD remoteDataPort;
01204 WORD remoteControlPort;
01205
01206 PIPSocket::Address remoteTransmitAddress;
01207
01208 BOOL shutdownRead;
01209 BOOL shutdownWrite;
01210
01211 PUDPSocket * dataSocket;
01212 PUDPSocket * controlSocket;
01213
01214 BOOL appliedQOS;
01215 };
01216
01217
01218 #endif // __OPAL_RTP_H
01219
01220