Permalink
Browse files

Implement XEP-0369/XEP-0405 (MIX): IQ queries

This implements all used IQ queries of XEP-0369: Mediated Information
eXchange (MIX) (v0.14.1) and XEP-0405: Mediated Information eXchange (MIX):
Participant Server Requirements (v0.3.1), including unit tests.
  • Loading branch information...
lnjX authored and jlaine committed Jan 3, 2019
1 parent 2a34abc commit 95063b18660246efe91391d71dd08ec5ab69810d
@@ -46,5 +46,7 @@ Ongoing:
- XEP-0009: Jabber-RPC (API is not finalized yet)
- XEP-0060: Publish-Subscribe (Only basic IQ implemented)
- XEP-0077: In-Band Registration (Only basic IQ implemented)
- XEP-0369: Mediated Information eXchange (MIX) (Only IQ queries implemented) (v0.14.1)
- XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements (Only IQ queries implemented) (v0.3.1)

*/
@@ -25,6 +25,7 @@ set(INSTALL_HEADER_FILES
base/QXmppLogger.h
base/QXmppMamIq.h
base/QXmppMessage.h
base/QXmppMixIq.h
base/QXmppMucIq.h
base/QXmppNonSASLAuth.h
base/QXmppPingIq.h
@@ -99,6 +100,7 @@ set(SOURCE_FILES
base/QXmppLogger.cpp
base/QXmppMamIq.cpp
base/QXmppMessage.cpp
base/QXmppMixIq.cpp
base/QXmppMucIq.cpp
base/QXmppNonSASLAuth.cpp
base/QXmppPingIq.cpp
@@ -132,3 +132,15 @@ const char* ns_idle = "urn:xmpp:idle:1";
const char* ns_chat_markers = "urn:xmpp:chat-markers:0";
// XEP-0352: Client State Indication
const char* ns_csi = "urn:xmpp:csi:0";
// XEP-0369: Mediated Information eXchange (MIX)
const char* ns_mix = "urn:xmpp:mix:core:0";
const char* ns_mix_create_channel = "urn:xmpp:mix:core:0#create-channel";
const char* ns_mix_searchable = "urn:xmpp:mix:core:0#searchable";
const char* ns_mix_node_messages = "urn:xmpp:mix:nodes:messages";
const char* ns_mix_node_participants = "urn:xmpp:mix:nodes:participants";
const char* ns_mix_node_presence = "urn:xmpp:mix:nodes:presence";
const char* ns_mix_node_config = "urn:xmpp:mix:nodes:config";
const char* ns_mix_node_info = "urn:xmpp:mix:nodes:info";
// XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
const char* ns_mix_pam = "urn:xmpp:mix:pam:0";
const char* ns_mix_roster = "urn:xmpp:mix:roster:0";
@@ -144,5 +144,17 @@ extern const char* ns_idle;
extern const char* ns_chat_markers;
// XEP-0352: Client State Indication
extern const char* ns_csi;
// XEP-0369: Mediated Information eXchange (MIX)
extern const char* ns_mix;
extern const char* ns_mix_create_channel;
extern const char* ns_mix_searchable;
extern const char* ns_mix_node_messages;
extern const char* ns_mix_node_participants;
extern const char* ns_mix_node_presence;
extern const char* ns_mix_node_config;
extern const char* ns_mix_node_info;
// XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements
extern const char* ns_mix_pam;
extern const char* ns_mix_roster;

#endif // QXMPPCONSTANTS_H
@@ -0,0 +1,183 @@
/*
* Copyright (C) 2008-2019 The QXmpp developers
*
* Author:
* Linus Jahn <lnj@kaidan.im>
*
* Source:
* https://github.com/qxmpp-project/qxmpp
*
* This file is a part of QXmpp library.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/

#include "QXmppMixIq.h"
#include "QXmppDataForm.h"
#include "QXmppConstants_p.h"
#include "QXmppUtils.h"
#include <QDomElement>

static const QStringList MIX_ACTION_TYPES = QStringList() << ""
<< "client-join" << "client-leave" << "join" << "leave"
<< "update-subscription" << "setnick" << "create" << "destroy";

/// Returns the channel JID. It also contains a participant id for Join/
/// ClientJoin results.

QString QXmppMixIq::jid() const
{
return m_jid;
}

/// Sets the channel JID. For results of Join/ClientJoin queries this also
/// needs to contain a participant id.

void QXmppMixIq::setJid(const QString& jid)
{
m_jid = jid;
}

/// Returns the channel name (the name part of the channel JID). This may still
/// be empty, if a JID was set.

QString QXmppMixIq::channelName() const
{
return m_channelName;
}

/// Sets the channel name for creating/destroying specific channels. When you
/// create a new channel, this can also be left empty to let the server
/// generate a name.

void QXmppMixIq::setChannelName(const QString& channelName)
{
m_channelName = channelName;
}

/// Returns the list of nodes to subscribe to.

QStringList QXmppMixIq::nodes() const
{
return m_nodes;
}

/// Sets the nodes to subscribe to. Note that for UpdateSubscription queries
/// you only need to include the new subscriptions.

void QXmppMixIq::setNodes(const QStringList& nodes)
{
m_nodes = nodes;
}

/// Returns the user's nickname in the channel.

QString QXmppMixIq::nick() const
{
return m_nick;
}

/// Sets the nickname for the channel.

void QXmppMixIq::setNick(const QString& nick)
{
m_nick = nick;
}

/// Returns the MIX channel action type.

QXmppMixIq::Type QXmppMixIq::actionType() const
{
return m_actionType;
}

/// Sets the channel action.

void QXmppMixIq::setActionType(QXmppMixIq::Type type)
{
m_actionType = type;
}

/// \cond
bool QXmppMixIq::isMixIq(const QDomElement& element)
{
const QDomElement& child = element.firstChildElement();
return !child.isNull() && (child.namespaceURI() == ns_mix
|| child.namespaceURI() == ns_mix_pam);
}

void QXmppMixIq::parseElementFromChild(const QDomElement& element)
{
QDomElement child = element.firstChildElement();
// determine action type
m_actionType = (QXmppMixIq::Type) MIX_ACTION_TYPES.indexOf(child.tagName());

if (child.namespaceURI() == ns_mix_pam) {
if (child.hasAttribute("channel"))
m_jid = child.attribute("channel");

child = child.firstChildElement();
}

if (!child.isNull() && child.namespaceURI() == ns_mix) {
if (child.hasAttribute("jid"))
m_jid = child.attribute("jid");
if (child.hasAttribute("channel"))
m_channelName = child.attribute("channel");

QDomElement subChild = child.firstChildElement();
while (!subChild.isNull()) {
if (subChild.tagName() == "subscribe")
m_nodes << subChild.attribute("node");
else if (subChild.tagName() == "nick")
m_nick = subChild.text();

subChild = subChild.nextSiblingElement();
}
}
}

void QXmppMixIq::toXmlElementFromChild(QXmlStreamWriter* writer) const
{
if (m_actionType == None)
return;

writer->writeStartElement(MIX_ACTION_TYPES.at(m_actionType));
if (m_actionType == ClientJoin || m_actionType == ClientLeave) {
writer->writeAttribute("xmlns", ns_mix_pam);
if (type() == Set)
helperToXmlAddAttribute(writer, "channel", m_jid);

if (m_actionType == ClientJoin)
writer->writeStartElement("join");
else if (m_actionType == ClientLeave)
writer->writeStartElement("leave");
}

writer->writeAttribute("xmlns", ns_mix);
helperToXmlAddAttribute(writer, "channel", m_channelName);
if (type() == Result)
helperToXmlAddAttribute(writer, "jid", m_jid);

for (auto node : m_nodes) {
writer->writeStartElement("subscribe");
writer->writeAttribute("node", node);
writer->writeEndElement();
}
if (!m_nick.isEmpty())
writer->writeTextElement("nick", m_nick);

writer->writeEndElement();
if (m_actionType == ClientJoin || m_actionType == ClientLeave)
writer->writeEndElement();
}
/// \endcond
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2008-2019 The QXmpp developers
*
* Author:
* Linus Jahn <lnj@kaidan.im>
*
* Source:
* https://github.com/qxmpp-project/qxmpp
*
* This file is a part of QXmpp library.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/

#ifndef QXMPPMIXIQ_H
#define QXMPPMIXIQ_H

#include "QXmppIq.h"

/// \brief The QXmppMixIq class represents an IQ used to do actions on a MIX
/// channel as defined by XEP-0369: Mediated Information eXchange (MIX)
/// (v0.14.1) and XEP-0405: Mediated Information eXchange (MIX): Participant
/// Server Requirements (v0.3.1).
///
/// \ingroup Stanzas

class QXMPP_EXPORT QXmppMixIq : public QXmppIq
{
public:
enum Type {
None,
ClientJoin,
ClientLeave,
Join,
Leave,
UpdateSubscription,
SetNick,
Create,
Destroy
};

QXmppMixIq::Type actionType() const;
void setActionType(QXmppMixIq::Type);

QString jid() const;
void setJid(const QString&);

QString channelName() const;
void setChannelName(const QString&);

QStringList nodes() const;
void setNodes(const QStringList&);

QString nick() const;
void setNick(const QString&);

/// \cond
static bool isMixIq(const QDomElement&);
/// \endcond

protected:
/// \cond
void parseElementFromChild(const QDomElement&);
void toXmlElementFromChild(QXmlStreamWriter*) const;
/// \endcond

private:
QString m_jid;
QString m_channelName;
QStringList m_nodes;
QString m_nick;
QXmppMixIq::Type m_actionType = QXmppMixIq::None;
};

#endif // QXMPPMIXIQ_H
@@ -26,6 +26,7 @@ add_simple_test(qxmppiq)
add_simple_test(qxmppjingleiq)
add_simple_test(qxmppmammanager)
add_simple_test(qxmppmessage)
add_simple_test(qxmppmixiq)
add_simple_test(qxmppnonsaslauthiq)
add_simple_test(qxmpppresence)
add_simple_test(qxmpppubsubiq)
Oops, something went wrong.

0 comments on commit 95063b1

Please sign in to comment.