/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 | | */ |