317 lines
11 KiB
C++
317 lines
11 KiB
C++
/* -*- 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 <string>
|
|
#include <vector>
|
|
#include <sstream>
|
|
|
|
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<size_t>(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<std::string>& GetFormats() const = 0;
|
|
|
|
std::vector<std::string> 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<uint32_t>& 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<uint32_t>(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
|