/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef _SDPMEDIASECTION_H_ #define _SDPMEDIASECTION_H_ #include "mozilla/Maybe.h" #include "sdp/SdpEnum.h" #include "sdp/SdpAttributeList.h" #include #include #include namespace mozilla { class SdpAttributeList; class SdpConnection; class SdpMediaSection { public: enum MediaType { kAudio, kVideo, kText, kApplication, kMessage }; // don't add to enum to avoid warnings about unhandled enum values static const size_t kMediaTypes = static_cast(kMessage) + 1; enum Protocol { kRtpAvp, // RTP/AVP [RFC4566] kUdp, // udp [RFC4566] kVat, // vat [historic] kRtp, // rtp [historic] kUdptl, // udptl [ITU-T] kTcp, // TCP [RFC4145] kRtpAvpf, // RTP/AVPF [RFC4585] kTcpRtpAvp, // TCP/RTP/AVP [RFC4571] kRtpSavp, // RTP/SAVP [RFC3711] kTcpBfcp, // TCP/BFCP [RFC4583] kTcpTlsBfcp, // TCP/TLS/BFCP [RFC4583] kTcpTls, // TCP/TLS [RFC4572] kFluteUdp, // FLUTE/UDP [RFC-mehta-rmt-flute-sdp-05] kTcpMsrp, // TCP/MSRP [RFC4975] kTcpTlsMsrp, // TCP/TLS/MSRP [RFC4975] kDccp, // DCCP [RFC5762] kDccpRtpAvp, // DCCP/RTP/AVP [RFC5762] kDccpRtpSavp, // DCCP/RTP/SAVP [RFC5762] kDccpRtpAvpf, // DCCP/RTP/AVPF [RFC5762] kDccpRtpSavpf, // DCCP/RTP/SAVPF [RFC5762] kRtpSavpf, // RTP/SAVPF [RFC5124] kUdpTlsRtpSavp, // UDP/TLS/RTP/SAVP [RFC5764] kTcpDtlsRtpSavp, // TCP/DTLS/RTP/SAVP [RFC7850] kDccpTlsRtpSavp, // DCCP/TLS/RTP/SAVP [RFC5764] kUdpTlsRtpSavpf, // UDP/TLS/RTP/SAVPF [RFC5764] kTcpDtlsRtpSavpf, // TCP/DTLS/RTP/SAVPF [RFC7850] kDccpTlsRtpSavpf, // DCCP/TLS/RTP/SAVPF [RFC5764] kUdpMbmsFecRtpAvp, // UDP/MBMS-FEC/RTP/AVP [RFC6064] kUdpMbmsFecRtpSavp, // UDP/MBMS-FEC/RTP/SAVP [RFC6064] kUdpMbmsRepair, // UDP/MBMS-REPAIR [RFC6064] kFecUdp, // FEC/UDP [RFC6364] kUdpFec, // UDP/FEC [RFC6364] kTcpMrcpv2, // TCP/MRCPv2 [RFC6787] kTcpTlsMrcpv2, // TCP/TLS/MRCPv2 [RFC6787] kPstn, // PSTN [RFC7195] kUdpTlsUdptl, // UDP/TLS/UDPTL [RFC7345] kSctp, // SCTP [draft-ietf-mmusic-sctp-sdp-07] kDtlsSctp, // DTLS/SCTP [draft-ietf-mmusic-sctp-sdp-07] kUdpDtlsSctp, // UDP/DTLS/SCTP [draft-ietf-mmusic-sctp-sdp-21] kTcpDtlsSctp // TCP/DTLS/SCTP [draft-ietf-mmusic-sctp-sdp-21] }; explicit SdpMediaSection(size_t level) : mLevel(level) {} virtual MediaType GetMediaType() const = 0; virtual unsigned int GetPort() const = 0; virtual void SetPort(unsigned int port) = 0; virtual unsigned int GetPortCount() const = 0; virtual Protocol GetProtocol() const = 0; virtual const SdpConnection& GetConnection() const = 0; virtual SdpConnection& GetConnection() = 0; virtual uint32_t GetBandwidth(const std::string& type) const = 0; virtual const std::vector& GetFormats() const = 0; std::vector GetFormatsForSimulcastVersion( size_t simulcastVersion, bool send, bool recv) const; virtual const SdpAttributeList& GetAttributeList() const = 0; virtual SdpAttributeList& GetAttributeList() = 0; virtual SdpDirectionAttribute GetDirectionAttribute() const = 0; virtual void Serialize(std::ostream&) const = 0; virtual void AddCodec(const std::string& pt, const std::string& name, uint32_t clockrate, uint16_t channels) = 0; virtual void ClearCodecs() = 0; virtual void AddDataChannel(const std::string& name, uint16_t port, uint16_t streams, uint32_t message_size) = 0; size_t GetLevel() const { return mLevel; } inline bool IsReceiving() const { return GetDirection() & sdp::kRecv; } inline bool IsSending() const { return GetDirection() & sdp::kSend; } inline void SetReceiving(bool receiving) { auto direction = GetDirection(); if (direction & sdp::kSend) { SetDirection(receiving ? SdpDirectionAttribute::kSendrecv : SdpDirectionAttribute::kSendonly); } else { SetDirection(receiving ? SdpDirectionAttribute::kRecvonly : SdpDirectionAttribute::kInactive); } } inline void SetSending(bool sending) { auto direction = GetDirection(); if (direction & sdp::kRecv) { SetDirection(sending ? SdpDirectionAttribute::kSendrecv : SdpDirectionAttribute::kRecvonly); } else { SetDirection(sending ? SdpDirectionAttribute::kSendonly : SdpDirectionAttribute::kInactive); } } inline void SetDirection(SdpDirectionAttribute::Direction direction) { GetAttributeList().SetAttribute(new SdpDirectionAttribute(direction)); } inline SdpDirectionAttribute::Direction GetDirection() const { return GetDirectionAttribute().mValue; } const SdpFmtpAttributeList::Parameters* FindFmtp(const std::string& pt) const; void SetFmtp(const SdpFmtpAttributeList::Fmtp& fmtp); void RemoveFmtp(const std::string& pt); const SdpRtpmapAttributeList::Rtpmap* FindRtpmap(const std::string& pt) const; const SdpSctpmapAttributeList::Sctpmap* GetSctpmap() const; uint32_t GetSctpPort() const; bool GetMaxMessageSize(uint32_t* size) const; bool HasRtcpFb(const std::string& pt, SdpRtcpFbAttributeList::Type type, const std::string& subType) const; SdpRtcpFbAttributeList GetRtcpFbs() const; void SetRtcpFbs(const SdpRtcpFbAttributeList& rtcpfbs); bool HasFormat(const std::string& format) const { return std::find(GetFormats().begin(), GetFormats().end(), format) != GetFormats().end(); } void SetSsrcs(const std::vector& ssrcs, const std::string& cname); void AddMsid(const std::string& id, const std::string& appdata); const SdpRidAttributeList::Rid* FindRid(const std::string& id) const; private: size_t mLevel; }; inline std::ostream& operator<<(std::ostream& os, const SdpMediaSection& ms) { ms.Serialize(os); return os; } inline std::ostream& operator<<(std::ostream& os, SdpMediaSection::MediaType t) { switch (t) { case SdpMediaSection::kAudio: return os << "audio"; case SdpMediaSection::kVideo: return os << "video"; case SdpMediaSection::kText: return os << "text"; case SdpMediaSection::kApplication: return os << "application"; case SdpMediaSection::kMessage: return os << "message"; } MOZ_ASSERT(false, "Unknown MediaType"); return os << "?"; } inline std::ostream& operator<<(std::ostream& os, SdpMediaSection::Protocol p) { switch (p) { case SdpMediaSection::kRtpAvp: return os << "RTP/AVP"; case SdpMediaSection::kUdp: return os << "udp"; case SdpMediaSection::kVat: return os << "vat"; case SdpMediaSection::kRtp: return os << "rtp"; case SdpMediaSection::kUdptl: return os << "udptl"; case SdpMediaSection::kTcp: return os << "TCP"; case SdpMediaSection::kRtpAvpf: return os << "RTP/AVPF"; case SdpMediaSection::kTcpRtpAvp: return os << "TCP/RTP/AVP"; case SdpMediaSection::kRtpSavp: return os << "RTP/SAVP"; case SdpMediaSection::kTcpBfcp: return os << "TCP/BFCP"; case SdpMediaSection::kTcpTlsBfcp: return os << "TCP/TLS/BFCP"; case SdpMediaSection::kTcpTls: return os << "TCP/TLS"; case SdpMediaSection::kFluteUdp: return os << "FLUTE/UDP"; case SdpMediaSection::kTcpMsrp: return os << "TCP/MSRP"; case SdpMediaSection::kTcpTlsMsrp: return os << "TCP/TLS/MSRP"; case SdpMediaSection::kDccp: return os << "DCCP"; case SdpMediaSection::kDccpRtpAvp: return os << "DCCP/RTP/AVP"; case SdpMediaSection::kDccpRtpSavp: return os << "DCCP/RTP/SAVP"; case SdpMediaSection::kDccpRtpAvpf: return os << "DCCP/RTP/AVPF"; case SdpMediaSection::kDccpRtpSavpf: return os << "DCCP/RTP/SAVPF"; case SdpMediaSection::kRtpSavpf: return os << "RTP/SAVPF"; case SdpMediaSection::kUdpTlsRtpSavp: return os << "UDP/TLS/RTP/SAVP"; case SdpMediaSection::kTcpDtlsRtpSavp: return os << "TCP/DTLS/RTP/SAVP"; case SdpMediaSection::kDccpTlsRtpSavp: return os << "DCCP/TLS/RTP/SAVP"; case SdpMediaSection::kUdpTlsRtpSavpf: return os << "UDP/TLS/RTP/SAVPF"; case SdpMediaSection::kTcpDtlsRtpSavpf: return os << "TCP/DTLS/RTP/SAVPF"; case SdpMediaSection::kDccpTlsRtpSavpf: return os << "DCCP/TLS/RTP/SAVPF"; case SdpMediaSection::kUdpMbmsFecRtpAvp: return os << "UDP/MBMS-FEC/RTP/AVP"; case SdpMediaSection::kUdpMbmsFecRtpSavp: return os << "UDP/MBMS-FEC/RTP/SAVP"; case SdpMediaSection::kUdpMbmsRepair: return os << "UDP/MBMS-REPAIR"; case SdpMediaSection::kFecUdp: return os << "FEC/UDP"; case SdpMediaSection::kUdpFec: return os << "UDP/FEC"; case SdpMediaSection::kTcpMrcpv2: return os << "TCP/MRCPv2"; case SdpMediaSection::kTcpTlsMrcpv2: return os << "TCP/TLS/MRCPv2"; case SdpMediaSection::kPstn: return os << "PSTN"; case SdpMediaSection::kUdpTlsUdptl: return os << "UDP/TLS/UDPTL"; case SdpMediaSection::kSctp: return os << "SCTP"; case SdpMediaSection::kDtlsSctp: return os << "DTLS/SCTP"; case SdpMediaSection::kUdpDtlsSctp: return os << "UDP/DTLS/SCTP"; case SdpMediaSection::kTcpDtlsSctp: return os << "TCP/DTLS/SCTP"; } MOZ_ASSERT(false, "Unknown Protocol"); return os << "?"; } class SdpConnection { public: SdpConnection(sdp::AddrType addrType, std::string addr, uint8_t ttl = 0, uint32_t count = 0) : mAddrType(addrType), mAddr(addr), mTtl(ttl), mCount(count) {} ~SdpConnection() {} sdp::AddrType GetAddrType() const { return mAddrType; } const std::string& GetAddress() const { return mAddr; } void SetAddress(const std::string& address) { mAddr = address; if (mAddr.find(':') != std::string::npos) { mAddrType = sdp::kIPv6; } else { mAddrType = sdp::kIPv4; } } uint8_t GetTtl() const { return mTtl; } uint32_t GetCount() const { return mCount; } void Serialize(std::ostream& os) const { sdp::NetType netType = sdp::kInternet; os << "c=" << netType << " " << mAddrType << " " << mAddr; if (mTtl) { os << "/" << static_cast(mTtl); if (mCount) { os << "/" << mCount; } } os << "\r\n"; } private: sdp::AddrType mAddrType; std::string mAddr; uint8_t mTtl; // 0-255; 0 when unset uint32_t mCount; // 0 when unset }; inline std::ostream& operator<<(std::ostream& os, const SdpConnection& c) { c.Serialize(os); return os; } } // namespace mozilla #endif