aboutsummaryrefslogtreecommitdiff
path: root/src/base/QXmppJingleIq.cpp
diff options
context:
space:
mode:
authorTibor Csötönyi <work@taibsu.de>2023-05-03 15:13:18 +0200
committerLinus Jahn <lnj@kaidan.im>2023-05-14 23:58:01 +0200
commitfd1a242b154dd74765e4f29ad26e7f743a8bb478 (patch)
treeabd105be322cd4687b42718fd59c22ed2ab73f89 /src/base/QXmppJingleIq.cpp
parenta4dcd906850b5ebecfdf7331059a13192f094f07 (diff)
downloadqxmpp-fd1a242b154dd74765e4f29ad26e7f743a8bb478.tar.gz
Rename QXmppJingleIq.cpp/h to QXmppJingleData.cpp/h and test
Diffstat (limited to 'src/base/QXmppJingleIq.cpp')
-rw-r--r--src/base/QXmppJingleIq.cpp3207
1 files changed, 0 insertions, 3207 deletions
diff --git a/src/base/QXmppJingleIq.cpp b/src/base/QXmppJingleIq.cpp
deleted file mode 100644
index 67883fc8..00000000
--- a/src/base/QXmppJingleIq.cpp
+++ /dev/null
@@ -1,3207 +0,0 @@
-// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
-// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
-//
-// SPDX-License-Identifier: LGPL-2.1-or-later
-
-#include "QXmppJingleIq.h"
-
-#include "QXmppConstants_p.h"
-#include "QXmppUtils.h"
-
-#include <QDate>
-#include <QDateTime>
-#include <QDomElement>
-#include <QRegularExpression>
-
-static const int RTP_COMPONENT = 1;
-
-static const char *jingle_actions[] = {
- "content-accept",
- "content-add",
- "content-modify",
- "content-reject",
- "content-remove",
- "description-info",
- "security-info",
- "session-accept",
- "session-info",
- "session-initiate",
- "session-terminate",
- "transport-accept",
- "transport-info",
- "transport-reject",
- "transport-replace",
-};
-
-static const char *jingle_reasons[] = {
- "",
- "alternative-session",
- "busy",
- "cancel",
- "connectivity-error",
- "decline",
- "expired",
- "failed-application",
- "failed-transport",
- "general-error",
- "gone",
- "incompatible-parameters",
- "media-error",
- "security-error",
- "success",
- "timeout",
- "unsupported-applications",
- "unsupported-transports",
-};
-
-static const QStringList JINGLE_RTP_ERROR_CONDITIONS = {
- {},
- QStringLiteral("invalid-crypto"),
- QStringLiteral("crypto-required")
-};
-
-static const QStringList JINGLE_RTP_HEADER_EXTENSIONS_SENDERS = {
- QStringLiteral("both"),
- QStringLiteral("initiator"),
- QStringLiteral("responder")
-};
-
-static QString formatFingerprint(const QByteArray &digest)
-{
- QString fingerprint;
- const QString hx = digest.toHex().toUpper();
- for (int i = 0; i < hx.size(); i += 2) {
- if (!fingerprint.isEmpty()) {
- fingerprint += ':';
- }
- fingerprint += hx.mid(i, 2);
- }
- return fingerprint;
-}
-
-static QByteArray parseFingerprint(const QString &fingerprint)
-{
- QString z = fingerprint;
- z.replace(':', "");
- return QByteArray::fromHex(z.toUtf8());
-}
-
-static QString addressToSdp(const QHostAddress &host)
-{
- return QStringLiteral("IN %1 %2").arg(host.protocol() == QAbstractSocket::IPv6Protocol ? QStringLiteral("IP6") : QStringLiteral("IP4"), host.toString());
-}
-
-static bool candidateParseSdp(QXmppJingleCandidate *candidate, const QString &sdp)
-{
- if (!sdp.startsWith(QStringLiteral("candidate:"))) {
- return false;
- }
-
- const QStringList bits = sdp.mid(10).split(" ");
- if (bits.size() < 6) {
- return false;
- }
-
- candidate->setFoundation(bits[0]);
- candidate->setComponent(bits[1].toInt());
- candidate->setProtocol(bits[2].toLower());
- candidate->setPriority(bits[3].toInt());
- candidate->setHost(QHostAddress(bits[4]));
- candidate->setPort(bits[5].toInt());
- for (int i = 6; i < bits.size() - 1; i += 2) {
- if (bits[i] == QStringLiteral("typ")) {
- bool ok;
- candidate->setType(QXmppJingleCandidate::typeFromString(bits[i + 1], &ok));
- if (!ok) {
- return false;
- }
- } else if (bits[i] == QStringLiteral("generation")) {
- candidate->setGeneration(bits[i + 1].toInt());
- } else {
- qWarning() << "Candidate SDP contains unknown attribute" << bits[i];
- return false;
- }
- }
- return true;
-}
-
-static QString candidateToSdp(const QXmppJingleCandidate &candidate)
-{
- return QStringLiteral("candidate:%1 %2 %3 %4 %5 %6 typ %7 generation %8").arg(candidate.foundation(), QString::number(candidate.component()), candidate.protocol(), QString::number(candidate.priority()), candidate.host().toString(), QString::number(candidate.port()), QXmppJingleCandidate::typeToString(candidate.type()), QString::number(candidate.generation()));
-}
-
-// Parses all found SDP parameter elements of parent into parameters.
-static void parseSdpParameters(const QDomElement &parent, QVector<QXmppSdpParameter> &parameters)
-{
- for (auto childElement = parent.firstChildElement();
- !childElement.isNull();
- childElement = childElement.nextSiblingElement()) {
- if (QXmppSdpParameter::isSdpParameter(childElement)) {
- QXmppSdpParameter parameter;
- parameter.parse(childElement);
- parameters.append(parameter);
- }
- }
-}
-
-// Serializes the SDP parameters.
-static void sdpParametersToXml(QXmlStreamWriter *writer, const QVector<QXmppSdpParameter> &parameters)
-{
- for (const auto &parameter : parameters) {
- parameter.toXml(writer);
- }
-}
-
-// Parses all found RTP Feedback Negotiation elements inside of parent into properties and
-// intervals.
-static void parseJingleRtpFeedbackNegotiationElements(const QDomElement &parent, QVector<QXmppJingleRtpFeedbackProperty> &properties, QVector<QXmppJingleRtpFeedbackInterval> &intervals)
-{
- for (auto child = parent.firstChildElement();
- !child.isNull();
- child = child.nextSiblingElement()) {
- if (QXmppJingleRtpFeedbackProperty::isJingleRtpFeedbackProperty(child)) {
- QXmppJingleRtpFeedbackProperty property;
- property.parse(child);
- properties.append(property);
- } else if (QXmppJingleRtpFeedbackInterval::isJingleRtpFeedbackInterval(child)) {
- QXmppJingleRtpFeedbackInterval interval;
- interval.parse(child);
- intervals.append(interval);
- }
- }
-}
-
-// Serializes the RTP feedback properties and intervals.
-static void jingleRtpFeedbackNegotiationElementsToXml(QXmlStreamWriter *writer, const QVector<QXmppJingleRtpFeedbackProperty> &properties, const QVector<QXmppJingleRtpFeedbackInterval> &intervals)
-{
- for (const auto &property : properties) {
- property.toXml(writer);
- }
-
- for (const auto &interval : intervals) {
- interval.toXml(writer);
- }
-}
-
-// Parses all found RTP Header Extensions Negotiation elements inside of parent into properties and
-// isRtpHeaderExtensionMixingAllowed.
-static void parseJingleRtpHeaderExtensionsNegotiationElements(const QDomElement &parent, QVector<QXmppJingleRtpHeaderExtensionProperty> &properties, bool &isRtpHeaderExtensionMixingAllowed)
-{
- for (auto child = parent.firstChildElement();
- !child.isNull();
- child = child.nextSiblingElement()) {
- if (QXmppJingleRtpHeaderExtensionProperty::isJingleRtpHeaderExtensionProperty(child)) {
- QXmppJingleRtpHeaderExtensionProperty property;
- property.parse(child);
- properties.append(property);
- } else if (child.tagName() == QStringLiteral("extmap-allow-mixed") && child.namespaceURI() == ns_jingle_rtp_header_extensions_negotiation) {
- isRtpHeaderExtensionMixingAllowed = true;
- }
- }
-}
-
-// Serializes the RTP header extension properties and isRtpHeaderExtensionMixingAllowed.
-static void jingleRtpHeaderExtensionsNegotiationElementsToXml(QXmlStreamWriter *writer, const QVector<QXmppJingleRtpHeaderExtensionProperty> &properties, bool isRtpHeaderExtensionMixingAllowed)
-{
- for (const auto &property : properties) {
- property.toXml(writer);
- }
-
- if (isRtpHeaderExtensionMixingAllowed) {
- writer->writeStartElement(QStringLiteral("extmap-allow-mixed"));
- writer->writeDefaultNamespace(ns_jingle_rtp_header_extensions_negotiation);
- writer->writeEndElement();
- }
-}
-
-class QXmppJingleIqContentPrivate : public QSharedData
-{
-public:
- QXmppJingleIqContentPrivate();
-
- QString creator;
- QString disposition;
- QString name;
- QString senders;
-
- QXmppJingleDescription description;
- bool isRtpMultiplexingSupported = false;
-
- QString transportType;
- QString transportUser;
- QString transportPassword;
-
- QByteArray transportFingerprint;
- QString transportFingerprintHash;
- QString transportFingerprintSetup;
-
- QList<QXmppJingleCandidate> transportCandidates;
-
- // XEP-0167: Jingle RTP Sessions
- std::optional<QXmppJingleRtpEncryption> rtpEncryption;
-
- // XEP-0293: Jingle RTP Feedback Negotiation
- QVector<QXmppJingleRtpFeedbackProperty> rtpFeedbackProperties;
- QVector<QXmppJingleRtpFeedbackInterval> rtpFeedbackIntervals;
-
- // XEP-0294: Jingle RTP Header Extensions Negotiation
- QVector<QXmppJingleRtpHeaderExtensionProperty> rtpHeaderExtensionProperties;
- bool isRtpHeaderExtensionMixingAllowed = false;
-};
-
-QXmppJingleIqContentPrivate::QXmppJingleIqContentPrivate()
-{
- description.setSsrc(0);
-}
-
-///
-/// \enum QXmppJingleIq::Creator
-///
-/// Party that originially generated the content type
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// \struct QXmppJingleIq::RtpSessionStateActive
-///
-/// Actively participating in the session after having been on mute or having put the other party on
-/// hold
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// \struct QXmppJingleIq::RtpSessionStateHold
-///
-/// Temporarily not listening for media from the other party
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// \struct QXmppJingleIq::RtpSessionStateUnhold
-///
-/// Ending hold state
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// \struct QXmppJingleIq::RtpSessionStateMuting
-///
-/// State for muting or unmuting
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// \struct QXmppJingleIq::RtpSessionStateRinging
-///
-/// State after the callee acknowledged the call but did not yet interacted with it
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// \typedef QXmppJingleIq::RtpSessionState
-///
-/// Contains the state of an RTP session as specified by \xep{0167, Jingle RTP Sessions}
-/// Informational Messages.
-///
-/// \since QXmpp 1.5
-///
-
-/// Constructs an empty content.
-QXmppJingleIq::Content::Content()
- : d(new QXmppJingleIqContentPrivate())
-{
-}
-
-/// Copy-constructor.
-QXmppJingleIq::Content::Content(const QXmppJingleIq::Content &other) = default;
-/// Move-constructor.
-QXmppJingleIq::Content::Content(QXmppJingleIq::Content &&) = default;
-/// Assignment operator.
-QXmppJingleIq::Content &QXmppJingleIq::Content::operator=(const QXmppJingleIq::Content &) = default;
-/// Move-assignment operator.
-QXmppJingleIq::Content &QXmppJingleIq::Content::operator=(QXmppJingleIq::Content &&) = default;
-
-QXmppJingleIq::Content::~Content() = default;
-
-QString QXmppJingleIq::Content::creator() const
-{
- return d->creator;
-}
-
-void QXmppJingleIq::Content::setCreator(const QString &creator)
-{
- d->creator = creator;
-}
-
-QString QXmppJingleIq::Content::name() const
-{
- return d->name;
-}
-
-void QXmppJingleIq::Content::setName(const QString &name)
-{
- d->name = name;
-}
-
-QString QXmppJingleIq::Content::senders() const
-{
- return d->senders;
-}
-
-void QXmppJingleIq::Content::setSenders(const QString &senders)
-{
- d->senders = senders;
-}
-
-///
-/// Returns the description as specified by
-/// \xep{0167, Jingle RTP Sessions} and RFC 3550.
-///
-/// \since QXmpp 0.9
-///
-QXmppJingleDescription QXmppJingleIq::Content::description() const
-{
- return d->description;
-}
-
-void QXmppJingleIq::Content::setDescription(const QXmppJingleDescription &description)
-{
- d->description = description;
-}
-
-///
-/// Returns whether multiplexing of RTP data and control packets on a single port is supported as
-/// specified by \xep{0167, Jingle RTP Sessions} and RFC 5761.
-///
-/// \return whether multiplexing of RTP data and control packets is supported
-///
-/// \since QXmpp 1.5
-///
-bool QXmppJingleIq::Content::isRtpMultiplexingSupported() const
-{
- return d->isRtpMultiplexingSupported;
-}
-
-///
-/// Sets whether multiplexing of RTP data and control packets on a single port is supported as
-/// specified by \xep{0167, Jingle RTP Sessions} and RFC 5761.
-///
-/// \param isRtpMultiplexingSupported whether multiplexing of RTP data and control packets is
-/// supported
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::Content::setRtpMultiplexingSupported(bool isRtpMultiplexingSupported)
-{
- d->isRtpMultiplexingSupported = isRtpMultiplexingSupported;
-}
-
-///
-/// Returns the encryption used for SRTP negotiation as specified by
-/// \xep{0167, Jingle RTP Sessions}.
-///
-/// \return the RTP encryption via SRTP
-///
-/// \since QXmpp 1.5
-///
-std::optional<QXmppJingleRtpEncryption> QXmppJingleIq::Content::rtpEncryption() const
-{
- return d->rtpEncryption;
-}
-
-///
-/// Sets the encryption used for SRTP negotiation as specified by \xep{0167, Jingle RTP Sessions}.
-///
-/// \param rtpEncryption RTP encryption via SRTP
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::Content::setRtpEncryption(const std::optional<QXmppJingleRtpEncryption> &rtpEncryption)
-{
- d->rtpEncryption = rtpEncryption;
-}
-
-void QXmppJingleIq::Content::addTransportCandidate(const QXmppJingleCandidate &candidate)
-{
- d->transportType = ns_jingle_ice_udp;
- d->transportCandidates << candidate;
-}
-
-QList<QXmppJingleCandidate> QXmppJingleIq::Content::transportCandidates() const
-{
- return d->transportCandidates;
-}
-
-///
-/// Sets a list of transport candidates.
-///
-/// \since QXmpp 0.9.2
-///
-void QXmppJingleIq::Content::setTransportCandidates(const QList<QXmppJingleCandidate> &candidates)
-{
- d->transportType = candidates.isEmpty() ? QString() : ns_jingle_ice_udp;
- d->transportCandidates = candidates;
-}
-
-QString QXmppJingleIq::Content::transportUser() const
-{
- return d->transportUser;
-}
-
-void QXmppJingleIq::Content::setTransportUser(const QString &user)
-{
- d->transportUser = user;
-}
-
-QString QXmppJingleIq::Content::transportPassword() const
-{
- return d->transportPassword;
-}
-
-void QXmppJingleIq::Content::setTransportPassword(const QString &password)
-{
- d->transportPassword = password;
-}
-
-///
-/// Returns the properties of RTP feedback.
-///
-/// \return the RTP feedback properties
-///
-/// \since QXmpp 1.5
-///
-QVector<QXmppJingleRtpFeedbackProperty> QXmppJingleIq::Content::rtpFeedbackProperties() const
-{
- return d->rtpFeedbackProperties;
-}
-
-///
-/// Sets the properties of RTP feedback.
-///
-/// \param rtpFeedbackProperties RTP feedback properties
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::Content::setRtpFeedbackProperties(const QVector<QXmppJingleRtpFeedbackProperty> &rtpFeedbackProperties)
-{
- d->rtpFeedbackProperties = rtpFeedbackProperties;
-}
-
-///
-/// Returns the intervals of RTP feedback.
-///
-/// \return the RTP feedback intervals
-///
-/// \since QXmpp 1.5
-///
-QVector<QXmppJingleRtpFeedbackInterval> QXmppJingleIq::Content::rtpFeedbackIntervals() const
-{
- return d->rtpFeedbackIntervals;
-}
-
-///
-/// Sets the intervals of RTP feedback.
-///
-/// \param rtpFeedbackIntervals RTP feedback intervals
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::Content::setRtpFeedbackIntervals(const QVector<QXmppJingleRtpFeedbackInterval> &rtpFeedbackIntervals)
-{
- d->rtpFeedbackIntervals = rtpFeedbackIntervals;
-}
-
-///
-/// Returns the RTP header extension properties.
-///
-/// \return the RTP header extension properties
-///
-/// \since QXmpp 1.5
-///
-QVector<QXmppJingleRtpHeaderExtensionProperty> QXmppJingleIq::Content::rtpHeaderExtensionProperties() const
-{
- return d->rtpHeaderExtensionProperties;
-}
-
-///
-/// Sets the RTP header extension properties.
-///
-/// \param rtpHeaderExtensionProperties RTP header extension properties
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::Content::setRtpHeaderExtensionProperties(const QVector<QXmppJingleRtpHeaderExtensionProperty> &rtpHeaderExtensionProperties)
-{
- d->rtpHeaderExtensionProperties = rtpHeaderExtensionProperties;
-}
-
-///
-/// Returns whether mixing of RTP header extensions is allowed corresponding to the
-/// "extmap-allow-mixed" element as specified by
-/// \xep{0293, Jingle RTP Header Extensions Negotiation}.
-///
-/// \return whether mixing of RTP header extensions is allowed
-///
-/// \since QXmpp 1.5
-///
-bool QXmppJingleIq::Content::isRtpHeaderExtensionMixingAllowed() const
-{
- return d->isRtpHeaderExtensionMixingAllowed;
-}
-
-///
-/// Sets whether mixing of RTP header extensions is allowed corresponding to the
-/// "extmap-allow-mixed" element as specified by
-/// \xep{0293, Jingle RTP Header Extensions Negotiation}.
-///
-/// \param isAllowed whether mixing of RTP header extensions is allowed
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::Content::setRtpHeaderExtensionMixingAllowed(bool isRtpHeaderExtensionMixingAllowed)
-{
- d->isRtpHeaderExtensionMixingAllowed = isRtpHeaderExtensionMixingAllowed;
-}
-
-///
-/// Returns the fingerprint hash value for the transport key.
-///
-/// This is used for DTLS-SRTP as defined in \xep{0320}.
-///
-/// \since QXmpp 0.9
-///
-QByteArray QXmppJingleIq::Content::transportFingerprint() const
-{
- return d->transportFingerprint;
-}
-
-///
-/// Sets the fingerprint hash value for the transport key.
-///
-/// This is used for DTLS-SRTP as defined in \xep{0320}.
-///
-/// \since QXmpp 0.9
-///
-void QXmppJingleIq::Content::setTransportFingerprint(const QByteArray &fingerprint)
-{
- d->transportFingerprint = fingerprint;
-}
-
-///
-/// Returns the fingerprint hash algorithm for the transport key.
-///
-/// This is used for DTLS-SRTP as defined in \xep{0320}.
-///
-/// \since QXmpp 0.9
-///
-QString QXmppJingleIq::Content::transportFingerprintHash() const
-{
- return d->transportFingerprintHash;
-}
-
-///
-/// Sets the fingerprint hash algorithm for the transport key.
-///
-/// This is used for DTLS-SRTP as defined in \xep{0320}.
-///
-/// \since QXmpp 0.9
-///
-void QXmppJingleIq::Content::setTransportFingerprintHash(const QString &hash)
-{
- d->transportFingerprintHash = hash;
-}
-
-///
-/// Returns the setup role for the encrypted transport.
-///
-/// This is used for DTLS-SRTP as defined in \xep{0320}.
-///
-/// \since QXmpp 0.9
-///
-QString QXmppJingleIq::Content::transportFingerprintSetup() const
-{
- return d->transportFingerprintSetup;
-}
-
-///
-/// Sets the setup role for the encrypted transport.
-///
-/// This is used for DTLS-SRTP as defined in \xep{0320}.
-///
-/// \since QXmpp 0.9
-///
-void QXmppJingleIq::Content::setTransportFingerprintSetup(const QString &setup)
-{
- d->transportFingerprintSetup = setup;
-}
-
-/// \cond
-void QXmppJingleIq::Content::parse(const QDomElement &element)
-{
- d->creator = element.attribute(QStringLiteral("creator"));
- d->disposition = element.attribute(QStringLiteral("disposition"));
- d->name = element.attribute(QStringLiteral("name"));
- d->senders = element.attribute(QStringLiteral("senders"));
-
- // description
- QDomElement descriptionElement = element.firstChildElement(QStringLiteral("description"));
- d->description.setType(descriptionElement.namespaceURI());
- d->description.setMedia(descriptionElement.attribute(QStringLiteral("media")));
- d->description.setSsrc(descriptionElement.attribute(QStringLiteral("ssrc")).toULong());
- d->isRtpMultiplexingSupported = !descriptionElement.firstChildElement(QStringLiteral("rtcp-mux")).isNull();
-
- for (auto childElement = descriptionElement.firstChildElement();
- !childElement.isNull();
- childElement = childElement.nextSiblingElement()) {
- if (QXmppJingleRtpEncryption::isJingleRtpEncryption(childElement)) {
- QXmppJingleRtpEncryption encryption;
- encryption.parse(childElement);
- d->rtpEncryption = encryption;
- break;
- }
- }
-
- parseJingleRtpFeedbackNegotiationElements(descriptionElement, d->rtpFeedbackProperties, d->rtpFeedbackIntervals);
- parseJingleRtpHeaderExtensionsNegotiationElements(descriptionElement, d->rtpHeaderExtensionProperties, d->isRtpHeaderExtensionMixingAllowed);
-
- QDomElement child = descriptionElement.firstChildElement(QStringLiteral("payload-type"));
- while (!child.isNull()) {
- QXmppJinglePayloadType payload;
- payload.parse(child);
- d->description.addPayloadType(payload);
- child = child.nextSiblingElement(QStringLiteral("payload-type"));
- }
-
- // transport
- QDomElement transportElement = element.firstChildElement(QStringLiteral("transport"));
- d->transportType = transportElement.namespaceURI();
- d->transportUser = transportElement.attribute(QStringLiteral("ufrag"));
- d->transportPassword = transportElement.attribute(QStringLiteral("pwd"));
- child = transportElement.firstChildElement(QStringLiteral("candidate"));
- while (!child.isNull()) {
- QXmppJingleCandidate candidate;
- candidate.parse(child);
- d->transportCandidates << candidate;
- child = child.nextSiblingElement(QStringLiteral("candidate"));
- }
-
- /// XEP-0320
- child = transportElement.firstChildElement(QStringLiteral("fingerprint"));
- if (!child.isNull()) {
- d->transportFingerprint = parseFingerprint(child.text());
- d->transportFingerprintHash = child.attribute(QStringLiteral("hash"));
- d->transportFingerprintSetup = child.attribute(QStringLiteral("setup"));
- }
-}
-
-void QXmppJingleIq::Content::toXml(QXmlStreamWriter *writer) const
-{
- if (d->creator.isEmpty() || d->name.isEmpty()) {
- return;
- }
-
- writer->writeStartElement(QStringLiteral("content"));
- helperToXmlAddAttribute(writer, QStringLiteral("creator"), d->creator);
- helperToXmlAddAttribute(writer, QStringLiteral("disposition"), d->disposition);
- helperToXmlAddAttribute(writer, QStringLiteral("name"), d->name);
- helperToXmlAddAttribute(writer, QStringLiteral("senders"), d->senders);
-
- // description
- if (!d->description.type().isEmpty() || !d->description.payloadTypes().isEmpty()) {
- writer->writeStartElement(QStringLiteral("description"));
- writer->writeDefaultNamespace(d->description.type());
- helperToXmlAddAttribute(writer, QStringLiteral("media"), d->description.media());
-
- if (d->description.ssrc()) {
- writer->writeAttribute(QStringLiteral("ssrc"), QString::number(d->description.ssrc()));
- }
-
- if (d->isRtpMultiplexingSupported) {
- writer->writeEmptyElement(QStringLiteral("rtcp-mux"));
- }
-
- if (d->rtpEncryption) {
- d->rtpEncryption->toXml(writer);
- }
-
- jingleRtpFeedbackNegotiationElementsToXml(writer, d->rtpFeedbackProperties, d->rtpFeedbackIntervals);
- jingleRtpHeaderExtensionsNegotiationElementsToXml(writer, d->rtpHeaderExtensionProperties, d->isRtpHeaderExtensionMixingAllowed);
-
- for (const auto &payload : d->description.payloadTypes()) {
- payload.toXml(writer);
- }
-
- writer->writeEndElement();
- }
-
- // transport
- if (!d->transportType.isEmpty() || !d->transportCandidates.isEmpty()) {
- writer->writeStartElement(QStringLiteral("transport"));
- writer->writeDefaultNamespace(d->transportType);
- helperToXmlAddAttribute(writer, QStringLiteral("ufrag"), d->transportUser);
- helperToXmlAddAttribute(writer, QStringLiteral("pwd"), d->transportPassword);
- for (const auto &candidate : d->transportCandidates) {
- candidate.toXml(writer);
- }
-
- // XEP-0320: Use of DTLS-SRTP in Jingle Sessions
- if (!d->transportFingerprint.isEmpty() && !d->transportFingerprintHash.isEmpty()) {
- writer->writeStartElement(QStringLiteral("fingerprint"));
- writer->writeDefaultNamespace(ns_jingle_dtls);
- writer->writeAttribute(QStringLiteral("hash"), d->transportFingerprintHash);
- writer->writeAttribute(QStringLiteral("setup"), d->transportFingerprintSetup);
- writer->writeCharacters(formatFingerprint(d->transportFingerprint));
- writer->writeEndElement();
- }
- writer->writeEndElement();
- }
-
- writer->writeEndElement();
-}
-
-bool QXmppJingleIq::Content::parseSdp(const QString &sdp)
-{
- QList<QXmppJinglePayloadType> payloads;
- for (auto &line : sdp.split(QChar(u'\n'))) {
- if (line.endsWith('\r')) {
- line.resize(line.size() - 1);
- }
- if (line.startsWith(QStringLiteral("a="))) {
- int idx = line.indexOf(':');
- const QString attrName = idx != -1 ? line.mid(2, idx - 2) : line.mid(2);
- const QString attrValue = idx != -1 ? line.mid(idx + 1) : "";
-
- if (attrName == QStringLiteral("candidate")) {
- QXmppJingleCandidate candidate;
- if (!candidateParseSdp(&candidate, line.mid(2))) {
- qWarning() << "Could not parse candidate" << line;
- return false;
- }
- addTransportCandidate(candidate);
- } else if (attrName == QStringLiteral("fingerprint")) {
- const QStringList bits = attrValue.split(' ');
- if (bits.size() > 1) {
- d->transportFingerprintHash = bits[0];
- d->transportFingerprint = parseFingerprint(bits[1]);
- }
- } else if (attrName == QStringLiteral("fmtp")) {
- int spIdx = attrValue.indexOf(' ');
- if (spIdx == -1) {
- qWarning() << "Could not parse payload parameters" << line;
- return false;
- }
- const int id = attrValue.left(spIdx).toInt();
- const QString paramStr = attrValue.mid(spIdx + 1);
- for (auto &payload : payloads) {
- if (payload.id() == id) {
- QMap<QString, QString> params;
- if (payload.name() == QStringLiteral("telephone-event")) {
- params.insert(QStringLiteral("events"), paramStr);
- } else {
- thread_local static const auto regex = QRegularExpression(";\\s*");
- const auto paramParts = paramStr.split(regex);
- for (const auto &p : paramParts) {
- const QStringList bits = p.split('=');
- if (bits.size() == 2) {
- params.insert(bits.at(0), bits.at(1));
- }
- }
- }
- payload.setParameters(params);
- }
- }
- } else if (attrName == QStringLiteral("rtpmap")) {
- // payload type map
- const QStringList bits = attrValue.split(' ');
- if (bits.size() != 2) {
- continue;
- }
- bool ok = false;
- const int id = bits[0].toInt(&ok);
- if (!ok) {
- continue;
- }
-
- const QStringList args = bits[1].split('/');
- for (auto &payload : payloads) {
- if (payload.id() == id) {
- payload.setName(args[0]);
- if (args.size() > 1) {
- payload.setClockrate(args[1].toInt());
- }
- if (args.size() > 2) {
- payload.setChannels(args[2].toInt());
- }
- }
- }
- } else if (attrName == QStringLiteral("ice-ufrag")) {
- d->transportUser = attrValue;
- } else if (attrName == QStringLiteral("ice-pwd")) {
- d->transportPassword = attrValue;
- } else if (attrName == QStringLiteral("setup")) {
- d->transportFingerprintSetup = attrValue;
- } else if (attrName == QStringLiteral("ssrc")) {
- const QStringList bits = attrValue.split(' ');
- if (bits.isEmpty()) {
- qWarning() << "Could not parse ssrc" << line;
- return false;
- }
- d->description.setSsrc(bits[0].toULong());
- }
- } else if (line.startsWith(QStringLiteral("m="))) {
- // FIXME: what do we do with the profile (bits[2]) ?
- QStringList bits = line.mid(2).split(' ');
- if (bits.size() < 3) {
- qWarning() << "Could not parse media" << line;
- return false;
- }
- d->description.setMedia(bits[0]);
-
- // parse payload types
- for (int i = 3; i < bits.size(); ++i) {
- bool ok = false;
- int id = bits[i].toInt(&ok);
- if (!ok) {
- continue;
- }
- QXmppJinglePayloadType payload;
- payload.setId(id);
- payloads << payload;
- }
- }
- }
-
- d->description.setPayloadTypes(payloads);
- return true;
-}
-
-static bool candidateLessThan(const QXmppJingleCandidate &c1, const QXmppJingleCandidate &c2)
-{
- if (c1.type() == c2.type()) {
- return c1.priority() > c2.priority();
- } else {
- return c1.type() == QXmppJingleCandidate::ServerReflexiveType;
- }
-}
-
-QString QXmppJingleIq::Content::toSdp() const
-{
- // get default candidate
- QHostAddress localRtpAddress = QHostAddress::Any;
- quint16 localRtpPort = 0;
- QList<QXmppJingleCandidate> sortedCandidates = d->transportCandidates;
- std::sort(sortedCandidates.begin(), sortedCandidates.end(), candidateLessThan);
- for (const auto &candidate : sortedCandidates) {
- if (candidate.component() == RTP_COMPONENT) {
- localRtpAddress = candidate.host();
- localRtpPort = candidate.port();
- break;
- }
- }
-
- QStringList sdp;
-
- // media
- QString payloads;
- QStringList attrs;
- for (const QXmppJinglePayloadType &payload : d->description.payloadTypes()) {
- payloads += " " + QString::number(payload.id());
- QString rtpmap = QString::number(payload.id()) + " " + payload.name() + "/" + QString::number(payload.clockrate());
- if (payload.channels() > 1) {
- rtpmap += "/" + QString::number(payload.channels());
- }
- attrs << "a=rtpmap:" + rtpmap;
-
- // payload parameters
- QStringList paramList;
- const QMap<QString, QString> params = payload.parameters();
- if (payload.name() == QStringLiteral("telephone-event")) {
- if (params.contains(QStringLiteral("events"))) {
- paramList << params.value(QStringLiteral("events"));
- }
- } else {
- QMap<QString, QString>::const_iterator i;
- for (i = params.begin(); i != params.end(); ++i) {
- paramList << i.key() + QStringLiteral("=") + i.value();
- }
- }
- if (!paramList.isEmpty()) {
- attrs << QStringLiteral("a=fmtp:") + QByteArray::number(payload.id()) + QStringLiteral(" ") + paramList.join("; ");
- }
- }
- sdp << QStringLiteral("m=%1 %2 RTP/AVP%3").arg(d->description.media(), QString::number(localRtpPort), payloads);
- sdp << QStringLiteral("c=%1").arg(addressToSdp(localRtpAddress));
- sdp += attrs;
-
- // transport
- for (const auto &candidate : d->transportCandidates) {
- sdp << QStringLiteral("a=%1").arg(candidateToSdp(candidate));
- }
- if (!d->transportUser.isEmpty()) {
- sdp << QStringLiteral("a=ice-ufrag:%1").arg(d->transportUser);
- }
- if (!d->transportPassword.isEmpty()) {
- sdp << QStringLiteral("a=ice-pwd:%1").arg(d->transportPassword);
- }
- if (!d->transportFingerprint.isEmpty() && !d->transportFingerprintHash.isEmpty()) {
- sdp << QStringLiteral("a=fingerprint:%1 %2").arg(d->transportFingerprintHash, formatFingerprint(d->transportFingerprint));
- }
- if (!d->transportFingerprintSetup.isEmpty()) {
- sdp << QStringLiteral("a=setup:%1").arg(d->transportFingerprintSetup);
- }
-
- return sdp.join("\r\n") + "\r\n";
-}
-
-/// \endcond
-
-class QXmppJingleIqReasonPrivate : public QSharedData
-{
-public:
- QXmppJingleIqReasonPrivate();
-
- QString m_text;
- QXmppJingleReason::Type m_type;
- QXmppJingleReason::RtpErrorCondition m_rtpErrorCondition;
- QString m_namespaceUri;
-};
-
-QXmppJingleIqReasonPrivate::QXmppJingleIqReasonPrivate()
- : m_type(QXmppJingleReason::Type::None),
- m_rtpErrorCondition(QXmppJingleReason::RtpErrorCondition::NoErrorCondition)
-{
-}
-
-///
-/// \enum QXmppJingleIqReason::RtpErrorCondition
-///
-/// Condition of an RTP-specific error
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// \class QXmppJingleReason
-///
-/// The QXmppJingleReason class represents the "reason" element of a
-/// QXmppJingle element.
-///
-
-QXmppJingleReason::QXmppJingleReason()
- : d(new QXmppJingleIqReasonPrivate())
-{
-}
-
-/// Returns the reason's textual description.
-
-QString QXmppJingleReason::text() const
-{
- return d->m_text;
-}
-
-/// Sets the reason's textual description.
-
-void QXmppJingleReason::setText(const QString &text)
-{
- d->m_text = text;
-}
-
-/// Gets the reason's type.
-
-QXmppJingleReason::Type QXmppJingleReason::type() const
-{
- return d->m_type;
-}
-
-/// Sets the reason's type.
-
-void QXmppJingleReason::setType(QXmppJingleReason::Type type)
-{
- d->m_type = type;
-}
-
-///
-/// Returns the RTP error condition as specified by \xep{0167, Jingle RTP Sessions}.
-///
-/// \return the RTP error condition
-///
-/// \since QXmpp 1.5
-///
-QXmppJingleReason::RtpErrorCondition QXmppJingleReason::rtpErrorCondition() const
-{
- return d->m_rtpErrorCondition;
-}
-
-///
-/// Sets the RTP error condition as specified by \xep{0167, Jingle RTP Sessions}.
-///
-/// \param rtpErrorCondition RTP error condition
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleReason::setRtpErrorCondition(RtpErrorCondition rtpErrorCondition)
-{
- d->m_rtpErrorCondition = rtpErrorCondition;
-}
-
-///
-/// Returns the namespace URI of a reason element.
-///
-QString QXmppJingleReason::namespaceUri() const
-{
- return d->m_namespaceUri;
-}
-
-///
-/// Sets the namespace URI of a reason element.
-///
-void QXmppJingleReason::setNamespaceUri(const QString &namespaceUri)
-{
- d->m_namespaceUri = namespaceUri;
-}
-
-/// \cond
-void QXmppJingleReason::parse(const QDomElement &element)
-{
- d->m_text = element.firstChildElement(QStringLiteral("text")).text();
- for (int i = AlternativeSession; i <= UnsupportedTransports; i++) {
- if (!element.firstChildElement(jingle_reasons[i]).isNull()) {
- d->m_type = static_cast<Type>(i);
- break;
- }
- }
-
- for (auto child = element.firstChildElement();
- !child.isNull();
- child = child.nextSiblingElement()) {
- if (child.namespaceURI() == ns_jingle_rtp_errors) {
- if (const auto index = JINGLE_RTP_ERROR_CONDITIONS.indexOf(child.tagName());
- index != -1) {
- d->m_rtpErrorCondition = RtpErrorCondition(index);
- }
- break;
- }
- }
-
- if (!element.namespaceURI().isEmpty() && !element.parentNode().isNull() && element.parentNode().namespaceURI() != element.namespaceURI()) {
- d->m_namespaceUri = element.namespaceURI();
- }
-}
-
-void QXmppJingleReason::toXml(QXmlStreamWriter *writer) const
-{
- if (d->m_type < AlternativeSession || d->m_type > UnsupportedTransports) {
- return;
- }
-
- writer->writeStartElement(QStringLiteral("reason"));
-
- if (!d->m_namespaceUri.isEmpty()) {
- writer->writeDefaultNamespace(d->m_namespaceUri);
- }
-
- if (!d->m_text.isEmpty()) {
- helperToXmlAddTextElement(writer, QStringLiteral("text"), d->m_text);
- }
- writer->writeEmptyElement(jingle_reasons[d->m_type]);
-
- if (d->m_rtpErrorCondition != NoErrorCondition) {
- writer->writeStartElement(JINGLE_RTP_ERROR_CONDITIONS.at(d->m_rtpErrorCondition));
- writer->writeDefaultNamespace(ns_jingle_rtp_errors);
- writer->writeEndElement();
- }
-
- writer->writeEndElement();
-}
-/// \endcond
-
-class QXmppJingleIqPrivate : public QSharedData
-{
-public:
- QXmppJingleIqPrivate();
-
- QXmppJingleIq::Action action;
- QString initiator;
- QString responder;
- QString sid;
-
- QString mujiGroupChatJid;
-
- QList<QXmppJingleIq::Content> contents;
- QXmppJingleReason reason;
-
- std::optional<QXmppJingleIq::RtpSessionState> rtpSessionState;
-};
-
-QXmppJingleIqPrivate::QXmppJingleIqPrivate()
- : action(QXmppJingleIq::ContentAccept)
-{
-}
-
-/// Constructs a QXmppJingleIq.
-QXmppJingleIq::QXmppJingleIq()
- : d(new QXmppJingleIqPrivate())
-{
-}
-
-/// Copy-constructor.
-QXmppJingleIq::QXmppJingleIq(const QXmppJingleIq &) = default;
-/// Move-constructor.
-QXmppJingleIq::QXmppJingleIq(QXmppJingleIq &&) = default;
-
-QXmppJingleIq::~QXmppJingleIq() = default;
-
-/// Assignment operator.
-QXmppJingleIq &QXmppJingleIq::operator=(const QXmppJingleIq &) = default;
-/// Move-assignment operator.
-QXmppJingleIq &QXmppJingleIq::operator=(QXmppJingleIq &&) = default;
-
-///
-/// Returns the Jingle IQ's action.
-///
-QXmppJingleIq::Action QXmppJingleIq::action() const
-{
- return d->action;
-}
-
-/// Sets the Jingle IQ's action.
-///
-/// \param action
-
-void QXmppJingleIq::setAction(QXmppJingleIq::Action action)
-{
- d->action = action;
-}
-
-///
-/// Adds an element to the IQ's content elements.
-///
-/// \since QXmpp 0.9.2
-///
-void QXmppJingleIq::addContent(const QXmppJingleIq::Content &content)
-{
- d->contents << content;
-}
-
-///
-/// Returns the IQ's content elements.
-///
-/// \since QXmpp 0.9.2
-///
-QList<QXmppJingleIq::Content> QXmppJingleIq::contents() const
-{
- return d->contents;
-}
-
-///
-/// Sets the IQ's content elements.
-///
-/// \since QXmpp 0.9.2
-///
-void QXmppJingleIq::setContents(const QList<QXmppJingleIq::Content> &contents)
-{
- d->contents = contents;
-}
-
-/// Returns the session initiator.
-
-QString QXmppJingleIq::initiator() const
-{
- return d->initiator;
-}
-
-/// Sets the session initiator.
-///
-/// \param initiator
-
-void QXmppJingleIq::setInitiator(const QString &initiator)
-{
- d->initiator = initiator;
-}
-
-/// Returns a reference to the IQ's reason element.
-
-QXmppJingleReason &QXmppJingleIq::reason()
-{
- return d->reason;
-}
-
-/// Returns a const reference to the IQ's reason element.
-
-const QXmppJingleReason &QXmppJingleIq::reason() const
-{
- return d->reason;
-}
-
-/// Returns the session responder.
-
-QString QXmppJingleIq::responder() const
-{
- return d->responder;
-}
-
-/// Sets the session responder.
-///
-/// \param responder
-
-void QXmppJingleIq::setResponder(const QString &responder)
-{
- d->responder = responder;
-}
-
-///
-/// Returns true if the call is ringing.
-///
-/// \deprecated This method is deprecated since QXmpp 1.5. Use \c QXmppJingleIq::rtpSessionState()
-/// instead.
-///
-bool QXmppJingleIq::ringing() const
-{
- if (d->rtpSessionState) {
- return std::holds_alternative<RtpSessionStateRinging>(*d->rtpSessionState);
- }
-
- return false;
-}
-
-///
-/// Set to true if the call is ringing.
-///
-/// \param ringing
-///
-/// \deprecated This method is deprecated since QXmpp 1.5. Use
-/// \c QXmppJingleIq::setRtpSessionState() instead.
-///
-void QXmppJingleIq::setRinging(bool ringing)
-{
- if (ringing) {
- d->rtpSessionState = RtpSessionStateRinging();
- } else {
- d->rtpSessionState = std::nullopt;
- }
-}
-
-/// Returns the session ID.
-QString QXmppJingleIq::sid() const
-{
- return d->sid;
-}
-
-/// Sets the session ID.
-///
-/// \param sid
-
-void QXmppJingleIq::setSid(const QString &sid)
-{
- d->sid = sid;
-}
-
-///
-/// Returns the JID of the \xep{0272, Multiparty Jingle (Muji)} group chat.
-///
-/// \return the Muji group chat JID
-///
-/// \since QXmpp 1.5
-///
-QString QXmppJingleIq::mujiGroupChatJid() const
-{
- return d->mujiGroupChatJid;
-}
-
-///
-/// Sets the JID of the \xep{0272, Multiparty Jingle (Muji)} group chat.
-///
-/// \param mujiGroupChatJid Muji group chat JID
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::setMujiGroupChatJid(const QString &mujiGroupChatJid)
-{
- d->mujiGroupChatJid = mujiGroupChatJid;
-}
-
-///
-/// Returns the state of an RTP session as specified by \xep{0167, Jingle RTP Sessions}
-/// Informational Messages.
-///
-/// \return the session's state
-///
-/// \since QXmpp 1.5
-///
-std::optional<QXmppJingleIq::RtpSessionState> QXmppJingleIq::rtpSessionState() const
-{
- return d->rtpSessionState;
-}
-
-///
-/// Sets the state of an RTP session as specified by \xep{0167, Jingle RTP Sessions} Informational
-/// Messages.
-///
-/// The appropriate action is set as well.
-/// Thus, it is not needed to set it manually.
-///
-/// \param rtpSessionState session's state
-///
-/// \since QXmpp 1.5
-///
-void QXmppJingleIq::setRtpSessionState(const std::optional<RtpSessionState> &rtpSessionState)
-{
- d->rtpSessionState = rtpSessionState;
- d->action = Action::SessionInfo;
-}
-
-/// \cond
-bool QXmppJingleIq::isJingleIq(const QDomElement &element)
-{
- QDomElement jingleElement = element.firstChildElement(QStringLiteral("jingle"));
- return (jingleElement.namespaceURI() == ns_jingle);
-}
-
-void QXmppJingleIq::parseElementFromChild(const QDomElement &element)
-{
- QDomElement jingleElement = element.firstChildElement(QStringLiteral("jingle"));
- const QString action = jingleElement.attribute(QStringLiteral("action"));
- for (int i = ContentAccept; i <= TransportReplace; i++) {
- if (action == jingle_actions[i]) {
- d->action = static_cast<Action>(i);
- break;
- }
- }
- d->initiator = jingleElement.attribute(QStringLiteral("initiator"));
- d->responder = jingleElement.attribute(QStringLiteral("responder"));
- d->sid = jingleElement.attribute(QStringLiteral("sid"));
-
- // XEP-0272: Multiparty Jingle (Muji)
- if (const auto mujiGroupChatElement = jingleElement.firstChildElement(QStringLiteral("muji"));
- mujiGroupChatElement.namespaceURI() == ns_muji) {
- d->mujiGroupChatJid = mujiGroupChatElement.attribute(QStringLiteral("room"));
- }
-
- // content
- d->contents.clear();
- QDomElement contentElement = jingleElement.firstChildElement(QStringLiteral("content"));
- while (!contentElement.isNull()) {
- Content content;
- content.parse(contentElement);
- addContent(content);
- contentElement = contentElement.nextSiblingElement(QStringLiteral("content"));
- }
-
- QDomElement reasonElement = jingleElement.firstChildElement(QStringLiteral("reason"));
- d->reason.parse(reasonElement);
-
- for (auto childElement = jingleElement.firstChildElement();
- !childElement.isNull();
- childElement = childElement.nextSiblingElement()) {
- if (childElement.namespaceURI() == ns_jingle_rtp_info) {
- const auto elementTag = childElement.tagName();
-
- if (elementTag == QStringLiteral("active")) {
- d->rtpSessionState = RtpSessionStateActive();
- } else if (elementTag == QStringLiteral("hold")) {
- d->rtpSessionState = RtpSessionStateHold();
- } else if (elementTag == QStringLiteral("unhold")) {
- d->rtpSessionState = RtpSessionStateUnhold();
- } else if (const auto isMute = elementTag == QStringLiteral("mute"); isMute || elementTag == QStringLiteral("unmute")) {
- RtpSessionStateMuting muting;
- muting.isMute = isMute;
-
- if (const auto creator = childElement.attribute(QStringLiteral("creator")); creator == QStringLiteral("initiator")) {
- muting.creator = Initiator;
- } else if (creator == QStringLiteral("responder")) {
- muting.creator = Responder;
- }
-
- muting.name = childElement.attribute(QStringLiteral("name"));
-
- d->rtpSessionState = muting;
- } else if (elementTag == QStringLiteral("ringing")) {
- d->rtpSessionState = RtpSessionStateRinging();
- }
- }
- }
-}
-
-void QXmppJingleIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("jingle"));
- writer->writeDefaultNamespace(ns_jingle);
- helperToXmlAddAttribute(writer, QStringLiteral("action"), jingle_actions[d->action]);
- helperToXmlAddAttribute(writer, QStringLiteral("initiator"), d->initiator);
- helperToXmlAddAttribute(writer, QStringLiteral("responder"), d->responder);
- helperToXmlAddAttribute(writer, QStringLiteral("sid"), d->sid);
-
- // XEP-0272: Multiparty Jingle (Muji)
- if (!d->mujiGroupChatJid.isEmpty()) {
- writer->writeStartElement(QStringLiteral("muji"));
- writer->writeDefaultNamespace(ns_muji);
- helperToXmlAddAttribute(writer, QStringLiteral("room"), d->mujiGroupChatJid);
- writer->writeEndElement();
- }
-
- for (const auto &content : d->contents) {
- content.toXml(writer);
- }
-
- d->reason.toXml(writer);
-
- const auto writeStartElementWithNamespace = [=](const QString &tagName) {
- writer->writeStartElement(tagName);
- writer->writeDefaultNamespace(ns_jingle_rtp_info);
- };
-
- if (d->rtpSessionState) {
- if (std::holds_alternative<RtpSessionStateActive>(*d->rtpSessionState)) {
- writeStartElementWithNamespace(QStringLiteral("active"));
- } else if (std::holds_alternative<RtpSessionStateHold>(*d->rtpSessionState)) {
- writeStartElementWithNamespace(QStringLiteral("hold"));
- } else if (std::holds_alternative<RtpSessionStateUnhold>(*d->rtpSessionState)) {
- writeStartElementWithNamespace(QStringLiteral("unhold"));
- } else if (auto rtpSessionStateMuting = std::get_if<RtpSessionStateMuting>(&(*d->rtpSessionState))) {
- if (rtpSessionStateMuting->isMute) {
- writeStartElementWithNamespace(QStringLiteral("mute"));
- } else {
- writeStartElementWithNamespace(QStringLiteral("unmute"));
- }
-
- if (rtpSessionStateMuting->creator == Initiator) {
- helperToXmlAddAttribute(writer, QStringLiteral("creator"), QStringLiteral("initiator"));
- } else if (rtpSessionStateMuting->creator == Responder) {
- helperToXmlAddAttribute(writer, QStringLiteral("creator"), QStringLiteral("responder"));
- }
-
- helperToXmlAddAttribute(writer, QStringLiteral("name"), rtpSessionStateMuting->name);
- } else {
- writeStartElementWithNamespace(QStringLiteral("ringing"));
- }
-
- writer->writeEndElement();
- }
-
- writer->writeEndElement();
-}
-/// \endcond
-
-class QXmppJingleCandidatePrivate : public QSharedData
-{
-public:
- QXmppJingleCandidatePrivate();
-
- int component;
- QString foundation;
- int generation;
- QHostAddress host;
- QString id;
- int network;
- quint16 port;
- QString protocol;
- int priority;
- QXmppJingleCandidate::Type type;
-};
-
-QXmppJingleCandidatePrivate::QXmppJingleCandidatePrivate()
- : component(0), generation(0), network(0), port(0), priority(0), type(QXmppJingleCandidate::HostType)
-{
-}
-
-///
-/// Constructs an empty candidate.
-///
-QXmppJingleCandidate::QXmppJingleCandidate()
- : d(new QXmppJingleCandidatePrivate())
-{
-}
-
-/// Copy-constructor.
-QXmppJingleCandidate::QXmppJingleCandidate(const QXmppJingleCandidate &other) = default;
-/// Move-constructor.
-QXmppJingleCandidate::QXmppJingleCandidate(QXmppJingleCandidate &&) = default;
-QXmppJingleCandidate::~QXmppJingleCandidate() = default;
-/// Assignment operator.
-QXmppJingleCandidate &QXmppJingleCandidate::operator=(const QXmppJingleCandidate &other) = default;
-/// Move-assignment operator.
-QXmppJingleCandidate &QXmppJingleCandidate::operator=(QXmppJingleCandidate &&) = default;
-
-/// Returns the candidate's component ID.
-
-int QXmppJingleCandidate::component() const
-{
- return d->component;
-}
-
-/// Sets the candidates's component ID.
-///
-/// \param component
-
-void QXmppJingleCandidate::setComponent(int component)
-{
- d->component = component;
-}
-
-///
-/// Returns the candidate's foundation.
-///
-/// \since QXmpp 0.9
-///
-QString QXmppJingleCandidate::foundation() const
-{
- return d->foundation;
-}
-
-///
-/// Sets the candidate's foundation.
-///
-/// \param foundation
-///
-/// \since QXmpp 0.9
-///
-void QXmppJingleCandidate::setFoundation(const QString &foundation)
-{
- d->foundation = foundation;
-}
-
-///
-/// Returns the candidate's generation.
-///
-/// \since QXmpp 0.9
-///
-int QXmppJingleCandidate::generation() const
-{
- return d->generation;
-}
-
-///
-/// Sets the candidate's generation.
-///
-/// \param generation
-///
-/// \since QXmpp 0.9
-///
-void QXmppJingleCandidate::setGeneration(int generation)
-{
- d->generation = generation;
-}
-
-/// Returns the candidate's host address.
-///
-
-QHostAddress QXmppJingleCandidate::host() const
-{
- return d->host;
-}
-
-/// Sets the candidate's host address.
-///
-/// \param host
-
-void QXmppJingleCandidate::setHost(const QHostAddress &host)
-{
- d->host = host;
-}
-
-/// Returns the candidate's unique identifier.
-///
-
-QString QXmppJingleCandidate::id() const
-{
- return d->id;
-}
-
-/// Sets the candidate's unique identifier.
-///
-/// \param id
-
-void QXmppJingleCandidate::setId(const QString &id)
-{
- d->id = id;
-}
-
-/// Returns the network index (starting at 0) the candidate is on.
-///
-
-int QXmppJingleCandidate::network() const
-{
- return d->network;
-}
-
-/// Sets the network index (starting at 0) the candidate is on.
-///
-/// \param network
-
-void QXmppJingleCandidate::setNetwork(int network)
-{
- d->network = network;
-}
-
-/// Returns the candidate's port number.
-///
-
-quint16 QXmppJingleCandidate::port() const
-{
- return d->port;
-}
-
-/// Sets the candidate's port number.
-///
-/// \param port
-
-void QXmppJingleCandidate::setPort(quint16 port)
-{
- d->port = port;
-}
-
-/// Returns the candidate's priority.
-///
-
-int QXmppJingleCandidate::priority() const
-{
- return d->priority;
-}
-
-/// Sets the candidate's priority.
-///
-/// \param priority
-
-void QXmppJingleCandidate::setPriority(int priority)
-{
- d->priority = priority;
-}
-
-/// Returns the candidate's protocol (e.g. "udp").
-///
-
-QString QXmppJingleCandidate::protocol() const
-{
- return d->protocol;
-}
-
-/// Sets the candidate's protocol (e.g. "udp").
-///
-/// \param protocol
-
-void QXmppJingleCandidate::setProtocol(const QString &protocol)
-{
- d->protocol = protocol;
-}
-
-/// Returns the candidate type (e.g. "host").
-///
-
-QXmppJingleCandidate::Type QXmppJingleCandidate::type() const
-{
- return d->type;
-}
-
-/// Sets the candidate type (e.g. "host").
-///
-/// \param type
-
-void QXmppJingleCandidate::setType(QXmppJingleCandidate::Type type)
-{
- d->type = type;
-}
-
-/// Returns true if the host address or port are empty.
-///
-
-bool QXmppJingleCandidate::isNull() const
-{
- return d->host.isNull() || !d->port;
-}
-
-/// \cond
-void QXmppJingleCandidate::parse(const QDomElement &element)
-{
- d->component = element.attribute(QStringLiteral("component")).toInt();
- d->foundation = element.attribute(QStringLiteral("foundation"));
- d->generation = element.attribute(QStringLiteral("generation")).toInt();
- d->host = QHostAddress(element.attribute(QStringLiteral("ip")));
- d->id = element.attribute(QStringLiteral("id"));
- d->network = element.attribute(QStringLiteral("network")).toInt();
- d->port = element.attribute(QStringLiteral("port")).toInt();
- d->priority = element.attribute(QStringLiteral("priority")).toInt();
- d->protocol = element.attribute(QStringLiteral("protocol"));
- d->type = typeFromString(element.attribute(QStringLiteral("type")));
-}
-
-void QXmppJingleCandidate::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("candidate"));
- helperToXmlAddAttribute(writer, QStringLiteral("component"), QString::number(d->component));
- helperToXmlAddAttribute(writer, QStringLiteral("foundation"), d->foundation);
- helperToXmlAddAttribute(writer, QStringLiteral("generation"), QString::number(d->generation));
- helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id);
- helperToXmlAddAttribute(writer, QStringLiteral("ip"), d->host.toString());
- helperToXmlAddAttribute(writer, QStringLiteral("network"), QString::number(d->network));
- helperToXmlAddAttribute(writer, QStringLiteral("port"), QString::number(d->port));
- helperToXmlAddAttribute(writer, QStringLiteral("priority"), QString::number(d->priority));
- helperToXmlAddAttribute(writer, QStringLiteral("protocol"), d->protocol);
- helperToXmlAddAttribute(writer, QStringLiteral("type"), typeToString(d->type));
- writer->writeEndElement();
-}
-
-QXmppJingleCandidate::Type QXmppJingleCandidate::typeFromString(const QString &typeStr, bool *ok)
-{
- QXmppJingleCandidate::Type type;
- if (typeStr == QStringLiteral("host")) {
- type = HostType;
- } else if (typeStr == QStringLiteral("prflx")) {
- type = PeerReflexiveType;
- } else if (typeStr == QStringLiteral("srflx")) {
- type = ServerReflexiveType;
- } else if (typeStr == QStringLiteral("relay")) {
- type = RelayedType;
- } else {
- qWarning() << "Unknown candidate type" << typeStr;
- if (ok) {
- *ok = false;
- }
- return HostType;
- }
- if (ok) {
- *ok = true;
- }
- return type;
-}
-
-QString QXmppJingleCandidate::typeToString(QXmppJingleCandidate::Type type)
-{
- QString typeStr;
- switch (type) {
- case HostType:
- typeStr = QStringLiteral("host");
- break;
- case PeerReflexiveType:
- typeStr = QStringLiteral("prflx");
- break;
- case ServerReflexiveType:
- typeStr = QStringLiteral("srflx");
- break;
- case RelayedType:
- typeStr = QStringLiteral("relay");
- break;
- }
- return typeStr;
-}
-/// \endcond
-
-class QXmppJinglePayloadTypePrivate : public QSharedData
-{
-public:
- QXmppJinglePayloadTypePrivate();
-
- unsigned char channels;
- unsigned int clockrate;
- unsigned char id;
- unsigned int maxptime;
- QString name;
- QMap<QString, QString> parameters;
- unsigned int ptime;
-
- // XEP-0293: Jingle RTP Feedback Negotiation
- QVector<QXmppJingleRtpFeedbackProperty> rtpFeedbackProperties;
- QVector<QXmppJingleRtpFeedbackInterval> rtpFeedbackIntervals;
-};
-
-QXmppJinglePayloadTypePrivate::QXmppJinglePayloadTypePrivate()
- : channels(1), clockrate(0), id(0), maxptime(0), ptime(0)
-{
-}
-
-QXmppJinglePayloadType::QXmppJinglePayloadType()
- : d(new QXmppJinglePayloadTypePrivate())
-{
-}
-
-/// Constructs a copy of other.
-///
-/// \param other
-
-QXmppJinglePayloadType::QXmppJinglePayloadType(const QXmppJinglePayloadType &other)
- : d(other.d)
-{
-}
-
-QXmppJinglePayloadType::~QXmppJinglePayloadType()
-{
-}
-
-/// Returns the number of channels (e.g. 1 for mono, 2 for stereo).
-///
-
-unsigned char QXmppJinglePayloadType::channels() const
-{
- return d->channels;
-}
-
-/// Sets the number of channels (e.g. 1 for mono, 2 for stereo).
-///
-/// \param channels
-
-void QXmppJinglePayloadType::setChannels(unsigned char channels)
-{
- d->channels = channels;
-}
-
-/// Returns the clockrate in Hz, i.e. the number of samples per second.
-///
-
-unsigned int QXmppJinglePayloadType::clockrate() const
-{
- return d->clockrate;
-}
-
-/// Sets the clockrate in Hz, i.e. the number of samples per second.
-///
-/// \param clockrate
-
-void QXmppJinglePayloadType::setClockrate(unsigned int clockrate)
-{
- d->clockrate = clockrate;
-}
-
-/// Returns the payload type identifier.
-///
-
-unsigned char QXmppJinglePayloadType::id() const
-{
- return d->id;
-}
-
-/// Sets the payload type identifier.
-///
-
-void QXmppJinglePayloadType::setId(unsigned char id)
-{
- Q_ASSERT(id <= 127);
- d->id = id;
-}
-
-/// Returns the maximum packet time in milliseconds.
-///
-
-unsigned int QXmppJinglePayloadType::maxptime() const
-{
- return d->maxptime;
-}
-
-/// Sets the maximum packet type in milliseconds.
-///
-/// \param maxptime
-
-void QXmppJinglePayloadType::setMaxptime(unsigned int maxptime)
-{
- d->maxptime = maxptime;
-}
-
-/// Returns the payload type name.
-///
-
-QString QXmppJinglePayloadType::name() const
-{
- return d->name;
-}
-
-/// Sets the payload type name.
-///
-/// \param name
-
-void QXmppJinglePayloadType::setName(const QString &name)
-{
- d->name = name;
-}
-
-/// Returns the payload parameters.
-
-QMap<QString, QString> QXmppJinglePayloadType::parameters() const
-{
- return d->parameters;
-}
-
-/// Sets the payload parameters.
-
-void QXmppJinglePayloadType::setParameters(const QMap<QString, QString> &parameters)
-{
- d->parameters = parameters;
-}
-
-/// Returns the packet time in milliseconds (20 by default).
-///
-
-unsigned int QXmppJinglePayloadType::ptime() const
-{
- return d->ptime ? d->ptime : 20;
-}
-
-/// Sets the packet time in milliseconds (20 by default).
-///
-/// \param ptime
-
-void QXmppJinglePayloadType::setPtime(unsigned int ptime)
-{
- d->ptime = ptime;
-}
-
-///
-/// Returns the properties of RTP feedback.
-///
-/// \return the RTP feedback properties
-///
-/// \since QXmpp 1.5
-///
-QVector<QXmppJingleRtpFeedbackProperty> QXmppJinglePayloadType::rtpFeedbackProperties() const
-{
- return d->rtpFeedbackProperties;
-}
-
-///
-/// Sets the properties of RTP feedback.
-///
-/// \param rtpFeedbackProperties RTP feedback properties
-///
-/// \since QXmpp 1.5
-///
-void QXmppJinglePayloadType::setRtpFeedbackProperties(const QVector<QXmppJingleRtpFeedbackProperty> &rtpFeedbackProperties)
-{
- d->rtpFeedbackProperties = rtpFeedbackProperties;
-}
-
-///
-/// Returns the intervals of RTP feedback.
-///
-/// \return the RTP feedback intervals
-///
-QVector<QXmppJingleRtpFeedbackInterval> QXmppJinglePayloadType::rtpFeedbackIntervals() const
-{
- return d->rtpFeedbackIntervals;
-}
-
-///
-/// Sets the intervals of RTP feedback.
-///
-/// \param rtpFeedbackIntervals RTP feedback intervals
-///
-void QXmppJinglePayloadType::setRtpFeedbackIntervals(const QVector<QXmppJingleRtpFeedbackInterval> &rtpFeedbackIntervals)
-{
- d->rtpFeedbackIntervals = rtpFeedbackIntervals;
-}
-
-/// \cond
-void QXmppJinglePayloadType::parse(const QDomElement &element)
-{
- d->id = element.attribute(QStringLiteral("id")).toInt();
- d->name = element.attribute(QStringLiteral("name"));
- d->channels = element.attribute(QStringLiteral("channels")).toInt();
- if (!d->channels) {
- d->channels = 1;
- }
- d->clockrate = element.attribute(QStringLiteral("clockrate")).toInt();
- d->maxptime = element.attribute(QStringLiteral("maxptime")).toInt();
- d->ptime = element.attribute(QStringLiteral("ptime")).toInt();
-
- QDomElement child = element.firstChildElement(QStringLiteral("parameter"));
- while (!child.isNull()) {
- d->parameters.insert(child.attribute(QStringLiteral("name")), child.attribute(QStringLiteral("value")));
- child = child.nextSiblingElement(QStringLiteral("parameter"));
- }
-
- parseJingleRtpFeedbackNegotiationElements(element, d->rtpFeedbackProperties, d->rtpFeedbackIntervals);
-}
-
-void QXmppJinglePayloadType::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("payload-type"));
- helperToXmlAddAttribute(writer, QStringLiteral("id"), QString::number(d->id));
- helperToXmlAddAttribute(writer, QStringLiteral("name"), d->name);
- if (d->channels > 1) {
- helperToXmlAddAttribute(writer, QStringLiteral("channels"), QString::number(d->channels));
- }
- if (d->clockrate > 0) {
- helperToXmlAddAttribute(writer, QStringLiteral("clockrate"), QString::number(d->clockrate));
- }
- if (d->maxptime > 0) {
- helperToXmlAddAttribute(writer, QStringLiteral("maxptime"), QString::number(d->maxptime));
- }
- if (d->ptime > 0) {
- helperToXmlAddAttribute(writer, QStringLiteral("ptime"), QString::number(d->ptime));
- }
-
- for (auto itr = d->parameters.begin(); itr != d->parameters.end(); itr++) {
- writer->writeStartElement(QStringLiteral("parameter"));
- writer->writeAttribute(QStringLiteral("name"), itr.key());
- writer->writeAttribute(QStringLiteral("value"), itr.value());
- writer->writeEndElement();
- }
-
- jingleRtpFeedbackNegotiationElementsToXml(writer, d->rtpFeedbackProperties, d->rtpFeedbackIntervals);
-
- writer->writeEndElement();
-}
-/// \endcond
-
-/// Assigns the other payload type to this one.
-///
-/// \param other
-
-QXmppJinglePayloadType &QXmppJinglePayloadType::operator=(const QXmppJinglePayloadType &other)
-{
- d = other.d;
- return *this;
-}
-
-/// Returns true if this QXmppJinglePayloadType and \a other refer to the same payload type.
-///
-/// \param other
-
-bool QXmppJinglePayloadType::operator==(const QXmppJinglePayloadType &other) const
-{
- // FIXME : what to do with m_ptime and m_maxptime?
- if (d->id <= 95) {
- return other.d->id == d->id && other.d->clockrate == d->clockrate;
- } else {
- return other.d->channels == d->channels &&
- other.d->clockrate == d->clockrate &&
- other.d->name.toLower() == d->name.toLower();
- }
-}
-
-class QXmppJingleDescriptionPrivate : public QSharedData
-{
-public:
- QXmppJingleDescriptionPrivate() = default;
-
- QString media;
- quint32 ssrc;
- QString type;
- QList<QXmppJinglePayloadType> payloadTypes;
-};
-
-///
-/// \class QXmppJingleDescription
-///
-/// \brief The QXmppJingleDescription class represents descriptions for Jingle elements including
-/// media type, streaming source, namespace and payload types.
-///
-/// \since QXmpp 1.6
-///
-
-QXmppJingleDescription::QXmppJingleDescription()
- : d(new QXmppJingleDescriptionPrivate())
-{
-}
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleDescription)
-
-///
-/// Returns the media type.
-///
-QString QXmppJingleDescription::media() const
-{
- return d->media;
-}
-
-///
-/// Sets the media type.
-///
-void QXmppJingleDescription::setMedia(const QString &media)
-{
- d->media = media;
-}
-
-///
-/// Returns the streaming source.
-///
-quint32 QXmppJingleDescription::ssrc() const
-{
- return d->ssrc;
-}
-
-///
-/// Sets the streaming source.
-///
-void QXmppJingleDescription::setSsrc(quint32 ssrc)
-{
- d->ssrc = ssrc;
-}
-
-///
-/// Returns the description namespace.
-///
-QString QXmppJingleDescription::type() const
-{
- return d->type;
-}
-
-///
-/// Sets the description namespace.
-///
-void QXmppJingleDescription::setType(const QString &type)
-{
- d->type = type;
-}
-
-///
-/// Adds a payload type to the list of payload types.
-///
-void QXmppJingleDescription::addPayloadType(const QXmppJinglePayloadType &payload)
-{
- d->type = ns_jingle_rtp;
- d->payloadTypes.append(payload);
-}
-
-///
-/// Returns a list of payload types.
-///
-const QList<QXmppJinglePayloadType> &QXmppJingleDescription::payloadTypes() const
-{
- return d->payloadTypes;
-}
-
-///
-/// Sets the list of payload types.
-///
-void QXmppJingleDescription::setPayloadTypes(const QList<QXmppJinglePayloadType> &payloadTypes)
-{
- d->type = payloadTypes.isEmpty() ? QString() : ns_jingle_rtp;
- d->payloadTypes = payloadTypes;
-}
-
-/// \cond
-void QXmppJingleDescription::parse(const QDomElement &element)
-{
- d->type = element.namespaceURI();
- d->media = element.attribute(QStringLiteral("media"));
- d->ssrc = element.attribute(QStringLiteral("ssrc")).toULong();
-
- QDomElement child { element.firstChildElement(QStringLiteral("payload-type")) };
- while (!child.isNull()) {
- QXmppJinglePayloadType payload;
- payload.parse(child);
- d->payloadTypes.append(payload);
- child = child.nextSiblingElement(QStringLiteral("payload-type"));
- }
-}
-
-void QXmppJingleDescription::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("description"));
- writer->writeDefaultNamespace(d->type);
-
- helperToXmlAddAttribute(writer, QStringLiteral("media"), d->media);
-
- if (d->ssrc) {
- writer->writeAttribute(QStringLiteral("ssrc"), QString::number(d->ssrc));
- }
-
- for (const auto &payloadType : d->payloadTypes) {
- payloadType.toXml(writer);
- }
-
- writer->writeEndElement();
-}
-/// \endcond
-
-class QXmppSdpParameterPrivate : public QSharedData
-{
-public:
- QString name;
- QString value;
-};
-
-///
-/// \class QXmppSdpParameter
-///
-/// \brief The QXmppSdpParameter class represents a Session Description Protocol (SDP) parameter
-/// specified by RFC 4566 and used by several XEPs based on \xep{0166, Jingle}.
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// Constructs a Session Description Protocol parameter.
-///
-QXmppSdpParameter::QXmppSdpParameter()
- : d(new QXmppSdpParameterPrivate())
-{
-}
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppSdpParameter)
-
-///
-/// Returns the name of the parameter.
-///
-/// \return the parameter's name
-///
-QString QXmppSdpParameter::name() const
-{
- return d->name;
-}
-
-///
-/// Sets the name of the parameter.
-///
-/// \param name parameter's name
-///
-void QXmppSdpParameter::setName(const QString &name)
-{
- d->name = name;
-}
-
-///
-/// Returns the value of the parameter.
-///
-/// \return the parameter's value
-///
-QString QXmppSdpParameter::value() const
-{
- return d->value;
-}
-
-///
-/// Sets the value of the parameter.
-///
-/// A parameter in the form "a=b" can be created by this method.
-/// Any other form of parameters can be created by not using this method.
-/// The value stays a default-constructed QString then.
-///
-/// \param value parameter's value
-///
-void QXmppSdpParameter::setValue(const QString &value)
-{
- d->value = value;
-}
-
-/// \cond
-void QXmppSdpParameter::parse(const QDomElement &element)
-{
- d->name = element.attribute(QStringLiteral("name"));
- d->value = element.attribute(QStringLiteral("value"));
-}
-
-void QXmppSdpParameter::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("parameter"));
- helperToXmlAddAttribute(writer, QStringLiteral("name"), d->name);
-
- if (!d->value.isEmpty()) {
- helperToXmlAddAttribute(writer, QStringLiteral("value"), d->value);
- }
-
- writer->writeEndElement();
-}
-/// \endcond
-
-///
-/// Determines whether the given DOM element is a Session Description Protocol parameter element.
-///
-/// \param element DOM element being checked
-///
-/// \return whether element is a Session Description Protocol parameter element
-///
-bool QXmppSdpParameter::isSdpParameter(const QDomElement &element)
-{
- return element.tagName() == QStringLiteral("parameter");
-}
-
-class QXmppJingleRtpCryptoElementPrivate : public QSharedData
-{
-public:
- uint32_t tag = 0;
- QString cryptoSuite;
- QString keyParams;
- QString sessionParams;
-};
-
-///
-/// \class QXmppJingleRtpCryptoElement
-///
-/// \brief The QXmppJingleRtpCryptoElement class represents the \xep{0167: Jingle RTP Sessions}
-/// "crypto" element used for SRTP negotiation.
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// Constructs a Jingle RTP crypto element.
-///
-QXmppJingleRtpCryptoElement::QXmppJingleRtpCryptoElement()
- : d(new QXmppJingleRtpCryptoElementPrivate())
-{
-}
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleRtpCryptoElement)
-
-///
-/// Returns the tag used as an identifier for the crypto element.
-///
-/// \return the identifying tag
-///
-uint32_t QXmppJingleRtpCryptoElement::tag() const
-{
- return d->tag;
-}
-
-///
-/// Sets the tag used as an identifier for the crypto element.
-///
-/// \param tag identifying tag
-///
-void QXmppJingleRtpCryptoElement::setTag(uint32_t tag)
-{
- d->tag = tag;
-}
-
-///
-/// Returns the crypto suite used as an identifier for describing the encryption and authentication
-/// algorithms.
-///
-/// \return the identifying crypto suite
-///
-QString QXmppJingleRtpCryptoElement::cryptoSuite() const
-{
- return d->cryptoSuite;
-}
-
-///
-/// Sets the crypto suite used as an identifier for describing the encryption and authentication
-/// algorithms.
-///
-/// \param cryptoSuite identifying crypto suite
-///
-void QXmppJingleRtpCryptoElement::setCryptoSuite(const QString &cryptoSuite)
-{
- d->cryptoSuite = cryptoSuite;
-}
-
-///
-/// Returns the key parameters providing one or more sets of keying material for the crypto suite.
-///
-/// \return the key parameters providing one or more sets of keying material
-///
-QString QXmppJingleRtpCryptoElement::keyParams() const
-{
- return d->keyParams;
-}
-
-///
-/// Sets the key parameters providing one or more sets of keying material for the crypto suite.
-///
-/// \param keyParams key parameters providing one or more sets of keying material
-///
-void QXmppJingleRtpCryptoElement::setKeyParams(const QString &keyParams)
-{
- d->keyParams = keyParams;
-}
-
-///
-/// Returns the session parameters providing transport-specific data.
-///
-/// \return the session parameters providing transport-specific data
-///
-QString QXmppJingleRtpCryptoElement::sessionParams() const
-{
- return d->sessionParams;
-}
-
-///
-/// Sets the session parameters providing transport-specific data.
-///
-/// \param sessionParams session parameters providing transport-specific data
-///
-void QXmppJingleRtpCryptoElement::setSessionParams(const QString &sessionParams)
-{
- d->sessionParams = sessionParams;
-}
-
-/// \cond
-void QXmppJingleRtpCryptoElement::parse(const QDomElement &element)
-{
- d->tag = element.attribute(QStringLiteral("tag")).toUInt();
- d->cryptoSuite = element.attribute(QStringLiteral("crypto-suite"));
- d->keyParams = element.attribute(QStringLiteral("key-params"));
- d->sessionParams = element.attribute(QStringLiteral("session-params"));
-}
-
-void QXmppJingleRtpCryptoElement::toXml(QXmlStreamWriter *writer) const
-{
- if (!d->cryptoSuite.isEmpty() && !d->keyParams.isEmpty()) {
- writer->writeStartElement(QStringLiteral("crypto"));
- writer->writeAttribute(QStringLiteral("tag"), QString::number(d->tag));
- writer->writeAttribute(QStringLiteral("crypto-suite"), d->cryptoSuite);
- writer->writeAttribute(QStringLiteral("key-params"), d->keyParams);
- helperToXmlAddAttribute(writer, QStringLiteral("session-params"), d->sessionParams);
- writer->writeEndElement();
- }
-}
-/// \endcond
-
-///
-/// Determines whether the given DOM element is an RTP crypto element.
-///
-/// \param element DOM element being checked
-///
-/// \return whether element is an RTP crypto element
-///
-bool QXmppJingleRtpCryptoElement::isJingleRtpCryptoElement(const QDomElement &element)
-{
- return element.tagName() == QStringLiteral("crypto");
-}
-
-class QXmppJingleRtpEncryptionPrivate : public QSharedData
-{
-public:
- bool isRequired = false;
- QVector<QXmppJingleRtpCryptoElement> cryptoElements;
-};
-
-///
-/// \class QXmppJingleRtpEncryption
-///
-/// \brief The QXmppJingleRtpEncryption class represents the \xep{0167: Jingle RTP Sessions}
-/// "encryption" element used for SRTP negotiation.
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// Constructs a Jingle RTP encryption.
-///
-QXmppJingleRtpEncryption::QXmppJingleRtpEncryption()
- : d(new QXmppJingleRtpEncryptionPrivate())
-{
-}
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleRtpEncryption)
-
-///
-/// Returns whether encryption via SRTP is required.
-///
-/// \return whether encryption is required
-///
-bool QXmppJingleRtpEncryption::isRequired() const
-{
- return d->isRequired;
-}
-
-///
-/// Sets whether encryption via SRTP is required.
-///
-/// \param isRequired whether encryption is required
-///
-void QXmppJingleRtpEncryption::setRequired(bool isRequired)
-{
- d->isRequired = isRequired;
-}
-
-///
-/// Returns the crypto elements used for encryption via SRTP.
-///
-/// \return the crypto elements
-///
-QVector<QXmppJingleRtpCryptoElement> QXmppJingleRtpEncryption::cryptoElements() const
-{
- return d->cryptoElements;
-}
-
-///
-/// Sets the crypto elements used for encryption via SRTP.
-///
-/// \param cryptoElements the crypto elements
-///
-void QXmppJingleRtpEncryption::setCryptoElements(const QVector<QXmppJingleRtpCryptoElement> &cryptoElements)
-{
- d->cryptoElements = cryptoElements;
-}
-
-/// \cond
-void QXmppJingleRtpEncryption::parse(const QDomElement &element)
-{
- d->isRequired = element.attribute(QStringLiteral("required")) == QStringLiteral("true") ||
- element.attribute(QStringLiteral("required")) == QStringLiteral("1");
-
- for (auto childElement = element.firstChildElement();
- !childElement.isNull();
- childElement = childElement.nextSiblingElement()) {
- if (QXmppJingleRtpCryptoElement::isJingleRtpCryptoElement(childElement)) {
- QXmppJingleRtpCryptoElement cryptoElement;
- cryptoElement.parse(childElement);
- d->cryptoElements.append(std::move(cryptoElement));
- }
- }
-}
-
-void QXmppJingleRtpEncryption::toXml(QXmlStreamWriter *writer) const
-{
- if (!d->cryptoElements.isEmpty()) {
- writer->writeStartElement(QStringLiteral("encryption"));
- writer->writeDefaultNamespace(ns_jingle_rtp);
-
- if (d->isRequired) {
- writer->writeAttribute(QStringLiteral("required"), QStringLiteral("1"));
- }
-
- for (const auto &cryptoElement : std::as_const(d->cryptoElements)) {
- cryptoElement.toXml(writer);
- }
-
- writer->writeEndElement();
- }
-}
-/// \endcond
-
-///
-/// Determines whether the given DOM element is an RTP encryption element.
-///
-/// \param element DOM element being checked
-///
-/// \return whether element is an RTP encryption element
-///
-bool QXmppJingleRtpEncryption::isJingleRtpEncryption(const QDomElement &element)
-{
- return element.tagName() == QStringLiteral("encryption") &&
- element.namespaceURI() == ns_jingle_rtp;
-}
-
-class QXmppJingleRtpFeedbackPropertyPrivate : public QSharedData
-{
-public:
- QString type;
- QString subtype;
- QVector<QXmppSdpParameter> parameters;
-};
-
-///
-/// \class QXmppJingleRtpFeedbackProperty
-///
-/// \brief The QXmppJingleRtpFeedbackProperty class represents the
-/// \xep{0293, Jingle RTP Feedback Negotiation} "rtcp-fb" element.
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// Constructs a Jingle RTP feedback property.
-///
-QXmppJingleRtpFeedbackProperty::QXmppJingleRtpFeedbackProperty()
- : d(new QXmppJingleRtpFeedbackPropertyPrivate())
-{
-}
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleRtpFeedbackProperty)
-
-///
-/// Returns the type of RTP feedback.
-///
-/// \return the RTP feedback type
-///
-QString QXmppJingleRtpFeedbackProperty::type() const
-{
- return d->type;
-}
-
-///
-/// Sets the type of RTP feedback.
-///
-/// \param type RTP feedback type
-///
-void QXmppJingleRtpFeedbackProperty::setType(const QString &type)
-{
- d->type = type;
-}
-
-///
-/// Returns the subtype for RTP feedback.
-///
-/// \return the RTP feedback subtype
-///
-QString QXmppJingleRtpFeedbackProperty::subtype() const
-{
- return d->subtype;
-}
-
-///
-/// Sets the subtype of RTP feedback.
-///
-/// If there is more than one parameter, use QXmppJingleRtpFeedbackProperty::setParameters()
-/// instead of this method.
-///
-/// \param subtype RTP feedback subtype
-///
-void QXmppJingleRtpFeedbackProperty::setSubtype(const QString &subtype)
-{
- d->subtype = subtype;
-}
-
-///
-/// Returns the parameters of RTP feedback.
-///
-/// \return the RTP feedback parameters
-///
-QVector<QXmppSdpParameter> QXmppJingleRtpFeedbackProperty::parameters() const
-{
- return d->parameters;
-}
-
-///
-/// Sets the parameters of RTP feedback.
-///
-/// Additional parameters can be set by this method.
-/// If there is only one parameter, use QXmppJingleRtpFeedbackProperty::setSubtype()
-/// instead of this method.
-///
-/// \param parameters RTP feedback parameters
-///
-void QXmppJingleRtpFeedbackProperty::setParameters(const QVector<QXmppSdpParameter> &parameters)
-{
- d->parameters = parameters;
-}
-
-/// \cond
-void QXmppJingleRtpFeedbackProperty::parse(const QDomElement &element)
-{
- d->type = element.attribute(QStringLiteral("type"));
- d->subtype = element.attribute(QStringLiteral("subtype"));
- parseSdpParameters(element, d->parameters);
-}
-
-void QXmppJingleRtpFeedbackProperty::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("rtcp-fb"));
- writer->writeDefaultNamespace(ns_jingle_rtp_feedback_negotiation);
- helperToXmlAddAttribute(writer, QStringLiteral("type"), d->type);
-
- // If there are parameters, they must be used instead of the subtype.
- if (d->subtype.isEmpty()) {
- sdpParametersToXml(writer, d->parameters);
- } else {
- helperToXmlAddAttribute(writer, QStringLiteral("subtype"), d->subtype);
- }
-
- writer->writeEndElement();
-}
-/// \endcond
-
-///
-/// Determines whether the given DOM element is an RTP feedback property element.
-///
-/// \param element DOM element being checked
-///
-/// \return whether element is an RTP feedback property element
-///
-bool QXmppJingleRtpFeedbackProperty::isJingleRtpFeedbackProperty(const QDomElement &element)
-{
- return element.tagName() == QStringLiteral("rtcp-fb") &&
- element.namespaceURI() == ns_jingle_rtp_feedback_negotiation;
-}
-
-///
-/// \class QXmppJingleRtpFeedbackInterval
-///
-/// \brief The QXmppJingleRtpFeedbackInterval class represents the
-/// \xep{0293, Jingle RTP Feedback Negotiation} "rtcp-fb-trr-int" element.
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// Constructs a Jingle RTP feedback interval.
-///
-QXmppJingleRtpFeedbackInterval::QXmppJingleRtpFeedbackInterval()
-{
-}
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleRtpFeedbackInterval)
-
-///
-/// Returns the value of the RTP feedback interval.
-///
-/// \return the RTP feedback interval value
-///
-uint64_t QXmppJingleRtpFeedbackInterval::value() const
-{
- return m_value;
-}
-
-///
-/// Sets the value of the RTP feedback interval.
-///
-/// \param value RTP feedback interval value
-///
-void QXmppJingleRtpFeedbackInterval::setValue(uint64_t value)
-{
- m_value = value;
-}
-
-/// \cond
-void QXmppJingleRtpFeedbackInterval::parse(const QDomElement &element)
-{
- m_value = element.attribute(QStringLiteral("value")).toUInt();
-}
-
-void QXmppJingleRtpFeedbackInterval::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("rtcp-fb-trr-int"));
- writer->writeDefaultNamespace(ns_jingle_rtp_feedback_negotiation);
- helperToXmlAddAttribute(writer, QStringLiteral("value"), QString::number(m_value));
- writer->writeEndElement();
-}
-/// \endcond
-
-///
-/// Determines whether the given DOM element is an RTP feedback interval element.
-///
-/// \param element DOM element being checked
-///
-/// \return whether element is an RTP feedback interval element
-///
-bool QXmppJingleRtpFeedbackInterval::isJingleRtpFeedbackInterval(const QDomElement &element)
-{
- return element.tagName() == QStringLiteral("rtcp-fb-trr-int") &&
- element.namespaceURI() == ns_jingle_rtp_feedback_negotiation;
-}
-
-class QXmppJingleRtpHeaderExtensionPropertyPrivate : public QSharedData
-{
-public:
- uint32_t id = 0;
- QString uri;
- QXmppJingleRtpHeaderExtensionProperty::Senders senders = QXmppJingleRtpHeaderExtensionProperty::Both;
- QVector<QXmppSdpParameter> parameters;
-};
-
-///
-/// \enum QXmppJingleRtpHeaderExtensionProperty::Senders
-///
-/// Parties that are allowed to send the negotiated RTP header extension
-///
-
-///
-/// \class QXmppJingleRtpHeaderExtensionProperty
-///
-/// \brief The QXmppJingleRtpHeaderExtensionProperty class represents the
-/// \xep{0294, Jingle RTP Header Extensions Negotiation} "rtp-hdrext" element.
-///
-/// \since QXmpp 1.5
-///
-
-///
-/// Constructs a Jingle RTP header extension property.
-///
-QXmppJingleRtpHeaderExtensionProperty::QXmppJingleRtpHeaderExtensionProperty()
- : d(new QXmppJingleRtpHeaderExtensionPropertyPrivate())
-{
-}
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleRtpHeaderExtensionProperty)
-
-///
-/// Returns the ID of the RTP header extension.
-///
-/// The ID is 0 if it is unset.
-///
-/// \return the RTP header extension's ID
-///
-uint32_t QXmppJingleRtpHeaderExtensionProperty::id() const
-{
- return d->id;
-}
-
-///
-/// Sets the ID of the RTP header extension.
-///
-/// The ID must either be at least 1 and at most 256 or at least 4096 and at most 4351.
-///
-/// \param id RTP header extension's ID
-///
-void QXmppJingleRtpHeaderExtensionProperty::setId(uint32_t id)
-{
- d->id = id;
-}
-
-///
-/// Returns the URI defning the RTP header extension.
-///
-/// \return the RTP header extension's URI
-///
-QString QXmppJingleRtpHeaderExtensionProperty::uri() const
-{
- return d->uri;
-}
-
-///
-/// Sets the URI defning the RTP header extension.
-///
-/// \param uri RTP header extension's URI
-///
-void QXmppJingleRtpHeaderExtensionProperty::setUri(const QString &uri)
-{
- d->uri = uri;
-}
-
-///
-/// Returns the parties that are allowed to send the negotiated RTP header extensions.
-///
-/// \return the parties that are allowed to send the RTP header extensions
-///
-QXmppJingleRtpHeaderExtensionProperty::Senders QXmppJingleRtpHeaderExtensionProperty::senders() const
-{
- return d->senders;
-}
-
-///
-/// Sets the parties that are allowed to send the negotiated RTP header extensions.
-///
-/// \param senders parties that are allowed to send the RTP header extensions
-///
-void QXmppJingleRtpHeaderExtensionProperty::setSenders(Senders senders)
-{
- d->senders = senders;
-}
-
-///
-/// Returns the parameters of the RTP header extension.
-///
-/// \return the RTP header extension's parameters
-///
-QVector<QXmppSdpParameter> QXmppJingleRtpHeaderExtensionProperty::parameters() const
-{
- return d->parameters;
-}
-
-///
-/// Sets the parameters of the RTP header extension.
-///
-/// Additional parameters can be set by this method.
-///
-/// \param parameters RTP header extension's parameters
-///
-void QXmppJingleRtpHeaderExtensionProperty::setParameters(const QVector<QXmppSdpParameter> &parameters)
-{
- d->parameters = parameters;
-}
-
-/// \cond
-void QXmppJingleRtpHeaderExtensionProperty::parse(const QDomElement &element)
-{
- if (element.tagName() == QStringLiteral("rtp-hdrext") && element.namespaceURI() == ns_jingle_rtp_header_extensions_negotiation) {
- d->id = element.attribute(QStringLiteral("id")).toUInt();
- d->uri = element.attribute(QStringLiteral("uri"));
-
- if (const auto senders = JINGLE_RTP_HEADER_EXTENSIONS_SENDERS.indexOf(element.attribute(QStringLiteral("senders"))); senders > QXmppJingleRtpHeaderExtensionProperty::Both) {
- d->senders = static_cast<QXmppJingleRtpHeaderExtensionProperty::Senders>(senders);
- }
-
- parseSdpParameters(element, d->parameters);
- }
-}
-
-void QXmppJingleRtpHeaderExtensionProperty::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(QStringLiteral("rtp-hdrext"));
- writer->writeDefaultNamespace(ns_jingle_rtp_header_extensions_negotiation);
- helperToXmlAddAttribute(writer, QStringLiteral("id"), QString::number(d->id));
- helperToXmlAddAttribute(writer, QStringLiteral("uri"), d->uri);
-
- if (d->senders != QXmppJingleRtpHeaderExtensionProperty::Both) {
- helperToXmlAddAttribute(writer, QStringLiteral("senders"), JINGLE_RTP_HEADER_EXTENSIONS_SENDERS.at(d->senders));
- }
-
- sdpParametersToXml(writer, d->parameters);
-
- writer->writeEndElement();
-}
-/// \endcond
-
-///
-/// Determines whether the given DOM element is an RTP header extensions property element.
-///
-/// \param element DOM element being checked
-///
-/// \return whether element is an RTP header extension property element
-///
-bool QXmppJingleRtpHeaderExtensionProperty::isJingleRtpHeaderExtensionProperty(const QDomElement &element)
-{
- return element.tagName() == QStringLiteral("rtp-hdrext") &&
- element.namespaceURI() == ns_jingle_rtp_header_extensions_negotiation;
-}
-
-class QXmppJingleMessageInitiationElementPrivate : public QSharedData
-{
-public:
- QXmppJingleMessageInitiationElementPrivate() = default;
-
- QXmppJingleMessageInitiationElement::Type type { QXmppJingleMessageInitiationElement::Type::None };
- QString id;
-
- std::optional<QXmppJingleDescription> description;
- std::optional<QXmppJingleReason> reason;
- QString migratedTo;
-
- bool containsTieBreak;
-};
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleReason)
-
-///
-/// \enum QXmppJingleMessageInitiationElement::Type
-///
-/// Possible types of Jingle Message Initiation elements
-///
-
-///
-/// \class QXmppJingleMessageInitiationElement
-///
-/// \brief The QXmppJingleMessageInitiationElement class represents a Jingle Message Initiation
-/// element as specified by \xep{0353}: Jingle Message Initiation.
-///
-/// \ingroup Stanzas
-///
-/// \since QXmpp 1.6
-///
-
-///
-/// \brief Constructs a Jingle Message Initiation element.
-/// \param type The JMI element type
-///
-QXmppJingleMessageInitiationElement::QXmppJingleMessageInitiationElement()
- : d(new QXmppJingleMessageInitiationElementPrivate())
-{
-}
-
-///
-/// Returns the Jingle Message Initiation element type
-///
-QXmppJingleMessageInitiationElement::Type QXmppJingleMessageInitiationElement::type() const
-{
- return d->type;
-}
-
-///
-/// Sets the Jingle Message Initiation element type.
-///
-void QXmppJingleMessageInitiationElement::setType(Type type)
-{
- d->type = type;
-}
-
-///
-/// Returns the Jingle Message Initiation element id.
-///
-QString QXmppJingleMessageInitiationElement::id() const
-{
- return d->id;
-}
-
-///
-/// Sets the Jingle Message Initiation element id.
-///
-void QXmppJingleMessageInitiationElement::setId(const QString &id)
-{
- d->id = id;
-}
-
-///
-/// Returns the Jingle Message Initiation element description.
-///
-std::optional<QXmppJingleDescription> QXmppJingleMessageInitiationElement::description() const
-{
- return d->description;
-}
-
-///
-/// Sets the Jingle Message Initiation element description.
-///
-void QXmppJingleMessageInitiationElement::setDescription(std::optional<QXmppJingleDescription> description)
-{
- d->description = description;
-}
-
-///
-/// Returns the Jingle Message Initiation element reason.
-///
-std::optional<QXmppJingleReason> QXmppJingleMessageInitiationElement::reason() const
-{
- return d->reason;
-}
-
-///
-/// Sets the Jingle Message Initiation element reason.
-///
-void QXmppJingleMessageInitiationElement::setReason(std::optional<QXmppJingleReason> reason)
-{
- d->reason = reason;
-
- if (d->reason) {
- d->reason->setNamespaceUri(ns_jingle);
- }
-}
-
-///
-/// Returns true if the Jingle Message Initiation element contains a <tie-break/> tag.
-///
-bool QXmppJingleMessageInitiationElement::containsTieBreak() const
-{
- return d->containsTieBreak;
-}
-
-///
-/// Sets if the Jingle Message Initiation element contains a <tie-break/> tag.
-///
-void QXmppJingleMessageInitiationElement::setContainsTieBreak(bool containsTieBreak)
-{
- d->containsTieBreak = containsTieBreak;
-}
-
-///
-/// Returns the Jingle Message Initiation element ID migrated to if the Jingle is being migrated
-/// to a different device.
-///
-QString QXmppJingleMessageInitiationElement::migratedTo() const
-{
- return d->migratedTo;
-}
-
-///
-/// Sets the Jingle Message Initiation element ID migrated to if the Jingle is being migrated
-/// to a different device.
-///
-void QXmppJingleMessageInitiationElement::setMigratedTo(const QString &migratedTo)
-{
- d->migratedTo = migratedTo;
-}
-
-/// \cond
-void QXmppJingleMessageInitiationElement::parse(const QDomElement &element)
-{
- d->type = stringToJmiElementType(element.nodeName());
-
- if (d->type == Type::None) {
- return;
- }
-
- d->id = element.attribute(QStringLiteral("id"));
-
- // Type::Proceed and Type::Ringing don't need any parsing aside of the id.
- switch (d->type) {
- case Type::Propose: {
- if (const auto &descriptionElement = element.firstChildElement("description"); !descriptionElement.isNull()) {
- d->description = QXmppJingleDescription();
- d->description->parse(descriptionElement);
- }
-
- break;
- }
- case Type::Reject:
- case Type::Retract:
- d->containsTieBreak = !element.firstChildElement("tie-break").isNull();
-
- if (const auto &reasonElement = element.firstChildElement("reason"); !reasonElement.isNull()) {
- d->reason = QXmppJingleReason();
- d->reason->parse(reasonElement);
- }
-
- break;
- case Type::Finish:
- if (const auto &reasonElement = element.firstChildElement("reason"); !reasonElement.isNull()) {
- d->reason = QXmppJingleReason();
- d->reason->parse(reasonElement);
- }
-
- if (const auto &migratedToElement = element.firstChildElement("migrated"); !migratedToElement.isNull()) {
- d->migratedTo = migratedToElement.attribute("to");
- }
-
- break;
- default:
- break;
- }
-}
-
-void QXmppJingleMessageInitiationElement::toXml(QXmlStreamWriter *writer) const
-{
- writer->writeStartElement(jmiElementTypeToString(d->type));
- writer->writeDefaultNamespace(ns_jingle_message_initiation);
-
- helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id);
-
- if (d->description) {
- d->description->toXml(writer);
- }
-
- if (d->reason) {
- d->reason->toXml(writer);
- }
-
- if (d->containsTieBreak) {
- writer->writeEmptyElement(QStringLiteral("tie-break"));
- }
-
- if (!d->migratedTo.isEmpty()) {
- writer->writeEmptyElement(QStringLiteral("migrated"));
- helperToXmlAddAttribute(writer, QStringLiteral("to"), d->migratedTo);
- }
-
- writer->writeEndElement();
-}
-/// \endcond
-
-QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleMessageInitiationElement)
-
-///
-/// Returns true if passed QDomElement is a Jingle Message Initiation element
-///
-bool QXmppJingleMessageInitiationElement::isJingleMessageInitiationElement(const QDomElement &element)
-{
- return (element.nodeName() == QStringLiteral("propose") || element.nodeName() == QStringLiteral("ringing") || element.nodeName() == QStringLiteral("proceed") || element.nodeName() == QStringLiteral("retract") || element.nodeName() == QStringLiteral("reject") || element.nodeName() == QStringLiteral("finish")) && element.hasAttribute(QStringLiteral("id")) && element.namespaceURI() == ns_jingle_message_initiation;
-}
-
-///
-/// Takes a Jingle Message Initiation element type and parses it to a string.
-///
-QString QXmppJingleMessageInitiationElement::jmiElementTypeToString(Type type) const
-{
- switch (type) {
- case Type::Propose:
- return "propose";
- case Type::Ringing:
- return "ringing";
- case Type::Proceed:
- return "proceed";
- case Type::Reject:
- return "reject";
- case Type::Retract:
- return "retract";
- case Type::Finish:
- return "finish";
- default:
- return {};
- }
-}
-
-///
-/// Takes a string and parses it to a Jingle Message Initiation element type.
-///
-QXmppJingleMessageInitiationElement::Type QXmppJingleMessageInitiationElement::stringToJmiElementType(const QString &typeStr) const
-{
- if (typeStr == "propose") {
- return Type::Propose;
- } else if (typeStr == "ringing") {
- return Type::Ringing;
- } else if (typeStr == "proceed") {
- return Type::Proceed;
- } else if (typeStr == "reject") {
- return Type::Reject;
- } else if (typeStr == "retract") {
- return Type::Retract;
- } else if (typeStr == "finish") {
- return Type::Finish;
- }
-
- return Type::None;
-}