Coverage Report

Created: 2024-04-23 06:04

/src/resiprocate/resip/stack/SdpContents.hxx
Line
Count
Source (jump to first uncovered line)
1
#if !defined(RESIP_SDPCONTENTS_HXX)
2
#define RESIP_SDPCONTENTS_HXX
3
4
#include <functional>
5
#include <vector>
6
#include <list>
7
#include <iosfwd>
8
#include <map>
9
#include <memory>
10
11
#include "resip/stack/Contents.hxx"
12
#include "resip/stack/Uri.hxx"
13
#include "rutil/Data.hxx"
14
#include "rutil/HashMap.hxx"
15
#include "rutil/HeapInstanceCounter.hxx"
16
17
namespace resip
18
{
19
20
class SdpContents;
21
22
class TrickleIceContents;
23
24
class AttributeHelper
25
{
26
   public:
27
      RESIP_HeapCount(AttributeHelper);
28
      AttributeHelper();
29
      AttributeHelper(const AttributeHelper& rhs);
30
      AttributeHelper& operator=(const AttributeHelper& rhs);
31
32
      bool exists(const Data& key) const;
33
      const std::list<Data>& getValues(const Data& key) const;
34
      EncodeStream& encode(EncodeStream& s) const;
35
      void parse(ParseBuffer& pb);
36
      void addAttribute(const Data& key, const Data& value = Data::Empty);
37
      void clearAttribute(const Data& key);
38
   private:
39
      std::list<std::pair<Data, Data> > mAttributeList;  // used to ensure attribute ordering on encode
40
      HashMap< Data, std::list<Data> > mAttributes;
41
};
42
43
/**
44
   @ingroup sip_payload
45
   @brief  Provides an interface to process and generate SDP bodies (MIME content-type application/sdp). 
46
  * 
47
  * This class performs both the parsing and generation of SDP.  Most 
48
  * interaction with the SDP will be through the Session object, 
49
  * accessible through the session() method.
50
  *
51
  **/
52
class SdpContents : public Contents
53
{
54
   public:
55
      RESIP_HeapCount(SdpContents);
56
      typedef enum {IP4=1, IP6} AddrType;
57
      static const SdpContents Empty;
58
59
      class Session;
60
      
61
      /** @brief  Provides an interface to read and modify SDP
62
        * bodies.
63
        * 
64
        **/
65
      class Session
66
      {
67
         public:
68
            class Medium;
69
70
            /** @brief  parameters for a specific codec are stored in this class.
71
              * 
72
              **/
73
            class Codec
74
            {
75
               public:
76
2
                  Codec() : mName(), mRate(0), mPayloadType(-1) {}
77
                  
78
                  /** @brief full constructor for a Codec.
79
                    * 
80
                    *   This constructor allows a rate and optional parameters to be specified.
81
                    * 
82
                    * @param name a string identifying the codec
83
                    * @param rate number of samples/sec
84
                    * @param parameters optional list of parameters for the codec
85
                    * @param encodingParameters optional encoding parameters for the codec
86
                    * 
87
                    **/
88
                  Codec(const Data& name, unsigned long rate, const Data& parameters = Data::Empty, const Data& encodingParameters = Data::Empty);
89
                  
90
                  /** @brief constructor for a Codec
91
                    * 
92
                    *   This constructor allows for payload type and rate parameters to be specified.
93
                    * 
94
                    * @param name a string identifying the codec
95
                    * @param payloadType RTP payload type to associate with this codec
96
                    * @param rate sample rate of this codec
97
                    * 
98
                    **/
99
                  Codec(const Data& name, int payloadType, int rate=8000);
100
                  Codec(const Codec& rhs);
101
                  Codec& operator=(const Codec& codec);
102
103
                  void parse(ParseBuffer& pb,
104
                             const SdpContents::Session::Medium& medium,
105
                             int payLoadType);
106
                  void assignFormatParameters(const SdpContents::Session::Medium& medium);
107
108
                  /** @brief returns the name of the codec.
109
                    *  @return name of the codec
110
                    **/
111
                  const Data& getName() const;
112
                  /** @brief returns the name of the codec.
113
                    *  @return name of the codec
114
                    **/
115
                  int getRate() const;
116
117
                  /** @brief returns the RTP payload type associated with this codec.
118
                    * @return RTP payload type
119
                    **/
120
0
                  int payloadType() const {return mPayloadType;}
121
                  /** @brief returns the RTP payload type associated with this codec.
122
                    * @return RTP payload type
123
                    **/
124
0
                  int& payloadType() {return mPayloadType;}
125
                  
126
                  /** @brief returns the parameters associated with this codec
127
                    * @return codec parameters
128
                    **/
129
0
                  const Data& parameters() const {return mParameters;}
130
                  /** @brief returns the parameters associated with this codec
131
                    * @return codec parameters
132
                    **/
133
0
                  Data& parameters() {return mParameters;}
134
                  
135
                  /** @brief returns the encoding parameters associated with this codec
136
                    * @return encoding parameters
137
                    **/
138
0
                  const Data& encodingParameters() const {return mEncodingParameters;}
139
                  /** @brief returns the encoding parameters associated with this codec
140
                    * @return encoding parameters
141
                    **/
142
0
                  Data& encodingParameters() {return mEncodingParameters;}
143
144
                  static const Codec ULaw_8000;
145
                  static const Codec GSM_8000;
146
                  static const Codec G723_8000;
147
                  static const Codec ALaw_8000;
148
                  static const Codec G722_8000;
149
                  static const Codec CN;
150
                  static const Codec G729_8000;
151
                  static const Codec H263;
152
153
                  static const Codec TelephoneEvent;
154
                  static const Codec FrfDialedDigit;
155
156
                  typedef HashMap<int, Codec> CodecMap;
157
                  // "static" payload types as defined in RFC 3551.
158
                  // Maps payload type (number) to Codec definition.
159
                  static CodecMap& getStaticCodecs();
160
161
                  friend bool operator==(const Codec&, const Codec&);
162
163
               private:
164
                  Data mName;
165
                  unsigned long mRate;
166
                  int mPayloadType;
167
                  Data mParameters;  // Format parameters
168
                  Data mEncodingParameters;
169
170
                  static std::unique_ptr<CodecMap> sStaticCodecs;
171
                  static bool sStaticCodecsCreated;
172
                  friend EncodeStream& operator<<(EncodeStream&, const Codec&);
173
            };
174
175
            /** @brief  processes o= lines in SDP
176
              **/
177
            class Origin
178
            {
179
               public:
180
                  /** @brief constructor for origin line
181
                    * 
182
                    * @param user session user
183
                    * @param sessionId session ID
184
                    * @param version session version
185
                    * @param addr session address type (IP4 or IP6)
186
                    * @param address IP address of the session
187
                    * 
188
                    **/
189
                  Origin(const Data& user,
190
                         const uint64_t& sessionId,
191
                         const uint64_t& version,
192
                         AddrType addr,
193
                         const Data& address);
194
                  Origin(const Origin& rhs);
195
                  Origin& operator=(const Origin& rhs);
196
197
                  void parse(ParseBuffer& pb);
198
                  EncodeStream& encode(EncodeStream&) const;
199
200
                  /** @brief returns the session ID
201
                    * @return session ID
202
                    **/
203
0
                  const uint64_t& getSessionId() const {return mSessionId;}
204
                  /** @brief returns the session ID
205
                    * @return session ID
206
                    **/
207
0
                  uint64_t& getSessionId() { return mSessionId; }
208
                  
209
                  /** @brief returns the session version
210
                    * @return session version
211
                    **/
212
0
                  const uint64_t& getVersion() const {return mVersion;}
213
                  /** @brief returns the session version
214
                    * @return session version
215
                    **/
216
0
                  uint64_t& getVersion() { return mVersion; }
217
                  /** @brief returns the user string for the session
218
                    * @return user string
219
                    **/
220
0
                  const Data& user() const {return mUser;}
221
                  /** @brief returns the user string for the session
222
                    * @return user string
223
                    **/
224
0
                  Data& user() {return mUser;}
225
                  
226
                  /** @brief returns the session address type
227
                    * 
228
                    * @return address type (IP4 or IP6)
229
                    **/
230
0
                  AddrType getAddressType() const {return mAddrType;}
231
                  /** @brief returns the session address type
232
                    * 
233
                    * @return address type (IP4 or IP6)
234
                    **/
235
0
                  const Data& getAddress() const {return mAddress;}
236
                  
237
                  /** @brief set the address for the session
238
                    * 
239
                    * @param host IP address to associate with the session
240
               * @param type type of addressing
241
                    **/
242
                  void setAddress(const Data& host, AddrType type = IP4);
243
244
               private:
245
                  Origin();
246
247
                  Data mUser;
248
                  uint64_t mSessionId;
249
                  uint64_t mVersion;
250
                  AddrType mAddrType;
251
                  Data mAddress;
252
253
                  friend class Session;
254
            };
255
256
            /** @brief  process e= (email) lines in the SDP
257
              * 
258
              **/
259
            class Email
260
            {
261
               public:
262
                  /** @brief constructor
263
                    * 
264
                    * @param address email address
265
                    * @param freeText string describing the email address
266
                    * 
267
                    **/
268
                  Email(const Data& address,
269
                        const Data& freeText);
270
271
                  Email(const Email& rhs);
272
                  Email& operator=(const Email& rhs);
273
274
                  void parse(ParseBuffer& pb);
275
                  EncodeStream& encode(EncodeStream&) const;
276
277
                  /** @brief returns the email address
278
                    * 
279
                    * @return email address
280
                    **/
281
0
                  const Data& getAddress() const {return mAddress;}
282
                  /** @brief returns the string describing the email address
283
                    * 
284
                    * @return string
285
                    **/
286
0
                  const Data& getFreeText() const {return mFreeText;}
287
288
               private:
289
1.83k
                  Email() {}
290
291
                  Data mAddress;
292
                  Data mFreeText;
293
294
                  friend class Session;
295
            };
296
            
297
            /** @brief  process p= (phone number) lines in the SDP
298
              * 
299
              **/
300
            class Phone
301
            {
302
               public:
303
                  /** @brief constructor
304
                    * 
305
                    * @param number phone number
306
                    * @param freeText text string describing the phone number
307
                    * 
308
                    **/
309
                  Phone(const Data& number,
310
                        const Data& freeText);
311
                  Phone(const Phone& rhs);
312
                  Phone& operator=(const Phone& rhs);
313
314
                  void parse(ParseBuffer& pb);
315
                  EncodeStream& encode(EncodeStream&) const;
316
317
                  
318
                  /** @brief return the phone number
319
                    * 
320
                    * @return phone number
321
                    **/
322
0
                  const Data& getNumber() const {return mNumber;}
323
                  /** @brief return text string describing the phone number
324
                    * 
325
                    * @return text string describing the phone number
326
                    **/
327
0
                  const Data& getFreeText() const {return mFreeText;}
328
329
               private:
330
1.95k
                  Phone() {}
331
332
                  Data mNumber;
333
                  Data mFreeText;
334
335
                  friend class Session;
336
            };
337
338
            /** @brief  Process c= (connection) lines in SDP
339
              * 
340
              * This line specifies the IP address and address type used in the session
341
              * 
342
              **/
343
            class Connection
344
            {
345
               public:
346
                  /** @brief constructor
347
                    * 
348
                    * @param addType address type (IP4 or IP6)
349
                    * @param address IP address
350
               * @param ttl time to live
351
                    * 
352
                    **/
353
                  Connection(AddrType addType,
354
                             const Data& address,
355
                             unsigned long ttl = 0);
356
                  Connection(const Connection& rhs);
357
                  Connection& operator=(const Connection& rhs);
358
359
                  void parse(ParseBuffer& pb);
360
                  EncodeStream& encode(EncodeStream&) const;
361
362
                  /** @brief returns the connection address type
363
                    * 
364
                    * @return address type (IP4 or IP6)
365
                    **/
366
0
                  AddrType getAddressType() const {return mAddrType;}
367
                  
368
                  /** @brief returns the connection address
369
                    * 
370
                    * @return IP address
371
                    **/
372
12.3k
                  const Data& getAddress() const {return mAddress;}
373
                  
374
                  /** @brief set the address for the connection
375
                    * 
376
                    * @param host IP address to associate with the connection
377
               * @param type type of addressing
378
                    **/
379
                  void setAddress(const Data& host, AddrType type = IP4);
380
0
                  unsigned long ttl() const {return mTTL;}
381
0
                  unsigned long& ttl() {return mTTL;}
382
383
               private:
384
                  Connection();
385
386
                  AddrType mAddrType;
387
                  Data mAddress;
388
                  unsigned long mTTL;
389
390
                  friend class Session;
391
                  friend class Medium;
392
            };
393
394
            /** @brief  Process optional b= (bandwidth) lines in SDP
395
              * 
396
              **/
397
            class Bandwidth
398
            {
399
               public:
400
                  /** @brief Constructor
401
                    * 
402
                    * @param modifier alphanumeric word giving the meaning of the bandwidth figure
403
                    * @param kbPerSecond number of kilobits per second
404
                    * 
405
                    **/
406
                  Bandwidth(const Data& modifier,
407
                            unsigned long kbPerSecond);
408
                  Bandwidth(const Bandwidth& rhs);
409
                  Bandwidth& operator=(const Bandwidth& rhs);
410
411
                  void parse(ParseBuffer& pb);
412
                  EncodeStream& encode(EncodeStream&) const;
413
414
                  /** @brief returns the modifier string
415
                    * 
416
                    * @return modifier string
417
                    **/
418
0
                  const Data& modifier() const {return mModifier;}
419
                  /** @brief returns the modifier string
420
                    * 
421
                    * @return modifier string
422
                    **/
423
0
                  Data modifier() {return mModifier;}
424
                  /** @brief returns the number of kilobits/second maximum bandwidth
425
                    * 
426
                    * @return maximum bandwidth in kilobits/second
427
                    **/
428
0
                  unsigned long kbPerSecond() const {return mKbPerSecond;}
429
                  /** @brief returns the number of kilobits/second maximum bandwidth
430
                    * 
431
                    * @return maximum bandwidth in kilobits/second
432
                    **/
433
0
                  unsigned long& kbPerSecond() {return mKbPerSecond;}
434
435
               private:
436
1.78k
                  Bandwidth() {}
437
                  Data mModifier;
438
                  unsigned long mKbPerSecond;
439
440
                  friend class Session;
441
                  friend class Medium;
442
            };
443
444
            /** @brief  Process t= (start/stop time) lines in SDP
445
              * 
446
              **/
447
            class Time
448
            {
449
               public:
450
                  /** @brief Constructor
451
                    * 
452
                    *   The times given are the decimal part of an NTP timestamp.  To convert these values to UNIX time,
453
                    * subtract decimal 2208988800 from the value.
454
                    * 
455
                    * @param start start time
456
                    * @param stop stop time
457
                    * 
458
                    **/
459
                  Time(unsigned long start,
460
                       unsigned long stop);
461
                  Time(const Time& rhs);
462
                  Time& operator=(const Time& rhs);
463
464
                  void parse(ParseBuffer& pb);
465
                  EncodeStream& encode(EncodeStream&) const;
466
467
                  /** @brief  Repeat time.  Not used for SIP
468
                    * 
469
                    **/
470
                  class Repeat
471
                  {
472
                     public:
473
                        Repeat(unsigned long interval,
474
                               unsigned long duration,
475
                               std::list<int> offsets);
476
                        void parse(ParseBuffer& pb);
477
                        EncodeStream& encode(EncodeStream&) const;
478
479
0
                        unsigned long getInterval() const {return mInterval;}
480
0
                        unsigned long getDuration() const {return mDuration;}
481
0
                        const std::list<int> getOffsets() const {return mOffsets;}
482
483
                     private:
484
1.76k
                        Repeat() {}
485
                        unsigned long mInterval;
486
                        unsigned long mDuration;
487
                        std::list<int> mOffsets;
488
489
                        friend class Time;
490
                  };
491
492
                  void addRepeat(const Repeat& repeat);
493
494
                  /** @brief return the start time
495
                    * 
496
                    * @return start time
497
                    **/
498
0
                  unsigned long getStart() const {return mStart;}
499
                  /** @brief return the stop time
500
                    * 
501
                    * @return stop time
502
                    **/
503
0
                  unsigned long getStop() const {return mStop;}
504
0
                  const std::list<Repeat>& getRepeats() const {return mRepeats;}
505
506
               private:
507
1.30k
                  Time() {}
508
                  unsigned long mStart;
509
                  unsigned long mStop;
510
                  std::list<Repeat> mRepeats;
511
512
                  friend class Session;
513
            };
514
            
515
            /** @brief  process z= (timezone) lines
516
              * 
517
              * Not used in SIP
518
              * 
519
              **/
520
            class Timezones
521
            {
522
               public:
523
                  /** @brief  specify the time at which a timezone shift will occur and the offset, in seconds
524
                      @deprecated Unused
525
                  */
526
                  class Adjustment
527
                  {
528
                     public:
529
                        Adjustment(unsigned long time,
530
                                   int offset);
531
                        Adjustment(const Adjustment& rhs);
532
                        Adjustment& operator=(const Adjustment& rhs);
533
534
                        unsigned long time;
535
                        int offset;
536
                  };
537
538
                  Timezones();
539
                  Timezones(const Timezones& rhs);
540
                  Timezones& operator=(const Timezones& rhs);
541
542
                  void parse(ParseBuffer& pb);
543
                  EncodeStream& encode(EncodeStream&) const;
544
545
                  void addAdjustment(const Adjustment& adjusment);
546
0
                  const std::list<Adjustment>& getAdjustments() const {return mAdjustments; }
547
               private:
548
                  std::list<Adjustment> mAdjustments;
549
            };
550
551
            /** @brief  process k= (encryption key) line
552
              * 
553
              **/
554
            class Encryption
555
            {
556
               public:
557
                  typedef enum {NoEncryption = 0, Prompt, Clear, Base64, UriKey} KeyType;
558
                  Encryption(const KeyType& method,
559
                             const Data& key);
560
                  Encryption(const Encryption& rhs);
561
                  Encryption& operator=(const Encryption& rhs);
562
563
564
                  void parse(ParseBuffer& pb);
565
                  EncodeStream& encode(EncodeStream&) const;
566
567
0
                  const KeyType& getMethod() const {return mMethod;}
568
0
                  const KeyType& method() const {return mMethod;}
569
0
                  KeyType& method() {return mMethod;}
570
0
                  const Data& getKey() const {return mKey;}
571
0
                  const Data& key() const {return mKey;}
572
0
                  Data& key() {return mKey;}
573
574
                  Encryption();
575
               private:
576
                  KeyType mMethod;
577
                  Data mKey;
578
            };
579
580
            class Direction;
581
            typedef std::vector<std::reference_wrapper<const SdpContents::Session::Direction>> DirectionList;
582
583
            class Direction
584
            {
585
               public:
586
                  static const Direction INACTIVE;
587
                  static const Direction SENDONLY;
588
                  static const Direction RECVONLY;
589
                  static const Direction SENDRECV;
590
591
                  const std::reference_wrapper<const Direction> cref;
592
593
8
                  const Data& name() const { return mName; }
594
                  typedef std::pair<Data, std::reference_wrapper<const SdpContents::Session::Direction>> Tuple;
595
                  const Tuple tuple() const
596
8
                  {
597
8
                     return Tuple(name(), cref);
598
8
                  }
599
600
0
                  static bool valid(const Data& name) { return directions.find(name) != directions.end(); }
601
0
                  static const Direction& get(const Data& name) { return directions.find(name)->second; }
602
603
0
                  bool send() const { return mSend; }
604
0
                  bool recv() const { return mRecv; }
605
606
0
                  static DirectionList ordered() {
607
0
                     return { Direction::SENDRECV, Direction::RECVONLY, Direction::SENDONLY, Direction::INACTIVE };
608
0
                  }
609
610
0
                  bool operator==(const Direction& d) const { return &d == this || d.mName == mName; }
611
0
                  bool operator<(const Direction& d) const { return mName < d.mName; }
612
613
               private:
614
                  Direction(const Data& name, bool send, bool recv)
615
8
                    : cref(std::ref(*this)), mName(name), mSend(send), mRecv(recv) {};
616
                  Direction(const Direction& d) = delete;
617
                  void operator=(const Direction& d) = delete;
618
619
                  Data mName;
620
                  bool mSend;
621
                  bool mRecv;
622
623
                  static const std::map<Tuple::first_type, Tuple::second_type> directions;
624
            };
625
626
            /** @brief  process m= (media announcement) blocks
627
              * 
628
              **/
629
            class Medium
630
            {
631
               public:
632
                  Medium();
633
                  Medium(const Medium& rhs);
634
                  /** @brief Constructor
635
                    * 
636
                    * @param name media type (audio, video, application, data, etc.)
637
                    * @param port UDP port that will receive RTP
638
                    * @param multicast a misnomer.  If multicast > 1, the next (multicast)
639
                    *   even ports will convey RTP and the next (multicast) odd ports will
640
                    *   convey corresponding RTCP
641
                    * @param protocol the transport used to convey the media.  Usually "RTP/AVP" for SIP.
642
                    * 
643
                    **/
644
                  Medium(const Data& name,
645
                         unsigned long port,
646
                         unsigned long multicast,
647
                         const Data& protocol);
648
                  Medium& operator=(const Medium& rhs);
649
650
                  void parse(ParseBuffer& pb);
651
                  EncodeStream& encode(EncodeStream&) const;
652
653
                  /** @brief add a format identifier to the m= line
654
                    * 
655
                    *   This will need to be called for each codec used in the SDP.
656
                    * 
657
                    * @param format format identifier
658
                    *
659
                    **/
660
                  void addFormat(const Data& format);
661
                  /** @brief set the media connection line.  Optional if main SDP has c= line.
662
                    * 
663
                    * @param connection connection line to use
664
                    **/
665
                  void setConnection(const Connection& connection);
666
                  /** @brief add a media connection line.  Optional if main SDP has c= line.
667
                    * 
668
                    * @param connection connection line to use
669
                    **/                  
670
                  void addConnection(const Connection& connection);
671
                  void setBandwidth(const Bandwidth& bandwidth);
672
                  void addBandwidth(const Bandwidth& bandwidth);
673
                  /** @brief add a media attribute line
674
                    * 
675
                    * @param key attribute key
676
                    * @param value attribute value
677
                    * 
678
                    **/
679
                  void addAttribute(const Data& key, const Data& value = Data::Empty);
680
                  
681
                  /** @brief return the media type
682
                    * 
683
                    * @return media type  
684
                    **/
685
0
                  const Data& name() const {return mName;}
686
                  /** @brief return the media type
687
                    * 
688
                    * @return media type  
689
                    **/                  
690
0
                  Data& name() {return mName;}
691
                  /** @brief return the base port
692
                    * 
693
                    * @return base port  
694
                    **/
695
0
                  int port() const {return mPort;}
696
                  /** @brief return the base port
697
                    * 
698
                    * @return base port  
699
                    **/
700
0
                  unsigned long& port() {return mPort;}
701
                  /** @brief change the base port
702
                    * 
703
                    * @param port new base port
704
                    *  
705
                    **/
706
                  void setPort(int port);
707
                  /** @brief get the value of the first specified RTCP port
708
                   *         or if no rtcp: attribute found, the default port()
709
                   *         value.  RFC 3605.
710
                   *
711
                   *  @return the RTCP port
712
                   */
713
                  int firstRtcpPort() const
714
0
                  {
715
0
                     return exists("rtcp") ? getValues("rtcp").front().convertInt() : port()+1;
716
0
                  }
717
                  /** @brief get the number of transport port pairs
718
                    * 
719
                    * @return number of transport port pairs  
720
                    **/
721
0
                  int multicast() const {return mMulticast;}
722
                  /** @brief get the number of transport port pairs
723
                    * 
724
                    * @return number of transport port pairs  
725
                    **/
726
0
                  unsigned long& multicast() {return mMulticast;}
727
                  /** @brief return the transport protocol
728
                    * 
729
                    * @return transport protocol name  
730
                    **/
731
0
                  const Data& protocol() const {return mProtocol;}
732
                  /** @brief return the transport protocol
733
                    * 
734
                    * @return transport protocol name  
735
                    **/
736
0
                  Data& protocol() {return mProtocol;}
737
738
                  // preferred codec/format interface
739
                  typedef std::list<Codec> CodecContainer;
740
                  /** preferred codec/format interface
741
                     @note internal storage of formats, rtpmap attributes, and 
742
                        ftmp attributes are cleared out after codecs() is 
743
                        called, since they get converted internally as Codec 
744
                        objects
745
                  */
746
                  const CodecContainer& codecs() const;
747
                  CodecContainer& codecs();
748
                  
749
                  /** @brief remove all codecs from SDP **/
750
                  void clearCodecs();
751
                  /** @brief add a codec to the m= line
752
                    * 
753
                    * @param codec codec to add
754
                    *  
755
                    **/
756
                  void addCodec(const Codec& codec);
757
758
                  /** @brief return a list of codec formats
759
                    * 
760
                    *   These formats correspond to RTP payload type identifiers
761
                    * 
762
                    * @note formats are cleared out and converted in codec 
763
                    *   objects when codecs() is called
764
                    * @return list of codec formats  
765
                    **/
766
0
                  const std::list<Data>& getFormats() const {return mFormats;}
767
                  
768
                  /** @brief get optional i= (information) line contents
769
                    * 
770
                    * @return contents  
771
                    **/
772
0
                  const Data& information() const {return mInformation;}
773
                  /** @brief get optional i= (information) line contents
774
                    * 
775
                    * @return contents  
776
                    **/
777
0
                  Data& information() {return mInformation;}
778
                  /** @brief get a list of bandwidth lines
779
                    * 
780
                    * @return list of Bandwidth objects  
781
                    **/
782
0
                  const std::list<Bandwidth>& bandwidths() const {return mBandwidths;}
783
0
                  std::list<Bandwidth>& bandwidths() {return mBandwidths;}
784
785
                  /** @brief get a list of Connection objects, including the Session's c= line.
786
                    * 
787
                    *   If the media's c= line is empty, use the Session's c= line.
788
                    * 
789
                    * @return list of connections  
790
                    **/
791
                  const std::list<Connection> getConnections() const;
792
                  /** @brief get a list of Connection objects from the m= section.  Does not include session c= line.
793
                    * 
794
                    * @return list of connections  
795
                    **/
796
0
                  const std::list<Connection>& getMediumConnections() const {return mConnections;}
797
0
                  std::list<Connection>& getMediumConnections() {return mConnections;}
798
0
                  const Encryption& getEncryption() const {return mEncryption;}
799
0
                  const Encryption& encryption() const {return mEncryption;}
800
0
                  Encryption& encryption() {return mEncryption;}
801
                  /** @brief tests if an a= key is present in the media section
802
                    * 
803
                    * @param key key to check
804
                    *
805
                    * @return true if key exists, false otherwise  
806
                    **/
807
                  bool exists(const Data& key) const;
808
                  /** @brief get the attribute values corresponding to the key
809
                    * 
810
                    * @param key key to check
811
                    *
812
                    * @return list of values for given key
813
                    **/
814
                  const std::list<Data>& getValues(const Data& key) const;
815
                  /** @brief erase all attributes for a given key
816
                    * 
817
                    * @param key key to clear
818
                    *  
819
                    **/
820
                  void clearAttribute(const Data& key);
821
822
                  // Search through this mediums codecs to find and return the first match from the passed in list
823
                  // Note:  The codecList item that matched the codec from the medium is passed back via pMatchingCodec 
824
                  //        if a non-NULL pointer is passed in.  The codec returned if from this medium.
825
                  const Codec& findFirstMatchingCodecs(const CodecContainer& codecs, Codec* pMatchingCodec = 0) const;
826
                  // Search through this mediums codecs to find and return the first match from the passed in medium
827
                  // Note:  The passed in medium's codec that matched the codec from this medium is passed back 
828
                  //        via pMatchingCodec if a non-NULL pointer is passed in.  The codec returned if from this medium.
829
                  const Codec& findFirstMatchingCodecs(const Medium& medium, Codec* pMatchingCodec = 0) const;
830
831
                  /** @brief finds the telephone-event codec
832
                  *
833
                  * @return telephone-event "codec"
834
                  **/
835
                  const Codec& findTelephoneEventPayloadCodec() const;
836
837
                  /** @brief finds the telephone-event payload type
838
                    * 
839
                    * @return payload type of telephone-event "codec"  
840
                    **/
841
                  int findTelephoneEventPayloadType() const;
842
843
                  const Direction& getDirection() const;
844
                  const Direction& getDirection(const Direction& sessionDefault) const;
845
846
               private:
847
                  void setSession(Session* session);
848
                  Session* mSession;
849
850
                  Data mName;
851
                  unsigned long mPort;
852
                  unsigned long mMulticast;
853
                  Data mProtocol;
854
                  std::list<Data> mFormats;
855
                  CodecContainer mCodecs;
856
                  Data mTransport;
857
                  Data mInformation;
858
                  std::list<Connection> mConnections;
859
                  std::list<Bandwidth> mBandwidths;
860
                  Encryption mEncryption;
861
                  AttributeHelper mAttributeHelper;
862
863
                  bool mRtpMapDone;
864
                  typedef HashMap<int, Codec> RtpMap;
865
                  RtpMap mRtpMap;
866
867
                  friend class Session;
868
            };
869
870
            /** @brief session constructor
871
              * 
872
              *   Create a new session from origin line, version, and session anme
873
              * 
874
              * @param version session version
875
              * @param origin Origin line
876
              * @param name session name
877
              * 
878
              **/
879
            Session(int version,
880
                    const Origin& origin,
881
                    const Data& name);
882
883
6.45k
            Session() : mVersion(0) {}
884
            Session(const Session& rhs);
885
            Session& operator=(const Session& rhs);
886
887
            void parse(ParseBuffer& pb);
888
            EncodeStream& encode(EncodeStream&) const;
889
890
            /** @brief return session version
891
              * 
892
              * @return session version  
893
              **/
894
0
            int version() const {return mVersion;}
895
            /** @brief return session version
896
              * 
897
              * @return session version  
898
              **/
899
0
            int& version() {return mVersion;}
900
            /** @brief return session Origin line
901
              * 
902
              * @return Origin line  
903
              **/
904
0
            const Origin& origin() const {return mOrigin;}
905
            /** @brief return session Origin line
906
              * 
907
              * @return Origin line  
908
              **/
909
0
            Origin& origin() {return mOrigin;}
910
            /** @brief return session name
911
              *
912
              * @return name  
913
              **/
914
0
            const Data& name() const {return mName;}
915
            /** @brief return session name
916
              *
917
              * @return name  
918
              **/
919
0
            Data& name() {return mName;}
920
            /** @brief return session Information
921
              *
922
              * @return Information line  
923
              **/
924
0
            const Data& information() const {return mInformation;}
925
            /** @brief return session Information
926
              *
927
              * @return Information line  
928
              **/
929
0
            Data& information() {return mInformation;}
930
            /** @brief return session Uri
931
              *
932
              * @return Uri line  
933
              **/
934
0
            const Uri& uri() const {return mUri;}
935
            /** @brief return session Uri
936
              *
937
              * @return Uri line  
938
              **/
939
0
            Uri& uri() {return mUri;}
940
            /** @brief return session Email list
941
              *
942
              * @return Email list  
943
              **/
944
0
            const std::list<Email>& getEmails() const {return mEmails;}
945
            /** @brief return session Phone number list
946
              *
947
              * @return Phone number list  
948
              **/
949
0
            const std::list<Phone>& getPhones() const {return mPhones;}
950
            /** @brief return session Connection
951
              *
952
              * @return Connection line  
953
              **/
954
0
            const Connection& connection() const {return mConnection;}
955
            /** @brief return session Connection
956
              *
957
              * @return Connection line  
958
              **/
959
0
            Connection& connection() {return mConnection;} // !dlb! optional?
960
            /** @brief check if a c= line is present for the session
961
              * 
962
              * @return true if c= line is present  
963
              **/
964
0
            bool isConnection() const { return mConnection.mAddress != Data::Empty; }
965
            /** @brief return session Bandwidth lines
966
              *
967
              * @return Bandwidth lines  
968
              **/
969
0
            const std::list<Bandwidth>& bandwidths() const {return mBandwidths;}
970
            /** @brief return session Bandwidth lines
971
              *
972
              * @return Bandwidth lines  
973
              **/
974
0
            std::list<Bandwidth>& bandwidths() {return mBandwidths;}
975
            /** @brief return session Time lines
976
              *
977
              * @return Time lines  
978
              **/
979
0
            const std::list<Time>& getTimes() const {return mTimes;}
980
            /** @brief return session Time lines
981
              *
982
              * @return Time lines  
983
              **/
984
0
            std::list<Time>& getTimes() {return mTimes;}
985
0
            const Timezones& getTimezones() const {return mTimezones;}
986
0
            const Encryption& getEncryption() const {return mEncryption;}
987
0
            const Encryption& encryption() const {return mEncryption;}
988
0
            Encryption& encryption() {return mEncryption;}
989
            typedef std::list<Medium> MediumContainer;
990
            /** @brief return session Media lines
991
              *
992
              * @return Media lines  
993
              **/
994
0
            const MediumContainer& media() const {return mMedia;}
995
            /** @brief return session Media lines
996
              *
997
              * @return Media lines  
998
              **/
999
0
            MediumContainer& media() {return mMedia;}
1000
            /** @brief return session Media lines filtered by type
1001
              * @param type the type
1002
              * @return Media lines
1003
              */
1004
            std::list<std::reference_wrapper<Medium>> getMediaByType(const Data& type);
1005
1006
            /** @brief add an e= (email) line to session
1007
              * 
1008
              * @param email Email line to add
1009
              *  
1010
              **/
1011
            void addEmail(const Email& email);
1012
            /** @brief add a p= (phone number) line to session
1013
              * 
1014
              * @param phone Phone line to add
1015
              *  
1016
              **/
1017
            void addPhone(const Phone& phone);
1018
            /** @brief add a b= (Bandwidth) line to session
1019
              * 
1020
              * @param bandwidth Bandwidth line to add
1021
              *  
1022
              **/
1023
            void addBandwidth(const Bandwidth& bandwidth);
1024
            /** @brief add a t= (Time) line to session
1025
              * 
1026
              * @param t Time line to add
1027
              *  
1028
              **/
1029
            void addTime(const Time& t);
1030
            /** @brief add an m= (Medium) section to session
1031
              * 
1032
              * @param medium Medium section to add
1033
              *  
1034
              **/
1035
            void addMedium(const Medium& medium);
1036
            /** @brief remove all Medium sections from session
1037
              *   
1038
              **/
1039
0
            void clearMedium() {  mMedia.clear(); }
1040
            /** @brief erase all attributes for a given key
1041
              * 
1042
              * @param key key to clear
1043
              *  
1044
              **/
1045
            void clearAttribute(const Data& key);
1046
            /** @brief add a session attribute line
1047
              * 
1048
              * @param key attribute key
1049
              * @param value attribute value
1050
              * 
1051
              **/
1052
            void addAttribute(const Data& key, const Data& value = Data::Empty);
1053
            /** @brief tests if an a= key is present in the session
1054
              * 
1055
              * @param key key to check
1056
              *
1057
              * @return true if key exists, false otherwise  
1058
              **/
1059
            bool exists(const Data& key) const;
1060
            /** @brief get the attribute values corresponding to the key
1061
              * 
1062
              * @param key key to check
1063
              *
1064
              * @return list of values for given key
1065
              **/
1066
            const std::list<Data>& getValues(const Data& key) const;
1067
1068
            const Direction& getDirection() const;
1069
            /** @brief examine direction for streams of given types
1070
              *
1071
              * @param types
1072
              * @params protocolTypes
1073
              */
1074
            const Direction& getDirection(const std::set<Data> types,
1075
               const std::set<Data> protocolTypes) const;
1076
1077
            DirectionList getDirections() const;
1078
            DirectionList getNetDirections(const SdpContents& remote) const;
1079
            /** @brief retrieve label (RFC 4574) attributes in a set
1080
              *
1081
              * @return set of label attribute values, if any
1082
              **/
1083
            std::set<Data> getMediaStreamLabels() const;
1084
            /** @brief determine if the SDP appears to conform to WebRTC
1085
              *
1086
              * @return true if the SDP appears to be WebRTC
1087
              */
1088
            bool isWebRTC() const;
1089
1090
            /** @brief determine if ice-options:trickle is present
1091
              * @return true if ice-options:trickle is present
1092
              */
1093
            bool isTrickleIceSupported() const;
1094
            /** @brief apply RFC 4145 COMEDIA transform
1095
              *
1096
              * sets the IP port number of each media to 9 and
1097
              * adds the setup attribute.  Early versions of the
1098
              * draft up to draft-ietf-mmusic-sdp-comedia-05.txt
1099
              * used the attribute name "direction", later versions
1100
              * and the RFC 4145 use the attribute name "setup"
1101
              */
1102
            void transformCOMedia(const Data& setupDirection = "active", const Data& cOMediaAttribute = "setup");
1103
            /** @brief change the direction attributes as if the
1104
              *        peer who created the SDP is on hold or not
1105
              *
1106
              * @param holding whether to represent hold or normal
1107
              */
1108
            void transformLocalHold(bool holding);
1109
            /** @brief find the Medium with given mid value
1110
              * @param mid the mid value to search for
1111
              * @return nullptr if no match found
1112
              */
1113
            const Medium* getMediumByMid(const Data& mid) const;
1114
            /** @brief based on the original SDP in this instances of SdpContents,
1115
             *         find the relevant ICE and m= line(s), copy them into a new
1116
             *         SDP fragment and add the candidate line provided
1117
             *  @param fragment the candidate line to include
1118
              * @return a new TrickleIceContents
1119
              */
1120
            std::shared_ptr<TrickleIceContents> makeIceFragment(const Data& fragment,
1121
               unsigned int lineIndex, const Data& mid);
1122
1123
         private:
1124
            int mVersion;
1125
            Origin mOrigin;
1126
            Data mName;
1127
            MediumContainer mMedia;
1128
1129
            // applies to all Media where unspecified
1130
            Data mInformation;
1131
            Uri mUri;
1132
            std::list<Email> mEmails;
1133
            std::list<Phone> mPhones;
1134
            Connection mConnection;
1135
            std::list<Bandwidth> mBandwidths;
1136
            std::list<Time> mTimes;
1137
            Timezones mTimezones;
1138
            Encryption mEncryption;
1139
            AttributeHelper mAttributeHelper;
1140
1141
            friend class SdpContents;
1142
      };
1143
1144
      SdpContents();
1145
      SdpContents(const HeaderFieldValue& hfv, const Mime& contentTypes);
1146
      virtual ~SdpContents();
1147
1148
      // !nash! there is no need for overriding copy ctor as every members gets copied
1149
      //SdpContents(const SdpContents& rhs);
1150
      SdpContents& operator=(const SdpContents& rhs);
1151
1152
      /** @brief duplicate an SdpContents object
1153
        * 
1154
        * @return pointer to a new SdpContents object  
1155
        **/
1156
      virtual Contents* clone() const;
1157
1158
      /** @brief get the parsed SDP
1159
        * 
1160
        * @return parsed SDP object  
1161
        **/
1162
0
      Session& session() {checkParsed(); return mSession;}
1163
0
      const Session& session() const {checkParsed(); return mSession;}
1164
1165
      virtual EncodeStream& encodeParsed(EncodeStream& str) const;
1166
      virtual void parse(ParseBuffer& pb);
1167
      static const Mime& getStaticType() ;
1168
1169
      static bool init();
1170
1171
   private:
1172
      SdpContents(const Data& data, const Mime& contentTypes);
1173
      Session mSession;
1174
};
1175
1176
static bool invokeSdpContentsInit = SdpContents::init();
1177
1178
// Silence compiler warning for invokeSdpContentsInit defined, but not used
1179
0
static inline void foo(){if(0){(void) invokeSdpContentsInit;}};
Unexecuted instantiation: fuzzStack.cxx:resip::foo()
Unexecuted instantiation: DtmfPayloadContents.cxx:resip::foo()
Unexecuted instantiation: SdpContents.cxx:resip::foo()
Unexecuted instantiation: Transport.cxx:resip::foo()
Unexecuted instantiation: TrickleIceContents.cxx:resip::foo()
Unexecuted instantiation: Uri.cxx:resip::foo()
Unexecuted instantiation: Helper.cxx:resip::foo()
1180
1181
typedef SdpContents::Session::Codec Codec;
1182
1183
bool operator==(const SdpContents::Session::Codec& lhs,
1184
                const SdpContents::Session::Codec& rhs);
1185
bool operator!=(const SdpContents::Session::Codec& lhs,
1186
                const SdpContents::Session::Codec& rhs);
1187
1188
EncodeStream& operator<<(EncodeStream& str, const SdpContents::Session::Codec& codec);
1189
1190
void skipEol(ParseBuffer& pb);
1191
1192
}
1193
1194
#endif
1195
1196
/* ====================================================================
1197
 * The Vovida Software License, Version 1.0
1198
 *
1199
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
1200
 *
1201
 * Redistribution and use in source and binary forms, with or without
1202
 * modification, are permitted provided that the following conditions
1203
 * are met:
1204
 *
1205
 * 1. Redistributions of source code must retain the above copyright
1206
 *    notice, this list of conditions and the following disclaimer.
1207
 *
1208
 * 2. Redistributions in binary form must reproduce the above copyright
1209
 *    notice, this list of conditions and the following disclaimer in
1210
 *    the documentation and/or other materials provided with the
1211
 *    distribution.
1212
 *
1213
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1214
 *    and "Vovida Open Communication Application Library (VOCAL)" must
1215
 *    not be used to endorse or promote products derived from this
1216
 *    software without prior written permission. For written
1217
 *    permission, please contact vocal@vovida.org.
1218
 *
1219
 * 4. Products derived from this software may not be called "VOCAL", nor
1220
 *    may "VOCAL" appear in their name, without prior written
1221
 *    permission of Vovida Networks, Inc.
1222
 *
1223
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1224
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1225
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1226
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
1227
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1228
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1229
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1230
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1231
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1232
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1233
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1234
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1235
 * DAMAGE.
1236
 *
1237
 * ====================================================================
1238
 *
1239
 * This software consists of voluntary contributions made by Vovida
1240
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1241
 * Inc.  For more information on Vovida Networks, Inc., please see
1242
 * <http://www.vovida.org/>.
1243
 *
1244
 */