Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef _SDPATTRIBUTE_H_
8 : #define _SDPATTRIBUTE_H_
9 :
10 : #include <algorithm>
11 : #include <cctype>
12 : #include <vector>
13 : #include <ostream>
14 : #include <sstream>
15 : #include <cstring>
16 : #include <iomanip>
17 : #include <string>
18 :
19 : #include "mozilla/UniquePtr.h"
20 : #include "mozilla/Attributes.h"
21 : #include "mozilla/Assertions.h"
22 : #include "mozilla/Maybe.h"
23 :
24 : #include "signaling/src/sdp/SdpEnum.h"
25 : #include "signaling/src/common/EncodingConstraints.h"
26 :
27 : namespace mozilla
28 : {
29 :
30 : /**
31 : * Base class for SDP attributes
32 : */
33 0 : class SdpAttribute
34 : {
35 : public:
36 : enum AttributeType {
37 : kFirstAttribute = 0,
38 : kBundleOnlyAttribute = 0,
39 : kCandidateAttribute,
40 : kConnectionAttribute,
41 : kDirectionAttribute,
42 : kDtlsMessageAttribute,
43 : kEndOfCandidatesAttribute,
44 : kExtmapAttribute,
45 : kFingerprintAttribute,
46 : kFmtpAttribute,
47 : kGroupAttribute,
48 : kIceLiteAttribute,
49 : kIceMismatchAttribute,
50 : kIceOptionsAttribute,
51 : kIcePwdAttribute,
52 : kIceUfragAttribute,
53 : kIdentityAttribute,
54 : kImageattrAttribute,
55 : kInactiveAttribute,
56 : kLabelAttribute,
57 : kMaxptimeAttribute,
58 : kMidAttribute,
59 : kMsidAttribute,
60 : kMsidSemanticAttribute,
61 : kPtimeAttribute,
62 : kRecvonlyAttribute,
63 : kRemoteCandidatesAttribute,
64 : kRidAttribute,
65 : kRtcpAttribute,
66 : kRtcpFbAttribute,
67 : kRtcpMuxAttribute,
68 : kRtcpRsizeAttribute,
69 : kRtpmapAttribute,
70 : kSctpmapAttribute,
71 : kSendonlyAttribute,
72 : kSendrecvAttribute,
73 : kSetupAttribute,
74 : kSimulcastAttribute,
75 : kSsrcAttribute,
76 : kSsrcGroupAttribute,
77 : kSctpPortAttribute,
78 : kMaxMessageSizeAttribute,
79 : kLastAttribute = kMaxMessageSizeAttribute
80 : };
81 :
82 0 : explicit SdpAttribute(AttributeType type) : mType(type) {}
83 0 : virtual ~SdpAttribute() {}
84 :
85 : AttributeType
86 0 : GetType() const
87 : {
88 0 : return mType;
89 : }
90 :
91 : virtual void Serialize(std::ostream&) const = 0;
92 :
93 : static bool IsAllowedAtSessionLevel(AttributeType type);
94 : static bool IsAllowedAtMediaLevel(AttributeType type);
95 : static const std::string GetAttributeTypeString(AttributeType type);
96 :
97 : protected:
98 : AttributeType mType;
99 : };
100 :
101 0 : inline std::ostream& operator<<(std::ostream& os, const SdpAttribute& attr)
102 : {
103 0 : attr.Serialize(os);
104 0 : return os;
105 : }
106 :
107 0 : inline std::ostream& operator<<(std::ostream& os,
108 : const SdpAttribute::AttributeType type)
109 : {
110 0 : os << SdpAttribute::GetAttributeTypeString(type);
111 0 : return os;
112 : }
113 :
114 : ///////////////////////////////////////////////////////////////////////////
115 : // a=candidate, RFC5245
116 : //-------------------------------------------------------------------------
117 : //
118 : // candidate-attribute = "candidate" ":" foundation SP component-id SP
119 : // transport SP
120 : // priority SP
121 : // connection-address SP ;from RFC 4566
122 : // port ;port from RFC 4566
123 : // SP cand-type
124 : // [SP rel-addr]
125 : // [SP rel-port]
126 : // *(SP extension-att-name SP
127 : // extension-att-value)
128 : // foundation = 1*32ice-char
129 : // component-id = 1*5DIGIT
130 : // transport = "UDP" / transport-extension
131 : // transport-extension = token ; from RFC 3261
132 : // priority = 1*10DIGIT
133 : // cand-type = "typ" SP candidate-types
134 : // candidate-types = "host" / "srflx" / "prflx" / "relay" / token
135 : // rel-addr = "raddr" SP connection-address
136 : // rel-port = "rport" SP port
137 : // extension-att-name = byte-string ;from RFC 4566
138 : // extension-att-value = byte-string
139 : // ice-char = ALPHA / DIGIT / "+" / "/"
140 :
141 : // We use a SdpMultiStringAttribute for candidates
142 :
143 : ///////////////////////////////////////////////////////////////////////////
144 : // a=connection, RFC4145
145 : //-------------------------------------------------------------------------
146 : // connection-attr = "a=connection:" conn-value
147 : // conn-value = "new" / "existing"
148 0 : class SdpConnectionAttribute : public SdpAttribute
149 : {
150 : public:
151 : enum ConnValue { kNew, kExisting };
152 :
153 : explicit SdpConnectionAttribute(SdpConnectionAttribute::ConnValue value)
154 : : SdpAttribute(kConnectionAttribute), mValue(value)
155 : {
156 : }
157 :
158 : virtual void Serialize(std::ostream& os) const override;
159 :
160 : ConnValue mValue;
161 : };
162 :
163 0 : inline std::ostream& operator<<(std::ostream& os,
164 : SdpConnectionAttribute::ConnValue c)
165 : {
166 0 : switch (c) {
167 : case SdpConnectionAttribute::kNew:
168 0 : os << "new";
169 0 : break;
170 : case SdpConnectionAttribute::kExisting:
171 0 : os << "existing";
172 0 : break;
173 : default:
174 0 : MOZ_ASSERT(false);
175 : os << "?";
176 : }
177 0 : return os;
178 : }
179 :
180 : ///////////////////////////////////////////////////////////////////////////
181 : // a=sendrecv / a=sendonly / a=recvonly / a=inactive, RFC 4566
182 : //-------------------------------------------------------------------------
183 0 : class SdpDirectionAttribute : public SdpAttribute
184 : {
185 : public:
186 : enum Direction {
187 : kInactive = 0,
188 : kSendonly = sdp::kSend,
189 : kRecvonly = sdp::kRecv,
190 : kSendrecv = sdp::kSend | sdp::kRecv
191 : };
192 :
193 0 : explicit SdpDirectionAttribute(Direction value)
194 0 : : SdpAttribute(kDirectionAttribute), mValue(value)
195 : {
196 0 : }
197 :
198 : virtual void Serialize(std::ostream& os) const override;
199 :
200 : Direction mValue;
201 : };
202 :
203 0 : inline std::ostream& operator<<(std::ostream& os,
204 : SdpDirectionAttribute::Direction d)
205 : {
206 0 : switch (d) {
207 : case SdpDirectionAttribute::kSendonly:
208 0 : os << "sendonly";
209 0 : break;
210 : case SdpDirectionAttribute::kRecvonly:
211 0 : os << "recvonly";
212 0 : break;
213 : case SdpDirectionAttribute::kSendrecv:
214 0 : os << "sendrecv";
215 0 : break;
216 : case SdpDirectionAttribute::kInactive:
217 0 : os << "inactive";
218 0 : break;
219 : default:
220 0 : MOZ_ASSERT(false);
221 : os << "?";
222 : }
223 0 : return os;
224 : }
225 :
226 : inline SdpDirectionAttribute::Direction
227 0 : reverse(SdpDirectionAttribute::Direction d)
228 : {
229 0 : switch (d) {
230 : case SdpDirectionAttribute::Direction::kInactive:
231 0 : return SdpDirectionAttribute::Direction::kInactive;
232 : case SdpDirectionAttribute::Direction::kSendonly:
233 0 : return SdpDirectionAttribute::Direction::kRecvonly;
234 : case SdpDirectionAttribute::Direction::kRecvonly:
235 0 : return SdpDirectionAttribute::Direction::kSendonly;
236 : case SdpDirectionAttribute::Direction::kSendrecv:
237 0 : return SdpDirectionAttribute::Direction::kSendrecv;
238 : }
239 0 : MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Invalid direction!");
240 : MOZ_RELEASE_ASSERT(false);
241 : }
242 :
243 : inline SdpDirectionAttribute::Direction
244 : operator|(SdpDirectionAttribute::Direction d1,
245 : SdpDirectionAttribute::Direction d2)
246 : {
247 : return (SdpDirectionAttribute::Direction)((unsigned)d1 | (unsigned)d2);
248 : }
249 :
250 : inline SdpDirectionAttribute::Direction
251 0 : operator&(SdpDirectionAttribute::Direction d1,
252 : SdpDirectionAttribute::Direction d2)
253 : {
254 0 : return (SdpDirectionAttribute::Direction)((unsigned)d1 & (unsigned)d2);
255 : }
256 :
257 : ///////////////////////////////////////////////////////////////////////////
258 : // a=dtls-message, draft-rescorla-dtls-in-sdp
259 : //-------------------------------------------------------------------------
260 : // attribute =/ dtls-message-attribute
261 : //
262 : // dtls-message-attribute = "dtls-message" ":" role SP value
263 : //
264 : // role = "client" / "server"
265 : //
266 : // value = 1*(ALPHA / DIGIT / "+" / "/" / "=" )
267 : // ; base64 encoded message
268 0 : class SdpDtlsMessageAttribute : public SdpAttribute
269 : {
270 : public:
271 : enum Role {
272 : kClient,
273 : kServer
274 : };
275 :
276 : explicit SdpDtlsMessageAttribute(Role role, const std::string& value)
277 : : SdpAttribute(kDtlsMessageAttribute),
278 : mRole(role),
279 : mValue(value)
280 : {}
281 :
282 0 : explicit SdpDtlsMessageAttribute(const std::string& unparsed)
283 0 : : SdpAttribute(kDtlsMessageAttribute),
284 0 : mRole(kClient)
285 : {
286 0 : std::istringstream is(unparsed);
287 0 : std::string error;
288 : // We're not really worried about errors here if we don't parse;
289 : // this attribute is a pure optimization.
290 0 : Parse(is, &error);
291 0 : }
292 :
293 : virtual void Serialize(std::ostream& os) const override;
294 : bool Parse(std::istream& is, std::string* error);
295 :
296 : Role mRole;
297 : std::string mValue;
298 : };
299 :
300 0 : inline std::ostream& operator<<(std::ostream& os,
301 : SdpDtlsMessageAttribute::Role r)
302 : {
303 0 : switch (r) {
304 : case SdpDtlsMessageAttribute::kClient:
305 0 : os << "client";
306 0 : break;
307 : case SdpDtlsMessageAttribute::kServer:
308 0 : os << "server";
309 0 : break;
310 : default:
311 0 : MOZ_ASSERT(false);
312 : os << "?";
313 : }
314 0 : return os;
315 : }
316 :
317 :
318 : ///////////////////////////////////////////////////////////////////////////
319 : // a=extmap, RFC5285
320 : //-------------------------------------------------------------------------
321 : // RFC5285
322 : // extmap = mapentry SP extensionname [SP extensionattributes]
323 : //
324 : // extensionname = URI
325 : //
326 : // direction = "sendonly" / "recvonly" / "sendrecv" / "inactive"
327 : //
328 : // mapentry = "extmap:" 1*5DIGIT ["/" direction]
329 : //
330 : // extensionattributes = byte-string
331 : //
332 : // URI = <Defined in RFC 3986>
333 : //
334 : // byte-string = <Defined in RFC 4566>
335 : //
336 : // SP = <Defined in RFC 5234>
337 : //
338 : // DIGIT = <Defined in RFC 5234>
339 0 : class SdpExtmapAttributeList : public SdpAttribute
340 : {
341 : public:
342 0 : SdpExtmapAttributeList() : SdpAttribute(kExtmapAttribute) {}
343 :
344 0 : struct Extmap {
345 : uint16_t entry;
346 : SdpDirectionAttribute::Direction direction;
347 : bool direction_specified;
348 : std::string extensionname;
349 : std::string extensionattributes;
350 : };
351 :
352 : void
353 0 : PushEntry(uint16_t entry, SdpDirectionAttribute::Direction direction,
354 : bool direction_specified, const std::string& extensionname,
355 : const std::string& extensionattributes = "")
356 : {
357 : Extmap value = { entry, direction, direction_specified, extensionname,
358 0 : extensionattributes };
359 0 : mExtmaps.push_back(value);
360 0 : }
361 :
362 : virtual void Serialize(std::ostream& os) const override;
363 :
364 : std::vector<Extmap> mExtmaps;
365 : };
366 :
367 : ///////////////////////////////////////////////////////////////////////////
368 : // a=fingerprint, RFC4572
369 : //-------------------------------------------------------------------------
370 : // fingerprint-attribute = "fingerprint" ":" hash-func SP fingerprint
371 : //
372 : // hash-func = "sha-1" / "sha-224" / "sha-256" /
373 : // "sha-384" / "sha-512" /
374 : // "md5" / "md2" / token
375 : // ; Additional hash functions can only come
376 : // ; from updates to RFC 3279
377 : //
378 : // fingerprint = 2UHEX *(":" 2UHEX)
379 : // ; Each byte in upper-case hex, separated
380 : // ; by colons.
381 : //
382 : // UHEX = DIGIT / %x41-46 ; A-F uppercase
383 0 : class SdpFingerprintAttributeList : public SdpAttribute
384 : {
385 : public:
386 0 : SdpFingerprintAttributeList() : SdpAttribute(kFingerprintAttribute) {}
387 :
388 : enum HashAlgorithm {
389 : kSha1,
390 : kSha224,
391 : kSha256,
392 : kSha384,
393 : kSha512,
394 : kMd5,
395 : kMd2,
396 : kUnknownAlgorithm
397 : };
398 :
399 0 : struct Fingerprint {
400 : HashAlgorithm hashFunc;
401 : std::vector<uint8_t> fingerprint;
402 : };
403 :
404 : // For use by application programmers. Enforces that it's a known and
405 : // non-crazy algorithm.
406 : void
407 0 : PushEntry(std::string algorithm_str,
408 : const std::vector<uint8_t>& fingerprint,
409 : bool enforcePlausible = true)
410 : {
411 : std::transform(algorithm_str.begin(),
412 : algorithm_str.end(),
413 : algorithm_str.begin(),
414 0 : ::tolower);
415 :
416 : SdpFingerprintAttributeList::HashAlgorithm algorithm =
417 0 : SdpFingerprintAttributeList::kUnknownAlgorithm;
418 :
419 0 : if (algorithm_str == "sha-1") {
420 0 : algorithm = SdpFingerprintAttributeList::kSha1;
421 0 : } else if (algorithm_str == "sha-224") {
422 0 : algorithm = SdpFingerprintAttributeList::kSha224;
423 0 : } else if (algorithm_str == "sha-256") {
424 0 : algorithm = SdpFingerprintAttributeList::kSha256;
425 0 : } else if (algorithm_str == "sha-384") {
426 0 : algorithm = SdpFingerprintAttributeList::kSha384;
427 0 : } else if (algorithm_str == "sha-512") {
428 0 : algorithm = SdpFingerprintAttributeList::kSha512;
429 0 : } else if (algorithm_str == "md5") {
430 0 : algorithm = SdpFingerprintAttributeList::kMd5;
431 0 : } else if (algorithm_str == "md2") {
432 0 : algorithm = SdpFingerprintAttributeList::kMd2;
433 : }
434 :
435 0 : if ((algorithm == SdpFingerprintAttributeList::kUnknownAlgorithm) ||
436 0 : fingerprint.empty()) {
437 0 : if (enforcePlausible) {
438 0 : MOZ_ASSERT(false, "Unknown fingerprint algorithm");
439 : } else {
440 0 : return;
441 : }
442 : }
443 :
444 0 : PushEntry(algorithm, fingerprint);
445 : }
446 :
447 : void
448 0 : PushEntry(HashAlgorithm hashFunc, const std::vector<uint8_t>& fingerprint)
449 : {
450 0 : Fingerprint value = { hashFunc, fingerprint };
451 0 : mFingerprints.push_back(value);
452 0 : }
453 :
454 : virtual void Serialize(std::ostream& os) const override;
455 :
456 : std::vector<Fingerprint> mFingerprints;
457 :
458 : static std::string FormatFingerprint(const std::vector<uint8_t>& fp);
459 : static std::vector<uint8_t> ParseFingerprint(const std::string& str);
460 : };
461 :
462 0 : inline std::ostream& operator<<(std::ostream& os,
463 : SdpFingerprintAttributeList::HashAlgorithm a)
464 : {
465 0 : switch (a) {
466 : case SdpFingerprintAttributeList::kSha1:
467 0 : os << "sha-1";
468 0 : break;
469 : case SdpFingerprintAttributeList::kSha224:
470 0 : os << "sha-224";
471 0 : break;
472 : case SdpFingerprintAttributeList::kSha256:
473 0 : os << "sha-256";
474 0 : break;
475 : case SdpFingerprintAttributeList::kSha384:
476 0 : os << "sha-384";
477 0 : break;
478 : case SdpFingerprintAttributeList::kSha512:
479 0 : os << "sha-512";
480 0 : break;
481 : case SdpFingerprintAttributeList::kMd5:
482 0 : os << "md5";
483 0 : break;
484 : case SdpFingerprintAttributeList::kMd2:
485 0 : os << "md2";
486 0 : break;
487 : default:
488 0 : MOZ_ASSERT(false);
489 : os << "?";
490 : }
491 0 : return os;
492 : }
493 :
494 : ///////////////////////////////////////////////////////////////////////////
495 : // a=group, RFC5888
496 : //-------------------------------------------------------------------------
497 : // group-attribute = "a=group:" semantics
498 : // *(SP identification-tag)
499 : // semantics = "LS" / "FID" / semantics-extension
500 : // semantics-extension = token
501 : // identification-tag = token
502 0 : class SdpGroupAttributeList : public SdpAttribute
503 : {
504 : public:
505 0 : SdpGroupAttributeList() : SdpAttribute(kGroupAttribute) {}
506 :
507 : enum Semantics {
508 : kLs, // RFC5888
509 : kFid, // RFC5888
510 : kSrf, // RFC3524
511 : kAnat, // RFC4091
512 : kFec, // RFC5956
513 : kFecFr, // RFC5956
514 : kCs, // draft-mehta-rmt-flute-sdp-05
515 : kDdp, // RFC5583
516 : kDup, // RFC7104
517 : kBundle // draft-ietf-mmusic-bundle
518 : };
519 :
520 0 : struct Group {
521 : Semantics semantics;
522 : std::vector<std::string> tags;
523 : };
524 :
525 : void
526 0 : PushEntry(Semantics semantics, const std::vector<std::string>& tags)
527 : {
528 0 : Group value = { semantics, tags };
529 0 : mGroups.push_back(value);
530 0 : }
531 :
532 : void
533 0 : RemoveMid(const std::string& mid)
534 : {
535 0 : for (auto i = mGroups.begin(); i != mGroups.end();) {
536 0 : auto tag = std::find(i->tags.begin(), i->tags.end(), mid);
537 0 : if (tag != i->tags.end()) {
538 0 : i->tags.erase(tag);
539 : }
540 :
541 0 : if (i->tags.empty()) {
542 0 : i = mGroups.erase(i);
543 : } else {
544 0 : ++i;
545 : }
546 : }
547 0 : }
548 :
549 : virtual void Serialize(std::ostream& os) const override;
550 :
551 : std::vector<Group> mGroups;
552 : };
553 :
554 0 : inline std::ostream& operator<<(std::ostream& os,
555 : SdpGroupAttributeList::Semantics s)
556 : {
557 0 : switch (s) {
558 : case SdpGroupAttributeList::kLs:
559 0 : os << "LS";
560 0 : break;
561 : case SdpGroupAttributeList::kFid:
562 0 : os << "FID";
563 0 : break;
564 : case SdpGroupAttributeList::kSrf:
565 0 : os << "SRF";
566 0 : break;
567 : case SdpGroupAttributeList::kAnat:
568 0 : os << "ANAT";
569 0 : break;
570 : case SdpGroupAttributeList::kFec:
571 0 : os << "FEC";
572 0 : break;
573 : case SdpGroupAttributeList::kFecFr:
574 0 : os << "FEC-FR";
575 0 : break;
576 : case SdpGroupAttributeList::kCs:
577 0 : os << "CS";
578 0 : break;
579 : case SdpGroupAttributeList::kDdp:
580 0 : os << "DDP";
581 0 : break;
582 : case SdpGroupAttributeList::kDup:
583 0 : os << "DUP";
584 0 : break;
585 : case SdpGroupAttributeList::kBundle:
586 0 : os << "BUNDLE";
587 0 : break;
588 : default:
589 0 : MOZ_ASSERT(false);
590 : os << "?";
591 : }
592 0 : return os;
593 : }
594 :
595 : ///////////////////////////////////////////////////////////////////////////
596 : // a=identity, draft-ietf-rtcweb-security-arch
597 : //-------------------------------------------------------------------------
598 : // identity-attribute = "identity:" identity-assertion
599 : // [ SP identity-extension
600 : // *(";" [ SP ] identity-extension) ]
601 : // identity-assertion = base64
602 : // base64 = 1*(ALPHA / DIGIT / "+" / "/" / "=" )
603 : // identity-extension = extension-att-name [ "=" extension-att-value ]
604 : // extension-att-name = token
605 : // extension-att-value = 1*(%x01-09 / %x0b-0c / %x0e-3a / %x3c-ff)
606 : // ; byte-string from [RFC4566] omitting ";"
607 :
608 : // We're just using an SdpStringAttribute for this right now
609 : #if 0
610 : class SdpIdentityAttribute : public SdpAttribute
611 : {
612 : public:
613 : explicit SdpIdentityAttribute(const std::string &assertion,
614 : const std::vector<std::string> &extensions =
615 : std::vector<std::string>()) :
616 : SdpAttribute(kIdentityAttribute),
617 : mAssertion(assertion),
618 : mExtensions(extensions) {}
619 :
620 : virtual void Serialize(std::ostream& os) const override;
621 :
622 : std::string mAssertion;
623 : std::vector<std::string> mExtensions;
624 : }
625 : #endif
626 :
627 : ///////////////////////////////////////////////////////////////////////////
628 : // a=imageattr, RFC6236
629 : //-------------------------------------------------------------------------
630 : // image-attr = "imageattr:" PT 1*2( 1*WSP ( "send" / "recv" )
631 : // 1*WSP attr-list )
632 : // PT = 1*DIGIT / "*"
633 : // attr-list = ( set *(1*WSP set) ) / "*"
634 : // ; WSP and DIGIT defined in [RFC5234]
635 : //
636 : // set= "[" "x=" xyrange "," "y=" xyrange *( "," key-value ) "]"
637 : // ; x is the horizontal image size range (pixel count)
638 : // ; y is the vertical image size range (pixel count)
639 : //
640 : // key-value = ( "sar=" srange )
641 : // / ( "par=" prange )
642 : // / ( "q=" qvalue )
643 : // ; Key-value MAY be extended with other keyword
644 : // ; parameters.
645 : // ; At most, one instance each of sar, par, or q
646 : // ; is allowed in a set.
647 : // ;
648 : // ; sar (sample aspect ratio) is the sample aspect ratio
649 : // ; associated with the set (optional, MAY be ignored)
650 : // ; par (picture aspect ratio) is the allowed
651 : // ; ratio between the display's x and y physical
652 : // ; size (optional)
653 : // ; q (optional, range [0.0..1.0], default value 0.5)
654 : // ; is the preference for the given set,
655 : // ; a higher value means a higher preference
656 : //
657 : // onetonine = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"
658 : // ; Digit between 1 and 9
659 : // xyvalue = onetonine *5DIGIT
660 : // ; Digit between 1 and 9 that is
661 : // ; followed by 0 to 5 other digits
662 : // step = xyvalue
663 : // xyrange = ( "[" xyvalue ":" [ step ":" ] xyvalue "]" )
664 : // ; Range between a lower and an upper value
665 : // ; with an optional step, default step = 1
666 : // ; The rightmost occurrence of xyvalue MUST have a
667 : // ; higher value than the leftmost occurrence.
668 : // / ( "[" xyvalue 1*( "," xyvalue ) "]" )
669 : // ; Discrete values separated by ','
670 : // / ( xyvalue )
671 : // ; A single value
672 : // spvalue = ( "0" "." onetonine *3DIGIT )
673 : // ; Values between 0.1000 and 0.9999
674 : // / ( onetonine "." 1*4DIGIT )
675 : // ; Values between 1.0000 and 9.9999
676 : // srange = ( "[" spvalue 1*( "," spvalue ) "]" )
677 : // ; Discrete values separated by ','.
678 : // ; Each occurrence of spvalue MUST be
679 : // ; greater than the previous occurrence.
680 : // / ( "[" spvalue "-" spvalue "]" )
681 : // ; Range between a lower and an upper level (inclusive)
682 : // ; The second occurrence of spvalue MUST have a higher
683 : // ; value than the first
684 : // / ( spvalue )
685 : // ; A single value
686 : //
687 : // prange = ( "[" spvalue "-" spvalue "]" )
688 : // ; Range between a lower and an upper level (inclusive)
689 : // ; The second occurrence of spvalue MUST have a higher
690 : // ; value than the first
691 : //
692 : // qvalue = ( "0" "." 1*2DIGIT )
693 : // / ( "1" "." 1*2("0") )
694 : // ; Values between 0.00 and 1.00
695 : //
696 : // XXX TBD -- We don't use this yet, and it's a project unto itself.
697 : //
698 :
699 0 : class SdpImageattrAttributeList : public SdpAttribute
700 : {
701 : public:
702 0 : SdpImageattrAttributeList() : SdpAttribute(kImageattrAttribute) {}
703 :
704 0 : class XYRange
705 : {
706 : public:
707 0 : XYRange() : min(0), max(0), step(1) {}
708 : void Serialize(std::ostream& os) const;
709 : bool Parse(std::istream& is, std::string* error);
710 : bool ParseAfterBracket(std::istream& is, std::string* error);
711 : bool ParseAfterMin(std::istream& is, std::string* error);
712 : bool ParseDiscreteValues(std::istream& is, std::string* error);
713 : std::vector<uint32_t> discreteValues;
714 : // min/max are used iff discreteValues is empty
715 : uint32_t min;
716 : uint32_t max;
717 : uint32_t step;
718 : };
719 :
720 0 : class SRange
721 : {
722 : public:
723 0 : SRange() : min(0), max(0) {}
724 : void Serialize(std::ostream& os) const;
725 : bool Parse(std::istream& is, std::string* error);
726 : bool ParseAfterBracket(std::istream& is, std::string* error);
727 : bool ParseAfterMin(std::istream& is, std::string* error);
728 : bool ParseDiscreteValues(std::istream& is, std::string* error);
729 0 : bool IsSet() const
730 : {
731 0 : return !discreteValues.empty() || (min && max);
732 : }
733 : std::vector<float> discreteValues;
734 : // min/max are used iff discreteValues is empty
735 : float min;
736 : float max;
737 : };
738 :
739 : class PRange
740 : {
741 : public:
742 0 : PRange() : min(0), max(0) {}
743 : void Serialize(std::ostream& os) const;
744 : bool Parse(std::istream& is, std::string* error);
745 0 : bool IsSet() const
746 : {
747 0 : return min && max;
748 : }
749 : float min;
750 : float max;
751 : };
752 :
753 0 : class Set
754 : {
755 : public:
756 0 : Set() : qValue(-1) {}
757 : void Serialize(std::ostream& os) const;
758 : bool Parse(std::istream& is, std::string* error);
759 : XYRange xRange;
760 : XYRange yRange;
761 : SRange sRange;
762 : PRange pRange;
763 : float qValue;
764 : };
765 :
766 0 : class Imageattr
767 : {
768 : public:
769 0 : Imageattr() : pt(), sendAll(false), recvAll(false) {}
770 : void Serialize(std::ostream& os) const;
771 : bool Parse(std::istream& is, std::string* error);
772 : bool ParseSets(std::istream& is, std::string* error);
773 : // If not set, this means all payload types
774 : Maybe<uint16_t> pt;
775 : bool sendAll;
776 : std::vector<Set> sendSets;
777 : bool recvAll;
778 : std::vector<Set> recvSets;
779 : };
780 :
781 : virtual void Serialize(std::ostream& os) const override;
782 : bool PushEntry(const std::string& raw, std::string* error, size_t* errorPos);
783 :
784 : std::vector<Imageattr> mImageattrs;
785 : };
786 :
787 : ///////////////////////////////////////////////////////////////////////////
788 : // a=msid, draft-ietf-mmusic-msid
789 : //-------------------------------------------------------------------------
790 : // msid-attr = "msid:" identifier [ SP appdata ]
791 : // identifier = 1*64token-char ; see RFC 4566
792 : // appdata = 1*64token-char ; see RFC 4566
793 0 : class SdpMsidAttributeList : public SdpAttribute
794 : {
795 : public:
796 0 : SdpMsidAttributeList() : SdpAttribute(kMsidAttribute) {}
797 :
798 0 : struct Msid {
799 : std::string identifier;
800 : std::string appdata;
801 : };
802 :
803 : void
804 0 : PushEntry(const std::string& identifier, const std::string& appdata = "")
805 : {
806 0 : Msid value = { identifier, appdata };
807 0 : mMsids.push_back(value);
808 0 : }
809 :
810 : virtual void Serialize(std::ostream& os) const override;
811 :
812 : std::vector<Msid> mMsids;
813 : };
814 :
815 : ///////////////////////////////////////////////////////////////////////////
816 : // a=msid-semantic, draft-ietf-mmusic-msid
817 : //-------------------------------------------------------------------------
818 : // msid-semantic-attr = "msid-semantic:" msid-semantic msid-list
819 : // msid-semantic = token ; see RFC 4566
820 : // msid-list = *(" " msid-id) / " *"
821 0 : class SdpMsidSemanticAttributeList : public SdpAttribute
822 : {
823 : public:
824 0 : SdpMsidSemanticAttributeList() : SdpAttribute(kMsidSemanticAttribute) {}
825 :
826 0 : struct MsidSemantic
827 : {
828 : // TODO: Once we have some more of these, we might want to make an enum
829 : std::string semantic;
830 : std::vector<std::string> msids;
831 : };
832 :
833 : void
834 0 : PushEntry(const std::string& semantic, const std::vector<std::string>& msids)
835 : {
836 0 : MsidSemantic value = {semantic, msids};
837 0 : mMsidSemantics.push_back(value);
838 0 : }
839 :
840 : virtual void Serialize(std::ostream& os) const override;
841 :
842 : std::vector<MsidSemantic> mMsidSemantics;
843 : };
844 :
845 : ///////////////////////////////////////////////////////////////////////////
846 : // a=remote-candiate, RFC5245
847 : //-------------------------------------------------------------------------
848 : // remote-candidate-att = "remote-candidates" ":" remote-candidate
849 : // 0*(SP remote-candidate)
850 : // remote-candidate = component-ID SP connection-address SP port
851 0 : class SdpRemoteCandidatesAttribute : public SdpAttribute
852 : {
853 : public:
854 0 : struct Candidate {
855 : std::string id;
856 : std::string address;
857 : uint16_t port;
858 : };
859 :
860 : explicit SdpRemoteCandidatesAttribute(
861 : const std::vector<Candidate>& candidates)
862 : : SdpAttribute(kRemoteCandidatesAttribute), mCandidates(candidates)
863 : {
864 : }
865 :
866 : virtual void Serialize(std::ostream& os) const override;
867 :
868 : std::vector<Candidate> mCandidates;
869 : };
870 :
871 : /*
872 : a=rid, draft-pthatcher-mmusic-rid-01
873 :
874 : rid-syntax = "a=rid:" rid-identifier SP rid-dir
875 : [ rid-pt-param-list / rid-param-list ]
876 :
877 : rid-identifier = 1*(alpha-numeric / "-" / "_")
878 :
879 : rid-dir = "send" / "recv"
880 :
881 : rid-pt-param-list = SP rid-fmt-list *(";" rid-param)
882 :
883 : rid-param-list = SP rid-param *(";" rid-param)
884 :
885 : rid-fmt-list = "pt=" fmt *( "," fmt )
886 : ; fmt defined in {{RFC4566}}
887 :
888 : rid-param = rid-width-param
889 : / rid-height-param
890 : / rid-fps-param
891 : / rid-fs-param
892 : / rid-br-param
893 : / rid-pps-param
894 : / rid-depend-param
895 : / rid-param-other
896 :
897 : rid-width-param = "max-width" [ "=" int-param-val ]
898 :
899 : rid-height-param = "max-height" [ "=" int-param-val ]
900 :
901 : rid-fps-param = "max-fps" [ "=" int-param-val ]
902 :
903 : rid-fs-param = "max-fs" [ "=" int-param-val ]
904 :
905 : rid-br-param = "max-br" [ "=" int-param-val ]
906 :
907 : rid-pps-param = "max-pps" [ "=" int-param-val ]
908 :
909 : rid-depend-param = "depend=" rid-list
910 :
911 : rid-param-other = 1*(alpha-numeric / "-") [ "=" param-val ]
912 :
913 : rid-list = rid-identifier *( "," rid-identifier )
914 :
915 : int-param-val = 1*DIGIT
916 :
917 : param-val = *( %x20-58 / %x60-7E )
918 : ; Any printable character except semicolon
919 : */
920 0 : class SdpRidAttributeList : public SdpAttribute
921 : {
922 : public:
923 0 : explicit SdpRidAttributeList()
924 0 : : SdpAttribute(kRidAttribute)
925 0 : {}
926 :
927 0 : struct Rid
928 : {
929 0 : Rid() :
930 0 : direction(sdp::kSend)
931 0 : {}
932 :
933 : bool Parse(std::istream& is, std::string* error);
934 : bool ParseParameters(std::istream& is, std::string* error);
935 : bool ParseDepend(std::istream& is, std::string* error);
936 : bool ParseFormats(std::istream& is, std::string* error);
937 : void Serialize(std::ostream& os) const;
938 : void SerializeParameters(std::ostream& os) const;
939 : bool HasFormat(const std::string& format) const;
940 0 : bool HasParameters() const
941 : {
942 0 : return !formats.empty() ||
943 0 : constraints.maxWidth ||
944 0 : constraints.maxHeight ||
945 0 : constraints.maxFps ||
946 0 : constraints.maxFs ||
947 0 : constraints.maxBr ||
948 0 : constraints.maxPps ||
949 0 : !dependIds.empty();
950 : }
951 :
952 :
953 : std::string id;
954 : sdp::Direction direction;
955 : std::vector<uint16_t> formats; // Empty implies all
956 : EncodingConstraints constraints;
957 : std::vector<std::string> dependIds;
958 : };
959 :
960 : virtual void Serialize(std::ostream& os) const override;
961 : bool PushEntry(const std::string& raw, std::string* error, size_t* errorPos);
962 :
963 : std::vector<Rid> mRids;
964 : };
965 :
966 : ///////////////////////////////////////////////////////////////////////////
967 : // a=rtcp, RFC3605
968 : //-------------------------------------------------------------------------
969 : // rtcp-attribute = "a=rtcp:" port [nettype space addrtype space
970 : // connection-address] CRLF
971 0 : class SdpRtcpAttribute : public SdpAttribute
972 : {
973 : public:
974 0 : explicit SdpRtcpAttribute(uint16_t port)
975 0 : : SdpAttribute(kRtcpAttribute),
976 : mPort(port),
977 : mNetType(sdp::kNetTypeNone),
978 0 : mAddrType(sdp::kAddrTypeNone)
979 0 : {}
980 :
981 0 : SdpRtcpAttribute(uint16_t port,
982 : sdp::NetType netType,
983 : sdp::AddrType addrType,
984 : const std::string& address)
985 0 : : SdpAttribute(kRtcpAttribute),
986 : mPort(port),
987 : mNetType(netType),
988 : mAddrType(addrType),
989 0 : mAddress(address)
990 : {
991 0 : MOZ_ASSERT(netType != sdp::kNetTypeNone);
992 0 : MOZ_ASSERT(addrType != sdp::kAddrTypeNone);
993 0 : MOZ_ASSERT(!address.empty());
994 0 : }
995 :
996 : virtual void Serialize(std::ostream& os) const override;
997 :
998 : uint16_t mPort;
999 : sdp::NetType mNetType;
1000 : sdp::AddrType mAddrType;
1001 : std::string mAddress;
1002 : };
1003 :
1004 : ///////////////////////////////////////////////////////////////////////////
1005 : // a=rtcp-fb, RFC4585
1006 : //-------------------------------------------------------------------------
1007 : // rtcp-fb-syntax = "a=rtcp-fb:" rtcp-fb-pt SP rtcp-fb-val CRLF
1008 : //
1009 : // rtcp-fb-pt = "*" ; wildcard: applies to all formats
1010 : // / fmt ; as defined in SDP spec
1011 : //
1012 : // rtcp-fb-val = "ack" rtcp-fb-ack-param
1013 : // / "nack" rtcp-fb-nack-param
1014 : // / "trr-int" SP 1*DIGIT
1015 : // / rtcp-fb-id rtcp-fb-param
1016 : //
1017 : // rtcp-fb-id = 1*(alpha-numeric / "-" / "_")
1018 : //
1019 : // rtcp-fb-param = SP "app" [SP byte-string]
1020 : // / SP token [SP byte-string]
1021 : // / ; empty
1022 : //
1023 : // rtcp-fb-ack-param = SP "rpsi"
1024 : // / SP "app" [SP byte-string]
1025 : // / SP token [SP byte-string]
1026 : // / ; empty
1027 : //
1028 : // rtcp-fb-nack-param = SP "pli"
1029 : // / SP "sli"
1030 : // / SP "rpsi"
1031 : // / SP "app" [SP byte-string]
1032 : // / SP token [SP byte-string]
1033 : // / ; empty
1034 : //
1035 0 : class SdpRtcpFbAttributeList : public SdpAttribute
1036 : {
1037 : public:
1038 0 : SdpRtcpFbAttributeList() : SdpAttribute(kRtcpFbAttribute) {}
1039 :
1040 : enum Type { kAck, kApp, kCcm, kNack, kTrrInt, kRemb };
1041 :
1042 : static const char* pli;
1043 : static const char* sli;
1044 : static const char* rpsi;
1045 : static const char* app;
1046 :
1047 : static const char* fir;
1048 : static const char* tmmbr;
1049 : static const char* tstr;
1050 : static const char* vbcm;
1051 :
1052 0 : struct Feedback {
1053 : std::string pt;
1054 : Type type;
1055 : std::string parameter;
1056 : std::string extra;
1057 : };
1058 :
1059 : void
1060 0 : PushEntry(const std::string& pt, Type type, const std::string& parameter = "",
1061 : const std::string& extra = "")
1062 : {
1063 0 : Feedback value = { pt, type, parameter, extra };
1064 0 : mFeedbacks.push_back(value);
1065 0 : }
1066 :
1067 : virtual void Serialize(std::ostream& os) const override;
1068 :
1069 : std::vector<Feedback> mFeedbacks;
1070 : };
1071 :
1072 0 : inline std::ostream& operator<<(std::ostream& os,
1073 : SdpRtcpFbAttributeList::Type type)
1074 : {
1075 0 : switch (type) {
1076 : case SdpRtcpFbAttributeList::kAck:
1077 0 : os << "ack";
1078 0 : break;
1079 : case SdpRtcpFbAttributeList::kApp:
1080 0 : os << "app";
1081 0 : break;
1082 : case SdpRtcpFbAttributeList::kCcm:
1083 0 : os << "ccm";
1084 0 : break;
1085 : case SdpRtcpFbAttributeList::kNack:
1086 0 : os << "nack";
1087 0 : break;
1088 : case SdpRtcpFbAttributeList::kTrrInt:
1089 0 : os << "trr-int";
1090 0 : break;
1091 : case SdpRtcpFbAttributeList::kRemb:
1092 0 : os << "goog-remb";
1093 0 : break;
1094 : default:
1095 0 : MOZ_ASSERT(false);
1096 : os << "?";
1097 : }
1098 0 : return os;
1099 : }
1100 :
1101 : ///////////////////////////////////////////////////////////////////////////
1102 : // a=rtpmap, RFC4566
1103 : //-------------------------------------------------------------------------
1104 : // a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>]
1105 0 : class SdpRtpmapAttributeList : public SdpAttribute
1106 : {
1107 : public:
1108 0 : SdpRtpmapAttributeList() : SdpAttribute(kRtpmapAttribute) {}
1109 :
1110 : // Minimal set to get going
1111 : enum CodecType {
1112 : kOpus,
1113 : kG722,
1114 : kPCMU,
1115 : kPCMA,
1116 : kVP8,
1117 : kVP9,
1118 : kiLBC,
1119 : kiSAC,
1120 : kH264,
1121 : kRed,
1122 : kUlpfec,
1123 : kTelephoneEvent,
1124 : kOtherCodec
1125 : };
1126 :
1127 0 : struct Rtpmap {
1128 : std::string pt;
1129 : CodecType codec;
1130 : std::string name;
1131 : uint32_t clock;
1132 : // Technically, this could mean something else in the future.
1133 : // In practice, that's probably not going to happen.
1134 : uint32_t channels;
1135 : };
1136 :
1137 : void
1138 0 : PushEntry(const std::string& pt, CodecType codec, const std::string& name,
1139 : uint32_t clock, uint32_t channels = 0)
1140 : {
1141 0 : Rtpmap value = { pt, codec, name, clock, channels };
1142 0 : mRtpmaps.push_back(value);
1143 0 : }
1144 :
1145 : virtual void Serialize(std::ostream& os) const override;
1146 :
1147 : bool
1148 0 : HasEntry(const std::string& pt) const
1149 : {
1150 0 : for (auto it = mRtpmaps.begin(); it != mRtpmaps.end(); ++it) {
1151 0 : if (it->pt == pt) {
1152 0 : return true;
1153 : }
1154 : }
1155 0 : return false;
1156 : }
1157 :
1158 : const Rtpmap&
1159 0 : GetEntry(const std::string& pt) const
1160 : {
1161 0 : for (auto it = mRtpmaps.begin(); it != mRtpmaps.end(); ++it) {
1162 0 : if (it->pt == pt) {
1163 0 : return *it;
1164 : }
1165 : }
1166 0 : MOZ_CRASH();
1167 : }
1168 :
1169 : std::vector<Rtpmap> mRtpmaps;
1170 : };
1171 :
1172 : inline std::ostream& operator<<(std::ostream& os,
1173 : SdpRtpmapAttributeList::CodecType c)
1174 : {
1175 : switch (c) {
1176 : case SdpRtpmapAttributeList::kOpus:
1177 : os << "opus";
1178 : break;
1179 : case SdpRtpmapAttributeList::kG722:
1180 : os << "G722";
1181 : break;
1182 : case SdpRtpmapAttributeList::kPCMU:
1183 : os << "PCMU";
1184 : break;
1185 : case SdpRtpmapAttributeList::kPCMA:
1186 : os << "PCMA";
1187 : break;
1188 : case SdpRtpmapAttributeList::kVP8:
1189 : os << "VP8";
1190 : break;
1191 : case SdpRtpmapAttributeList::kVP9:
1192 : os << "VP9";
1193 : break;
1194 : case SdpRtpmapAttributeList::kiLBC:
1195 : os << "iLBC";
1196 : break;
1197 : case SdpRtpmapAttributeList::kiSAC:
1198 : os << "iSAC";
1199 : break;
1200 : case SdpRtpmapAttributeList::kH264:
1201 : os << "H264";
1202 : break;
1203 : case SdpRtpmapAttributeList::kRed:
1204 : os << "red";
1205 : break;
1206 : case SdpRtpmapAttributeList::kUlpfec:
1207 : os << "ulpfec";
1208 : break;
1209 : case SdpRtpmapAttributeList::kTelephoneEvent:
1210 : os << "telephone-event";
1211 : break;
1212 : default:
1213 : MOZ_ASSERT(false);
1214 : os << "?";
1215 : }
1216 : return os;
1217 : }
1218 :
1219 : ///////////////////////////////////////////////////////////////////////////
1220 : // a=fmtp, RFC4566, RFC5576
1221 : //-------------------------------------------------------------------------
1222 : // a=fmtp:<format> <format specific parameters>
1223 : //
1224 0 : class SdpFmtpAttributeList : public SdpAttribute
1225 : {
1226 : public:
1227 0 : SdpFmtpAttributeList() : SdpAttribute(kFmtpAttribute) {}
1228 :
1229 : // Base class for format parameters
1230 0 : class Parameters
1231 : {
1232 : public:
1233 0 : explicit Parameters(SdpRtpmapAttributeList::CodecType aCodec)
1234 0 : : codec_type(aCodec)
1235 : {
1236 0 : }
1237 :
1238 0 : virtual ~Parameters() {}
1239 : virtual Parameters* Clone() const = 0;
1240 : virtual void Serialize(std::ostream& os) const = 0;
1241 :
1242 : SdpRtpmapAttributeList::CodecType codec_type;
1243 : };
1244 :
1245 0 : class RedParameters : public Parameters
1246 : {
1247 : public:
1248 0 : RedParameters()
1249 0 : : Parameters(SdpRtpmapAttributeList::kRed)
1250 : {
1251 0 : }
1252 :
1253 : virtual Parameters*
1254 0 : Clone() const override
1255 : {
1256 0 : return new RedParameters(*this);
1257 : }
1258 :
1259 : virtual void
1260 0 : Serialize(std::ostream& os) const override
1261 : {
1262 0 : for(size_t i = 0; i < encodings.size(); ++i) {
1263 : os << (i != 0 ? "/" : "")
1264 0 : << std::to_string(encodings[i]);
1265 : }
1266 0 : }
1267 :
1268 : std::vector<uint8_t> encodings;
1269 : };
1270 :
1271 0 : class H264Parameters : public Parameters
1272 : {
1273 : public:
1274 : static const uint32_t kDefaultProfileLevelId = 0x420010;
1275 :
1276 0 : H264Parameters()
1277 0 : : Parameters(SdpRtpmapAttributeList::kH264),
1278 : packetization_mode(0),
1279 : level_asymmetry_allowed(false),
1280 : profile_level_id(kDefaultProfileLevelId),
1281 : max_mbps(0),
1282 : max_fs(0),
1283 : max_cpb(0),
1284 : max_dpb(0),
1285 0 : max_br(0)
1286 : {
1287 0 : memset(sprop_parameter_sets, 0, sizeof(sprop_parameter_sets));
1288 0 : }
1289 :
1290 : virtual Parameters*
1291 0 : Clone() const override
1292 : {
1293 0 : return new H264Parameters(*this);
1294 : }
1295 :
1296 : virtual void
1297 0 : Serialize(std::ostream& os) const override
1298 : {
1299 : // Note: don't move this, since having an unconditional param up top
1300 : // lets us avoid a whole bunch of conditional streaming of ';' below
1301 0 : os << "profile-level-id=" << std::hex << std::setfill('0') << std::setw(6)
1302 0 : << profile_level_id << std::dec << std::setfill(' ');
1303 :
1304 0 : os << ";level-asymmetry-allowed=" << (level_asymmetry_allowed ? 1 : 0);
1305 :
1306 0 : if (strlen(sprop_parameter_sets)) {
1307 0 : os << ";sprop-parameter-sets=" << sprop_parameter_sets;
1308 : }
1309 :
1310 0 : if (packetization_mode != 0) {
1311 0 : os << ";packetization-mode=" << packetization_mode;
1312 : }
1313 :
1314 0 : if (max_mbps != 0) {
1315 0 : os << ";max-mbps=" << max_mbps;
1316 : }
1317 :
1318 0 : if (max_fs != 0) {
1319 0 : os << ";max-fs=" << max_fs;
1320 : }
1321 :
1322 0 : if (max_cpb != 0) {
1323 0 : os << ";max-cpb=" << max_cpb;
1324 : }
1325 :
1326 0 : if (max_dpb != 0) {
1327 0 : os << ";max-dpb=" << max_dpb;
1328 : }
1329 :
1330 0 : if (max_br != 0) {
1331 0 : os << ";max-br=" << max_br;
1332 : }
1333 0 : }
1334 :
1335 : static const size_t max_sprop_len = 128;
1336 : char sprop_parameter_sets[max_sprop_len];
1337 : unsigned int packetization_mode;
1338 : bool level_asymmetry_allowed;
1339 : unsigned int profile_level_id;
1340 : unsigned int max_mbps;
1341 : unsigned int max_fs;
1342 : unsigned int max_cpb;
1343 : unsigned int max_dpb;
1344 : unsigned int max_br;
1345 : };
1346 :
1347 : // Also used for VP9 since they share parameters
1348 0 : class VP8Parameters : public Parameters
1349 : {
1350 : public:
1351 0 : explicit VP8Parameters(SdpRtpmapAttributeList::CodecType type)
1352 0 : : Parameters(type), max_fs(0), max_fr(0)
1353 : {
1354 0 : }
1355 :
1356 : virtual Parameters*
1357 0 : Clone() const override
1358 : {
1359 0 : return new VP8Parameters(*this);
1360 : }
1361 :
1362 : virtual void
1363 0 : Serialize(std::ostream& os) const override
1364 : {
1365 : // draft-ietf-payload-vp8-11 says these are mandatory, upper layer
1366 : // needs to ensure they're set properly.
1367 0 : os << "max-fs=" << max_fs;
1368 0 : os << ";max-fr=" << max_fr;
1369 0 : }
1370 :
1371 : unsigned int max_fs;
1372 : unsigned int max_fr;
1373 : };
1374 :
1375 0 : class OpusParameters : public Parameters
1376 : {
1377 : public:
1378 : enum { kDefaultMaxPlaybackRate = 48000,
1379 : kDefaultStereo = 0,
1380 : kDefaultUseInBandFec = 0 };
1381 0 : OpusParameters() :
1382 : Parameters(SdpRtpmapAttributeList::kOpus),
1383 : maxplaybackrate(kDefaultMaxPlaybackRate),
1384 : stereo(kDefaultStereo),
1385 0 : useInBandFec(kDefaultUseInBandFec)
1386 0 : {}
1387 :
1388 : Parameters*
1389 0 : Clone() const override
1390 : {
1391 0 : return new OpusParameters(*this);
1392 : }
1393 :
1394 : void
1395 0 : Serialize(std::ostream& os) const override
1396 : {
1397 0 : os << "maxplaybackrate=" << maxplaybackrate
1398 0 : << ";stereo=" << stereo
1399 0 : << ";useinbandfec=" << useInBandFec;
1400 0 : }
1401 :
1402 : unsigned int maxplaybackrate;
1403 : unsigned int stereo;
1404 : unsigned int useInBandFec;
1405 : };
1406 :
1407 0 : class TelephoneEventParameters : public Parameters
1408 : {
1409 : public:
1410 0 : TelephoneEventParameters() :
1411 : Parameters(SdpRtpmapAttributeList::kTelephoneEvent),
1412 0 : dtmfTones("0-15")
1413 0 : {}
1414 :
1415 : virtual Parameters*
1416 0 : Clone() const override
1417 : {
1418 0 : return new TelephoneEventParameters(*this);
1419 : }
1420 :
1421 : void
1422 0 : Serialize(std::ostream& os) const override
1423 : {
1424 0 : os << dtmfTones;
1425 0 : }
1426 :
1427 : std::string dtmfTones;
1428 : };
1429 :
1430 0 : class Fmtp
1431 : {
1432 : public:
1433 0 : Fmtp(const std::string& aFormat, UniquePtr<Parameters> aParameters)
1434 0 : : format(aFormat),
1435 0 : parameters(Move(aParameters))
1436 : {
1437 0 : }
1438 :
1439 0 : Fmtp(const std::string& aFormat, const Parameters& aParameters)
1440 0 : : format(aFormat),
1441 0 : parameters(aParameters.Clone())
1442 : {
1443 0 : }
1444 :
1445 : // TODO: Rip all of this out when we have move semantics in the stl.
1446 0 : Fmtp(const Fmtp& orig) { *this = orig; }
1447 :
1448 0 : Fmtp& operator=(const Fmtp& rhs)
1449 : {
1450 0 : if (this != &rhs) {
1451 0 : format = rhs.format;
1452 0 : parameters.reset(rhs.parameters ? rhs.parameters->Clone() : nullptr);
1453 : }
1454 0 : return *this;
1455 : }
1456 :
1457 : // The contract around these is as follows:
1458 : // * |parameters| is only set if we recognized the media type and had
1459 : // a subclass of Parameters to represent that type of parameters
1460 : // * |parameters| is a best-effort representation; it might be missing
1461 : // stuff
1462 : // * Parameters::codec_type tells you the concrete class, eg
1463 : // kH264 -> H264Parameters
1464 : std::string format;
1465 : UniquePtr<Parameters> parameters;
1466 : };
1467 :
1468 : virtual void Serialize(std::ostream& os) const override;
1469 :
1470 : void
1471 0 : PushEntry(const std::string& format, UniquePtr<Parameters> parameters)
1472 : {
1473 0 : mFmtps.push_back(Fmtp(format, Move(parameters)));
1474 0 : }
1475 :
1476 : std::vector<Fmtp> mFmtps;
1477 : };
1478 :
1479 : ///////////////////////////////////////////////////////////////////////////
1480 : // a=sctpmap, draft-ietf-mmusic-sctp-sdp-05
1481 : //-------------------------------------------------------------------------
1482 : // sctpmap-attr = "a=sctpmap:" sctpmap-number media-subtypes
1483 : // [streams]
1484 : // sctpmap-number = 1*DIGIT
1485 : // protocol = labelstring
1486 : // labelstring = text
1487 : // text = byte-string
1488 : // streams = 1*DIGIT
1489 : //
1490 : // We're going to pretend that there are spaces where they make sense.
1491 0 : class SdpSctpmapAttributeList : public SdpAttribute
1492 : {
1493 : public:
1494 0 : SdpSctpmapAttributeList() : SdpAttribute(kSctpmapAttribute) {}
1495 :
1496 0 : struct Sctpmap {
1497 : std::string pt;
1498 : std::string name;
1499 : uint32_t streams;
1500 : };
1501 :
1502 : void
1503 0 : PushEntry(const std::string& pt, const std::string& name,
1504 : uint32_t streams = 0)
1505 : {
1506 0 : Sctpmap value = { pt, name, streams };
1507 0 : mSctpmaps.push_back(value);
1508 0 : }
1509 :
1510 : virtual void Serialize(std::ostream& os) const override;
1511 :
1512 : bool
1513 : HasEntry(const std::string& pt) const
1514 : {
1515 : for (auto it = mSctpmaps.begin(); it != mSctpmaps.end(); ++it) {
1516 : if (it->pt == pt) {
1517 : return true;
1518 : }
1519 : }
1520 : return false;
1521 : }
1522 :
1523 : const Sctpmap&
1524 0 : GetFirstEntry() const
1525 : {
1526 0 : return mSctpmaps[0];
1527 : }
1528 :
1529 : std::vector<Sctpmap> mSctpmaps;
1530 : };
1531 :
1532 : ///////////////////////////////////////////////////////////////////////////
1533 : // a=setup, RFC4145
1534 : //-------------------------------------------------------------------------
1535 : // setup-attr = "a=setup:" role
1536 : // role = "active" / "passive" / "actpass" / "holdconn"
1537 0 : class SdpSetupAttribute : public SdpAttribute
1538 : {
1539 : public:
1540 : enum Role { kActive, kPassive, kActpass, kHoldconn };
1541 :
1542 0 : explicit SdpSetupAttribute(Role role)
1543 0 : : SdpAttribute(kSetupAttribute), mRole(role)
1544 : {
1545 0 : }
1546 :
1547 : virtual void Serialize(std::ostream& os) const override;
1548 :
1549 : Role mRole;
1550 : };
1551 :
1552 0 : inline std::ostream& operator<<(std::ostream& os, SdpSetupAttribute::Role r)
1553 : {
1554 0 : switch (r) {
1555 : case SdpSetupAttribute::kActive:
1556 0 : os << "active";
1557 0 : break;
1558 : case SdpSetupAttribute::kPassive:
1559 0 : os << "passive";
1560 0 : break;
1561 : case SdpSetupAttribute::kActpass:
1562 0 : os << "actpass";
1563 0 : break;
1564 : case SdpSetupAttribute::kHoldconn:
1565 0 : os << "holdconn";
1566 0 : break;
1567 : default:
1568 0 : MOZ_ASSERT(false);
1569 : os << "?";
1570 : }
1571 0 : return os;
1572 : }
1573 :
1574 : // sc-attr = "a=simulcast:" 1*2( WSP sc-str-list ) [WSP sc-pause-list]
1575 : // sc-str-list = sc-dir WSP sc-id-type "=" sc-alt-list *( ";" sc-alt-list )
1576 : // sc-pause-list = "paused=" sc-alt-list
1577 : // sc-dir = "send" / "recv"
1578 : // sc-id-type = "pt" / "rid" / token
1579 : // sc-alt-list = sc-id *( "," sc-id )
1580 : // sc-id = fmt / rid-identifier / token
1581 : // ; WSP defined in [RFC5234]
1582 : // ; fmt, token defined in [RFC4566]
1583 : // ; rid-identifier defined in [I-D.pthatcher-mmusic-rid]
1584 0 : class SdpSimulcastAttribute : public SdpAttribute
1585 : {
1586 : public:
1587 0 : SdpSimulcastAttribute() : SdpAttribute(kSimulcastAttribute) {}
1588 :
1589 : void Serialize(std::ostream& os) const override;
1590 : bool Parse(std::istream& is, std::string* error);
1591 :
1592 0 : class Version
1593 : {
1594 : public:
1595 : void Serialize(std::ostream& os) const;
1596 0 : bool IsSet() const
1597 : {
1598 0 : return !choices.empty();
1599 : }
1600 : bool Parse(std::istream& is, std::string* error);
1601 : bool GetChoicesAsFormats(std::vector<uint16_t>* formats) const;
1602 :
1603 : std::vector<std::string> choices;
1604 : };
1605 :
1606 0 : class Versions : public std::vector<Version>
1607 : {
1608 : public:
1609 : enum Type {
1610 : kPt,
1611 : kRid
1612 : };
1613 :
1614 0 : Versions() : type(kRid) {}
1615 : void Serialize(std::ostream& os) const;
1616 0 : bool IsSet() const
1617 : {
1618 0 : if (empty()) {
1619 0 : return false;
1620 : }
1621 :
1622 0 : for (const Version& version : *this) {
1623 0 : if (version.IsSet()) {
1624 0 : return true;
1625 : }
1626 : }
1627 :
1628 0 : return false;
1629 : }
1630 :
1631 : bool Parse(std::istream& is, std::string* error);
1632 : Type type;
1633 : };
1634 :
1635 : Versions sendVersions;
1636 : Versions recvVersions;
1637 : };
1638 :
1639 : ///////////////////////////////////////////////////////////////////////////
1640 : // a=ssrc, RFC5576
1641 : //-------------------------------------------------------------------------
1642 : // ssrc-attr = "ssrc:" ssrc-id SP attribute
1643 : // ; The base definition of "attribute" is in RFC 4566.
1644 : // ; (It is the content of "a=" lines.)
1645 : //
1646 : // ssrc-id = integer ; 0 .. 2**32 - 1
1647 : //-------------------------------------------------------------------------
1648 : // TODO -- In the future, it might be nice if we ran a parse on the
1649 : // attribute section of this so that we could interpret it semantically.
1650 : // For WebRTC, the key use case for a=ssrc is assocaiting SSRCs with
1651 : // media sections, and we're not really going to care about the attribute
1652 : // itself. So we're just going to store it as a string for the time being.
1653 : // Issue 187.
1654 0 : class SdpSsrcAttributeList : public SdpAttribute
1655 : {
1656 : public:
1657 0 : SdpSsrcAttributeList() : SdpAttribute(kSsrcAttribute) {}
1658 :
1659 0 : struct Ssrc {
1660 : uint32_t ssrc;
1661 : std::string attribute;
1662 : };
1663 :
1664 : void
1665 0 : PushEntry(uint32_t ssrc, const std::string& attribute)
1666 : {
1667 0 : Ssrc value = { ssrc, attribute };
1668 0 : mSsrcs.push_back(value);
1669 0 : }
1670 :
1671 : virtual void Serialize(std::ostream& os) const override;
1672 :
1673 : std::vector<Ssrc> mSsrcs;
1674 : };
1675 :
1676 : ///////////////////////////////////////////////////////////////////////////
1677 : // a=ssrc-group, RFC5576
1678 : //-------------------------------------------------------------------------
1679 : // ssrc-group-attr = "ssrc-group:" semantics *(SP ssrc-id)
1680 : //
1681 : // semantics = "FEC" / "FID" / token
1682 : //
1683 : // ssrc-id = integer ; 0 .. 2**32 - 1
1684 0 : class SdpSsrcGroupAttributeList : public SdpAttribute
1685 : {
1686 : public:
1687 : enum Semantics {
1688 : kFec, // RFC5576
1689 : kFid, // RFC5576
1690 : kFecFr, // RFC5956
1691 : kDup // RFC7104
1692 : };
1693 :
1694 0 : struct SsrcGroup {
1695 : Semantics semantics;
1696 : std::vector<uint32_t> ssrcs;
1697 : };
1698 :
1699 : SdpSsrcGroupAttributeList() : SdpAttribute(kSsrcGroupAttribute) {}
1700 :
1701 : void
1702 : PushEntry(Semantics semantics, const std::vector<uint32_t>& ssrcs)
1703 : {
1704 : SsrcGroup value = { semantics, ssrcs };
1705 : mSsrcGroups.push_back(value);
1706 : }
1707 :
1708 : virtual void Serialize(std::ostream& os) const override;
1709 :
1710 : std::vector<SsrcGroup> mSsrcGroups;
1711 : };
1712 :
1713 0 : inline std::ostream& operator<<(std::ostream& os,
1714 : SdpSsrcGroupAttributeList::Semantics s)
1715 : {
1716 0 : switch (s) {
1717 : case SdpSsrcGroupAttributeList::kFec:
1718 0 : os << "FEC";
1719 0 : break;
1720 : case SdpSsrcGroupAttributeList::kFid:
1721 0 : os << "FID";
1722 0 : break;
1723 : case SdpSsrcGroupAttributeList::kFecFr:
1724 0 : os << "FEC-FR";
1725 0 : break;
1726 : case SdpSsrcGroupAttributeList::kDup:
1727 0 : os << "DUP";
1728 0 : break;
1729 : default:
1730 0 : MOZ_ASSERT(false);
1731 : os << "?";
1732 : }
1733 0 : return os;
1734 : }
1735 :
1736 : ///////////////////////////////////////////////////////////////////////////
1737 0 : class SdpMultiStringAttribute : public SdpAttribute
1738 : {
1739 : public:
1740 0 : explicit SdpMultiStringAttribute(AttributeType type) : SdpAttribute(type) {}
1741 :
1742 : void
1743 0 : PushEntry(const std::string& entry)
1744 : {
1745 0 : mValues.push_back(entry);
1746 0 : }
1747 :
1748 : virtual void Serialize(std::ostream& os) const;
1749 :
1750 : std::vector<std::string> mValues;
1751 : };
1752 :
1753 : // otherwise identical to SdpMultiStringAttribute, this is used for
1754 : // ice-options and other places where the value is serialized onto
1755 : // a single line with space separating tokens
1756 0 : class SdpOptionsAttribute : public SdpAttribute
1757 : {
1758 : public:
1759 0 : explicit SdpOptionsAttribute(AttributeType type) : SdpAttribute(type) {}
1760 :
1761 : void
1762 0 : PushEntry(const std::string& entry)
1763 : {
1764 0 : mValues.push_back(entry);
1765 0 : }
1766 :
1767 : void Load(const std::string& value);
1768 :
1769 : virtual void Serialize(std::ostream& os) const;
1770 :
1771 : std::vector<std::string> mValues;
1772 : };
1773 :
1774 : // Used for attributes that take no value (eg; a=ice-lite)
1775 0 : class SdpFlagAttribute : public SdpAttribute
1776 : {
1777 : public:
1778 0 : explicit SdpFlagAttribute(AttributeType type) : SdpAttribute(type) {}
1779 :
1780 : virtual void Serialize(std::ostream& os) const override;
1781 : };
1782 :
1783 : // Used for any other kind of single-valued attribute not otherwise specialized
1784 0 : class SdpStringAttribute : public SdpAttribute
1785 : {
1786 : public:
1787 0 : explicit SdpStringAttribute(AttributeType type, const std::string& value)
1788 0 : : SdpAttribute(type), mValue(value)
1789 : {
1790 0 : }
1791 :
1792 : virtual void Serialize(std::ostream& os) const override;
1793 :
1794 : std::string mValue;
1795 : };
1796 :
1797 : // Used for any purely (non-negative) numeric attribute
1798 0 : class SdpNumberAttribute : public SdpAttribute
1799 : {
1800 : public:
1801 0 : explicit SdpNumberAttribute(AttributeType type, uint32_t value = 0)
1802 0 : : SdpAttribute(type), mValue(value)
1803 : {
1804 0 : }
1805 :
1806 : virtual void Serialize(std::ostream& os) const override;
1807 :
1808 : uint32_t mValue;
1809 : };
1810 :
1811 : } // namespace mozilla
1812 :
1813 : #endif
|