1#if defined(HAVE_CONFIG_H)
19#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
146 if (namespacePrefix.
empty())
148 return tagName == compareToTagNoPrefix;
150 Data compareToTagWithPrefix(namespacePrefix);
151 compareToTagWithPrefix += compareToTagNoPrefix;
152 return tagName == compareToTagWithPrefix;
185 static Mime type(
"application",
"dialog-info+xml");
192 bool hasSharedAppearanceElements =
false;
195 for (DialogList::const_iterator it = mDialogs.begin(); it != mDialogs.end(); it++)
197 if (it->hasExclusive() || it->hasAppearance() || !it->getReplacedDialogs().empty() || !it->getJoinedDialogs().empty())
199 hasSharedAppearanceElements =
true;
204 str <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" <<
Symbols::CRLF;
206 if (hasSharedAppearanceElements)
213 for (DialogList::const_iterator it = mDialogs.begin(); it != mDialogs.end(); it++)
215 it->encodeParsed(str, mIndent);
228 std::pair <std::multimap<Data, Data>::const_iterator, std::multimap<Data, Data>::const_iterator> filteredList;
229 filteredList = mExtraDialogElements.equal_range(childElementName);
231 for (std::multimap<Data, Data>::const_iterator matchListIterator = filteredList.first; matchListIterator != filteredList.second; ++matchListIterator)
233 if(instance == matchCount)
235 elementValue = matchListIterator->second;
246DialogInfoContents::Dialog::encodeParsed(EncodeStream& str,
const Data& indent)
const
249 str << indent <<
"<dialog id=\"" <<
mId.xmlCharDataEncode() <<
"\"";
250 if (!mCallId.empty())
252 str <<
" call-id=\"" << mCallId.xmlCharDataEncode() <<
"\"";
254 if (!mLocalTag.empty())
258 if (!mRemoteTag.empty())
269 str << indent << indent <<
"<state";
276 str <<
" code=\"" << mStateCode <<
"\"";
283 str << indent << indent <<
"<duration>" << mDuration <<
"</duration>" <<
Symbols::CRLF;
287 if (!mReplaces.mCallId.empty())
294 if (!mReferredBy.uri().host().empty())
296 str << indent << indent;
297 encodeNameAddrElement(str,
"referred-by", mReferredBy);
302 if (!mRouteSet.empty())
305 for (NameAddrs::const_iterator itNA = mRouteSet.begin(); itNA != mRouteSet.end(); itNA++)
313 mLocalParticipant.encode(str,
"local", indent);
316 mRemoteParticipant.encode(str,
"remote", indent);
336 for (
auto replacedDialogsIterator = mReplacedDialogs.begin(); replacedDialogsIterator != mReplacedDialogs.end(); replacedDialogsIterator++)
345 for (
auto joinedDialogsIterator = mJoinedDialogs.begin(); joinedDialogsIterator != mJoinedDialogs.end(); joinedDialogsIterator++)
355 for(std::multimap<Data, Data>::const_iterator elementIterator = mExtraDialogElements.begin();
356 elementIterator != mExtraDialogElements.end();
359 DebugLog(<<
"Dialog child element Name: \"" << elementIterator->first <<
"\" Value: \"" << elementIterator->second <<
"\"");
360 str << indent << indent <<
'<' << elementIterator->first <<
'>'
361 << elementIterator->second.xmlCharDataEncode()
371DialogInfoContents::encodeNameAddrElement(EncodeStream& str,
const char* elementName,
const NameAddr& nameAddr)
373 str <<
"<" << elementName;
385 mTarget = targetWithContactParams.
uri();
392 if (!paramsData.
empty())
406 pb.
data(name, anchor);
415 value = pb.
data(anchor);
424 value = pb.
data(anchor);
426 mTargetParams[name] = value;
431 mTargetParams[pb.
data(anchor)] =
"true";
446 TargetParams::const_iterator it = mTargetParams.find(name);
447 if (it != mTargetParams.end())
456DialogInfoContents::Dialog::Participant::encode(EncodeStream& str,
const char* baseElementName,
const Data& indent)
const
459 if (!mIdentity.uri().host().empty() || !mTarget.host().empty() || !mSessionDescription.empty() || mHasCSeq)
461 str << indent << indent <<
"<" << baseElementName <<
">" <<
Symbols::CRLF;
462 if (!mIdentity.uri().host().empty())
464 str << indent << indent << indent;
465 encodeNameAddrElement(str,
"identity", mIdentity);
468 if (!mTarget.host().empty())
471 if (mTargetParams.empty())
479 for (TargetParams::const_iterator itParm = mTargetParams.begin(); itParm != mTargetParams.end(); itParm++)
483 str << indent << indent << indent <<
"</target>" <<
Symbols::CRLF;
486 if (!mSessionDescription.empty())
489 str << indent << indent << indent <<
"<session-description type=\"" << mSessionDescriptionType <<
"\">" << mSessionDescription.
xmlCharDataEncode() <<
"</session-description>" <<
Symbols::CRLF;
493 str << indent << indent << indent <<
"<cseq>" << mCSeq <<
"</cseq>" <<
Symbols::CRLF;
495 str << indent << indent <<
"</" << baseElementName <<
">" <<
Symbols::CRLF;
506 bool baseDialogInfoNamespaceUriFound =
false;
507 for (; itAttr != attr.
end(); itAttr++)
509 if (itAttr->first.prefix(
"xmlns"))
519 pb.
data(prefix, anchor);
523 baseDialogInfoNamespaceUriFound =
true;
524 mBaseDialogInfoNamespacePrefix = prefix;
528 mSharedAppearanceDialogInfoNamespacePrefix = prefix;
531 else if (itAttr->first ==
"version")
533 mVersion = itAttr->second.convertUnsignedLong();
535 else if (itAttr->first ==
"state")
539 else if (itAttr->first ==
"entity")
541 mEntity =
Uri(itAttr->second.xmlCharDataDecode());
545 DebugLog(<<
"Unknown root attribute: " << itAttr->first <<
"=" << itAttr->second);
549 if (!baseDialogInfoNamespaceUriFound)
573DialogInfoContents::parseDialog(
XMLCursor& xml)
578 for (; itAttr != attr.
end(); itAttr++)
580 if (itAttr->first ==
"id")
582 dialog.mId = itAttr->second.xmlCharDataDecode();
584 else if (itAttr->first ==
"call-id")
586 dialog.mCallId = itAttr->second.xmlCharDataDecode();
588 else if (itAttr->first ==
"local-tag")
590 dialog.mLocalTag = itAttr->second.xmlCharDataDecode();
592 else if (itAttr->first ==
"remote-tag")
594 dialog.mRemoteTag = itAttr->second.xmlCharDataDecode();
596 else if (itAttr->first ==
"direction")
602 DebugLog(<<
"Unknown dialog attribute: " << itAttr->first <<
"=" << itAttr->second);
606 if (dialog.mId.empty())
608 WarningLog(<<
"Dialog Id was not found for dialog element");
619 for (itAttr = attr.
begin(); itAttr != attr.
end(); itAttr++)
621 if (itAttr->first ==
"event")
625 else if (itAttr->first ==
"code")
627 dialog.mStateCode = itAttr->second.convertInt();
631 DebugLog(<<
"Unknown state attribute: " << itAttr->first <<
"=" << itAttr->second);
640 else if (
compareTag(xml.
getTag(),
"duration", mBaseDialogInfoNamespacePrefix))
645 dialog.mHasDuration =
true;
649 else if (
compareTag(xml.
getTag(),
"replaces", mBaseDialogInfoNamespacePrefix))
651 parseDialogIdInfo(xml, dialog.mReplaces);
653 else if (
compareTag(xml.
getTag(),
"referred-by", mBaseDialogInfoNamespacePrefix))
655 parseNameAddrElement(xml, dialog.mReferredBy);
657 else if (
compareTag(xml.
getTag(),
"route-set", mBaseDialogInfoNamespacePrefix))
666 if (parseUriValue(xml, nameAddr.
uri()))
673 DebugLog(<<
"Unknown dialog/route-set element: " << xml.
getTag());
681 dialog.mLocalParticipant.parse(xml, mBaseDialogInfoNamespacePrefix);
683 else if (
compareTag(xml.
getTag(),
"remote", mBaseDialogInfoNamespacePrefix))
685 dialog.mRemoteParticipant.parse(xml, mBaseDialogInfoNamespacePrefix);
688 else if (
compareTag(xml.
getTag(),
"appearance", mSharedAppearanceDialogInfoNamespacePrefix))
693 dialog.mHasAppearance =
true;
697 else if (
compareTag(xml.
getTag(),
"exclusive", mSharedAppearanceDialogInfoNamespacePrefix))
702 dialog.mHasExclusive =
true;
706 else if (
compareTag(xml.
getTag(),
"replaced-dialog", mSharedAppearanceDialogInfoNamespacePrefix))
708 Dialog::DialogIdInfo dialogIdInfo;
709 if (parseDialogIdInfo(xml, dialogIdInfo))
711 dialog.mReplacedDialogs.push_back(dialogIdInfo);
714 else if (
compareTag(xml.
getTag(),
"joined-dialog", mSharedAppearanceDialogInfoNamespacePrefix))
716 Dialog::DialogIdInfo dialogIdInfo;
717 if (parseDialogIdInfo(xml, dialogIdInfo))
719 dialog.mJoinedDialogs.push_back(dialogIdInfo);
733 DebugLog(<<
"Unknown dialog element: " << elementName);
741 mDialogs.push_back(dialog);
745DialogInfoContents::parseDialogIdInfo(
XMLCursor& xml, Dialog::DialogIdInfo& dialogIdInfo)
750 if (itAttr->first ==
"call-id")
752 dialogIdInfo.mCallId = itAttr->second.xmlCharDataDecode();
754 else if (itAttr->first ==
"local-tag")
756 dialogIdInfo.mLocalTag = itAttr->second.xmlCharDataDecode();
758 else if (itAttr->first ==
"remote-tag")
760 dialogIdInfo.mRemoteTag = itAttr->second.xmlCharDataDecode();
764 DebugLog(<<
"Unknown dialog/replaces attribute: " << itAttr->first <<
"=" << itAttr->second);
767 return !dialogIdInfo.mCallId.empty() && !dialogIdInfo.mLocalTag.empty() && !dialogIdInfo.mRemoteTag.empty();
771DialogInfoContents::parseUriValue(
XMLCursor& xml,
Uri& uri)
773 bool parseGood =
false;
795 for (; itAttr != attr.
end(); itAttr++)
797 if (itAttr->first ==
"display")
803 DebugLog(<<
"Unknown NameAddr attribute: " << itAttr->first <<
"=" << itAttr->second);
806 return parseUriValue(xml, nameAddr.
uri());
810DialogInfoContents::Dialog::Participant::parse(
XMLCursor& xml,
const Data& namespacePrefix)
818 parseNameAddrElement(xml, mIdentity);
826 for (; itAttr != attr.
end(); itAttr++)
828 if (itAttr->first ==
"uri")
830 mTarget =
Uri(itAttr->second.xmlCharDataDecode());
834 DebugLog(<<
"Unknown dialog/participant/target attribute: " << itAttr->first <<
"=" << itAttr->second);
848 DebugLog(<<
"Unknown dialog/particpant/target element: " << xml.
getTag());
863 for (; itAttr != attr.
end(); itAttr++)
865 if (itAttr->first ==
"type")
867 mSessionDescriptionType = itAttr->second.xmlCharDataDecode();
871 DebugLog(<<
"Unknown dialog/participant/session-description attribute: " << itAttr->first <<
"=" << itAttr->second);
891 DebugLog(<<
"Unknown dialog participant element: " << xml.
getTag());
899DialogInfoContents::Dialog::Participant::parseParam(
XMLCursor& xml)
905 for (; itAttr != attr.
end(); itAttr++)
907 if (itAttr->first ==
"pname")
911 else if (itAttr->first ==
"pval")
917 DebugLog(<<
"Unknown dialog/participant/target/param attribute: " << itAttr->first <<
"=" << itAttr->second);
922 mTargetParams[name] = value;
932 mDialogs.push_back(dialog);
939 for (DialogList::iterator it = mDialogs.begin(); it != mDialogs.end(); it++)
static const Data BaseDialogInfoNamespaceUri("urn:ietf:params:xml:ns:dialog-info")
static const char * DirectionStrings[]
static const char * DialogStateEventStrings[]
static const char * DialogInfoStateStrings[]
static const Data SharedAppearanceDialogInfoNamespacePrefix("sa:")
static const Data SharedAppearanceDialogInfoNamespaceUri("urn:ietf:params:xml:ns:sa-dialog-info")
static const Data DefaultEncodeIndent(" ")
static const char * DialogStateStrings[]
#define WarningLog(args_)
The abstract base-class for all exceptions thrown by resip code.
Base class for all SIP body types.
An iostream that operates on an existing Data.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Data xmlCharDataDecode() const
Performs in-place XML Character Data un-escaping of a Data.
unsigned long convertUnsignedLong() const
Data xmlCharDataEncode() const
Performs in-place XML Character Data escaping of a Data.
bool empty() const noexcept
Checks whether the Data is empty.
static Data from(const T &x)
Converts from arbitrary other type to Data.
void setTarget(const Uri &target)
bool getTargetParam(const Data &name, Data &value) const
bool getDialogElement(const Data &childElementName, Data &elementValue, int instance=0) const
SIP body type for holding DialogInfo contents (MIME content-type application/dialog-info+xml).
virtual void parse(ParseBuffer &pb)
virtual ~DialogInfoContents()
void addDialog(const Dialog &dialog)
static const char * dialogInfoStateToString(const DialogInfoState &dialogInfoState)
virtual Contents * clone() const
duplicate an DialogInfoContents object
@ MaxOrUnsetDialogStateEvent
static const char * dialogStateEventToString(const DialogStateEvent &dialogStateEvent)
static DialogState dialogStateStringToEnum(const Data &dialogStateString)
static bool compareTag(const Data &tagName, const Data &compareToTagNoPrefix, const Data &namespacePrefix)
static const char * directionToString(const Direction &direction)
static Direction directionStringToEnum(const Data &directionString)
bool removeDialog(const Data &id)
static const char * dialogStateToString(const DialogState &dialogState)
static const DialogInfoContents Empty
virtual EncodeStream & encodeParsed(EncodeStream &str) const
static const Mime & getStaticType()
static DialogInfoState dialogInfoStateStringToEnum(const Data &dialogInfoStateString)
static DialogStateEvent dialogStateEventStringToEnum(const Data &dialogStateEventString)
dcm! – kill typedef std::list<DialogId> DialogIdSet;
List::const_iterator const_iterator
Represents the "media-type" element in the RFC 3261 grammar.
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
Provides string-parsing functionality with protection from buffer overflow.
CurrentPosition skipToEnd()
CurrentPosition skipWhitespace()
CurrentPosition skipToChar(char c)
CurrentPosition position() const
CurrentPosition skipToOneOf(const char *cs)
CurrentPosition skipChar()
void data(Data &data, const char *start) const
make the passed in data share memory with the buffer (uses Data::Share)
EncodeStream & encodeParameters(EncodeStream &str) const
Encodes parameters as they should appear on the wire.
void push_back(const T &t)
Inserts a header field value at the back of this container.
static const char * COLON
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
const Data & getValue() const
const Data & getTag() const
const AttributeMap & getAttributes() const
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)