mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1091242 - Part 1: SDP wrapper code around sipcc sdp impl. See https://github.com/unicorn-wg/gecko-dev/tree/multistream_rebase for more history. r=jesup
This commit is contained in:
parent
5f2852c277
commit
2967aafd0c
195
media/webrtc/signaling/src/sdp/Sdp.h
Normal file
195
media/webrtc/signaling/src/sdp/Sdp.h
Normal file
@ -0,0 +1,195 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
/*
|
||||
|
||||
,-----. ,--. ,--.
|
||||
' .--./ ,--,--.,--.,--.,-' '-.`--' ,---. ,--,--,
|
||||
| | ' ,-. || || |'-. .-',--.| .-. || `
|
||||
' '--'\\ '-' |' '' ' | | | |' '-' '| || |
|
||||
`-----' `--`--' `----' `--' `--' `---' `--''--'
|
||||
|
||||
:+o+-
|
||||
-dNNNNNd.
|
||||
yNNNNNNNs
|
||||
:mNNNNNm-
|
||||
`/sso/``-://-
|
||||
.:+sydNNNNNNms: `://`
|
||||
`-/+shmNNNNNNNNNNNNNNNms- :mNNNm/
|
||||
`-/oydmNNNNNNNNNNNNNNNNNNNNNNNNdo- +NNNNNN+
|
||||
.shmNNNNNNNNNNNmdyo/:dNNNNNNNNNNNNNNNNdo. `sNNNNNm+
|
||||
hNNNNNNNNmhs+:-` .dNNNNNNNNNNNNNNNNNNNNh+-` `hNNNNNm:
|
||||
-yddyo/:. -dNNNNm::ymNNNNNNNNNNNNNNNmdy+/dNNNNNd.
|
||||
:mNNNNd. `/ymNNNNNNNNNNNNNNNNNNNNNNh`
|
||||
+NNNNNh` `+hNNNNNNNNNNNNNNNNNNNs
|
||||
sNNNNNy` .yNNNNNm`-/oymNNNm+
|
||||
`yNNNNNo oNNNNNm` `-.
|
||||
.dNNNNm/ oNNNNNm`
|
||||
oNNNNm: +NNNNNm`
|
||||
`+yho. +NNNNNm`
|
||||
+NNNNNNs.
|
||||
`yNNNNNNmy-
|
||||
-smNNNNNNh:
|
||||
.smNNNNNNh/
|
||||
`omNNNNNNd:
|
||||
`+dNNNNNd
|
||||
````......```` /hmdy-
|
||||
`.:/+osyhddmNNMMMMMMMMMMMMMMMMMMMMNNmddhyso+/:.`
|
||||
`-+shmNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNmhs+-`
|
||||
-smMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMds-
|
||||
hMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh
|
||||
yMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMs
|
||||
.ohNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNh+.
|
||||
./oydmMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmhyo:.
|
||||
`.:/+osyyhddmmNNMMMMMMMMMMMMMMNNmmddhyyso+/:.`
|
||||
|
||||
,--------.,--. ,--. ,--.
|
||||
'--. .--'| ,---. `--' ,---. | | ,---.
|
||||
| | | .-. |,--.( .-' | |( .-'
|
||||
| | | | | || |.-' `) | |.-' `)
|
||||
`--' `--' `--'`--'`----' `--'`----'
|
||||
,--.
|
||||
,---. ,------. ,------. ,--. | |
|
||||
' .-' | .-. \ | .--. ' ,--,--.,--.--.,-' '-. ,--,--.| |
|
||||
`. `-. | | \ :| '--' |' ,-. || .--''-. .-'' ,-. || |
|
||||
.-' || '--' /| | --' \ '-' || | | | \ '-' |`--'
|
||||
`-----' `-------' `--' `--`--'`--' `--' `--`--'.--.
|
||||
'__'
|
||||
*/
|
||||
|
||||
#ifndef _SDP_H_
|
||||
#define _SDP_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
#include "signaling/src/sdp/SdpAttributeList.h"
|
||||
#include "signaling/src/sdp/SdpEnum.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SdpOrigin;
|
||||
class SdpEncryptionKey;
|
||||
class SdpMediaSection;
|
||||
|
||||
/**
|
||||
* Base class for an SDP
|
||||
*/
|
||||
class Sdp
|
||||
{
|
||||
public:
|
||||
Sdp(){};
|
||||
virtual ~Sdp(){};
|
||||
|
||||
virtual const SdpOrigin& GetOrigin() const = 0;
|
||||
// Note: connection information is always retrieved from media sections
|
||||
virtual uint32_t GetBandwidth(const std::string& type) const = 0;
|
||||
|
||||
virtual const SdpAttributeList& GetAttributeList() const = 0;
|
||||
virtual SdpAttributeList& GetAttributeList() = 0;
|
||||
|
||||
virtual size_t GetMediaSectionCount() const = 0;
|
||||
virtual const SdpMediaSection& GetMediaSection(size_t level) const = 0;
|
||||
virtual SdpMediaSection& GetMediaSection(size_t level) = 0;
|
||||
|
||||
virtual SdpMediaSection& AddMediaSection(SdpMediaSection::MediaType media,
|
||||
SdpDirectionAttribute::Direction dir,
|
||||
uint16_t port,
|
||||
SdpMediaSection::Protocol proto,
|
||||
sdp::AddrType addrType,
|
||||
const std::string& addr) = 0;
|
||||
|
||||
virtual void Serialize(std::ostream&) const = 0;
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Sdp& sdp)
|
||||
{
|
||||
sdp.Serialize(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
Sdp::ToString() const
|
||||
{
|
||||
std::stringstream s;
|
||||
s << *this;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
class SdpOrigin
|
||||
{
|
||||
public:
|
||||
SdpOrigin(const std::string& username, uint64_t sessId, uint64_t sessVer,
|
||||
sdp::AddrType addrType, const std::string& addr)
|
||||
: mUsername(username),
|
||||
mSessionId(sessId),
|
||||
mSessionVersion(sessVer),
|
||||
mAddrType(addrType),
|
||||
mAddress(addr)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string&
|
||||
GetUsername() const
|
||||
{
|
||||
return mUsername;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GetSessionId() const
|
||||
{
|
||||
return mSessionId;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GetSessionVersion() const
|
||||
{
|
||||
return mSessionVersion;
|
||||
}
|
||||
|
||||
const sdp::AddrType
|
||||
GetAddrType() const
|
||||
{
|
||||
return mAddrType;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
GetAddress() const
|
||||
{
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
void
|
||||
Serialize(std::ostream& os) const
|
||||
{
|
||||
sdp::NetType netType = sdp::kInternet;
|
||||
os << "o=" << mUsername << " " << mSessionId << " " << mSessionVersion
|
||||
<< " " << netType << " " << mAddrType << " " << mAddress << "\r\n";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string mUsername;
|
||||
uint64_t mSessionId;
|
||||
uint64_t mSessionVersion;
|
||||
sdp::AddrType mAddrType;
|
||||
std::string mAddress;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const SdpOrigin& origin)
|
||||
{
|
||||
origin.Serialize(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
588
media/webrtc/signaling/src/sdp/SdpAttribute.cpp
Normal file
588
media/webrtc/signaling/src/sdp/SdpAttribute.cpp
Normal file
@ -0,0 +1,588 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "signaling/src/sdp/SdpAttribute.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#ifdef CRLF
|
||||
#undef CRLF
|
||||
#endif
|
||||
#define CRLF "\r\n"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
void
|
||||
SdpConnectionAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mValue << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpDirectionAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mValue << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpExtmapAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mExtmaps.begin(); i != mExtmaps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->entry;
|
||||
if (i->direction_specified) {
|
||||
os << "/" << i->direction;
|
||||
}
|
||||
os << " " << i->extensionname;
|
||||
if (i->extensionattributes.length()) {
|
||||
os << " " << i->extensionattributes;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpFingerprintAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mFingerprints.begin(); i != mFingerprints.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->hashFunc << " "
|
||||
<< FormatFingerprint(i->fingerprint) << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
// Format the fingerprint in RFC 4572 Section 5 attribute format
|
||||
std::string
|
||||
SdpFingerprintAttributeList::FormatFingerprint(const std::vector<uint8_t>& fp)
|
||||
{
|
||||
if (fp.empty()) {
|
||||
MOZ_ASSERT(false, "Cannot format an empty fingerprint.");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
for (auto i = fp.begin(); i != fp.end(); ++i) {
|
||||
os << ":" << std::hex << std::uppercase << std::setw(2) << std::setfill('0')
|
||||
<< static_cast<uint32_t>(*i);
|
||||
}
|
||||
return os.str().substr(1);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
FromUppercaseHex(char ch)
|
||||
{
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
return ch - '0';
|
||||
}
|
||||
if ((ch >= 'A') && (ch <= 'F')) {
|
||||
return ch - 'A' + 10;
|
||||
}
|
||||
return 16; // invalid
|
||||
}
|
||||
|
||||
// Parse the fingerprint from RFC 4572 Section 5 attribute format
|
||||
std::vector<uint8_t>
|
||||
SdpFingerprintAttributeList::ParseFingerprint(const std::string& str)
|
||||
{
|
||||
size_t targetSize = (str.length() + 1) / 3;
|
||||
std::vector<uint8_t> fp(targetSize);
|
||||
size_t fpIndex = 0;
|
||||
|
||||
if (str.length() % 3 != 2) {
|
||||
fp.clear();
|
||||
return fp;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < str.length(); i += 3) {
|
||||
uint8_t high = FromUppercaseHex(str[i]);
|
||||
uint8_t low = FromUppercaseHex(str[i + 1]);
|
||||
if (high > 0xf || low > 0xf ||
|
||||
(i + 2 < str.length() && str[i + 2] != ':')) {
|
||||
fp.clear(); // error
|
||||
return fp;
|
||||
}
|
||||
fp[fpIndex++] = high << 4 | low;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
void
|
||||
SdpFmtpAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mFmtps.begin(); i != mFmtps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->format << " ";
|
||||
if (i->parameters) {
|
||||
i->parameters->Serialize(os);
|
||||
} else {
|
||||
os << i->parameters_string;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpGroupAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mGroups.begin(); i != mGroups.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->semantics;
|
||||
for (auto j = i->tags.begin(); j != i->tags.end(); ++j) {
|
||||
os << " " << (*j);
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
// We're just using an SdpStringAttribute for this right now
|
||||
#if 0
|
||||
void SdpIdentityAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mAssertion;
|
||||
for (auto i = mExtensions.begin(); i != mExtensions.end(); i++) {
|
||||
os << (i == mExtensions.begin() ? " " : ";") << (*i);
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
SdpImageattrAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
MOZ_ASSERT(false, "Serializer not yet implemented");
|
||||
}
|
||||
|
||||
void
|
||||
SdpMsidAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mMsids.begin(); i != mMsids.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->identifier;
|
||||
if (i->appdata.length()) {
|
||||
os << " " << i->appdata;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpRemoteCandidatesAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
if (mCandidates.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
os << "a=" << mType;
|
||||
for (auto i = mCandidates.begin(); i != mCandidates.end(); i++) {
|
||||
os << (i == mCandidates.begin() ? ":" : " ") << i->id << " " << i->address
|
||||
<< " " << i->port;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpRtcpAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mPort;
|
||||
if (mNetType != sdp::kNetTypeNone && mAddrType != sdp::kAddrTypeNone) {
|
||||
os << " " << mNetType << " " << mAddrType << " " << mAddress;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
|
||||
const char* SdpRtcpFbAttributeList::pli = "pli";
|
||||
const char* SdpRtcpFbAttributeList::sli = "sli";
|
||||
const char* SdpRtcpFbAttributeList::rpsi = "rpsi";
|
||||
const char* SdpRtcpFbAttributeList::app = "app";
|
||||
|
||||
const char* SdpRtcpFbAttributeList::fir = "fir";
|
||||
const char* SdpRtcpFbAttributeList::tmmbr = "tmmbr";
|
||||
const char* SdpRtcpFbAttributeList::tstr = "tstr";
|
||||
const char* SdpRtcpFbAttributeList::vbcm = "vbcm";
|
||||
|
||||
void
|
||||
SdpRtcpFbAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mFeedbacks.begin(); i != mFeedbacks.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->pt << " " << i->type;
|
||||
if (i->parameter.length()) {
|
||||
os << " " << i->parameter;
|
||||
if (i->extra.length()) {
|
||||
os << " " << i->extra;
|
||||
}
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldSerializeChannels(SdpRtpmapAttributeList::CodecType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SdpRtpmapAttributeList::kOpus:
|
||||
case SdpRtpmapAttributeList::kG722:
|
||||
return true;
|
||||
case SdpRtpmapAttributeList::kPCMU:
|
||||
case SdpRtpmapAttributeList::kPCMA:
|
||||
case SdpRtpmapAttributeList::kVP8:
|
||||
case SdpRtpmapAttributeList::kVP9:
|
||||
case SdpRtpmapAttributeList::kiLBC:
|
||||
case SdpRtpmapAttributeList::kiSAC:
|
||||
case SdpRtpmapAttributeList::kH264:
|
||||
return false;
|
||||
case SdpRtpmapAttributeList::kOtherCodec:
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
void
|
||||
SdpRtpmapAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mRtpmaps.begin(); i != mRtpmaps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->pt << " " << i->name << "/" << i->clock;
|
||||
if (i->channels && ShouldSerializeChannels(i->codec)) {
|
||||
os << "/" << i->channels;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpSctpmapAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mSctpmaps.begin(); i != mSctpmaps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->pt << " " << i->name;
|
||||
if (i->streams) {
|
||||
os << " " << i->streams;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpSetupAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mRole << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpSsrcAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mSsrcs.begin(); i != mSsrcs.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->ssrc << " " << i->attribute << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpSsrcGroupAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mSsrcGroups.begin(); i != mSsrcGroups.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->semantics;
|
||||
for (auto j = i->ssrcs.begin(); j != i->ssrcs.end(); ++j) {
|
||||
os << " " << (*j);
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpMultiStringAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mValues.begin(); i != mValues.end(); ++i) {
|
||||
os << "a=" << mType << ":" << *i << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpOptionsAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
if (mValues.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
os << "a=" << mType << ":";
|
||||
|
||||
for (auto i = mValues.begin(); i != mValues.end(); ++i) {
|
||||
if (i != mValues.begin()) {
|
||||
os << " ";
|
||||
}
|
||||
os << *i;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpOptionsAttribute::Load(const std::string& value)
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t end = value.find(' ');
|
||||
while (end != std::string::npos) {
|
||||
PushEntry(value.substr(start, end));
|
||||
start = end + 1;
|
||||
end = value.find(' ', start);
|
||||
}
|
||||
PushEntry(value.substr(start));
|
||||
}
|
||||
|
||||
void
|
||||
SdpFlagAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpStringAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mValue << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpNumberAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mValue << CRLF;
|
||||
}
|
||||
|
||||
bool
|
||||
SdpAttribute::IsAllowedAtMediaLevel(AttributeType type)
|
||||
{
|
||||
switch (type) {
|
||||
case kBundleOnlyAttribute:
|
||||
return true;
|
||||
case kCandidateAttribute:
|
||||
return true;
|
||||
case kConnectionAttribute:
|
||||
return true;
|
||||
case kDirectionAttribute:
|
||||
return true;
|
||||
case kEndOfCandidatesAttribute:
|
||||
return true;
|
||||
case kExtmapAttribute:
|
||||
return true;
|
||||
case kFingerprintAttribute:
|
||||
return true;
|
||||
case kFmtpAttribute:
|
||||
return true;
|
||||
case kGroupAttribute:
|
||||
return false;
|
||||
case kIceLiteAttribute:
|
||||
return false;
|
||||
case kIceMismatchAttribute:
|
||||
return true;
|
||||
// RFC 5245 says this is session-level only, but
|
||||
// draft-ietf-mmusic-ice-sip-sdp-03 updates this to allow at the media
|
||||
// level.
|
||||
case kIceOptionsAttribute:
|
||||
return true;
|
||||
case kIcePwdAttribute:
|
||||
return true;
|
||||
case kIceUfragAttribute:
|
||||
return true;
|
||||
case kIdentityAttribute:
|
||||
return false;
|
||||
case kImageattrAttribute:
|
||||
return true;
|
||||
case kInactiveAttribute:
|
||||
return true;
|
||||
case kLabelAttribute:
|
||||
return true;
|
||||
case kMaxptimeAttribute:
|
||||
return true;
|
||||
case kMidAttribute:
|
||||
return true;
|
||||
case kMsidAttribute:
|
||||
return true;
|
||||
case kMsidSemanticAttribute:
|
||||
return false;
|
||||
case kPtimeAttribute:
|
||||
return true;
|
||||
case kRecvonlyAttribute:
|
||||
return true;
|
||||
case kRemoteCandidatesAttribute:
|
||||
return true;
|
||||
case kRtcpAttribute:
|
||||
return true;
|
||||
case kRtcpFbAttribute:
|
||||
return true;
|
||||
case kRtcpMuxAttribute:
|
||||
return true;
|
||||
case kRtcpRsizeAttribute:
|
||||
return true;
|
||||
case kRtpmapAttribute:
|
||||
return true;
|
||||
case kSctpmapAttribute:
|
||||
return true;
|
||||
case kSendonlyAttribute:
|
||||
return true;
|
||||
case kSendrecvAttribute:
|
||||
return true;
|
||||
case kSetupAttribute:
|
||||
return true;
|
||||
case kSsrcAttribute:
|
||||
return true;
|
||||
case kSsrcGroupAttribute:
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH("Unknown attribute type");
|
||||
}
|
||||
|
||||
bool
|
||||
SdpAttribute::IsAllowedAtSessionLevel(AttributeType type)
|
||||
{
|
||||
switch (type) {
|
||||
case kBundleOnlyAttribute:
|
||||
return false;
|
||||
case kCandidateAttribute:
|
||||
return false;
|
||||
case kConnectionAttribute:
|
||||
return true;
|
||||
case kDirectionAttribute:
|
||||
return true;
|
||||
case kEndOfCandidatesAttribute:
|
||||
return true;
|
||||
case kExtmapAttribute:
|
||||
return true;
|
||||
case kFingerprintAttribute:
|
||||
return true;
|
||||
case kFmtpAttribute:
|
||||
return false;
|
||||
case kGroupAttribute:
|
||||
return true;
|
||||
case kIceLiteAttribute:
|
||||
return true;
|
||||
case kIceMismatchAttribute:
|
||||
return false;
|
||||
case kIceOptionsAttribute:
|
||||
return true;
|
||||
case kIcePwdAttribute:
|
||||
return true;
|
||||
case kIceUfragAttribute:
|
||||
return true;
|
||||
case kIdentityAttribute:
|
||||
return true;
|
||||
case kImageattrAttribute:
|
||||
return false;
|
||||
case kInactiveAttribute:
|
||||
return true;
|
||||
case kLabelAttribute:
|
||||
return false;
|
||||
case kMaxptimeAttribute:
|
||||
return false;
|
||||
case kMidAttribute:
|
||||
return false;
|
||||
case kMsidSemanticAttribute:
|
||||
return true;
|
||||
case kMsidAttribute:
|
||||
return false;
|
||||
case kPtimeAttribute:
|
||||
return false;
|
||||
case kRecvonlyAttribute:
|
||||
return true;
|
||||
case kRemoteCandidatesAttribute:
|
||||
return false;
|
||||
case kRtcpAttribute:
|
||||
return false;
|
||||
case kRtcpFbAttribute:
|
||||
return false;
|
||||
case kRtcpMuxAttribute:
|
||||
return false;
|
||||
case kRtcpRsizeAttribute:
|
||||
return false;
|
||||
case kRtpmapAttribute:
|
||||
return false;
|
||||
case kSctpmapAttribute:
|
||||
return false;
|
||||
case kSendonlyAttribute:
|
||||
return true;
|
||||
case kSendrecvAttribute:
|
||||
return true;
|
||||
case kSetupAttribute:
|
||||
return true;
|
||||
case kSsrcAttribute:
|
||||
return false;
|
||||
case kSsrcGroupAttribute:
|
||||
return false;
|
||||
}
|
||||
MOZ_CRASH("Unknown attribute type");
|
||||
}
|
||||
|
||||
const std::string
|
||||
SdpAttribute::GetAttributeTypeString(AttributeType type)
|
||||
{
|
||||
switch (type) {
|
||||
case kBundleOnlyAttribute:
|
||||
return "bundle-only";
|
||||
case kCandidateAttribute:
|
||||
return "candidate";
|
||||
case kConnectionAttribute:
|
||||
return "connection";
|
||||
case kEndOfCandidatesAttribute:
|
||||
return "end-of-candidates";
|
||||
case kExtmapAttribute:
|
||||
return "extmap";
|
||||
case kFingerprintAttribute:
|
||||
return "fingerprint";
|
||||
case kFmtpAttribute:
|
||||
return "fmtp";
|
||||
case kGroupAttribute:
|
||||
return "group";
|
||||
case kIceLiteAttribute:
|
||||
return "ice-lite";
|
||||
case kIceMismatchAttribute:
|
||||
return "ice-mismatch";
|
||||
case kIceOptionsAttribute:
|
||||
return "ice-options";
|
||||
case kIcePwdAttribute:
|
||||
return "ice-pwd";
|
||||
case kIceUfragAttribute:
|
||||
return "ice-ufrag";
|
||||
case kIdentityAttribute:
|
||||
return "identity";
|
||||
case kImageattrAttribute:
|
||||
return "imageattr";
|
||||
case kInactiveAttribute:
|
||||
return "inactive";
|
||||
case kLabelAttribute:
|
||||
return "label";
|
||||
case kMaxptimeAttribute:
|
||||
return "maxptime";
|
||||
case kMidAttribute:
|
||||
return "mid";
|
||||
case kMsidAttribute:
|
||||
return "msid";
|
||||
case kMsidSemanticAttribute:
|
||||
return "msid-semantic";
|
||||
case kPtimeAttribute:
|
||||
return "ptime";
|
||||
case kRecvonlyAttribute:
|
||||
return "recvonly";
|
||||
case kRemoteCandidatesAttribute:
|
||||
return "remote-candidates";
|
||||
case kRtcpAttribute:
|
||||
return "rtcp";
|
||||
case kRtcpFbAttribute:
|
||||
return "rtcp-fb";
|
||||
case kRtcpMuxAttribute:
|
||||
return "rtcp-mux";
|
||||
case kRtcpRsizeAttribute:
|
||||
return "rtcp-rsize";
|
||||
case kRtpmapAttribute:
|
||||
return "rtpmap";
|
||||
case kSctpmapAttribute:
|
||||
return "sctpmap";
|
||||
case kSendonlyAttribute:
|
||||
return "sendonly";
|
||||
case kSendrecvAttribute:
|
||||
return "sendrecv";
|
||||
case kSetupAttribute:
|
||||
return "setup";
|
||||
case kSsrcAttribute:
|
||||
return "ssrc";
|
||||
case kSsrcGroupAttribute:
|
||||
return "ssrc-group";
|
||||
case kDirectionAttribute:
|
||||
MOZ_CRASH("kDirectionAttribute not valid here");
|
||||
}
|
||||
MOZ_CRASH("Unknown attribute type");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
1314
media/webrtc/signaling/src/sdp/SdpAttribute.h
Normal file
1314
media/webrtc/signaling/src/sdp/SdpAttribute.h
Normal file
File diff suppressed because it is too large
Load Diff
90
media/webrtc/signaling/src/sdp/SdpAttributeList.h
Normal file
90
media/webrtc/signaling/src/sdp/SdpAttributeList.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* -*- 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 _SDPATTRIBUTELIST_H_
|
||||
#define _SDPATTRIBUTELIST_H_
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "signaling/src/sdp/SdpAttribute.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SdpAttributeList
|
||||
{
|
||||
public:
|
||||
typedef SdpAttribute::AttributeType AttributeType;
|
||||
|
||||
// Avoid default params on virtual functions
|
||||
bool
|
||||
HasAttribute(AttributeType type) const
|
||||
{
|
||||
return HasAttribute(type, true);
|
||||
}
|
||||
|
||||
const SdpAttribute*
|
||||
GetAttribute(AttributeType type) const
|
||||
{
|
||||
return GetAttribute(type, true);
|
||||
}
|
||||
|
||||
virtual bool HasAttribute(AttributeType type, bool sessionFallback) const = 0;
|
||||
virtual const SdpAttribute* GetAttribute(AttributeType type,
|
||||
bool sessionFallback) const = 0;
|
||||
// The setter takes an attribute of any type, and takes ownership
|
||||
virtual void SetAttribute(SdpAttribute* attr) = 0;
|
||||
virtual void RemoveAttribute(AttributeType type) = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
virtual const SdpConnectionAttribute& GetConnection() const = 0;
|
||||
virtual const SdpOptionsAttribute& GetIceOptions() const = 0;
|
||||
virtual const SdpRtcpAttribute& GetRtcp() const = 0;
|
||||
virtual const SdpRemoteCandidatesAttribute& GetRemoteCandidates() const = 0;
|
||||
virtual const SdpSetupAttribute& GetSetup() const = 0;
|
||||
|
||||
// These attributes can appear multiple times, so the returned
|
||||
// classes actually represent a collection of values.
|
||||
virtual const std::vector<std::string>& GetCandidate() const = 0;
|
||||
virtual const SdpExtmapAttributeList& GetExtmap() const = 0;
|
||||
virtual const SdpFingerprintAttributeList& GetFingerprint() const = 0;
|
||||
virtual const SdpFmtpAttributeList& GetFmtp() const = 0;
|
||||
virtual const SdpGroupAttributeList& GetGroup() const = 0;
|
||||
virtual const SdpImageattrAttributeList& GetImageattr() const = 0;
|
||||
virtual const SdpMsidAttributeList& GetMsid() const = 0;
|
||||
virtual const SdpRtcpFbAttributeList& GetRtcpFb() const = 0;
|
||||
virtual const SdpRtpmapAttributeList& GetRtpmap() const = 0;
|
||||
virtual const SdpSctpmapAttributeList& GetSctpmap() const = 0;
|
||||
virtual const SdpSsrcAttributeList& GetSsrc() const = 0;
|
||||
virtual const SdpSsrcGroupAttributeList& GetSsrcGroup() const = 0;
|
||||
|
||||
// These attributes are effectively simple types, so we'll make life
|
||||
// easy by just returning their value.
|
||||
virtual const std::string& GetIcePwd() const = 0;
|
||||
virtual const std::string& GetIceUfrag() const = 0;
|
||||
virtual const std::string& GetIdentity() const = 0;
|
||||
virtual const std::string& GetLabel() const = 0;
|
||||
virtual unsigned int GetMaxptime() const = 0;
|
||||
virtual const std::string& GetMid() const = 0;
|
||||
virtual const std::string& GetMsidSemantic() const = 0;
|
||||
virtual unsigned int GetPtime() const = 0;
|
||||
|
||||
// This is "special", because it's multiple things
|
||||
virtual SdpDirectionAttribute::Direction GetDirection() const = 0;
|
||||
|
||||
virtual void Serialize(std::ostream&) const = 0;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const SdpAttributeList& al)
|
||||
{
|
||||
al.Serialize(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
53
media/webrtc/signaling/src/sdp/SdpEnum.h
Normal file
53
media/webrtc/signaling/src/sdp/SdpEnum.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- 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 _SDPENUM_H_
|
||||
#define _SDPENUM_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
namespace sdp
|
||||
{
|
||||
|
||||
enum NetType { kNetTypeNone, kInternet };
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, sdp::NetType t)
|
||||
{
|
||||
switch (t) {
|
||||
case sdp::kNetTypeNone:
|
||||
MOZ_ASSERT(false);
|
||||
return os << "NONE";
|
||||
case sdp::kInternet:
|
||||
return os << "IN";
|
||||
}
|
||||
MOZ_CRASH("Unknown NetType");
|
||||
}
|
||||
|
||||
enum AddrType { kAddrTypeNone, kIPv4, kIPv6 };
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, sdp::AddrType t)
|
||||
{
|
||||
switch (t) {
|
||||
case sdp::kAddrTypeNone:
|
||||
MOZ_ASSERT(false);
|
||||
return os << "NONE";
|
||||
case sdp::kIPv4:
|
||||
return os << "IP4";
|
||||
case sdp::kIPv6:
|
||||
return os << "IP6";
|
||||
}
|
||||
MOZ_CRASH("Unknown AddrType");
|
||||
}
|
||||
|
||||
} // namespace sdp
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
50
media/webrtc/signaling/src/sdp/SdpErrorHolder.h
Normal file
50
media/webrtc/signaling/src/sdp/SdpErrorHolder.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* -*- 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 _SDPERRORHOLDER_H_
|
||||
#define _SDPERRORHOLDER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SdpErrorHolder
|
||||
{
|
||||
public:
|
||||
SdpErrorHolder() {}
|
||||
virtual ~SdpErrorHolder() {}
|
||||
|
||||
void
|
||||
AddParseError(size_t line, const std::string& message)
|
||||
{
|
||||
mErrors.push_back(std::make_pair(line, message));
|
||||
}
|
||||
|
||||
void
|
||||
ClearParseErrors()
|
||||
{
|
||||
mErrors.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the list of parse errors.
|
||||
* This gets cleared out when you call Parse.
|
||||
*/
|
||||
const std::vector<std::pair<size_t, std::string> >&
|
||||
GetParseErrors() const
|
||||
{
|
||||
return mErrors;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<size_t, std::string> > mErrors;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
284
media/webrtc/signaling/src/sdp/SdpMediaSection.h
Normal file
284
media/webrtc/signaling/src/sdp/SdpMediaSection.h
Normal file
@ -0,0 +1,284 @@
|
||||
/* -*- 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 "signaling/src/sdp/SdpEnum.h"
|
||||
#include "signaling/src/sdp/SdpAttributeList.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "signaling/src/sdp/SdpEnum.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SdpAttributeList;
|
||||
|
||||
class SdpConnection;
|
||||
|
||||
class SdpMediaSection
|
||||
{
|
||||
public:
|
||||
enum MediaType { kAudio, kVideo, kText, kApplication, kMessage };
|
||||
|
||||
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]
|
||||
kTcpTlsRtpSavp, // TCP/TLS/RTP/SAVP [JSEP-TBD]
|
||||
kDccpTlsRtpSavp, // DCCP/TLS/RTP/SAVP [RFC5764]
|
||||
kUdpTlsRtpSavpf, // UDP/TLS/RTP/SAVPF [RFC5764]
|
||||
kTcpTlsRtpSavpf, // TCP/TLS/RTP/SAVPF [JSEP-TBD]
|
||||
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]
|
||||
kSctpDtls, // SCTP/DTLS [draft-ietf-mmusic-sctp-sdp-07]
|
||||
kDtlsSctp // DTLS/SCTP [draft-ietf-mmusic-sctp-sdp-07]
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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 AddDataChannel(const std::string& pt, const std::string& name,
|
||||
uint16_t streams) = 0;
|
||||
|
||||
size_t
|
||||
GetLevel() const
|
||||
{
|
||||
return mLevel;
|
||||
}
|
||||
|
||||
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::kTcpTlsRtpSavp:
|
||||
return os << "TCP/TLS/RTP/SAVP";
|
||||
case SdpMediaSection::kDccpTlsRtpSavp:
|
||||
return os << "DCCP/TLS/RTP/SAVP";
|
||||
case SdpMediaSection::kUdpTlsRtpSavpf:
|
||||
return os << "UDP/TLS/RTP/SAVPF";
|
||||
case SdpMediaSection::kTcpTlsRtpSavpf:
|
||||
return os << "TCP/TLS/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::kSctpDtls:
|
||||
return os << "SCTP/DTLS";
|
||||
case SdpMediaSection::kDtlsSctp:
|
||||
return os << "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;
|
||||
}
|
||||
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
|
186
media/webrtc/signaling/src/sdp/SipccSdp.cpp
Normal file
186
media/webrtc/signaling/src/sdp/SipccSdp.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "signaling/src/sdp/SipccSdp.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "signaling/src/sdp/SdpErrorHolder.h"
|
||||
|
||||
#ifdef CRLF
|
||||
#undef CRLF
|
||||
#endif
|
||||
#define CRLF "\r\n"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
SipccSdp::~SipccSdp()
|
||||
{
|
||||
for (auto i = mMediaSections.begin(); i != mMediaSections.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
const SdpOrigin&
|
||||
SipccSdp::GetOrigin() const
|
||||
{
|
||||
return mOrigin;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SipccSdp::GetBandwidth(const std::string& type) const
|
||||
{
|
||||
auto found = mBandwidths.find(type);
|
||||
if (found == mBandwidths.end()) {
|
||||
return 0;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
const SdpMediaSection&
|
||||
SipccSdp::GetMediaSection(size_t level) const
|
||||
{
|
||||
if (level > mMediaSections.size()) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
return *mMediaSections[level];
|
||||
}
|
||||
|
||||
SdpMediaSection&
|
||||
SipccSdp::GetMediaSection(size_t level)
|
||||
{
|
||||
if (level > mMediaSections.size()) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
return *mMediaSections[level];
|
||||
}
|
||||
|
||||
SdpMediaSection&
|
||||
SipccSdp::AddMediaSection(SdpMediaSection::MediaType mediaType,
|
||||
SdpDirectionAttribute::Direction dir, uint16_t port,
|
||||
SdpMediaSection::Protocol protocol,
|
||||
sdp::AddrType addrType, const std::string& addr)
|
||||
{
|
||||
size_t level = mMediaSections.size();
|
||||
SipccSdpMediaSection* media =
|
||||
new SipccSdpMediaSection(level, &mAttributeList);
|
||||
media->mMediaType = mediaType;
|
||||
media->mPort = port;
|
||||
media->mPortCount = 0;
|
||||
media->mProtocol = protocol;
|
||||
media->mConnection = MakeUnique<SdpConnection>(addrType, addr);
|
||||
media->GetAttributeList().SetAttribute(new SdpDirectionAttribute(dir));
|
||||
mMediaSections.push_back(media);
|
||||
return *media;
|
||||
}
|
||||
|
||||
bool
|
||||
SipccSdp::LoadOrigin(sdp_t* sdp, SdpErrorHolder& errorHolder)
|
||||
{
|
||||
std::string username = sdp_get_owner_username(sdp);
|
||||
uint64_t sessId = strtoul(sdp_get_owner_sessionid(sdp), nullptr, 10);
|
||||
uint64_t sessVer = strtoul(sdp_get_owner_version(sdp), nullptr, 10);
|
||||
|
||||
sdp_nettype_e type = sdp_get_owner_network_type(sdp);
|
||||
if (type != SDP_NT_INTERNET) {
|
||||
errorHolder.AddParseError(2, "Unsupported network type");
|
||||
return false;
|
||||
}
|
||||
|
||||
sdp::AddrType addrType;
|
||||
switch (sdp_get_owner_address_type(sdp)) {
|
||||
case SDP_AT_IP4:
|
||||
addrType = sdp::kIPv4;
|
||||
break;
|
||||
case SDP_AT_IP6:
|
||||
addrType = sdp::kIPv6;
|
||||
break;
|
||||
default:
|
||||
errorHolder.AddParseError(2, "Unsupported address type");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string address = sdp_get_owner_address(sdp);
|
||||
mOrigin = SdpOrigin(username, sessId, sessVer, addrType, address);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SipccSdp::Load(sdp_t* sdp, SdpErrorHolder& errorHolder)
|
||||
{
|
||||
// Believe it or not, SDP_SESSION_LEVEL is 0xFFFF
|
||||
if (!mAttributeList.Load(sdp, SDP_SESSION_LEVEL, errorHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LoadOrigin(sdp, errorHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mBandwidths.Load(sdp, SDP_SESSION_LEVEL, errorHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sdp_get_num_media_lines(sdp); ++i) {
|
||||
// note that we pass a "level" here that is one higher
|
||||
// sipcc counts media sections from 1, using 0xFFFF as the "session"
|
||||
UniquePtr<SipccSdpMediaSection> section(
|
||||
new SipccSdpMediaSection(i, &mAttributeList));
|
||||
if (!section->Load(sdp, i + 1, errorHolder)) {
|
||||
return false;
|
||||
}
|
||||
mMediaSections.push_back(section.release());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SipccSdp::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "v=0" << CRLF << mOrigin << "s=-" << CRLF;
|
||||
|
||||
// We don't support creating i=, u=, e=, p=
|
||||
// We don't generate c= at the session level (only in media)
|
||||
|
||||
mBandwidths.Serialize(os);
|
||||
os << "t=0 0" << CRLF;
|
||||
|
||||
// We don't support r= or z=
|
||||
|
||||
// attributes
|
||||
os << mAttributeList;
|
||||
|
||||
// media sections
|
||||
for (auto i = mMediaSections.begin(); i != mMediaSections.end(); ++i) {
|
||||
os << (**i);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SipccSdpBandwidths::Load(sdp_t* sdp, uint16_t level,
|
||||
SdpErrorHolder& errorHolder)
|
||||
{
|
||||
size_t count = sdp_get_num_bw_lines(sdp, level);
|
||||
for (size_t i = 1; i <= count; ++i) {
|
||||
sdp_bw_modifier_e bwtype = sdp_get_bw_modifier(sdp, level, i);
|
||||
uint32_t bandwidth = sdp_get_bw_value(sdp, level, i);
|
||||
if (bwtype != SDP_BW_MODIFIER_UNSUPPORTED) {
|
||||
const char* typeName = sdp_get_bw_modifier_name(bwtype);
|
||||
(*this)[typeName] = bandwidth;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SipccSdpBandwidths::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = begin(); i != end(); ++i) {
|
||||
os << "b=" << i->first << ":" << i->second << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
88
media/webrtc/signaling/src/sdp/SipccSdp.h
Normal file
88
media/webrtc/signaling/src/sdp/SipccSdp.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* -*- 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 _SIPCCSDP_H_
|
||||
#define _SIPCCSDP_H_
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "signaling/src/sdp/Sdp.h"
|
||||
#include "signaling/src/sdp/SipccSdpMediaSection.h"
|
||||
#include "signaling/src/sdp/SipccSdpAttributeList.h"
|
||||
extern "C" {
|
||||
#include "signaling/src/sdp/sipcc/sdp.h"
|
||||
}
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SipccSdpParser;
|
||||
class SdpErrorHolder;
|
||||
|
||||
class SipccSdp MOZ_FINAL : public Sdp
|
||||
{
|
||||
friend class SipccSdpParser;
|
||||
|
||||
public:
|
||||
explicit SipccSdp(const SdpOrigin& origin)
|
||||
: mOrigin(origin), mAttributeList(nullptr)
|
||||
{
|
||||
}
|
||||
~SipccSdp();
|
||||
|
||||
virtual const SdpOrigin& GetOrigin() const MOZ_OVERRIDE;
|
||||
|
||||
// Note: connection information is always retrieved from media sections
|
||||
virtual uint32_t GetBandwidth(const std::string& type) const MOZ_OVERRIDE;
|
||||
|
||||
virtual size_t
|
||||
GetMediaSectionCount() const MOZ_OVERRIDE
|
||||
{
|
||||
return mMediaSections.size();
|
||||
}
|
||||
|
||||
virtual const SdpAttributeList&
|
||||
GetAttributeList() const MOZ_OVERRIDE
|
||||
{
|
||||
return mAttributeList;
|
||||
}
|
||||
|
||||
virtual SdpAttributeList&
|
||||
GetAttributeList() MOZ_OVERRIDE
|
||||
{
|
||||
return mAttributeList;
|
||||
}
|
||||
|
||||
virtual const SdpMediaSection& GetMediaSection(size_t level) const
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
virtual SdpMediaSection& GetMediaSection(size_t level) MOZ_OVERRIDE;
|
||||
|
||||
virtual SdpMediaSection& AddMediaSection(
|
||||
SdpMediaSection::MediaType media, SdpDirectionAttribute::Direction dir,
|
||||
uint16_t port, SdpMediaSection::Protocol proto, sdp::AddrType addrType,
|
||||
const std::string& addr) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Serialize(std::ostream&) const MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
SipccSdp() : mOrigin("", 0, 0, sdp::kIPv4, ""), mAttributeList(nullptr) {}
|
||||
|
||||
bool Load(sdp_t* sdp, SdpErrorHolder& errorHolder);
|
||||
bool LoadOrigin(sdp_t* sdp, SdpErrorHolder& errorHolder);
|
||||
|
||||
SdpOrigin mOrigin;
|
||||
SipccSdpBandwidths mBandwidths;
|
||||
SipccSdpAttributeList mAttributeList;
|
||||
std::vector<SipccSdpMediaSection*> mMediaSections;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _sdp_h_
|
1116
media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp
Normal file
1116
media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp
Normal file
File diff suppressed because it is too large
Load Diff
133
media/webrtc/signaling/src/sdp/SipccSdpAttributeList.h
Normal file
133
media/webrtc/signaling/src/sdp/SipccSdpAttributeList.h
Normal file
@ -0,0 +1,133 @@
|
||||
/* -*- 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 _SIPCCSDPATTRIBUTELIST_H_
|
||||
#define _SIPCCSDPATTRIBUTELIST_H_
|
||||
|
||||
#include "signaling/src/sdp/SdpAttributeList.h"
|
||||
|
||||
extern "C" {
|
||||
#include "signaling/src/sdp/sipcc/sdp.h"
|
||||
}
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SipccSdp;
|
||||
class SipccSdpMediaSection;
|
||||
class SdpErrorHolder;
|
||||
|
||||
class SipccSdpAttributeList : public SdpAttributeList
|
||||
{
|
||||
friend class SipccSdpMediaSection;
|
||||
friend class SipccSdp;
|
||||
|
||||
public:
|
||||
// Make sure we don't hide the default arg thunks
|
||||
using SdpAttributeList::HasAttribute;
|
||||
using SdpAttributeList::GetAttribute;
|
||||
|
||||
virtual bool HasAttribute(AttributeType type,
|
||||
bool sessionFallback) const MOZ_OVERRIDE;
|
||||
virtual const SdpAttribute* GetAttribute(
|
||||
AttributeType type, bool sessionFallback) const MOZ_OVERRIDE;
|
||||
virtual void SetAttribute(SdpAttribute* attr) MOZ_OVERRIDE;
|
||||
virtual void RemoveAttribute(AttributeType type) MOZ_OVERRIDE;
|
||||
virtual void Clear() MOZ_OVERRIDE;
|
||||
|
||||
virtual const SdpConnectionAttribute& GetConnection() const MOZ_OVERRIDE;
|
||||
virtual const SdpFingerprintAttributeList& GetFingerprint() const
|
||||
MOZ_OVERRIDE;
|
||||
virtual const SdpGroupAttributeList& GetGroup() const MOZ_OVERRIDE;
|
||||
virtual const SdpOptionsAttribute& GetIceOptions() const MOZ_OVERRIDE;
|
||||
virtual const SdpRtcpAttribute& GetRtcp() const MOZ_OVERRIDE;
|
||||
virtual const SdpRemoteCandidatesAttribute& GetRemoteCandidates() const
|
||||
MOZ_OVERRIDE;
|
||||
virtual const SdpSetupAttribute& GetSetup() const MOZ_OVERRIDE;
|
||||
virtual const SdpSsrcAttributeList& GetSsrc() const MOZ_OVERRIDE;
|
||||
virtual const SdpSsrcGroupAttributeList& GetSsrcGroup() const MOZ_OVERRIDE;
|
||||
|
||||
// These attributes can appear multiple times, so the returned
|
||||
// classes actually represent a collection of values.
|
||||
virtual const std::vector<std::string>& GetCandidate() const MOZ_OVERRIDE;
|
||||
virtual const SdpExtmapAttributeList& GetExtmap() const MOZ_OVERRIDE;
|
||||
virtual const SdpFmtpAttributeList& GetFmtp() const MOZ_OVERRIDE;
|
||||
virtual const SdpImageattrAttributeList& GetImageattr() const MOZ_OVERRIDE;
|
||||
virtual const SdpMsidAttributeList& GetMsid() const MOZ_OVERRIDE;
|
||||
virtual const SdpRtcpFbAttributeList& GetRtcpFb() const MOZ_OVERRIDE;
|
||||
virtual const SdpRtpmapAttributeList& GetRtpmap() const MOZ_OVERRIDE;
|
||||
virtual const SdpSctpmapAttributeList& GetSctpmap() const MOZ_OVERRIDE;
|
||||
|
||||
// These attributes are effectively simple types, so we'll make life
|
||||
// easy by just returning their value.
|
||||
virtual const std::string& GetIcePwd() const MOZ_OVERRIDE;
|
||||
virtual const std::string& GetIceUfrag() const MOZ_OVERRIDE;
|
||||
virtual const std::string& GetIdentity() const MOZ_OVERRIDE;
|
||||
virtual const std::string& GetLabel() const MOZ_OVERRIDE;
|
||||
virtual unsigned int GetMaxptime() const MOZ_OVERRIDE;
|
||||
virtual const std::string& GetMid() const MOZ_OVERRIDE;
|
||||
virtual const std::string& GetMsidSemantic() const MOZ_OVERRIDE;
|
||||
virtual unsigned int GetPtime() const MOZ_OVERRIDE;
|
||||
|
||||
virtual SdpDirectionAttribute::Direction GetDirection() const MOZ_OVERRIDE;
|
||||
|
||||
virtual void Serialize(std::ostream&) const MOZ_OVERRIDE;
|
||||
|
||||
virtual ~SipccSdpAttributeList();
|
||||
|
||||
private:
|
||||
static const std::string kEmptyString;
|
||||
static const size_t kNumAttributeTypes = SdpAttribute::kLastAttribute + 1;
|
||||
|
||||
// Pass a session-level attribute list if constructing a media-level one,
|
||||
// otherwise pass nullptr
|
||||
explicit SipccSdpAttributeList(const SipccSdpAttributeList* sessionLevel);
|
||||
|
||||
bool Load(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void LoadSimpleStrings(sdp_t* sdp, uint16_t level,
|
||||
SdpErrorHolder& errorHolder);
|
||||
void LoadSimpleString(sdp_t* sdp, uint16_t level, sdp_attr_e attr,
|
||||
AttributeType targetType, SdpErrorHolder& errorHolder);
|
||||
void LoadSimpleNumbers(sdp_t* sdp, uint16_t level,
|
||||
SdpErrorHolder& errorHolder);
|
||||
void LoadSimpleNumber(sdp_t* sdp, uint16_t level, sdp_attr_e attr,
|
||||
AttributeType targetType, SdpErrorHolder& errorHolder);
|
||||
void LoadFlags(sdp_t* sdp, uint16_t level);
|
||||
void LoadDirection(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
bool LoadRtpmap(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
bool LoadSctpmap(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void LoadIceAttributes(sdp_t* sdp, uint16_t level);
|
||||
bool LoadFingerprint(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void LoadCandidate(sdp_t* sdp, uint16_t level);
|
||||
void LoadSetup(sdp_t* sdp, uint16_t level);
|
||||
bool LoadGroups(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void LoadFmtp(sdp_t* sdp, uint16_t level);
|
||||
void LoadMsids(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void LoadExtmap(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void LoadRtcpFb(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
static SdpRtpmapAttributeList::CodecType GetCodecType(rtp_ptype type);
|
||||
|
||||
bool
|
||||
AtSessionLevel() const
|
||||
{
|
||||
return !mSessionLevel;
|
||||
}
|
||||
bool IsAllowedHere(SdpAttribute::AttributeType type) const;
|
||||
void WarnAboutMisplacedAttribute(SdpAttribute::AttributeType type,
|
||||
uint32_t lineNumber,
|
||||
SdpErrorHolder& errorHolder);
|
||||
|
||||
const SipccSdpAttributeList* mSessionLevel;
|
||||
|
||||
SdpAttribute* mAttributes[kNumAttributeTypes];
|
||||
|
||||
SipccSdpAttributeList(const SipccSdpAttributeList& orig) MOZ_DELETE;
|
||||
SipccSdpAttributeList& operator=(const SipccSdpAttributeList& rhs) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
332
media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp
Normal file
332
media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "signaling/src/sdp/SipccSdpMediaSection.h"
|
||||
|
||||
#include <ostream>
|
||||
#include "signaling/src/sdp/SdpErrorHolder.h"
|
||||
|
||||
#ifdef CRLF
|
||||
#undef CRLF
|
||||
#endif
|
||||
#define CRLF "\r\n"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
unsigned int
|
||||
SipccSdpMediaSection::GetPort() const
|
||||
{
|
||||
return mPort;
|
||||
}
|
||||
|
||||
void
|
||||
SipccSdpMediaSection::SetPort(unsigned int port)
|
||||
{
|
||||
mPort = port;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
SipccSdpMediaSection::GetPortCount() const
|
||||
{
|
||||
return mPortCount;
|
||||
}
|
||||
|
||||
SdpMediaSection::Protocol
|
||||
SipccSdpMediaSection::GetProtocol() const
|
||||
{
|
||||
return mProtocol;
|
||||
}
|
||||
|
||||
const SdpConnection&
|
||||
SipccSdpMediaSection::GetConnection() const
|
||||
{
|
||||
return *mConnection;
|
||||
}
|
||||
|
||||
SdpConnection&
|
||||
SipccSdpMediaSection::GetConnection()
|
||||
{
|
||||
return *mConnection;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SipccSdpMediaSection::GetBandwidth(const std::string& type) const
|
||||
{
|
||||
auto found = mBandwidths.find(type);
|
||||
if (found == mBandwidths.end()) {
|
||||
return 0;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
const std::vector<std::string>&
|
||||
SipccSdpMediaSection::GetFormats() const
|
||||
{
|
||||
return mFormats;
|
||||
}
|
||||
|
||||
const SdpAttributeList&
|
||||
SipccSdpMediaSection::GetAttributeList() const
|
||||
{
|
||||
return mAttributeList;
|
||||
}
|
||||
|
||||
SdpAttributeList&
|
||||
SipccSdpMediaSection::GetAttributeList()
|
||||
{
|
||||
return mAttributeList;
|
||||
}
|
||||
|
||||
SdpDirectionAttribute
|
||||
SipccSdpMediaSection::GetDirectionAttribute() const
|
||||
{
|
||||
return SdpDirectionAttribute(mAttributeList.GetDirection());
|
||||
}
|
||||
|
||||
bool
|
||||
SipccSdpMediaSection::Load(sdp_t* sdp, uint16_t level,
|
||||
SdpErrorHolder& errorHolder)
|
||||
{
|
||||
switch (sdp_get_media_type(sdp, level)) {
|
||||
case SDP_MEDIA_AUDIO:
|
||||
mMediaType = kAudio;
|
||||
break;
|
||||
case SDP_MEDIA_VIDEO:
|
||||
mMediaType = kVideo;
|
||||
break;
|
||||
case SDP_MEDIA_APPLICATION:
|
||||
mMediaType = kApplication;
|
||||
break;
|
||||
case SDP_MEDIA_TEXT:
|
||||
mMediaType = kText;
|
||||
break;
|
||||
|
||||
default:
|
||||
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
|
||||
"Unsupported media section type");
|
||||
return false;
|
||||
}
|
||||
|
||||
mPort = sdp_get_media_portnum(sdp, level);
|
||||
int32_t pc = sdp_get_media_portcount(sdp, level);
|
||||
if (pc == SDP_INVALID_VALUE) {
|
||||
// SDP_INVALID_VALUE (ie; -2) is used when there is no port count. :(
|
||||
mPortCount = 0;
|
||||
} else if (pc > static_cast<int32_t>(UINT16_MAX) || pc < 0) {
|
||||
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
|
||||
"Invalid port count");
|
||||
return false;
|
||||
} else {
|
||||
mPortCount = pc;
|
||||
}
|
||||
|
||||
if (!LoadProtocol(sdp, level, errorHolder)) {
|
||||
return false;
|
||||
}
|
||||
LoadFormats(sdp, level);
|
||||
|
||||
if (!mAttributeList.Load(sdp, level, errorHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mBandwidths.Load(sdp, level, errorHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return LoadConnection(sdp, level, errorHolder);
|
||||
}
|
||||
|
||||
bool
|
||||
SipccSdpMediaSection::LoadProtocol(sdp_t* sdp, uint16_t level,
|
||||
SdpErrorHolder& errorHolder)
|
||||
{
|
||||
switch (sdp_get_media_transport(sdp, level)) {
|
||||
case SDP_TRANSPORT_RTPAVP:
|
||||
mProtocol = kRtpAvp;
|
||||
break;
|
||||
case SDP_TRANSPORT_RTPSAVP:
|
||||
mProtocol = kRtpSavp;
|
||||
break;
|
||||
case SDP_TRANSPORT_RTPAVPF:
|
||||
mProtocol = kRtpAvpf;
|
||||
break;
|
||||
case SDP_TRANSPORT_RTPSAVPF:
|
||||
mProtocol = kRtpSavpf;
|
||||
break;
|
||||
case SDP_TRANSPORT_UDPTLSRTPSAVP:
|
||||
mProtocol = kUdpTlsRtpSavp;
|
||||
break;
|
||||
case SDP_TRANSPORT_UDPTLSRTPSAVPF:
|
||||
mProtocol = kUdpTlsRtpSavpf;
|
||||
break;
|
||||
case SDP_TRANSPORT_TCPTLSRTPSAVP:
|
||||
mProtocol = kTcpTlsRtpSavp;
|
||||
break;
|
||||
case SDP_TRANSPORT_TCPTLSRTPSAVPF:
|
||||
mProtocol = kTcpTlsRtpSavpf;
|
||||
break;
|
||||
case SDP_TRANSPORT_DTLSSCTP:
|
||||
mProtocol = kDtlsSctp;
|
||||
break;
|
||||
|
||||
default:
|
||||
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
|
||||
"Unsupported media transport type");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SipccSdpMediaSection::LoadFormats(sdp_t* sdp, uint16_t level)
|
||||
{
|
||||
sdp_media_e mtype = sdp_get_media_type(sdp, level);
|
||||
|
||||
if (mtype == SDP_MEDIA_APPLICATION) {
|
||||
uint32_t ptype = sdp_get_media_sctp_port(sdp, level);
|
||||
std::ostringstream osPayloadType;
|
||||
osPayloadType << ptype;
|
||||
mFormats.push_back(osPayloadType.str());
|
||||
} else if (mtype == SDP_MEDIA_AUDIO || mtype == SDP_MEDIA_VIDEO) {
|
||||
uint16_t count = sdp_get_media_num_payload_types(sdp, level);
|
||||
for (uint16_t i = 0; i < count; ++i) {
|
||||
sdp_payload_ind_e indicator; // we ignore this, which is fine
|
||||
uint32_t ptype =
|
||||
sdp_get_media_payload_type(sdp, level, i + 1, &indicator);
|
||||
|
||||
std::ostringstream osPayloadType;
|
||||
// sipcc stores payload types in a funny way. When sipcc and the SDP it
|
||||
// parsed differ on what payload type number should be used for a given
|
||||
// codec, sipcc's value goes in the lower byte, and the SDP's value in
|
||||
// the upper byte. When they do not differ, only the lower byte is used.
|
||||
// We want what was in the SDP, verbatim.
|
||||
osPayloadType << GET_DYN_PAYLOAD_TYPE_VALUE(ptype);
|
||||
mFormats.push_back(osPayloadType.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SipccSdpMediaSection::LoadConnection(sdp_t* sdp, uint16_t level,
|
||||
SdpErrorHolder& errorHolder)
|
||||
{
|
||||
if (!sdp_connection_valid(sdp, level)) {
|
||||
level = SDP_SESSION_LEVEL;
|
||||
if (!sdp_connection_valid(sdp, level)) {
|
||||
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
|
||||
"Missing c= line");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sdp_nettype_e type = sdp_get_conn_nettype(sdp, level);
|
||||
if (type != SDP_NT_INTERNET) {
|
||||
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
|
||||
"Unsupported network type");
|
||||
return false;
|
||||
}
|
||||
|
||||
sdp::AddrType addrType;
|
||||
switch (sdp_get_conn_addrtype(sdp, level)) {
|
||||
case SDP_AT_IP4:
|
||||
addrType = sdp::kIPv4;
|
||||
break;
|
||||
case SDP_AT_IP6:
|
||||
addrType = sdp::kIPv6;
|
||||
break;
|
||||
default:
|
||||
errorHolder.AddParseError(sdp_get_media_line_number(sdp, level),
|
||||
"Unsupported address type");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string address = sdp_get_conn_address(sdp, level);
|
||||
int16_t ttl = static_cast<uint16_t>(sdp_get_mcast_ttl(sdp, level));
|
||||
if (ttl < 0) {
|
||||
ttl = 0;
|
||||
}
|
||||
int32_t numAddr =
|
||||
static_cast<uint32_t>(sdp_get_mcast_num_of_addresses(sdp, level));
|
||||
if (numAddr < 0) {
|
||||
numAddr = 0;
|
||||
}
|
||||
mConnection = MakeUnique<SdpConnection>(addrType, address, ttl, numAddr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SipccSdpMediaSection::AddCodec(const std::string& pt, const std::string& name,
|
||||
uint32_t clockrate, uint16_t channels)
|
||||
{
|
||||
mFormats.push_back(pt);
|
||||
|
||||
SdpRtpmapAttributeList* rtpmap = new SdpRtpmapAttributeList();
|
||||
if (mAttributeList.HasAttribute(SdpAttribute::kRtpmapAttribute)) {
|
||||
const SdpRtpmapAttributeList& old = mAttributeList.GetRtpmap();
|
||||
for (auto it = old.mRtpmaps.begin(); it != old.mRtpmaps.end(); ++it) {
|
||||
rtpmap->mRtpmaps.push_back(*it);
|
||||
}
|
||||
}
|
||||
SdpRtpmapAttributeList::CodecType codec = SdpRtpmapAttributeList::kOtherCodec;
|
||||
if (name == "opus") {
|
||||
codec = SdpRtpmapAttributeList::kOpus;
|
||||
} else if (name == "G722") {
|
||||
codec = SdpRtpmapAttributeList::kG722;
|
||||
} else if (name == "PCMU") {
|
||||
codec = SdpRtpmapAttributeList::kPCMU;
|
||||
} else if (name == "PCMA") {
|
||||
codec = SdpRtpmapAttributeList::kPCMA;
|
||||
} else if (name == "VP8") {
|
||||
codec = SdpRtpmapAttributeList::kVP8;
|
||||
} else if (name == "H264") {
|
||||
codec = SdpRtpmapAttributeList::kH264;
|
||||
}
|
||||
|
||||
rtpmap->PushEntry(pt, codec, name, clockrate, channels);
|
||||
mAttributeList.SetAttribute(rtpmap);
|
||||
}
|
||||
|
||||
void
|
||||
SipccSdpMediaSection::AddDataChannel(const std::string& pt,
|
||||
const std::string& name, uint16_t streams)
|
||||
{
|
||||
// Only one allowed, for now. This may change as the specs (and deployments)
|
||||
// evolve.
|
||||
mFormats.clear();
|
||||
mFormats.push_back(pt);
|
||||
SdpSctpmapAttributeList* sctpmap = new SdpSctpmapAttributeList();
|
||||
sctpmap->PushEntry(pt, name, streams);
|
||||
mAttributeList.SetAttribute(sctpmap);
|
||||
}
|
||||
|
||||
void
|
||||
SipccSdpMediaSection::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "m=" << mMediaType << " " << mPort;
|
||||
if (mPortCount) {
|
||||
os << "/" << mPortCount;
|
||||
}
|
||||
os << " " << mProtocol;
|
||||
for (auto i = mFormats.begin(); i != mFormats.end(); ++i) {
|
||||
os << " " << (*i);
|
||||
}
|
||||
os << CRLF;
|
||||
|
||||
// We dont do i=
|
||||
|
||||
if (mConnection) {
|
||||
os << *mConnection;
|
||||
}
|
||||
|
||||
mBandwidths.Serialize(os);
|
||||
|
||||
// We dont do k= because they're evil
|
||||
|
||||
os << mAttributeList;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
93
media/webrtc/signaling/src/sdp/SipccSdpMediaSection.h
Normal file
93
media/webrtc/signaling/src/sdp/SipccSdpMediaSection.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* -*- 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 _SIPCCSDPMEDIASECTION_H_
|
||||
#define _SIPCCSDPMEDIASECTION_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
#include "signaling/src/sdp/SipccSdpAttributeList.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
extern "C" {
|
||||
#include "signaling/src/sdp/sipcc/sdp.h"
|
||||
}
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SipccSdp;
|
||||
class SdpErrorHolder;
|
||||
|
||||
class SipccSdpBandwidths MOZ_FINAL : public std::map<std::string, uint32_t>
|
||||
{
|
||||
public:
|
||||
bool Load(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void Serialize(std::ostream& os) const;
|
||||
};
|
||||
|
||||
class SipccSdpMediaSection MOZ_FINAL : public SdpMediaSection
|
||||
{
|
||||
friend class SipccSdp;
|
||||
|
||||
public:
|
||||
~SipccSdpMediaSection() {}
|
||||
|
||||
virtual MediaType
|
||||
GetMediaType() const MOZ_OVERRIDE
|
||||
{
|
||||
return mMediaType;
|
||||
}
|
||||
|
||||
virtual unsigned int GetPort() const MOZ_OVERRIDE;
|
||||
virtual void SetPort(unsigned int port) MOZ_OVERRIDE;
|
||||
virtual unsigned int GetPortCount() const MOZ_OVERRIDE;
|
||||
virtual Protocol GetProtocol() const MOZ_OVERRIDE;
|
||||
virtual const SdpConnection& GetConnection() const MOZ_OVERRIDE;
|
||||
virtual SdpConnection& GetConnection() MOZ_OVERRIDE;
|
||||
virtual uint32_t GetBandwidth(const std::string& type) const MOZ_OVERRIDE;
|
||||
virtual const std::vector<std::string>& GetFormats() const MOZ_OVERRIDE;
|
||||
|
||||
virtual const SdpAttributeList& GetAttributeList() const MOZ_OVERRIDE;
|
||||
virtual SdpAttributeList& GetAttributeList() MOZ_OVERRIDE;
|
||||
virtual SdpDirectionAttribute GetDirectionAttribute() const MOZ_OVERRIDE;
|
||||
|
||||
virtual void AddCodec(const std::string& pt, const std::string& name,
|
||||
uint32_t clockrate, uint16_t channels) MOZ_OVERRIDE;
|
||||
|
||||
virtual void AddDataChannel(const std::string& pt, const std::string& name,
|
||||
uint16_t streams) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Serialize(std::ostream&) const MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
SipccSdpMediaSection(size_t level, const SipccSdpAttributeList* sessionLevel)
|
||||
: SdpMediaSection(level), mAttributeList(sessionLevel)
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
bool LoadConnection(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
bool LoadProtocol(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
|
||||
void LoadFormats(sdp_t* sdp, uint16_t level);
|
||||
|
||||
// the following values are cached on first get
|
||||
MediaType mMediaType;
|
||||
uint16_t mPort;
|
||||
uint16_t mPortCount;
|
||||
Protocol mProtocol;
|
||||
std::vector<std::string> mFormats;
|
||||
|
||||
UniquePtr<SdpConnection> mConnection;
|
||||
SipccSdpBandwidths mBandwidths;
|
||||
|
||||
SipccSdpAttributeList mAttributeList;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
83
media/webrtc/signaling/src/sdp/SipccSdpParser.cpp
Normal file
83
media/webrtc/signaling/src/sdp/SipccSdpParser.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "signaling/src/sdp/SipccSdpParser.h"
|
||||
#include "signaling/src/sdp/SipccSdp.h"
|
||||
|
||||
#include <utility>
|
||||
extern "C" {
|
||||
#include "signaling/src/sdp/sipcc/sdp.h"
|
||||
}
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
extern "C" {
|
||||
|
||||
void
|
||||
sipcc_sdp_parser_error_handler(void *context, uint32_t line,
|
||||
const char *message)
|
||||
{
|
||||
SdpErrorHolder *errorHolder = static_cast<SdpErrorHolder *>(context);
|
||||
std::string err(message);
|
||||
errorHolder->AddParseError(line, err);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
UniquePtr<Sdp>
|
||||
SipccSdpParser::Parse(const std::string &sdpText)
|
||||
{
|
||||
ClearParseErrors();
|
||||
|
||||
sdp_conf_options_t *sipcc_config = sdp_init_config();
|
||||
if (!sipcc_config) {
|
||||
return UniquePtr<Sdp>();
|
||||
}
|
||||
|
||||
sdp_nettype_supported(sipcc_config, SDP_NT_INTERNET, true);
|
||||
sdp_addrtype_supported(sipcc_config, SDP_AT_IP4, true);
|
||||
sdp_addrtype_supported(sipcc_config, SDP_AT_IP6, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPAVP, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPAVPF, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPSAVP, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_RTPSAVPF, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_UDPTLSRTPSAVP, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_UDPTLSRTPSAVPF, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_TCPTLSRTPSAVP, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_TCPTLSRTPSAVPF, true);
|
||||
sdp_transport_supported(sipcc_config, SDP_TRANSPORT_DTLSSCTP, true);
|
||||
sdp_require_session_name(sipcc_config, false);
|
||||
|
||||
sdp_config_set_error_handler(sipcc_config, &sipcc_sdp_parser_error_handler,
|
||||
this);
|
||||
|
||||
// Takes ownership of |sipcc_config| iff it succeeds
|
||||
sdp_t *sdp = sdp_init_description(sipcc_config);
|
||||
if (!sdp) {
|
||||
sdp_free_config(sipcc_config);
|
||||
return UniquePtr<Sdp>();
|
||||
}
|
||||
|
||||
const char *rawString = sdpText.c_str();
|
||||
sdp_result_e sdpres = sdp_parse(sdp, rawString, sdpText.length());
|
||||
if (sdpres != SDP_SUCCESS) {
|
||||
sdp_free_description(sdp);
|
||||
return UniquePtr<Sdp>();
|
||||
}
|
||||
|
||||
UniquePtr<SipccSdp> sipccSdp(new SipccSdp);
|
||||
|
||||
bool success = sipccSdp->Load(sdp, *this);
|
||||
sdp_free_description(sdp);
|
||||
if (!success) {
|
||||
return UniquePtr<Sdp>();
|
||||
}
|
||||
|
||||
return UniquePtr<Sdp>(Move(sipccSdp));
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
35
media/webrtc/signaling/src/sdp/SipccSdpParser.h
Normal file
35
media/webrtc/signaling/src/sdp/SipccSdpParser.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* -*- 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 _SIPCCSDPPARSER_H_
|
||||
#define _SIPCCSDPPARSER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "signaling/src/sdp/Sdp.h"
|
||||
#include "signaling/src/sdp/SdpErrorHolder.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SipccSdpParser MOZ_FINAL : public SdpErrorHolder
|
||||
{
|
||||
public:
|
||||
SipccSdpParser() {}
|
||||
virtual ~SipccSdpParser() {}
|
||||
|
||||
/**
|
||||
* This parses the provided text into an SDP object.
|
||||
* This returns a nullptr-valued pointer if things go poorly.
|
||||
*/
|
||||
UniquePtr<Sdp> Parse(const std::string& sdpText);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user