OPAL  Version 3.12.9
rtp.h
Go to the documentation of this file.
1 /*
2  * rtp.h
3  *
4  * RTP protocol handler
5  *
6  * Open H323 Library
7  *
8  * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Open H323 Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions of this code were written with the assisance of funding from
25  * Vovida Networks, Inc. http://www.vovida.com.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 31007 $
30  * $Author: rjongbloed $
31  * $Date: 2013-11-29 12:10:28 +1100 (Fri, 29 Nov 2013) $
32  */
33 
34 #ifndef OPAL_RTP_RTP_H
35 #define OPAL_RTP_RTP_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #include <opal/buildopts.h>
42 
43 #include <ptclib/url.h>
44 
45 #include <set>
46 
47 
49 // Real Time Protocol - IETF RFC1889 and RFC1890
50 
53 class RTP_ControlFrame : public PBYTEArray
54 {
55  PCLASSINFO(RTP_ControlFrame, PBYTEArray);
56 
57  public:
58  RTP_ControlFrame(PINDEX compoundSize = 2048);
59 
60  unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
61 
62  unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
63  void SetCount(unsigned count);
64 
65  enum PayloadTypes {
66  e_FirstValidPayloadType = 192, // RFC5761
71  e_Goodbye = 203,
73  e_TransportLayerFeedBack = 205, // RFC4585
75  e_ExtendedReport = 207, // RFC3611
76  e_LastValidPayloadType = 223 // RFC5761
77  };
78 
79  unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
80  void SetPayloadType(unsigned t);
81 
82  PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
83  void SetPayloadSize(PINDEX sz);
84 
85  BYTE * GetPayloadPtr() const;
86 
87  bool ReadNextPacket();
88  bool StartNewPacket();
89  void EndPacket();
90 
91  PINDEX GetCompoundSize() const;
92 
93  void Reset(PINDEX size);
94 
95 #pragma pack(1)
96  struct ReceiverReport {
97  PUInt32b ssrc; /* data source being reported */
98  BYTE fraction; /* fraction lost since last SR/RR */
99  BYTE lost[3]; /* cumulative number of packets lost (signed!) */
100  PUInt32b last_seq; /* extended last sequence number received */
101  PUInt32b jitter; /* interarrival jitter */
102  PUInt32b lsr; /* last SR packet from this source */
103  PUInt32b dlsr; /* delay since last SR packet */
104 
105  unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
106  void SetLostPackets(unsigned lost);
107  };
108 
109  struct SenderReport {
110  PUInt32b ntp_sec; /* NTP timestamp */
111  PUInt32b ntp_frac;
112  PUInt32b rtp_ts; /* RTP timestamp */
113  PUInt32b psent; /* packets sent */
114  PUInt32b osent; /* octets sent */
115  };
116 
117  struct ExtendedReport {
118  /* VoIP Metrics Report Block */
119  BYTE bt; /* block type */
120  BYTE type_specific; /* determined by the block definition */
121  PUInt16b length; /* length of the report block */
122  PUInt32b ssrc; /* data source being reported */
123  BYTE loss_rate; /* fraction of RTP data packets lost */
124  BYTE discard_rate; /* fraction of RTP data packets discarded */
125  BYTE burst_density; /* fraction of RTP data packets within burst periods */
126  BYTE gap_density; /* fraction of RTP data packets within inter-burst gaps */
127  PUInt16b burst_duration; /* the mean duration, in ms, of burst periods */
128  PUInt16b gap_duration; /* the mean duration, in ms, of gap periods */
129  PUInt16b round_trip_delay; /* the most recently calculated round trip time */
130  PUInt16b end_system_delay; /* the most recently estimates end system delay */
131  BYTE signal_level; /* voice signal level related to 0 dBm */
132  BYTE noise_level; /* ratio of the silent background level to 0 dBm */
133  BYTE rerl; /* residual echo return loss */
134  BYTE gmin; /* gap threshold */
135  BYTE r_factor; /* voice quality metric of the call */
136  BYTE ext_r_factor; /* external R factor */
137  BYTE mos_lq; /* MOS for listen quality */
138  BYTE mos_cq; /* MOS for conversational quality */
139  BYTE rx_config; /* receiver configuration byte */
140  BYTE reserved; /* reserved for future definition */
141  PUInt16b jb_nominal; /* current nominal jitter buffer delay, in ms */
142  PUInt16b jb_maximum; /* current maximum jitter buffer delay, in ms */
143  PUInt16b jb_absolute; /* current absolute maximum jitter buffer delay, in ms */
144  };
145 
157  };
158 
160  PUInt32b src; /* first SSRC/CSRC */
161  struct Item {
162  BYTE type; /* type of SDES item (enum DescriptionTypes) */
163  BYTE length; /* length of SDES item (in octets) */
164  char data[1]; /* text, not zero-terminated */
165 
166  /* WARNING, SourceDescription may not be big enough to contain length and data, for
167  instance, when type == RTP_ControlFrame::e_END.
168  Be careful whan calling the following function of it may read to over to
169  memory allocated*/
170  unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
171  const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
172  Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
173  } item[1]; /* list of SDES items */
174  };
175 
177  DWORD src
178  );
179 
181  unsigned type,
182  const PString & data
183  );
184 
185  // RFC4585 Feedback Message Type (FMT)
186  unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
187  void SetFbType(unsigned type, PINDEX fciSize);
188 
191  e_TMMBR = 3,
193  };
194 
204  };
205 
206  struct FbHeader {
207  PUInt32b senderSSRC; /* data source of sender of message */
208  PUInt32b mediaSSRC; /* data source of media */
209  };
210 
211  struct FbFIR {
213  PUInt32b requestSSRC;
215  };
216 
217  struct FbTSTO {
219  PUInt32b requestSSRC;
221  BYTE reserver[2];
222  BYTE tradeOff;
223  };
224 
225  // Same for request (e_TMMBR) and notification (e_TMMBN)
226  struct FbTMMB {
228  PUInt32b requestSSRC;
229  PUInt32b bitRateAndOverhead; // Various bit fields
230 
231  unsigned GetBitRate() const;
232  unsigned GetOverhead() const { return bitRateAndOverhead & 0x1ff; }
233  };
234 
235 #pragma pack()
236 
237  protected:
239  PINDEX payloadSize;
240 };
241 
242 
245 class RTP_DataFrame : public PBYTEArray
246 {
247  PCLASSINFO(RTP_DataFrame, PBYTEArray);
248 
249  public:
250  RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
251  RTP_DataFrame(const BYTE * data, PINDEX len, bool dynamic = true);
252 
253  enum {
256  // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
257  MaxMtuPayloadSize = (576-20-16-12)
258  };
259 
261  PCMU, // G.711 u-Law
262  FS1016, // Federal Standard 1016 CELP
263  G721, // ADPCM - Subsumed by G.726
265  GSM, // GSM 06.10
266  G7231, // G.723.1 at 6.3kbps or 5.3 kbps
267  DVI4_8k, // DVI4 at 8kHz sample rate
268  DVI4_16k, // DVI4 at 16kHz sample rate
269  LPC, // LPC-10 Linear Predictive CELP
270  PCMA, // G.711 A-Law
271  G722, // G.722
272  L16_Stereo, // 16 bit linear PCM
273  L16_Mono, // 16 bit linear PCM
274  G723, // G.723
275  CN, // Confort Noise
276  MPA, // MPEG1 or MPEG2 audio
277  G728, // G.728 16kbps CELP
278  DVI4_11k, // DVI4 at 11kHz sample rate
279  DVI4_22k, // DVI4 at 22kHz sample rate
280  G729, // G.729 8kbps
281  Cisco_CN, // Cisco systems comfort noise (unofficial)
282 
283  CelB = 25, // Sun Systems Cell-B video
284  JPEG, // Motion JPEG
285  H261 = 31, // H.261
286  MPV, // MPEG1 or MPEG2 video
287  MP2T, // MPEG2 transport system
288  H263, // H.263
289 
290  T38 = 38, // T.38 (internal)
291 
293 
296 
300  };
301 
302  unsigned GetVersion() const { return (theArray[0]>>6)&3; }
303 
304  bool GetExtension() const { return (theArray[0]&0x10) != 0; }
305  void SetExtension(bool ext);
306 
307  bool GetMarker() const { return (theArray[1]&0x80) != 0; }
308  void SetMarker(bool m);
309 
310  bool GetPadding() const { return (theArray[0]&0x20) != 0; }
311  void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
312  BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
313 
314  PINDEX GetPaddingSize() const { return m_paddingSize; }
315  bool SetPaddingSize(PINDEX sz);
316 
317  PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
319 
320  WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
321  void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
322 
323  DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
324  void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
325 
326  DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
327  void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
328 
329  PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
330  DWORD GetContribSource(PINDEX idx) const;
331  void SetContribSource(PINDEX idx, DWORD src);
332 
333  PINDEX GetHeaderSize() const { return m_headerSize; }
334 
335  void CopyHeader(const RTP_DataFrame & other);
336 
343  BYTE * GetHeaderExtension(
344  unsigned & id,
345  PINDEX & length,
346  int idx = -1
347  ) const;
348 
354  };
355 
359  BYTE * GetHeaderExtension(
360  HeaderExtensionType type,
361  unsigned id,
362  PINDEX & length
363  ) const;
364 
371  bool SetHeaderExtension(
372  unsigned id,
373  PINDEX length,
374  const BYTE * data,
375  HeaderExtensionType type
376  );
377 
378  PINDEX GetExtensionSizeDWORDs() const; // get the number of 32 bit words in the extension (excluding the header).
379  bool SetExtensionSizeDWORDs(PINDEX sz); // set the number of 32 bit words in the extension (excluding the header)
380 
381  PINDEX GetPayloadSize() const { return m_payloadSize; }
382  bool SetPayloadSize(PINDEX sz);
383  BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); }
384 
385  virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
386  virtual void PrintOn(ostream & strm) const;
387 
388  // Note this sets the whole packet length, and calculates the various
389  // sub-section sizes: header payload and padding.
390  bool SetPacketSize(PINDEX sz);
391 
394  PTime GetAbsoluteTime() const { return m_absoluteTime; }
395 
398  void SetAbsoluteTime() { m_absoluteTime.SetCurrentTime(); }
399  void SetAbsoluteTime(const PTime & t) { m_absoluteTime = t; }
400 
405  unsigned GetDiscontinuity() const { return m_discontinuity; }
406 
407  void SetDiscontinuity(unsigned lost) { m_discontinuity = lost; }
408 
409  protected:
410  PINDEX m_headerSize;
414  unsigned m_discontinuity;
415 
416 #if PTRACING
417  friend ostream & operator<<(ostream & o, PayloadTypes t);
418 #endif
419 };
420 
421 PLIST(RTP_DataFrameList, RTP_DataFrame);
422 
423 
425 
428 class RTPExtensionHeaderInfo : public PObject
429 {
430  PCLASSINFO(RTPExtensionHeaderInfo, PObject);
431  public:
432  unsigned m_id;
433 
434  enum Direction {
435  Undefined = -1,
439  SendRecv
440  } m_direction;
441 
442  PURL m_uri;
443 
444  PString m_attributes;
445 
447  virtual Comparison Compare(const PObject & other) const;
448 
449 #if OPAL_SIP
450  bool ParseSDP(const PString & param);
451  void OutputSDP(ostream & strm) const;
452 #endif
453 };
454 
455 typedef std::set<RTPExtensionHeaderInfo> RTPExtensionHeaders;
456 
457 
458 #endif // OPAL_RTP_RTP_H
459