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 _SDPMEDIASECTION_H_
8 #define _SDPMEDIASECTION_H_
9 
10 #include "mozilla/Maybe.h"
11 #include "signaling/src/sdp/SdpEnum.h"
12 #include "signaling/src/sdp/SdpAttributeList.h"
13 #include <string>
14 #include <vector>
15 #include <sstream>
16 
17 namespace mozilla
18 {
19 
20 class SdpAttributeList;
21 
22 class SdpConnection;
23 
24 class SdpMediaSection
25 {
26 public:
27   enum MediaType { kAudio, kVideo, kText, kApplication, kMessage };
28   // don't add to enum to avoid warnings about unhandled enum values
29   static const size_t kMediaTypes = static_cast<size_t>(kMessage) + 1;
30 
31   enum Protocol {
32     kRtpAvp,            // RTP/AVP [RFC4566]
33     kUdp,               // udp [RFC4566]
34     kVat,               // vat [historic]
35     kRtp,               // rtp [historic]
36     kUdptl,             // udptl [ITU-T]
37     kTcp,               // TCP [RFC4145]
38     kRtpAvpf,           // RTP/AVPF [RFC4585]
39     kTcpRtpAvp,         // TCP/RTP/AVP [RFC4571]
40     kRtpSavp,           // RTP/SAVP [RFC3711]
41     kTcpBfcp,           // TCP/BFCP [RFC4583]
42     kTcpTlsBfcp,        // TCP/TLS/BFCP [RFC4583]
43     kTcpTls,            // TCP/TLS [RFC4572]
44     kFluteUdp,          // FLUTE/UDP [RFC-mehta-rmt-flute-sdp-05]
45     kTcpMsrp,           // TCP/MSRP [RFC4975]
46     kTcpTlsMsrp,        // TCP/TLS/MSRP [RFC4975]
47     kDccp,              // DCCP [RFC5762]
48     kDccpRtpAvp,        // DCCP/RTP/AVP [RFC5762]
49     kDccpRtpSavp,       // DCCP/RTP/SAVP [RFC5762]
50     kDccpRtpAvpf,       // DCCP/RTP/AVPF [RFC5762]
51     kDccpRtpSavpf,      // DCCP/RTP/SAVPF [RFC5762]
52     kRtpSavpf,          // RTP/SAVPF [RFC5124]
53     kUdpTlsRtpSavp,     // UDP/TLS/RTP/SAVP [RFC5764]
54     kTcpTlsRtpSavp,     // TCP/TLS/RTP/SAVP [JSEP-TBD]
55     kDccpTlsRtpSavp,    // DCCP/TLS/RTP/SAVP [RFC5764]
56     kUdpTlsRtpSavpf,    // UDP/TLS/RTP/SAVPF [RFC5764]
57     kTcpTlsRtpSavpf,    // TCP/TLS/RTP/SAVPF [JSEP-TBD]
58     kDccpTlsRtpSavpf,   // DCCP/TLS/RTP/SAVPF [RFC5764]
59     kUdpMbmsFecRtpAvp,  // UDP/MBMS-FEC/RTP/AVP [RFC6064]
60     kUdpMbmsFecRtpSavp, // UDP/MBMS-FEC/RTP/SAVP [RFC6064]
61     kUdpMbmsRepair,     // UDP/MBMS-REPAIR [RFC6064]
62     kFecUdp,            // FEC/UDP [RFC6364]
63     kUdpFec,            // UDP/FEC [RFC6364]
64     kTcpMrcpv2,         // TCP/MRCPv2 [RFC6787]
65     kTcpTlsMrcpv2,      // TCP/TLS/MRCPv2 [RFC6787]
66     kPstn,              // PSTN [RFC7195]
67     kUdpTlsUdptl,       // UDP/TLS/UDPTL [RFC7345]
68     kSctp,              // SCTP [draft-ietf-mmusic-sctp-sdp-07]
69     kSctpDtls,          // SCTP/DTLS [draft-ietf-mmusic-sctp-sdp-07]
70     kDtlsSctp           // DTLS/SCTP [draft-ietf-mmusic-sctp-sdp-07]
71   };
72 
SdpMediaSection(size_t level)73   explicit SdpMediaSection(size_t level) : mLevel(level) {}
74 
75   virtual MediaType GetMediaType() const = 0;
76   virtual unsigned int GetPort() const = 0;
77   virtual void SetPort(unsigned int port) = 0;
78   virtual unsigned int GetPortCount() const = 0;
79   virtual Protocol GetProtocol() const = 0;
80   virtual const SdpConnection& GetConnection() const = 0;
81   virtual SdpConnection& GetConnection() = 0;
82   virtual uint32_t GetBandwidth(const std::string& type) const = 0;
83   virtual const std::vector<std::string>& GetFormats() const = 0;
84 
85   std::vector<std::string> GetFormatsForSimulcastVersion(
86       size_t simulcastVersion, bool send, bool recv) const;
87   virtual const SdpAttributeList& GetAttributeList() const = 0;
88   virtual SdpAttributeList& GetAttributeList() = 0;
89 
90   virtual SdpDirectionAttribute GetDirectionAttribute() const = 0;
91 
92   virtual void Serialize(std::ostream&) const = 0;
93 
94   virtual void AddCodec(const std::string& pt, const std::string& name,
95                         uint32_t clockrate, uint16_t channels) = 0;
96   virtual void ClearCodecs() = 0;
97 
98   virtual void AddDataChannel(const std::string& pt, const std::string& name,
99                               uint16_t streams) = 0;
100 
101   size_t
GetLevel()102   GetLevel() const
103   {
104     return mLevel;
105   }
106 
107   inline bool
IsReceiving()108   IsReceiving() const
109   {
110     return GetDirectionAttribute().mValue & sdp::kRecv;
111   }
112 
113   inline bool
IsSending()114   IsSending() const
115   {
116     return GetDirectionAttribute().mValue & sdp::kSend;
117   }
118 
119   inline void
SetReceiving(bool receiving)120   SetReceiving(bool receiving)
121   {
122     auto direction = GetDirectionAttribute().mValue;
123     if (direction & sdp::kSend) {
124       SetDirection(receiving ?
125                    SdpDirectionAttribute::kSendrecv :
126                    SdpDirectionAttribute::kSendonly);
127     } else {
128       SetDirection(receiving ?
129                    SdpDirectionAttribute::kRecvonly :
130                    SdpDirectionAttribute::kInactive);
131     }
132   }
133 
134   inline void
SetSending(bool sending)135   SetSending(bool sending)
136   {
137     auto direction = GetDirectionAttribute().mValue;
138     if (direction & sdp::kRecv) {
139       SetDirection(sending ?
140                    SdpDirectionAttribute::kSendrecv :
141                    SdpDirectionAttribute::kRecvonly);
142     } else {
143       SetDirection(sending ?
144                    SdpDirectionAttribute::kSendonly :
145                    SdpDirectionAttribute::kInactive);
146     }
147   }
148 
SetDirection(SdpDirectionAttribute::Direction direction)149   inline void SetDirection(SdpDirectionAttribute::Direction direction)
150   {
151     GetAttributeList().SetAttribute(new SdpDirectionAttribute(direction));
152   }
153 
154   const SdpFmtpAttributeList::Parameters* FindFmtp(const std::string& pt) const;
155   void SetFmtp(const SdpFmtpAttributeList::Fmtp& fmtp);
156   void RemoveFmtp(const std::string& pt);
157   const SdpRtpmapAttributeList::Rtpmap* FindRtpmap(const std::string& pt) const;
158   const SdpSctpmapAttributeList::Sctpmap* FindSctpmap(
159       const std::string& pt) const;
160   bool HasRtcpFb(const std::string& pt,
161                  SdpRtcpFbAttributeList::Type type,
162                  const std::string& subType) const;
163   SdpRtcpFbAttributeList GetRtcpFbs() const;
164   void SetRtcpFbs(const SdpRtcpFbAttributeList& rtcpfbs);
HasFormat(const std::string & format)165   bool HasFormat(const std::string& format) const
166   {
167     return std::find(GetFormats().begin(), GetFormats().end(), format) !=
168         GetFormats().end();
169   }
170   void SetSsrcs(const std::vector<uint32_t>& ssrcs,
171                 const std::string& cname);
172   void AddMsid(const std::string& id, const std::string& appdata);
173   const SdpRidAttributeList::Rid* FindRid(const std::string& id) const;
174 
175 private:
176   size_t mLevel;
177 };
178 
179 inline std::ostream& operator<<(std::ostream& os, const SdpMediaSection& ms)
180 {
181   ms.Serialize(os);
182   return os;
183 }
184 
185 inline std::ostream& operator<<(std::ostream& os, SdpMediaSection::MediaType t)
186 {
187   switch (t) {
188     case SdpMediaSection::kAudio:
189       return os << "audio";
190     case SdpMediaSection::kVideo:
191       return os << "video";
192     case SdpMediaSection::kText:
193       return os << "text";
194     case SdpMediaSection::kApplication:
195       return os << "application";
196     case SdpMediaSection::kMessage:
197       return os << "message";
198   }
199   MOZ_ASSERT(false, "Unknown MediaType");
200   return os << "?";
201 }
202 
203 inline std::ostream& operator<<(std::ostream& os, SdpMediaSection::Protocol p)
204 {
205   switch (p) {
206     case SdpMediaSection::kRtpAvp:
207       return os << "RTP/AVP";
208     case SdpMediaSection::kUdp:
209       return os << "udp";
210     case SdpMediaSection::kVat:
211       return os << "vat";
212     case SdpMediaSection::kRtp:
213       return os << "rtp";
214     case SdpMediaSection::kUdptl:
215       return os << "udptl";
216     case SdpMediaSection::kTcp:
217       return os << "TCP";
218     case SdpMediaSection::kRtpAvpf:
219       return os << "RTP/AVPF";
220     case SdpMediaSection::kTcpRtpAvp:
221       return os << "TCP/RTP/AVP";
222     case SdpMediaSection::kRtpSavp:
223       return os << "RTP/SAVP";
224     case SdpMediaSection::kTcpBfcp:
225       return os << "TCP/BFCP";
226     case SdpMediaSection::kTcpTlsBfcp:
227       return os << "TCP/TLS/BFCP";
228     case SdpMediaSection::kTcpTls:
229       return os << "TCP/TLS";
230     case SdpMediaSection::kFluteUdp:
231       return os << "FLUTE/UDP";
232     case SdpMediaSection::kTcpMsrp:
233       return os << "TCP/MSRP";
234     case SdpMediaSection::kTcpTlsMsrp:
235       return os << "TCP/TLS/MSRP";
236     case SdpMediaSection::kDccp:
237       return os << "DCCP";
238     case SdpMediaSection::kDccpRtpAvp:
239       return os << "DCCP/RTP/AVP";
240     case SdpMediaSection::kDccpRtpSavp:
241       return os << "DCCP/RTP/SAVP";
242     case SdpMediaSection::kDccpRtpAvpf:
243       return os << "DCCP/RTP/AVPF";
244     case SdpMediaSection::kDccpRtpSavpf:
245       return os << "DCCP/RTP/SAVPF";
246     case SdpMediaSection::kRtpSavpf:
247       return os << "RTP/SAVPF";
248     case SdpMediaSection::kUdpTlsRtpSavp:
249       return os << "UDP/TLS/RTP/SAVP";
250     case SdpMediaSection::kTcpTlsRtpSavp:
251       return os << "TCP/TLS/RTP/SAVP";
252     case SdpMediaSection::kDccpTlsRtpSavp:
253       return os << "DCCP/TLS/RTP/SAVP";
254     case SdpMediaSection::kUdpTlsRtpSavpf:
255       return os << "UDP/TLS/RTP/SAVPF";
256     case SdpMediaSection::kTcpTlsRtpSavpf:
257       return os << "TCP/TLS/RTP/SAVPF";
258     case SdpMediaSection::kDccpTlsRtpSavpf:
259       return os << "DCCP/TLS/RTP/SAVPF";
260     case SdpMediaSection::kUdpMbmsFecRtpAvp:
261       return os << "UDP/MBMS-FEC/RTP/AVP";
262     case SdpMediaSection::kUdpMbmsFecRtpSavp:
263       return os << "UDP/MBMS-FEC/RTP/SAVP";
264     case SdpMediaSection::kUdpMbmsRepair:
265       return os << "UDP/MBMS-REPAIR";
266     case SdpMediaSection::kFecUdp:
267       return os << "FEC/UDP";
268     case SdpMediaSection::kUdpFec:
269       return os << "UDP/FEC";
270     case SdpMediaSection::kTcpMrcpv2:
271       return os << "TCP/MRCPv2";
272     case SdpMediaSection::kTcpTlsMrcpv2:
273       return os << "TCP/TLS/MRCPv2";
274     case SdpMediaSection::kPstn:
275       return os << "PSTN";
276     case SdpMediaSection::kUdpTlsUdptl:
277       return os << "UDP/TLS/UDPTL";
278     case SdpMediaSection::kSctp:
279       return os << "SCTP";
280     case SdpMediaSection::kSctpDtls:
281       return os << "SCTP/DTLS";
282     case SdpMediaSection::kDtlsSctp:
283       return os << "DTLS/SCTP";
284   }
285   MOZ_ASSERT(false, "Unknown Protocol");
286   return os << "?";
287 }
288 
289 class SdpConnection
290 {
291 public:
292   SdpConnection(sdp::AddrType addrType, std::string addr, uint8_t ttl = 0,
293                 uint32_t count = 0)
mAddrType(addrType)294       : mAddrType(addrType), mAddr(addr), mTtl(ttl), mCount(count)
295   {
296   }
~SdpConnection()297   ~SdpConnection() {}
298 
299   sdp::AddrType
GetAddrType()300   GetAddrType() const
301   {
302     return mAddrType;
303   }
304   const std::string&
GetAddress()305   GetAddress() const
306   {
307     return mAddr;
308   }
309   void
SetAddress(const std::string & address)310   SetAddress(const std::string& address)
311   {
312     mAddr = address;
313     if (mAddr.find(':') != std::string::npos) {
314       mAddrType = sdp::kIPv6;
315     } else {
316       mAddrType = sdp::kIPv4;
317     }
318   }
319   uint8_t
GetTtl()320   GetTtl() const
321   {
322     return mTtl;
323   }
324   uint32_t
GetCount()325   GetCount() const
326   {
327     return mCount;
328   }
329 
330   void
Serialize(std::ostream & os)331   Serialize(std::ostream& os) const
332   {
333     sdp::NetType netType = sdp::kInternet;
334 
335     os << "c=" << netType << " " << mAddrType << " " << mAddr;
336 
337     if (mTtl) {
338       os << "/" << static_cast<uint32_t>(mTtl);
339       if (mCount) {
340         os << "/" << mCount;
341       }
342     }
343     os << "\r\n";
344   }
345 
346 private:
347   sdp::AddrType mAddrType;
348   std::string mAddr;
349   uint8_t mTtl;    // 0-255; 0 when unset
350   uint32_t mCount; // 0 when unset
351 };
352 
353 inline std::ostream& operator<<(std::ostream& os, const SdpConnection& c)
354 {
355   c.Serialize(os);
356   return os;
357 }
358 
359 } // namespace mozilla
360 
361 #endif
362