OPAL  Version 3.14.3
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: 31009 $
30  * $Author: rjongbloed $
31  * $Date: 2013-11-29 12:26:12 +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_config.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  RTP_ControlFrame(const BYTE * data, PINDEX size, bool dynamic = true);
60 
61  bool IsValid() const;
62 
63  unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
64 
65  unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
66  void SetCount(unsigned count);
67 
68  enum PayloadTypes {
69  e_FirstValidPayloadType = 192, // RFC5761
74  e_Goodbye = 203,
76  e_TransportLayerFeedBack = 205, // RFC4585
78  e_ExtendedReport = 207, // RFC3611
79  e_LastValidPayloadType = 223 // RFC5761
80  };
81 
82  unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
83  void SetPayloadType(unsigned t);
84 
85  PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
86  void SetPayloadSize(PINDEX sz);
87 
88  BYTE * GetPayloadPtr() const;
89 
90  bool ReadNextPacket();
91  bool StartNewPacket();
92  void EndPacket();
93 
94  PINDEX GetCompoundSize() const;
95 
96  bool SetPacketSize(PINDEX size);
97 
98 #pragma pack(1)
99  struct ReceiverReport {
100  PUInt32b ssrc; /* data source being reported */
101  BYTE fraction; /* fraction lost since last SR/RR */
102  BYTE lost[3]; /* cumulative number of packets lost (signed!) */
103  PUInt32b last_seq; /* extended last sequence number received */
104  PUInt32b jitter; /* interarrival jitter */
105  PUInt32b lsr; /* last SR packet from this source */
106  PUInt32b dlsr; /* delay since last SR packet */
107 
108  unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
109  void SetLostPackets(unsigned lost);
110  };
111 
112  struct SenderReport {
113  PUInt32b ntp_sec; /* NTP timestamp */
114  PUInt32b ntp_frac;
115  PUInt32b rtp_ts; /* RTP timestamp */
116  PUInt32b psent; /* packets sent */
117  PUInt32b osent; /* octets sent */
118  };
119 
120  struct ExtendedReport {
121  /* VoIP Metrics Report Block */
122  BYTE bt; /* block type */
123  BYTE type_specific; /* determined by the block definition */
124  PUInt16b length; /* length of the report block */
125  PUInt32b ssrc; /* data source being reported */
126  BYTE loss_rate; /* fraction of RTP data packets lost */
127  BYTE discard_rate; /* fraction of RTP data packets discarded */
128  BYTE burst_density; /* fraction of RTP data packets within burst periods */
129  BYTE gap_density; /* fraction of RTP data packets within inter-burst gaps */
130  PUInt16b burst_duration; /* the mean duration, in ms, of burst periods */
131  PUInt16b gap_duration; /* the mean duration, in ms, of gap periods */
132  PUInt16b round_trip_delay; /* the most recently calculated round trip time */
133  PUInt16b end_system_delay; /* the most recently estimates end system delay */
134  BYTE signal_level; /* voice signal level related to 0 dBm */
135  BYTE noise_level; /* ratio of the silent background level to 0 dBm */
136  BYTE rerl; /* residual echo return loss */
137  BYTE gmin; /* gap threshold */
138  BYTE r_factor; /* voice quality metric of the call */
139  BYTE ext_r_factor; /* external R factor */
140  BYTE mos_lq; /* MOS for listen quality */
141  BYTE mos_cq; /* MOS for conversational quality */
142  BYTE rx_config; /* receiver configuration byte */
143  BYTE reserved; /* reserved for future definition */
144  PUInt16b jb_nominal; /* current nominal jitter buffer delay, in ms */
145  PUInt16b jb_maximum; /* current maximum jitter buffer delay, in ms */
146  PUInt16b jb_absolute; /* current absolute maximum jitter buffer delay, in ms */
147  };
148 
160  };
161 
163  PUInt32b src; /* first SSRC/CSRC */
164  struct Item {
165  BYTE type; /* type of SDES item (enum DescriptionTypes) */
166  BYTE length; /* length of SDES item (in octets) */
167  char data[1]; /* text, not zero-terminated */
168 
169  /* WARNING, SourceDescription may not be big enough to contain length and data, for
170  instance, when type == RTP_ControlFrame::e_END.
171  Be careful whan calling the following function of it may read to over to
172  memory allocated*/
173  unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
174  const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
175  Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
176  } item[1]; /* list of SDES items */
177  };
178 
180  DWORD src
181  );
182 
184  unsigned type,
185  const PString & data
186  );
187 
188  // RFC4585 Feedback Message Type (FMT)
189  unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
190  void SetFbType(unsigned type, PINDEX fciSize);
191 
194  e_TMMBR = 3,
196  };
197 
207  };
208 
209  struct FbHeader {
210  PUInt32b senderSSRC; /* data source of sender of message */
211  PUInt32b mediaSSRC; /* data source of media */
212  };
213 
214  struct FbFIR {
216  PUInt32b requestSSRC;
218  };
219 
220  struct FbTSTO {
222  PUInt32b requestSSRC;
224  BYTE reserver[2];
225  BYTE tradeOff;
226  };
227 
228  // Same for request (e_TMMBR) and notification (e_TMMBN)
229  struct FbTMMB {
231  PUInt32b requestSSRC;
232  PUInt32b bitRateAndOverhead; // Various bit fields
233 
234  unsigned GetBitRate() const;
235  unsigned GetOverhead() const { return bitRateAndOverhead & 0x1ff; }
236  };
237 
239  char m_type[5];
240  unsigned m_subType;
241  DWORD m_SSRC;
242  const BYTE * m_data;
243  PINDEX m_size;
244 
245  ApplDefinedInfo(const char * type, unsigned subType = 0, DWORD ssrc = 0, const BYTE * data = NULL, PINDEX size = 0);
246  ApplDefinedInfo(const RTP_ControlFrame & frame);
247  };
248  void SetApplDefined(const ApplDefinedInfo & info);
249 
250 #pragma pack()
251 
252  protected:
254  PINDEX payloadSize;
255 };
256 
257 
260 class RTP_DataFrame : public PBYTEArray
261 {
262  PCLASSINFO(RTP_DataFrame, PBYTEArray);
263 
264  public:
265  RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
266  RTP_DataFrame(const BYTE * data, PINDEX len, bool dynamic = true);
267 
268  enum {
271  // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
272  MaxMtuPayloadSize = (576-20-16-12)
273  };
274 
276  PCMU, // G.711 u-Law
277  FS1016, // Federal Standard 1016 CELP
278  G721, // ADPCM - Subsumed by G.726
280  GSM, // GSM 06.10
281  G7231, // G.723.1 at 6.3kbps or 5.3 kbps
282  DVI4_8k, // DVI4 at 8kHz sample rate
283  DVI4_16k, // DVI4 at 16kHz sample rate
284  LPC, // LPC-10 Linear Predictive CELP
285  PCMA, // G.711 A-Law
286  G722, // G.722
287  L16_Stereo, // 16 bit linear PCM
288  L16_Mono, // 16 bit linear PCM
289  G723, // G.723
290  CN, // Confort Noise
291  MPA, // MPEG1 or MPEG2 audio
292  G728, // G.728 16kbps CELP
293  DVI4_11k, // DVI4 at 11kHz sample rate
294  DVI4_22k, // DVI4 at 22kHz sample rate
295  G729, // G.729 8kbps
296  Cisco_CN, // Cisco systems comfort noise (unofficial)
297 
298  CelB = 25, // Sun Systems Cell-B video
299  JPEG, // Motion JPEG
300  H261 = 31, // H.261
301  MPV, // MPEG1 or MPEG2 video
302  MP2T, // MPEG2 transport system
303  H263, // H.263
304 
305  T38 = 38, // T.38 (internal)
306 
308 
311 
315  };
316 
317  unsigned GetVersion() const { return (theArray[0]>>6)&3; }
318 
319  bool GetExtension() const { return (theArray[0]&0x10) != 0; }
320  void SetExtension(bool ext);
321 
322  bool GetMarker() const { return (theArray[1]&0x80) != 0; }
323  void SetMarker(bool m);
324 
325  bool GetPadding() const { return (theArray[0]&0x20) != 0; }
326  void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
327  BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
328 
329  PINDEX GetPaddingSize() const { return m_paddingSize > 0 ? m_paddingSize-1 : 0; }
330  bool SetPaddingSize(PINDEX sz);
331 
332  PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
334 
335  WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
336  void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
337 
338  DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
339  void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
340 
341  DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
342  void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
343 
344  PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
345  DWORD GetContribSource(PINDEX idx) const;
346  void SetContribSource(PINDEX idx, DWORD src);
347 
348  PINDEX GetHeaderSize() const { return m_headerSize; }
349 
350  void CopyHeader(const RTP_DataFrame & other);
351  void Copy(const RTP_DataFrame & other);
352 
359  BYTE * GetHeaderExtension(
360  unsigned & id,
361  PINDEX & length,
362  int idx = -1
363  ) const;
364 
370  };
371 
375  BYTE * GetHeaderExtension(
376  HeaderExtensionType type,
377  unsigned id,
378  PINDEX & length
379  ) const;
380 
387  bool SetHeaderExtension(
388  unsigned id,
389  PINDEX length,
390  const BYTE * data,
391  HeaderExtensionType type
392  );
393 
394  PINDEX GetExtensionSizeDWORDs() const; // get the number of 32 bit words in the extension (excluding the header).
395  bool SetExtensionSizeDWORDs(PINDEX sz); // set the number of 32 bit words in the extension (excluding the header)
396 
397  PINDEX GetPayloadSize() const { return m_payloadSize; }
398  bool SetPayloadSize(PINDEX sz);
399  BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); }
400 
401  virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
402 #if PTRACING
403  virtual void PrintOn(ostream & strm) const;
404 #endif
405 
406  // Note this sets the whole packet length, and calculates the various
407  // sub-section sizes: header payload and padding.
408  bool SetPacketSize(PINDEX sz);
409 
410  // Get the packet size including headers, padding etc.
411  PINDEX GetPacketSize() const;
412 
415  PTime GetAbsoluteTime() const { return m_absoluteTime; }
416 
419  void SetAbsoluteTime() { m_absoluteTime.SetCurrentTime(); }
420  void SetAbsoluteTime(const PTime & t) { m_absoluteTime = t; }
421 
426  unsigned GetDiscontinuity() const { return m_discontinuity; }
427 
428  void SetDiscontinuity(unsigned lost) { m_discontinuity = lost; }
429 
430  protected:
431  bool AdjustHeaderSize(PINDEX newSize);
432 
433  PINDEX m_headerSize;
437  unsigned m_discontinuity;
438 
439 #if PTRACING
440  friend ostream & operator<<(ostream & o, PayloadTypes t);
441 #endif
442 };
443 
444 PLIST(RTP_DataFrameList, RTP_DataFrame);
445 
446 
448 
451 class RTPExtensionHeaderInfo : public PObject
452 {
453  PCLASSINFO(RTPExtensionHeaderInfo, PObject);
454  public:
455  unsigned m_id;
456 
457  enum Direction {
458  Undefined = -1,
462  SendRecv
463  } m_direction;
464 
465  PURL m_uri;
466 
467  PString m_attributes;
468 
470  virtual Comparison Compare(const PObject & other) const;
471 
472 #if OPAL_SIP
473  bool ParseSDP(const PString & param);
474  void OutputSDP(ostream & strm) const;
475 #endif
476 };
477 
478 typedef std::set<RTPExtensionHeaderInfo> RTPExtensionHeaders;
479 
480 
481 #if PTRACING
482 class RTP_TRACE_SRC
483 {
484  public:
485  RTP_TRACE_SRC(DWORD src)
486  : m_src(src)
487  {
488  }
489 
490  friend std::ostream & operator<<(std::ostream & strm, const RTP_TRACE_SRC & src)
491  {
492  return strm << src.m_src << " (0x" << std::hex << src.m_src << std::dec << ')';
493  }
494 
495  protected:
496  DWORD m_src;
497 };
498 #endif // PTRACING
499 
500 #endif // OPAL_RTP_RTP_H
501