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