OPAL  Version 3.14.3
sdp.h
Go to the documentation of this file.
1 /*
2  * sdp.h
3  *
4  * Session Description Protocol
5  *
6  * Open Phone Abstraction Library (OPAL)
7  * Formally known as the Open H323 project.
8  *
9  * Copyright (c) 2001 Equivalence Pty. Ltd.
10  *
11  * The contents of this file are subject to the Mozilla Public License
12  * Version 1.0 (the "License"); you may not use this file except in
13  * compliance with the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/
15  *
16  * Software distributed under the License is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18  * the License for the specific language governing rights and limitations
19  * under the License.
20  *
21  * The Original Code is Open Phone Abstraction Library.
22  *
23  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24  *
25  * Contributor(s): ______________________________________.
26  *
27  * $Revision: 32268 $
28  * $Author: rjongbloed $
29  * $Date: 2014-07-01 15:45:41 +1000 (Tue, 01 Jul 2014) $
30  */
31 
32 #ifndef OPAL_SIP_SDP_H
33 #define OPAL_SIP_SDP_H
34 
35 #ifdef P_USE_PRAGMA
36 #pragma interface
37 #endif
38 
39 #include <opal_config.h>
40 
41 #if OPAL_SDP
42 
43 #include <opal/transports.h>
44 #include <opal/mediatype.h>
45 #include <opal/mediafmt.h>
46 #include <rtp/rtp_session.h>
47 
48 
49 
53 #define OPAL_OPT_OFFER_SDP_PTIME "Offer-SDP-PTime"
54 
62 #define OPAL_OPT_OFFER_RTCP_FB "Offer-RTCP-FB"
63 
68 #define OPAL_OPT_FORCE_RTCP_FB "Force-RTCP-FB"
69 
73 #define OPAL_OPT_OFFER_ICE "Offer-ICE"
74 
75 
77 
78 class SDPBandwidth : public std::map<PCaselessString, OpalBandwidth>
79 {
80  typedef std::map<PCaselessString, OpalBandwidth> BaseClass;
81  public:
82  OpalBandwidth & operator[](const PCaselessString & type);
83  OpalBandwidth operator[](const PCaselessString & type) const;
84  friend ostream & operator<<(ostream & out, const SDPBandwidth & bw);
85  bool Parse(const PString & param);
86  void SetMax(const PCaselessString & type, OpalBandwidth value);
87 };
88 
90 
91 class SDPMediaDescription;
92 
93 class SDPMediaFormat : public PObject
94 {
95  PCLASSINFO(SDPMediaFormat, PObject);
96  protected:
97  SDPMediaFormat(SDPMediaDescription & parent);
98 
99  public:
100  virtual bool FromSDP(
101  const PString & portString
102  );
103 
104  virtual void FromMediaFormat(
105  const OpalMediaFormat & mediaFormat
106  );
107 
108  virtual void PrintOn(ostream & str) const;
109  virtual PObject * Clone() const { return new SDPMediaFormat(*this); }
110 
111  RTP_DataFrame::PayloadTypes GetPayloadType() const { return m_payloadType; }
112 
113  const PCaselessString & GetEncodingName() const { return m_encodingName; }
114  void SetEncodingName(const PString & v) { m_encodingName = v; }
115 
116  void SetFMTP(const PString & _fmtp);
117  PString GetFMTP() const;
118 
119  unsigned GetClockRate(void) { return m_clockRate ; }
120  void SetClockRate(unsigned v) { m_clockRate = v; }
121 
122  void SetParameters(const PString & v) { m_parameters = v; }
123 
124  const OpalMediaFormat & GetMediaFormat() const { return m_mediaFormat; }
125  OpalMediaFormat & GetWritableMediaFormat() { return m_mediaFormat; }
126 
127  virtual bool PreEncode();
128  virtual bool PostDecode(const OpalMediaFormatList & mediaFormats, unsigned bandwidth);
129 
130  protected:
131  virtual void SetMediaFormatOptions(OpalMediaFormat & mediaFormat) const;
132 
133  SDPMediaDescription & m_parent;
134  OpalMediaFormat m_mediaFormat;
135  RTP_DataFrame::PayloadTypes m_payloadType;
136  unsigned m_clockRate;
137  PCaselessString m_encodingName;
138  PString m_parameters;
139  PString m_fmtp;
140 
141  P_REMOVE_VIRTUAL(bool,Initialise(const PString &),false);
142  P_REMOVE_VIRTUAL_VOID(Initialise(const OpalMediaFormat &));
143 
144 };
145 
146 typedef PList<SDPMediaFormat> SDPMediaFormatList;
147 
148 
150 
151 class SDPCommonAttributes
152 {
153  public:
154  // The following enum is arranged so it can be used as a bit mask,
155  // e.g. GetDirection()&SendOnly indicates send is available
156  enum Direction {
157  Undefined = -1,
158  Inactive,
159  RecvOnly,
160  SendOnly,
161  SendRecv
162  };
163 
164  SDPCommonAttributes()
165  : m_direction(Undefined)
166  { }
167 
168  virtual ~SDPCommonAttributes() { }
169 
170  virtual void SetDirection(const Direction & d) { m_direction = d; }
171  virtual Direction GetDirection() const { return m_direction; }
172 
173  virtual OpalBandwidth GetBandwidth(const PString & type) const { return m_bandwidth[type]; }
174  virtual void SetBandwidth(const PString & type, OpalBandwidth value) { m_bandwidth[type] = value; }
175 
176  virtual const SDPBandwidth & GetBandwidth() const { return m_bandwidth; }
177 
178  virtual const RTPExtensionHeaders & GetExtensionHeaders() const { return m_extensionHeaders; }
179  virtual void SetExtensionHeader(const RTPExtensionHeaderInfo & ext) { m_extensionHeaders.insert(ext); }
180 
181  virtual void ParseAttribute(const PString & value);
182  virtual void SetAttribute(const PString & attr, const PString & value);
183 
184  virtual void OutputAttributes(ostream & strm) const;
185 
186  static const PCaselessString & ConferenceTotalBandwidthType();
187  static const PCaselessString & ApplicationSpecificBandwidthType();
188  static const PCaselessString & TransportIndependentBandwidthType(); // RFC3890
189 
190  protected:
191  Direction m_direction;
192  SDPBandwidth m_bandwidth;
193  RTPExtensionHeaders m_extensionHeaders;
194 #if OPAL_ICE
195  PStringSet m_iceOptions;
196 #endif //OPAL_ICE
197 };
198 
199 
201 
202 class SDPMediaDescription : public PObject, public SDPCommonAttributes
203 {
204  PCLASSINFO(SDPMediaDescription, PObject);
205  protected:
206  SDPMediaDescription();
207  SDPMediaDescription(
208  const OpalTransportAddress & address,
209  const OpalMediaType & mediaType
210  );
211 
212  public:
213  virtual bool PreEncode();
214  virtual void Encode(const OpalTransportAddress & commonAddr, ostream & str) const;
215 
216  virtual bool Decode(const PStringArray & tokens);
217  virtual bool Decode(char key, const PString & value);
218  virtual bool PostDecode(const OpalMediaFormatList & mediaFormats);
219 
220  // return the string used within SDP to identify this media type
221  virtual PString GetSDPMediaType() const;
222 
223  // return the string used within SDP to identify the transport used by this media
224  virtual PCaselessString GetSDPTransportType() const;
225 
226  // return the string used in factory to create session
227  virtual PCaselessString GetSessionType() const;
228 
229  virtual const SDPMediaFormatList & GetSDPMediaFormats() const;
230 
231  virtual OpalMediaFormatList GetMediaFormats() const;
232 
233  virtual void AddSDPMediaFormat(SDPMediaFormat * sdpMediaFormat);
234 
235  virtual void AddMediaFormat(const OpalMediaFormat & mediaFormat);
236  virtual void AddMediaFormats(const OpalMediaFormatList & mediaFormats, const OpalMediaType & mediaType);
237 
238 #if OPAL_SRTP
239  virtual void SetCryptoKeys(OpalMediaCryptoKeyList & cryptoKeys);
240  virtual OpalMediaCryptoKeyList GetCryptoKeys() const;
241  virtual bool HasCryptoKeys() const;
242 #endif
243 
244  virtual void SetAttribute(const PString & attr, const PString & value);
245  virtual void OutputAttributes(ostream & str) const;
246 
247  virtual Direction GetDirection() const { return m_mediaAddress.IsEmpty() ? Inactive : m_direction; }
248 
249  virtual bool SetSessionInfo(const OpalMediaSession * session, const SDPMediaDescription * offer);
250  virtual PString GetMediaGroupId() const { return m_mediaGroupId; }
251  virtual void SetMediaGroupId(const PString & id) { m_mediaGroupId = id; }
252 
253  const OpalTransportAddress & GetMediaAddress() const { return m_mediaAddress; }
254  const OpalTransportAddress & GetControlAddress() const { return m_controlAddress; }
255  bool SetAddresses(const OpalTransportAddress & media, const OpalTransportAddress & control);
256 
257  virtual WORD GetPort() const { return m_port; }
258 
259 #if OPAL_ICE
260  PString GetUsername() const { return m_username; }
261  PString GetPassword() const { return m_password; }
262  PNatCandidateList GetCandidates() const { return m_candidates; }
263  bool HasICE() const;
264  void SetICE(
265  const PString & username,
266  const PString & password,
267  const PNatCandidateList & candidates
268  )
269  {
270  m_username = username;
271  m_password = password;
272  m_candidates = candidates;
273  }
274 #endif //OPAL_ICE
275 
276  virtual OpalMediaType GetMediaType() const { return m_mediaType; }
277 
278  virtual void CreateSDPMediaFormats(const PStringArray & tokens);
279  virtual SDPMediaFormat * CreateSDPMediaFormat() = 0;
280 
281  virtual PString GetSDPPortList() const;
282 
283  virtual void ProcessMediaOptions(SDPMediaFormat & sdpFormat, const OpalMediaFormat & mediaFormat);
284 
285 #if OPAL_VIDEO
286  virtual OpalVideoFormat::ContentRole GetContentRole() const { return OpalVideoFormat::eNoRole; }
287 #endif
288 
289  void SetOptionStrings(const PStringOptions & options) { m_stringOptions = options; }
290  const PStringOptions & GetOptionStrings() const { return m_stringOptions; }
291 
292  protected:
293  virtual SDPMediaFormat * FindFormat(PString & str) const;
294 
295  OpalTransportAddress m_mediaAddress;
296  OpalTransportAddress m_controlAddress;
297  PCaselessString m_transportType;
298  PStringOptions m_stringOptions;
299  WORD m_port;
300  WORD m_portCount;
301  OpalMediaType m_mediaType;
302  PString m_mediaGroupId;
303 #if OPAL_ICE
304  PNatCandidateList m_candidates;
305  PString m_username;
306  PString m_password;
307 #endif //OPAL_ICE
308  SDPMediaFormatList m_formats;
309 
310  P_REMOVE_VIRTUAL(SDPMediaFormat *,CreateSDPMediaFormat(const PString &),0);
311  P_REMOVE_VIRTUAL(OpalTransportAddress,GetTransportAddress(),OpalTransportAddress());
312  P_REMOVE_VIRTUAL(PBoolean,SetTransportAddress(const OpalTransportAddress &),false);
313  P_REMOVE_VIRTUAL_VOID(Copy(SDPMediaDescription &));
314 };
315 
316 PARRAY(SDPMediaDescriptionArray, SDPMediaDescription);
317 
318 
319 class SDPDummyMediaDescription : public SDPMediaDescription
320 {
321  PCLASSINFO(SDPDummyMediaDescription, SDPMediaDescription);
322  public:
323  SDPDummyMediaDescription() { }
324  SDPDummyMediaDescription(const OpalTransportAddress & address, const PStringArray & tokens);
325  SDPDummyMediaDescription(const SDPMediaDescription & mediaDescription);
326 
327  virtual PString GetSDPMediaType() const;
328  virtual PCaselessString GetSDPTransportType() const;
329  virtual PCaselessString GetSessionType() const;
330  virtual SDPMediaFormat * CreateSDPMediaFormat();
331  virtual PString GetSDPPortList() const;
332 
333  private:
334  PStringArray m_tokens;
335 };
336 
337 
338 #if OPAL_SRTP
339 class SDPCryptoSuite : public PObject
340 {
341  PCLASSINFO(SDPCryptoSuite, PObject)
342  public:
343  SDPCryptoSuite(unsigned tag);
344 
345  bool SetKeyInfo(const OpalMediaCryptoKeyInfo & keyInfo);
346  OpalMediaCryptoKeyInfo * GetKeyInfo() const;
347 
348  bool Decode(const PString & attrib);
349  void PrintOn(ostream & strm) const;
350 
351  struct KeyParam {
352  KeyParam(const PString & keySalt)
353  : m_keySalt(keySalt)
354  , m_lifetime(0)
355  , m_mkiIndex(0)
356  , m_mkiLength(0)
357  { }
358 
359  PString m_keySalt;
360  PUInt64 m_lifetime;
361  unsigned m_mkiIndex;
362  unsigned m_mkiLength;
363  };
364 
365  unsigned GetTag() const { return m_tag; }
366  const PString & GetName() const { return m_suiteName; }
367 
368  protected:
369  unsigned m_tag;
370  PString m_suiteName;
371  list<KeyParam> m_keyParams;
372  PStringOptions m_sessionParams;
373 };
374 #endif // OPAL_SRTP
375 
376 
378 //
379 // SDP media description for media classes using RTP/AVP transport (audio and video)
380 //
381 
382 class SDPRTPAVPMediaDescription : public SDPMediaDescription
383 {
384  PCLASSINFO(SDPRTPAVPMediaDescription, SDPMediaDescription);
385  public:
386  SDPRTPAVPMediaDescription(const OpalTransportAddress & address, const OpalMediaType & mediaType);
387  virtual bool Decode(const PStringArray & tokens);
388  virtual PCaselessString GetSDPTransportType() const;
389  virtual SDPMediaFormat * CreateSDPMediaFormat();
390  virtual PString GetSDPPortList() const;
391  virtual void OutputAttributes(ostream & str) const;
392 #if OPAL_SRTP
393  virtual void SetCryptoKeys(OpalMediaCryptoKeyList & cryptoKeys);
394  virtual OpalMediaCryptoKeyList GetCryptoKeys() const;
395  virtual bool HasCryptoKeys() const;
396 #endif
397  virtual void SetAttribute(const PString & attr, const PString & value);
398  virtual bool SetSessionInfo(const OpalMediaSession * session, const SDPMediaDescription * offer);
399 
400  void EnableFeedback() { m_enableFeedback = true; }
401 
402  typedef std::map<DWORD, PStringOptions> SsrcInfo;
403  const SsrcInfo & GetSsrcInfo() const { return m_ssrcInfo; }
404 
405  protected:
406  class Format : public SDPMediaFormat
407  {
408  public:
409  Format(SDPRTPAVPMediaDescription & parent) : SDPMediaFormat(parent) { }
410  virtual bool FromSDP(const PString & portString);
411  };
412 
413  bool m_enableFeedback;
414  SsrcInfo m_ssrcInfo;
415 
416 #if OPAL_SRTP
417  PList<SDPCryptoSuite> m_cryptoSuites;
418 #endif
419 };
420 
422 //
423 // SDP media description for audio media
424 //
425 
426 class SDPAudioMediaDescription : public SDPRTPAVPMediaDescription
427 {
428  PCLASSINFO(SDPAudioMediaDescription, SDPRTPAVPMediaDescription);
429  public:
430  SDPAudioMediaDescription(const OpalTransportAddress & address);
431  virtual void OutputAttributes(ostream & str) const;
432  virtual void SetAttribute(const PString & attr, const PString & value);
433  virtual bool PostDecode(const OpalMediaFormatList & mediaFormats);
434 
435  protected:
436  unsigned m_PTime;
437  unsigned m_maxPTime;
438 };
439 
440 
441 #if OPAL_VIDEO
442 
444 //
445 // SDP media description for video media
446 //
447 
448 class SDPVideoMediaDescription : public SDPRTPAVPMediaDescription
449 {
450  PCLASSINFO(SDPVideoMediaDescription, SDPRTPAVPMediaDescription);
451  public:
452  SDPVideoMediaDescription(const OpalTransportAddress & address);
453  virtual SDPMediaFormat * CreateSDPMediaFormat();
454  virtual bool PreEncode();
455  virtual void OutputAttributes(ostream & str) const;
456  virtual void SetAttribute(const PString & attr, const PString & value);
457  virtual bool PostDecode(const OpalMediaFormatList & mediaFormats);
458  virtual OpalVideoFormat::ContentRole GetContentRole() const { return m_contentRole; }
459 
460  protected:
461  class Format : public SDPRTPAVPMediaDescription::Format
462  {
463  public:
464  Format(SDPVideoMediaDescription & parent);
465 
466  virtual void PrintOn(ostream & str) const;
467  virtual PObject * Clone() const { return new Format(*this); }
468 
469  virtual bool PreEncode();
470 
471  void AddRTCP_FB(const PString & str);
472  void SetRTCP_FB(const OpalVideoFormat::RTCPFeedback & v) { m_rtcp_fb = v; }
473  OpalVideoFormat::RTCPFeedback GetRTCP_FB() const { return m_rtcp_fb; }
474 
475  void ParseImageAttr(const PString & params);
476 
477  protected:
478  virtual void SetMediaFormatOptions(OpalMediaFormat & mediaFormat) const;
479 
480  OpalVideoFormat::RTCPFeedback m_rtcp_fb; // RFC4585
481 
482  unsigned m_minRxWidth;
483  unsigned m_minRxHeight;
484  unsigned m_maxRxWidth;
485  unsigned m_maxRxHeight;
486  unsigned m_minTxWidth;
487  unsigned m_minTxHeight;
488  unsigned m_maxTxWidth;
489  unsigned m_maxTxHeight;
490  };
491 
492  OpalVideoFormat::RTCPFeedback m_rtcp_fb;
493  OpalVideoFormat::ContentRole m_contentRole;
494  unsigned m_contentMask;
495 };
496 
497 #endif // OPAL_VIDEO
498 
499 
501 //
502 // SDP media description for application media
503 //
504 
505 class SDPApplicationMediaDescription : public SDPMediaDescription
506 {
507  PCLASSINFO(SDPApplicationMediaDescription, SDPMediaDescription);
508  public:
509  SDPApplicationMediaDescription(const OpalTransportAddress & address);
510  virtual PCaselessString GetSDPTransportType() const;
511  virtual SDPMediaFormat * CreateSDPMediaFormat();
512  virtual PString GetSDPMediaType() const;
513 
514  static const PCaselessString & TypeName();
515 
516  protected:
517  class Format : public SDPMediaFormat
518  {
519  public:
520  Format(SDPApplicationMediaDescription & parent) : SDPMediaFormat(parent) { }
521  virtual bool FromSDP(const PString & portString);
522  };
523 };
524 
526 
527 class SDPSessionDescription : public PObject, public SDPCommonAttributes
528 {
529  PCLASSINFO_WITH_CLONE(SDPSessionDescription, PObject);
530  public:
531  SDPSessionDescription(
532  time_t sessionId,
533  unsigned version,
534  const OpalTransportAddress & address
535  );
536 
537  virtual void PrintOn(ostream & strm) const;
538  virtual PString Encode() const;
539  virtual bool Decode(const PString & str, const OpalMediaFormatList & mediaFormats);
540  virtual void SetAttribute(const PString & attr, const PString & value);
541 
542  void SetSessionName(const PString & v);
543  PString GetSessionName() const { return sessionName; }
544 
545  void SetUserName(const PString & v);
546  PString GetUserName() const { return ownerUsername; }
547 
548  const SDPMediaDescriptionArray & GetMediaDescriptions() const { return mediaDescriptions; }
549 
550  SDPMediaDescription * GetMediaDescriptionByType(const OpalMediaType & rtpMediaType) const;
551  SDPMediaDescription * GetMediaDescriptionByIndex(PINDEX i) const;
552  void AddMediaDescription(SDPMediaDescription * md) { mediaDescriptions.Append(PAssertNULL(md)); }
553 
554  virtual SDPMediaDescription::Direction GetDirection(unsigned) const;
555  bool IsHold() const;
556  bool HasActiveSend() const;
557 
558  const OpalTransportAddress & GetDefaultConnectAddress() const { return defaultConnectAddress; }
559  void SetDefaultConnectAddress(
560  const OpalTransportAddress & address
561  );
562 
563  time_t GetOwnerSessionId() const { return ownerSessionId; }
564  void SetOwnerSessionId(time_t value) { ownerSessionId = value; }
565 
566  unsigned GetOwnerVersion() const { return ownerVersion; }
567  void SetOwnerVersion(unsigned value) { ownerVersion = value; }
568 
569  OpalTransportAddress GetOwnerAddress() const { return ownerAddress; }
570  void SetOwnerAddress(OpalTransportAddress addr) { ownerAddress = addr; }
571 
572  typedef PDictionary<PString, PStringArray> GroupDict;
573  GroupDict GetGroups() const { return m_groups; }
574 
575 #if OPAL_ICE
576  PStringSet GetICEOptions() const { return m_iceOptions; }
577 #endif
578 
579  OpalMediaFormatList GetMediaFormats() const;
580 
581  protected:
582  void ParseOwner(const PString & str);
583 
584  SDPMediaDescriptionArray mediaDescriptions;
585 
586  PINDEX protocolVersion;
587  PString sessionName;
588 
589  PString ownerUsername;
590  time_t ownerSessionId;
591  unsigned ownerVersion;
592  OpalTransportAddress ownerAddress;
593  OpalTransportAddress defaultConnectAddress;
594 
595  GroupDict m_groups;
596  PString m_groupId;
597 };
598 
600 
601 
602 #endif // OPAL_SDP
603 
604 #endif // OPAL_SIP_SDP_H
605 
606 
607 // End of File ///////////////////////////////////////////////////////////////