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 #ifndef __OPAL_RTP_H
00278 #define __OPAL_RTP_H
00279
00280 #ifdef P_USE_PRAGMA
00281 #pragma interface
00282 #endif
00283
00284
00285 #include <ptlib/sockets.h>
00286
00287
00288 class RTP_JitterBuffer;
00289 class PSTUNClient;
00290
00291
00292
00294
00295
00296
00297 class RTP_QOS : public PObject
00298 {
00299 PCLASSINFO(RTP_QOS,PObject);
00300 public:
00301 PQoS dataQoS;
00302 PQoS ctrlQoS;
00303 };
00304
00306
00307
00310 class RTP_DataFrame : public PBYTEArray
00311 {
00312 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00313
00314 public:
00315 RTP_DataFrame(PINDEX payloadSize = 2048);
00316
00317 enum {
00318 ProtocolVersion = 2,
00319 MinHeaderSize = 12,
00320
00321 MaxEthernetPayloadSize = (1518-14-4-8-20-16-12)
00322 };
00323
00324 enum PayloadTypes {
00325 PCMU,
00326 FS1016,
00327 G721,
00328 G726 = G721,
00329 GSM,
00330 G7231,
00331 DVI4_8k,
00332 DVI4_16k,
00333 LPC,
00334 PCMA,
00335 G722,
00336 L16_Stereo,
00337 L16_Mono,
00338 G723,
00339 CN,
00340 MPA,
00341 G728,
00342 DVI4_11k,
00343 DVI4_22k,
00344 G729,
00345 Cisco_CN,
00346
00347 CelB = 25,
00348 JPEG,
00349 H261 = 31,
00350 MPV,
00351 MP2T,
00352 H263,
00353
00354 LastKnownPayloadType,
00355
00356 DynamicBase = 96,
00357 MaxPayloadType = 127,
00358 IllegalPayloadType
00359 };
00360
00361 typedef std::map<PayloadTypes, PayloadTypes> PayloadMapType;
00362
00363 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00364
00365 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; }
00366 void SetExtension(BOOL ext);
00367
00368 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
00369 void SetMarker(BOOL m);
00370
00371 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00372 void SetPayloadType(PayloadTypes t);
00373
00374 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00375 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00376
00377 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00378 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00379
00380 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00381 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00382
00383 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00384 DWORD GetContribSource(PINDEX idx) const;
00385 void SetContribSource(PINDEX idx, DWORD src);
00386
00387 PINDEX GetHeaderSize() const;
00388
00389 int GetExtensionType() const;
00390 void SetExtensionType(int type);
00391 PINDEX GetExtensionSize() const;
00392 BOOL SetExtensionSize(PINDEX sz);
00393 BYTE * GetExtensionPtr() const;
00394
00395 PINDEX GetPayloadSize() const { return payloadSize; }
00396 BOOL SetPayloadSize(PINDEX sz);
00397 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); }
00398
00399 protected:
00400 PINDEX payloadSize;
00401
00402 #if PTRACING
00403 friend ostream & operator<<(ostream & o, PayloadTypes t);
00404 #endif
00405 };
00406
00407 PLIST(RTP_DataFrameList, RTP_DataFrame);
00408
00409
00412 class RTP_ControlFrame : public PBYTEArray
00413 {
00414 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00415
00416 public:
00417 RTP_ControlFrame(PINDEX compoundSize = 2048);
00418
00419 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00420
00421 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00422 void SetCount(unsigned count);
00423
00424 enum PayloadTypes {
00425 e_SenderReport = 200,
00426 e_ReceiverReport,
00427 e_SourceDescription,
00428 e_Goodbye,
00429 e_ApplDefined
00430 };
00431
00432 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00433 void SetPayloadType(unsigned t);
00434
00435 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00436 void SetPayloadSize(PINDEX sz);
00437
00438 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); }
00439
00440 BOOL ReadNextCompound();
00441 BOOL WriteNextCompound();
00442
00443 PINDEX GetCompoundSize() const { return compoundSize; }
00444
00445 #pragma pack(1)
00446 struct ReceiverReport {
00447 PUInt32b ssrc;
00448 BYTE fraction;
00449 BYTE lost[3];
00450 PUInt32b last_seq;
00451 PUInt32b jitter;
00452 PUInt32b lsr;
00453 PUInt32b dlsr;
00454
00455 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00456 void SetLostPackets(unsigned lost);
00457 };
00458
00459 struct SenderReport {
00460 PUInt32b ssrc;
00461 PUInt32b ntp_sec;
00462 PUInt32b ntp_frac;
00463 PUInt32b rtp_ts;
00464 PUInt32b psent;
00465 PUInt32b osent;
00466 };
00467
00468 enum DescriptionTypes {
00469 e_END,
00470 e_CNAME,
00471 e_NAME,
00472 e_EMAIL,
00473 e_PHONE,
00474 e_LOC,
00475 e_TOOL,
00476 e_NOTE,
00477 e_PRIV,
00478 NumDescriptionTypes
00479 };
00480
00481 struct SourceDescription {
00482 PUInt32b src;
00483 struct Item {
00484 BYTE type;
00485 BYTE length;
00486 char data[1];
00487
00488 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00489 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00490 } item[1];
00491 };
00492
00493 SourceDescription & AddSourceDescription(
00494 DWORD src
00495 );
00496
00497 SourceDescription::Item & AddSourceDescriptionItem(
00498 SourceDescription & sdes,
00499 unsigned type,
00500 const PString & data
00501 );
00502 #pragma pack()
00503
00504 protected:
00505 PINDEX compoundOffset;
00506 PINDEX compoundSize;
00507 };
00508
00509
00510 class RTP_Session;
00511
00516 class RTP_UserData : public PObject
00517 {
00518 PCLASSINFO(RTP_UserData, PObject);
00519
00520 public:
00527 virtual void OnTxStatistics(
00528 const RTP_Session & session
00529 ) const;
00530
00537 virtual void OnRxStatistics(
00538 const RTP_Session & session
00539 ) const;
00540 };
00541
00542
00545 class RTP_Session : public PObject
00546 {
00547 PCLASSINFO(RTP_Session, PObject);
00548
00549 public:
00554 RTP_Session(
00555 unsigned id,
00556 RTP_UserData * userData = NULL,
00557 BOOL autoDeleteUserData = TRUE
00558 );
00559
00563 ~RTP_Session();
00565
00577 void SetJitterBufferSize(
00578 unsigned minJitterDelay,
00579 unsigned maxJitterDelay,
00580 unsigned timeUnits = 8,
00581 PINDEX stackSize = 30000
00582 );
00583
00589 unsigned GetJitterBufferSize() const;
00590
00593 unsigned GetJitterTimeUnits() const;
00594
00596 virtual BOOL ModifyQOS(RTP_QOS * )
00597 { return FALSE; }
00598
00604 BOOL ReadBufferedData(
00605 DWORD timestamp,
00606 RTP_DataFrame & frame
00607 );
00608
00614 virtual BOOL ReadData(
00615 RTP_DataFrame & frame
00616 ) = 0;
00617
00620 virtual BOOL WriteData(
00621 RTP_DataFrame & frame
00622 ) = 0;
00623
00626 virtual BOOL WriteControl(
00627 RTP_ControlFrame & frame
00628 ) = 0;
00629
00632 virtual BOOL SendReport();
00633
00636 virtual void Close(
00637 BOOL reading
00638 ) = 0;
00639
00642 virtual void Reopen(
00643 BOOL isReading
00644 ) = 0;
00645
00648 virtual PString GetLocalHostName() = 0;
00650
00653 enum SendReceiveStatus {
00654 e_ProcessPacket,
00655 e_IgnorePacket,
00656 e_AbortTransport
00657 };
00658 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00659 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame);
00660 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00661
00662 class ReceiverReport : public PObject {
00663 PCLASSINFO(ReceiverReport, PObject);
00664 public:
00665 void PrintOn(ostream &) const;
00666
00667 DWORD sourceIdentifier;
00668 DWORD fractionLost;
00669 DWORD totalLost;
00670 DWORD lastSequenceNumber;
00671 DWORD jitter;
00672 PTimeInterval lastTimestamp;
00673 PTimeInterval delay;
00674 };
00675 PARRAY(ReceiverReportArray, ReceiverReport);
00676
00677 class SenderReport : public PObject {
00678 PCLASSINFO(SenderReport, PObject);
00679 public:
00680 void PrintOn(ostream &) const;
00681
00682 DWORD sourceIdentifier;
00683 PTime realTimestamp;
00684 DWORD rtpTimestamp;
00685 DWORD packetsSent;
00686 DWORD octetsSent;
00687 };
00688 virtual void OnRxSenderReport(const SenderReport & sender,
00689 const ReceiverReportArray & reports);
00690 virtual void OnRxReceiverReport(DWORD src,
00691 const ReceiverReportArray & reports);
00692
00693 class SourceDescription : public PObject {
00694 PCLASSINFO(SourceDescription, PObject);
00695 public:
00696 SourceDescription(DWORD src) { sourceIdentifier = src; }
00697 void PrintOn(ostream &) const;
00698
00699 DWORD sourceIdentifier;
00700 POrdinalToString items;
00701 };
00702 PARRAY(SourceDescriptionArray, SourceDescription);
00703 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00704
00705 virtual void OnRxGoodbye(const PDWORDArray & sources,
00706 const PString & reason);
00707
00708 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00709 const BYTE * data, PINDEX size);
00711
00716 unsigned GetSessionID() const { return sessionID; }
00717
00720 PString GetCanonicalName() const;
00721
00724 void SetCanonicalName(const PString & name);
00725
00728 PString GetToolName() const;
00729
00732 void SetToolName(const PString & name);
00733
00736 RTP_UserData * GetUserData() const { return userData; }
00737
00740 void SetUserData(
00741 RTP_UserData * data,
00742 BOOL autoDeleteUserData = TRUE
00743 );
00744
00747 DWORD GetSyncSourceOut() const { return syncSourceOut; }
00748
00751 void IncrementReference() { referenceCount++; }
00752
00755 BOOL DecrementReference() { return --referenceCount == 0; }
00756
00759 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
00760
00763 void SetIgnoreOtherSources(
00764 BOOL ignore
00765 ) { ignoreOtherSources = ignore; }
00766
00769 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00770
00773 void SetIgnoreOutOfOrderPackets(
00774 BOOL ignore
00775 ) { ignoreOutOfOrderPackets = ignore; }
00776
00779 void SetIgnorePayloadTypeChanges(
00780 BOOL ignore
00781 ) { ignorePayloadTypeChanges = ignore; }
00782
00785 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00786
00789 void SetReportTimeInterval(
00790 const PTimeInterval & interval
00791 ) { reportTimeInterval = interval; }
00792
00795 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00796
00799 void SetTxStatisticsInterval(
00800 unsigned packets
00801 );
00802
00805 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00806
00809 void SetRxStatisticsInterval(
00810 unsigned packets
00811 );
00812
00815 DWORD GetPacketsSent() const { return packetsSent; }
00816
00819 DWORD GetOctetsSent() const { return octetsSent; }
00820
00823 DWORD GetPacketsReceived() const { return packetsReceived; }
00824
00827 DWORD GetOctetsReceived() const { return octetsReceived; }
00828
00831 DWORD GetPacketsLost() const { return packetsLost; }
00832
00835 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00836
00839 DWORD GetPacketsTooLate() const;
00840
00845 DWORD GetAverageSendTime() const { return averageSendTime; }
00846
00851 DWORD GetMaximumSendTime() const { return maximumSendTime; }
00852
00857 DWORD GetMinimumSendTime() const { return minimumSendTime; }
00858
00863 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00864
00869 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00870
00875 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00876
00881 DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00882
00886 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00888
00889 protected:
00890 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00891
00892 unsigned sessionID;
00893 PString canonicalName;
00894 PString toolName;
00895 unsigned referenceCount;
00896 RTP_UserData * userData;
00897 BOOL autoDeleteUserData;
00898 RTP_JitterBuffer * jitter;
00899
00900 BOOL ignoreOtherSources;
00901 BOOL ignoreOutOfOrderPackets;
00902 DWORD syncSourceOut;
00903 DWORD syncSourceIn;
00904 BOOL allowSyncSourceInChange;
00905 BOOL allowRemoteTransmitAddressChange;
00906 BOOL allowSequenceChange;
00907 PTimeInterval reportTimeInterval;
00908 unsigned txStatisticsInterval;
00909 unsigned rxStatisticsInterval;
00910 WORD lastSentSequenceNumber;
00911 WORD expectedSequenceNumber;
00912 DWORD lastSentTimestamp;
00913 PTimeInterval lastSentPacketTime;
00914 PTimeInterval lastReceivedPacketTime;
00915 WORD lastRRSequenceNumber;
00916 PINDEX consecutiveOutOfOrderPackets;
00917
00918
00919 DWORD packetsSent;
00920 DWORD octetsSent;
00921 DWORD packetsReceived;
00922 DWORD octetsReceived;
00923 DWORD packetsLost;
00924 DWORD packetsOutOfOrder;
00925 DWORD averageSendTime;
00926 DWORD maximumSendTime;
00927 DWORD minimumSendTime;
00928 DWORD averageReceiveTime;
00929 DWORD maximumReceiveTime;
00930 DWORD minimumReceiveTime;
00931 DWORD jitterLevel;
00932 DWORD maximumJitterLevel;
00933
00934 unsigned txStatisticsCount;
00935 unsigned rxStatisticsCount;
00936
00937 DWORD averageSendTimeAccum;
00938 DWORD maximumSendTimeAccum;
00939 DWORD minimumSendTimeAccum;
00940 DWORD averageReceiveTimeAccum;
00941 DWORD maximumReceiveTimeAccum;
00942 DWORD minimumReceiveTimeAccum;
00943 DWORD packetsLostSinceLastRR;
00944 DWORD lastTransitTime;
00945
00946 RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
00947 BOOL ignorePayloadTypeChanges;
00948
00949 PMutex reportMutex;
00950 PTimer reportTimer;
00951 };
00952
00953
00956 class RTP_SessionManager : public PObject
00957 {
00958 PCLASSINFO(RTP_SessionManager, PObject);
00959
00960 public:
00965 RTP_SessionManager();
00966 RTP_SessionManager(const RTP_SessionManager & sm);
00967 RTP_SessionManager & operator=(const RTP_SessionManager & sm);
00969
00970
00984 RTP_Session * UseSession(
00985 unsigned sessionID
00986 );
00987
00994 void AddSession(
00995 RTP_Session * session
00996 );
00997
01001 void ReleaseSession(
01002 unsigned sessionID
01003 );
01004
01009 RTP_Session * GetSession(
01010 unsigned sessionID
01011 ) const;
01012
01029 RTP_Session * First();
01030
01037 RTP_Session * Next();
01038
01046 void Exit();
01048
01049
01050 protected:
01051 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
01052 SessionDict sessions;
01053 PMutex mutex;
01054 PINDEX enumerationIndex;
01055 };
01056
01057
01058
01061 class RTP_UDP : public RTP_Session
01062 {
01063 PCLASSINFO(RTP_UDP, RTP_Session);
01064
01065 public:
01070 RTP_UDP(
01071 unsigned id
01072 );
01073
01075 ~RTP_UDP();
01077
01085 virtual BOOL ReadData(RTP_DataFrame & frame);
01086
01089 virtual BOOL WriteData(RTP_DataFrame & frame);
01090
01093 virtual BOOL WriteControl(RTP_ControlFrame & frame);
01094
01097 virtual void Close(
01098 BOOL reading
01099 );
01100
01103 virtual PString GetLocalHostName();
01105
01108 virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
01109
01114 BOOL Open(
01115 PIPSocket::Address localAddress,
01116 WORD portBase,
01117 WORD portMax,
01118 BYTE ipTypeOfService,
01119 PSTUNClient * stun = NULL,
01120 RTP_QOS * rtpqos = NULL
01121 );
01123
01126 virtual void Reopen(BOOL isReading);
01128
01133 PIPSocket::Address GetLocalAddress() const { return localAddress; }
01134
01137 void SetLocalAddress(
01138 const PIPSocket::Address & addr
01139 ) { localAddress = addr; }
01140
01143 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01144
01147 WORD GetLocalDataPort() const { return localDataPort; }
01148
01151 WORD GetLocalControlPort() const { return localControlPort; }
01152
01155 WORD GetRemoteDataPort() const { return remoteDataPort; }
01156
01159 WORD GetRemoteControlPort() const { return remoteControlPort; }
01160
01163 PUDPSocket & GetDataSocket() { return *dataSocket; }
01164
01167 PUDPSocket & GetControlSocket() { return *controlSocket; }
01168
01171 BOOL SetRemoteSocketInfo(
01172 PIPSocket::Address address,
01173 WORD port,
01174 BOOL isDataPort
01175 );
01176
01179 void ApplyQOS(
01180 const PIPSocket::Address & addr
01181 );
01183
01184 protected:
01185 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01186 SendReceiveStatus ReadControlPDU();
01187 SendReceiveStatus ReadDataOrControlPDU(
01188 PUDPSocket & socket,
01189 PBYTEArray & frame,
01190 BOOL fromDataChannel
01191 );
01192
01193 PIPSocket::Address localAddress;
01194 WORD localDataPort;
01195 WORD localControlPort;
01196
01197 PIPSocket::Address remoteAddress;
01198 WORD remoteDataPort;
01199 WORD remoteControlPort;
01200
01201 PIPSocket::Address remoteTransmitAddress;
01202
01203 BOOL shutdownRead;
01204 BOOL shutdownWrite;
01205
01206 PUDPSocket * dataSocket;
01207 PUDPSocket * controlSocket;
01208
01209 BOOL appliedQOS;
01210 };
01211
01212
01213 #endif // __OPAL_RTP_H
01214
01215