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