1#if defined(HAVE_CONFIG_H)
16#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SDP
26const std::map<Data, std::reference_wrapper<const SdpContents::Session::Direction>> SdpContents::Session::Direction::directions = {
77 : mAttributeList(rhs.mAttributeList),
78 mAttributes(rhs.mAttributes)
91 mAttributeList = rhs.mAttributeList;
92 mAttributes = rhs.mAttributes;
100 return mAttributes.find(key) != mAttributes.end();
108 static const list<Data> emptyList;
111 return mAttributes.find(key)->second;
117 for (std::list<std::pair<Data, Data> >::const_iterator i = mAttributeList.begin();
118 i != mAttributeList.end(); ++i)
120 s <<
"a=" << i->first;
121 if (!i->second.empty())
141 pb.
data(key, anchor);
146 pb.
data(value, anchor);
154 pb.
fail(__FILE__, __LINE__,
"Too many distinct SDP attribute names");
157 mAttributeList.push_back(std::make_pair(key, value));
158 mAttributes[key].push_back(value);
165 mAttributeList.push_back(std::make_pair(key, value));
166 mAttributes[key].push_back(value);
172 for (std::list<std::pair<Data, Data> >::iterator i = mAttributeList.begin();
173 i != mAttributeList.end(); )
175 std::list<std::pair<Data, Data> >::iterator j = i++;
178 mAttributeList.erase(j);
181 mAttributes.erase(key);
210 mSession = rhs.mSession;
237 static Mime type(
"application",
"sdp");
243SdpContents::Session::Origin::Origin()
251SdpContents::Session::Origin::Origin(
const Origin& rhs)
253 mSessionId(rhs.mSessionId),
254 mVersion(rhs.mVersion),
255 mAddrType(rhs.mAddrType),
256 mAddress(rhs.mAddress)
266 mSessionId = rhs.mSessionId;
267 mVersion = rhs.mVersion;
268 mAddrType = rhs.mAddrType;
269 mAddress = rhs.mAddress;
275SdpContents::Session::Origin::Origin(
const Data& user,
281 mSessionId(sessionId),
314 pb.
data(mUser, anchor);
323 WarningLog(<<
"Exception parsing origin sessionid: " << e);
334 WarningLog(<<
"Exception parsing origin version: " << e);
345 pb.
data(addrType, anchor);
356 mAddrType =
static_cast<AddrType>(0);
361 pb.
data(mAddress, anchor);
366SdpContents::Session::Email::Email(
const Data& address,
367 const Data& freeText)
372SdpContents::Session::Email::Email(
const Email& rhs)
373 : mAddress(rhs.mAddress),
374 mFreeText(rhs.mFreeText)
382 mAddress = rhs.mAddress;
383 mFreeText = rhs.mFreeText;
391 s <<
"e=" << mAddress;
392 if (!mFreeText.empty())
419 pb.
data(eOrp, anchor);
428 pb.
data(freeText, anchor);
431 pb.
data(eOrp, anchor);
439 pb.
data(eOrp, anchor);
442 pb.
data(freeText, anchor);
458SdpContents::Session::Phone::Phone(
const Data& number,
459 const Data& freeText)
464SdpContents::Session::Phone::Phone(
const Phone& rhs)
465 : mNumber(rhs.mNumber),
466 mFreeText(rhs.mFreeText)
474 mNumber = rhs.mNumber;
475 mFreeText = rhs.mFreeText;
483 s <<
"p=" << mNumber;
484 if (!mFreeText.empty())
502SdpContents::Session::Connection::Connection(
AddrType addType,
505 : mAddrType(addType),
510SdpContents::Session::Connection::Connection()
516SdpContents::Session::Connection::Connection(
const Connection& rhs)
517 : mAddrType(rhs.mAddrType),
518 mAddress(rhs.mAddress),
528 mAddrType = rhs.mAddrType;
529 mAddress = rhs.mAddress;
567 pb.
data(addrType, anchor);
578 mAddrType =
static_cast<AddrType>(0);
583 pb.
data(mAddress, anchor);
599SdpContents::Session::Bandwidth::Bandwidth(
const Data& modifier,
600 unsigned long kbPerSecond)
601 : mModifier(modifier),
602 mKbPerSecond(kbPerSecond)
605SdpContents::Session::Bandwidth::Bandwidth(
const Bandwidth& rhs)
606 : mModifier(rhs.mModifier),
607 mKbPerSecond(rhs.mKbPerSecond)
615 mModifier = rhs.mModifier;
616 mKbPerSecond = rhs.mKbPerSecond;
640 pb.
data(mModifier, anchor);
649 pb.
fail(__FILE__, __LINE__);
653SdpContents::Session::Time::Time(
unsigned long start,
659SdpContents::Session::Time::Time(
const Time& rhs)
660 : mStart(rhs.mStart),
671 mRepeats = rhs.mRepeats;
683 for (list<Repeat>::const_iterator i = mRepeats.begin();
684 i != mRepeats.end(); ++i)
706 mRepeats.back().parse(pb);
713 mRepeats.push_back(repeat);
716SdpContents::Session::Time::Repeat::Repeat(
unsigned long interval,
717 unsigned long duration,
719 : mInterval(interval),
730 for (list<int>::const_iterator i = mOffsets.begin();
731 i != mOffsets.end(); ++i)
815 : mAdjustments(rhs.mAdjustments)
823 mAdjustments = rhs.mAdjustments;
831 if (!mAdjustments.empty())
835 for (list<Adjustment>::const_iterator i = mAdjustments.begin();
836 i != mAdjustments.end(); ++i)
878 mAdjustments.push_back(adjust);
882 : mMethod(NoEncryption),
893 : mMethod(rhs.mMethod),
902 mMethod = rhs.mMethod;
908const char*
KeyTypes[] = {
"????",
"prompt",
"clear",
"base64",
"uri"};
915 if (mMethod != Prompt)
950 pb.
data(mKey, anchor);
987 mOrigin = rhs.mOrigin;
990 mInformation = rhs.mInformation;
992 mEmails = rhs.mEmails;
993 mPhones = rhs.mPhones;
994 mConnection = rhs.mConnection;
995 mBandwidths = rhs.mBandwidths;
997 mTimezones = rhs.mTimezones;
998 mEncryption = rhs.mEncryption;
999 mAttributeHelper = rhs.mAttributeHelper;
1001 for (MediumContainer::iterator i=mMedia.begin(); i != mMedia.end(); ++i)
1003 i->setSession(
this);
1022 pb.
data(mName, anchor);
1030 pb.
data(mInformation, anchor);
1045 mEmails.back().parse(pb);
1051 mPhones.back().parse(pb);
1056 mConnection.parse(pb);
1062 mBandwidths.back().parse(pb);
1068 mTimes.back().parse(pb);
1073 mTimezones.parse(pb);
1078 mEncryption.parse(pb);
1081 mAttributeHelper.parse(pb);
1086 mMedia.back().parse(pb);
1097 if (!mInformation.empty())
1102 if (!mUri.host().empty())
1109 for (list<Email>::const_iterator i = mEmails.begin();
1110 i != mEmails.end(); ++i)
1115 for (list<Phone>::const_iterator i = mPhones.begin();
1116 i != mPhones.end(); ++i)
1121 if (!mConnection.getAddress().empty())
1123 mConnection.encode(s);
1126 for (list<Bandwidth>::const_iterator i = mBandwidths.begin();
1127 i != mBandwidths.end(); ++i)
1138 for (list<Time>::const_iterator i = mTimes.begin();
1139 i != mTimes.end(); ++i)
1145 mTimezones.encode(s);
1147 if (mEncryption.getMethod() != Encryption::NoEncryption)
1149 mEncryption.encode(s);
1152 mAttributeHelper.encode(s);
1154 for (MediumContainer::const_iterator i = mMedia.begin();
1155 i != mMedia.end(); ++i)
1163std::list<std::reference_wrapper<SdpContents::Session::Medium>>
1166 std::list<std::reference_wrapper<SdpContents::Session::Medium>> r;
1168 if(m.name() == type)
1170 r.push_back(std::ref(m));
1179 mEmails.push_back(email);
1185 mTimes.push_back(t);
1191 mPhones.push_back(phone);
1197 mBandwidths.push_back(bandwidth);
1203 mMedia.push_back(medium);
1204 mMedia.back().setSession(
this);
1210 mAttributeHelper.addAttribute(key, value);
1214 for (MediumContainer::iterator i = mMedia.begin();
1215 i != mMedia.end(); ++i)
1217 i->mRtpMapDone =
false;
1225 mAttributeHelper.clearAttribute(key);
1229 for (MediumContainer::iterator i = mMedia.begin();
1230 i != mMedia.end(); ++i)
1232 i->mRtpMapDone =
false;
1240 return mAttributeHelper.exists(key);
1246 return mAttributeHelper.getValues(key);
1252 for(
const Direction& k : Direction::ordered())
1260 return Direction::SENDRECV;
1266 for(
const Direction& k : Direction::ordered())
1280 return Direction::SENDRECV;
1288 for(
const Direction& k : Direction::ordered())
1296 return sessionDefault;
1303 const Direction& sessionDefault = getDirection();
1305 for(
auto& m : mMedia)
1307 directions.push_back(m.getDirection(sessionDefault).cref);
1319 if(localDirections.size() != remoteDirections.size())
1321 WarningLog(<<
"SDP media count mismatch: local = " << localDirections.size()
1322 <<
" and remote = " << remoteDirections.size());
1326 auto iLocal = localDirections.cbegin();
1327 auto iRemote = remoteDirections.cbegin();
1328 while(iLocal != localDirections.cend() && iRemote != remoteDirections.cend())
1332 if(_iLocal == Direction::INACTIVE || _iRemote == Direction::INACTIVE)
1334 result.push_back(Direction::INACTIVE.cref);
1336 else if(_iLocal == Direction::SENDONLY)
1338 result.push_back(Direction::SENDONLY.cref);
1340 else if(_iLocal == Direction::RECVONLY || _iRemote == Direction::SENDONLY)
1342 result.push_back(Direction::RECVONLY.cref);
1344 else if(_iRemote == Direction::RECVONLY)
1346 result.push_back(Direction::SENDONLY.cref);
1350 result.push_back(Direction::SENDRECV.cref);
1362 const std::set<Data> protocolTypes)
const
1364 const Direction& sessionDefault = getDirection();
1366 std::set<Data> directions;
1367 for(
const auto& m : mMedia)
1370 (protocolTypes.empty() || protocolTypes.find(m.protocol())!=protocolTypes.end()) &&
1371 m.getConnections().size() > 0 &&
1374 directions.insert(m.getDirection(sessionDefault).name());
1379 for(
const Direction& k : Direction::ordered())
1381 if(directions.find(k.name()) != directions.end())
1386 return sessionDefault;
1392 std::set<Data> labels;
1393 for (std::list<resip::SdpContents::Session::Medium>::const_iterator it = mMedia.cbegin(); it != mMedia.cend(); it++)
1398 const std::list<Data>& _labels = m.
getValues(
"label");
1399 labels.insert(_labels.begin(), _labels.end());
1408 std::set<resip::Data> mediumTransports;
1409 for(SdpContents::Session::MediumContainer::const_iterator it = mMedia.cbegin();
1410 it != mMedia.cend();
1414 mediumTransports.insert(m.
protocol());
1416 return std::find(mediumTransports.cbegin(),
1417 mediumTransports.end(),
1418 "RTP/SAVPF") != mediumTransports.end();
1424 if(!
exists(
"ice-options"))
1428 auto opts = getValues(
"ice-options");
1429 for(
auto opt = opts.cbegin(); opt != opts.cend(); opt++)
1431 if(*opt ==
"trickle")
1442 for(SdpContents::Session::MediumContainer::iterator it = mMedia.begin();
1455 SdpContents::Session::MediumContainer::iterator it = mMedia.begin();
1456 for(;it != mMedia.end(); it++)
1491 for(
auto _m = mMedia.cbegin(); _m != mMedia.end(); _m++)
1493 if(_m->exists(
"mid") && _m->getValues(
"mid").front() == mid)
1501std::shared_ptr<TrickleIceContents>
1503 unsigned int lineIndex,
const Data& mid)
1505 std::shared_ptr<TrickleIceContents> ret;
1506 const Medium* m = getMediumByMid(mid);
1507 if(m && m->
exists(
"ice-ufrag") && m->
exists(
"ice-pwd"))
1509 ret = std::make_shared<TrickleIceContents>();
1510 ret->addAttribute(
Data(
"ice-ufrag"), m->
getValues(
"ice-ufrag").front());
1511 ret->addAttribute(
Data(
"ice-pwd"), m->
getValues(
"ice-pwd").front());
1521 unsigned long multicast,
1522 const Data& protocol)
1526 mMulticast(multicast),
1527 mProtocol(protocol),
1542 mMulticast(rhs.mMulticast),
1543 mProtocol(rhs.mProtocol),
1544 mFormats(rhs.mFormats),
1545 mCodecs(rhs.mCodecs),
1546 mTransport(rhs.mTransport),
1547 mInformation(rhs.mInformation),
1548 mConnections(rhs.mConnections),
1549 mBandwidths(rhs.mBandwidths),
1550 mEncryption(rhs.mEncryption),
1551 mAttributeHelper(rhs.mAttributeHelper),
1552 mRtpMapDone(rhs.mRtpMapDone),
1553 mRtpMap(rhs.mRtpMap)
1566 mMulticast = rhs.mMulticast;
1567 mProtocol = rhs.mProtocol;
1568 mFormats = rhs.mFormats;
1569 mCodecs = rhs.mCodecs;
1570 mTransport = rhs.mTransport;
1571 mInformation = rhs.mInformation;
1572 mConnections = rhs.mConnections;
1573 mBandwidths = rhs.mBandwidths;
1574 mEncryption = rhs.mEncryption;
1575 mAttributeHelper = rhs.mAttributeHelper;
1576 mRtpMapDone = rhs.mRtpMapDone;
1577 mRtpMap = rhs.mRtpMap;
1601 pb.
data(mName, anchor);
1614 pb.
data(mProtocol, anchor);
1624 pb.
data(format, anchor);
1636 pb.
data(mInformation, anchor);
1644 mConnections.back().parse(pb);
1654 pb.
fail(__FILE__, __LINE__,
"Too many connection addresses");
1661 pb.
fail(__FILE__, __LINE__,
"IP address expected");
1666 if (addr[i] ==
'.' || addr[i] ==
':')
1678 for (
int i = 1; i < num; i++)
1681 mConnections.back().mAddress = before +
Data(after+i);
1690 for (
int i = 1; i < num; i++)
1693 memset(hexstring, 0,
sizeof(hexstring));
1695 mConnections.back().mAddress = before +
Data(hexstring);
1706 mBandwidths.back().parse(pb);
1711 mEncryption.
parse(pb);
1714 mAttributeHelper.
parse(pb);
1730 for (list<Data>::const_iterator i = mFormats.begin();
1731 i != mFormats.end(); ++i)
1736 if (!mCodecs.empty())
1738 for (CodecContainer::const_iterator i = mCodecs.begin();
1739 i != mCodecs.end(); ++i)
1747 if (!mInformation.
empty())
1752 for (list<Connection>::const_iterator i = mConnections.begin();
1753 i != mConnections.end(); ++i)
1758 for (list<Bandwidth>::const_iterator i = mBandwidths.begin();
1759 i != mBandwidths.end(); ++i)
1769 if (!mCodecs.empty())
1772 for (CodecContainer::const_iterator i = mCodecs.begin();
1773 i != mCodecs.end(); ++i)
1786 if (!i->parameters().empty())
1795 mAttributeHelper.
encode(s);
1803 mFormats.push_back(format);
1809 mConnections.clear();
1822 mBandwidths.clear();
1829 mBandwidths.push_back(bandwidth);
1838 mRtpMapDone =
false;
1842const list<SdpContents::Session::Connection>
1845 list<Connection> connections =
const_cast<Medium*
>(
this)->getMediumConnections();
1848 if (connections.empty() && mSession && !mSession->connection().getAddress().empty())
1850 connections.push_back(mSession->connection());
1859 if (mAttributeHelper.
exists(key))
1863 return mSession && mSession->
exists(key);
1869 if (mAttributeHelper.
exists(key))
1876 static list<Data> error;
1879 return mSession->getValues(key);
1885 const list<Data>& mediumValues = mAttributeHelper.
getValues(key);
1886 if (mSession && mSession->exists(key))
1888 if (mediumValues.size() > 0)
1891 list<Data> mergedValues = mediumValues;
1892 const list<Data>& sessionValues = mSession->getValues(key);
1893 mergedValues.insert(mergedValues.end(), sessionValues.begin(), sessionValues.end());
1894 return mergedValues;
1897 return mSession->getValues(key);
1900 return mediumValues;
1909 mRtpMapDone =
false;
1926 mCodecs.push_back(codec);
1933 return const_cast<Medium*
>(
this)->codecs();
1939#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310)
1959 mRtpMap[format].parse(pb, *
this, format);
1963 ErrLog(<<
"Caught exception: "<< e);
1964 mRtpMap.erase(format);
1969 for (list<Data>::const_iterator i = mFormats.begin();
1970 i != mFormats.end(); ++i)
1972 int mapKey = i->convertInt();
1973 RtpMap::const_iterator ri = mRtpMap.find(mapKey);
1974 if (ri != mRtpMap.end())
1977 mCodecs.push_back(ri->second);
1983 Codec::CodecMap::const_iterator ri = staticCodecs.find(mapKey);
1984 if (ri != staticCodecs.end())
1987 Codec codec(ri->second);
1992 mCodecs.push_back(codec);
2012 resip::SdpContents::Session::Medium::CodecContainer::const_iterator sIter;
2013 resip::SdpContents::Session::Medium::CodecContainer::const_iterator sEnd = internalCodecList.end();
2014 resip::SdpContents::Session::Medium::CodecContainer::const_iterator eIter;
2015 resip::SdpContents::Session::Medium::CodecContainer::const_iterator eEnd = codecList.end();
2016 for (eIter = codecList.begin(); eIter != eEnd ; ++eIter)
2018 for (sIter = internalCodecList.begin(); sIter != sEnd; ++sIter)
2020 if (*sIter == *eIter)
2024 *pMatchingCodec = *eIter;
2036 if (&medium ==
this)
2038 return codecs().front();
2042 return findFirstMatchingCodecs(medium.
codecs(), pMatchingCodec);
2050 for (CodecContainer::const_iterator i = codecList.begin(); i != codecList.end(); i++)
2063 const Codec& telephoneEventCodec = findTelephoneEventPayloadCodec();
2073 const Data& parameters,
2074 const Data& encodingParameters)
2078 mParameters(parameters),
2079 mEncodingParameters(encodingParameters)
2086 mPayloadType(rhs.mPayloadType),
2087 mParameters(rhs.mParameters),
2088 mEncodingParameters(rhs.mEncodingParameters)
2095 mPayloadType(payloadType)
2106 mPayloadType = rhs.mPayloadType;
2107 mParameters = rhs.mParameters;
2108 mEncodingParameters = rhs.mEncodingParameters;
2120 mName = pb.
data(anchor);
2131 mEncodingParameters = pb.
data(anchor);
2144 for (list<Data>::const_iterator i = medium.
getValues(
fmtp).begin();
2151 if (payload == mPayloadType)
2155 mParameters = pb.
data(anchor);
2161 InfoLog(<<
"Caught exception when parsing a=fmtp: "<< pe);
2181 if (! sStaticCodecsCreated)
2186 sStaticCodecs = std::unique_ptr<CodecMap>(
new CodecMap);
2189 sStaticCodecs->insert(make_pair(0,
Codec(
"PCMU",0,8000)));
2190 sStaticCodecs->insert(make_pair(3,
Codec(
"GSM",3,8000)));
2191 sStaticCodecs->insert(make_pair(4,
Codec(
"G723",4,8000)));
2192 sStaticCodecs->insert(make_pair(5,
Codec(
"DVI4",5,8000)));
2193 sStaticCodecs->insert(make_pair(6,
Codec(
"DVI4",6,16000)));
2194 sStaticCodecs->insert(make_pair(7,
Codec(
"LPC",7,8000)));
2195 sStaticCodecs->insert(make_pair(8,
Codec(
"PCMA",8,8000)));
2196 sStaticCodecs->insert(make_pair(9,
Codec(
"G722",9,8000)));
2197 sStaticCodecs->insert(make_pair(10,
Codec(
"L16-2",10,44100)));
2198 sStaticCodecs->insert(make_pair(11,
Codec(
"L16-1",11,44100)));
2199 sStaticCodecs->insert(make_pair(12,
Codec(
"QCELP",12,8000)));
2200 sStaticCodecs->insert(make_pair(13,
Codec(
"CN",13,8000)));
2201 sStaticCodecs->insert(make_pair(14,
Codec(
"MPA",14,90000)));
2202 sStaticCodecs->insert(make_pair(15,
Codec(
"G728",15,8000)));
2203 sStaticCodecs->insert(make_pair(16,
Codec(
"DVI4",16,11025)));
2204 sStaticCodecs->insert(make_pair(17,
Codec(
"DVI4",17,22050)));
2205 sStaticCodecs->insert(make_pair(18,
Codec(
"G729",18,8000)));
2208 sStaticCodecs->insert(make_pair(25,
Codec(
"CelB",25,90000)));
2209 sStaticCodecs->insert(make_pair(26,
Codec(
"JPEG",26,90000)));
2210 sStaticCodecs->insert(make_pair(28,
Codec(
"nv",28,90000)));
2211 sStaticCodecs->insert(make_pair(31,
Codec(
"H261",31,90000)));
2212 sStaticCodecs->insert(make_pair(32,
Codec(
"MPV",32,90000)));
2213 sStaticCodecs->insert(make_pair(33,
Codec(
"MP2T",33,90000)));
2214 sStaticCodecs->insert(make_pair(34,
Codec(
"H263",34,90000)));
2216 sStaticCodecsCreated =
true;
2218 return *(sStaticCodecs.get());
2224 static Data defaultEncodingParameters(
Data(
"1"));
2225 return (
isEqualNoCase(lhs.mName, rhs.mName) && lhs.mRate == rhs.mRate &&
2226 (lhs.mEncodingParameters == rhs.mEncodingParameters ||
2227 (lhs.mEncodingParameters.
empty() && rhs.mEncodingParameters == defaultEncodingParameters) ||
2228 (lhs.mEncodingParameters == defaultEncodingParameters && rhs.mEncodingParameters.
empty())));
2243 if(!codec.mEncodingParameters.
empty())
2246 str << codec.mEncodingParameters;
2263bool Codec::sStaticCodecsCreated =
false;
2264std::unique_ptr<Codec::CodecMap> Codec::sStaticCodecs;
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
void parseEorP(ParseBuffer &pb, Data &eOrp, Data &freeText)
static const Data rtpmap("rtpmap")
const char * NetworkType[]
int parseTypedTime(ParseBuffer &pb)
static const Data fmtp("fmtp")
static Data nullOrigin("0.0.0.0")
static const struct nv types[]
static constexpr size_t MaxParsedAttributeNames
parse() fails a section with more distinct attribute names than this
void clearAttribute(const Data &key)
const std::list< Data > & getValues(const Data &key) const
EncodeStream & encode(EncodeStream &s) const
AttributeHelper & operator=(const AttributeHelper &rhs)
void addAttribute(const Data &key, const Data &value=Data::Empty)
bool exists(const Data &key) const
void parse(ParseBuffer &pb)
Base class for all SIP body types.
bool exists(const HeaderBase &headerType) const
checks to see if a header is present
Contents & operator=(const Contents &rhs)
Assignment operator.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Data substr(size_type first, size_type count=Data::npos) const
Copies a portion of this Data into a new Data.
bool empty() const noexcept
Checks whether the Data is empty.
size_type size() const noexcept
Returns the number of bytes in this Data.
const char * data() const noexcept
Returns a pointer to the contents of this Data.
bool caseInsensitiveTokenCompare(const Data &rhs) const
static unsigned int hex2integer(const char *_s)
Converts a character string containing a hexidecimal value into an unsigned int.
static void integer2hex(char *_d, unsigned int _s, bool _l=true)
Converts an interger in a character string containing the hexidecimal representation of the integer.
Represents the "media-type" element in the RFC 3261 grammar.
Provides string-parsing functionality with protection from buffer overflow.
uint32_t uInt32()
dcm! – merge these, ask about length checks
CurrentPosition skipToEnd()
CurrentPosition skipWhitespace()
CurrentPosition skipToChar(char c)
CurrentPosition position() const
void reset(const char *pos)
CurrentPosition skipToOneOf(const char *cs)
CurrentPosition skipChar()
void fail(const char *file, unsigned int line, const Data &errmsg=Data::Empty) const
void data(Data &data, const char *start) const
make the passed in data share memory with the buffer (uses Data::Share)
const char * skipToEndQuote(char quote='"')
BaseException used to indicate parse failures.
Process optional b= (bandwidth) lines in SDP.
Bandwidth & operator=(const Bandwidth &rhs)
EncodeStream & encode(EncodeStream &) const
void parse(ParseBuffer &pb)
parameters for a specific codec are stored in this class.
static const Codec G723_8000
static const Codec G729_8000
static const Codec TelephoneEvent
static const Codec G722_8000
Codec & operator=(const Codec &codec)
void assignFormatParameters(const SdpContents::Session::Medium &medium)
static CodecMap & getStaticCodecs()
void parse(ParseBuffer &pb, const SdpContents::Session::Medium &medium, int payLoadType)
const Data & getName() const
returns the name of the codec.
static const Codec ULaw_8000
int payloadType() const
returns the RTP payload type associated with this codec.
HashMap< int, Codec > CodecMap
static const Codec FrfDialedDigit
static const Codec GSM_8000
int getRate() const
returns the name of the codec.
static const Codec ALaw_8000
Process c= (connection) lines in SDP.
void parse(ParseBuffer &pb)
const Data & getAddress() const
returns the connection address
void setAddress(const Data &host, AddrType type=IP4)
set the address for the connection
EncodeStream & encode(EncodeStream &) const
Connection & operator=(const Connection &rhs)
const Tuple tuple() const
static const Direction INACTIVE
static const Direction SENDRECV
static const Direction RECVONLY
static const Direction SENDONLY
process e= (email) lines in the SDP
void parse(ParseBuffer &pb)
EncodeStream & encode(EncodeStream &) const
Email & operator=(const Email &rhs)
process k= (encryption key) line
EncodeStream & encode(EncodeStream &) const
Encryption & operator=(const Encryption &rhs)
const KeyType & getMethod() const
void parse(ParseBuffer &pb)
process m= (media announcement) blocks
const Codec & findTelephoneEventPayloadCodec() const
finds the telephone-event codec
Medium & operator=(const Medium &rhs)
const std::list< Connection > getConnections() const
get a list of Connection objects, including the Session's c= line.
const Codec & findFirstMatchingCodecs(const CodecContainer &codecs, Codec *pMatchingCodec=0) const
void addBandwidth(const Bandwidth &bandwidth)
void setConnection(const Connection &connection)
set the media connection line.
void addAttribute(const Data &key, const Data &value=Data::Empty)
add a media attribute line
const std::list< Data > & getValues(const Data &key) const
get the attribute values corresponding to the key - returns the attributes set on this medium,...
EncodeStream & encode(EncodeStream &) const
bool exists(const Data &key) const
tests if an a= key is present in the media section
void addConnection(const Connection &connection)
add a media connection line.
void setBandwidth(const Bandwidth &bandwidth)
int port() const
return the base port
void addCodec(const Codec &codec)
add a codec to the m= line
void addFormat(const Data &format)
add a format identifier to the m= line
void parse(ParseBuffer &pb)
void setPort(int port)
change the base port
std::list< Codec > CodecContainer
std::list< Data > getMergedValues(const Data &key) const
get the attribute values corresponding to the key - returns both the attributes set on this medium,...
const CodecContainer & codecs() const
preferred codec/format interface
void clearCodecs()
remove all codecs from SDP
int multicast() const
get the number of transport port pairs
const Direction & getDirection() const
const Data & protocol() const
return the transport protocol
const Data & name() const
return the media type
int findTelephoneEventPayloadType() const
finds the telephone-event payload type
void clearAttribute(const Data &key)
erase all attributes for a given key
processes o= lines in SDP
EncodeStream & encode(EncodeStream &) const
void setAddress(const Data &host, AddrType type=IP4)
set the address for the session
void parse(ParseBuffer &pb)
Origin & operator=(const Origin &rhs)
process p= (phone number) lines in the SDP
void parse(ParseBuffer &pb)
EncodeStream & encode(EncodeStream &) const
Phone & operator=(const Phone &rhs)
void parse(ParseBuffer &pb)
EncodeStream & encode(EncodeStream &) const
Process t= (start/stop time) lines in SDP.
Time & operator=(const Time &rhs)
void parse(ParseBuffer &pb)
void addRepeat(const Repeat &repeat)
EncodeStream & encode(EncodeStream &) const
specify the time at which a timezone shift will occur and the offset, in seconds
Adjustment & operator=(const Adjustment &rhs)
Adjustment(unsigned long time, int offset)
process z= (timezone) lines
void addAdjustment(const Adjustment &adjusment)
EncodeStream & encode(EncodeStream &) const
Timezones & operator=(const Timezones &rhs)
void parse(ParseBuffer &pb)
Provides an interface to read and modify SDP bodies.
void addMedium(const Medium &medium)
add an m= (Medium) section to session
void addPhone(const Phone &phone)
add a p= (phone number) line to session
void addTime(const Time &t)
add a t= (Time) line to session
std::shared_ptr< TrickleIceContents > makeIceFragment(const Data &fragment, unsigned int lineIndex, const Data &mid)
based on the original SDP in this instances of SdpContents, find the relevant ICE and m= line(s),...
std::list< std::reference_wrapper< Medium > > getMediaByType(const Data &type)
return session Media lines filtered by type
const Direction & getDirection() const
int version() const
return session version
void parse(ParseBuffer &pb)
DirectionList getNetDirections(const SdpContents &remote) const
const Origin & origin() const
return session Origin line
Session & operator=(const Session &rhs)
const std::list< Data > & getValues(const Data &key) const
get the attribute values corresponding to the key
std::vector< std::reference_wrapper< const SdpContents::Session::Direction > > DirectionList
const Data & name() const
return session name
bool isWebRTC() const
determine if the SDP appears to conform to WebRTC
void addBandwidth(const Bandwidth &bandwidth)
add a b= (Bandwidth) line to session
std::set< Data > getMediaStreamLabels() const
retrieve label (RFC 4574) attributes in a set
void transformLocalHold(bool holding)
change the direction attributes as if the peer who created the SDP is on hold or not
const Connection & connection() const
return session Connection
const Medium * getMediumByMid(const Data &mid) const
find the Medium with given mid value
EncodeStream & encode(EncodeStream &) const
void clearAttribute(const Data &key)
erase all attributes for a given key
void addEmail(const Email &email)
add an e= (email) line to session
bool exists(const Data &key) const
tests if an a= key is present in the session
bool isTrickleIceSupported() const
determine if ice-options:trickle is present
DirectionList getDirections() const
void transformCOMedia(const Data &setupDirection="active", const Data &cOMediaAttribute="setup")
apply RFC 4145 COMEDIA transform
void addAttribute(const Data &key, const Data &value=Data::Empty)
add a session attribute line
Provides an interface to process and generate SDP bodies (MIME content-type application/sdp).
virtual EncodeStream & encodeParsed(EncodeStream &str) const
virtual void parse(ParseBuffer &pb)
static const SdpContents Empty
virtual Contents * clone() const
duplicate an SdpContents object
static const Mime & getStaticType()
Session & session()
get the parsed SDP
SdpContents & operator=(const SdpContents &rhs)
static const char * RPAREN
static const char * LPAREN
static const char * SPACE
static const char * COLON
static const char * SLASH
static const char * RA_QUOTE
static const char * EQUALS
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)
unsigned long long uint64_t
void skipEol(ParseBuffer &pb)
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
bool operator==(const char *lhs, const Data &rhs)
bool operator!=(const Data &lhs, const Data &rhs)