1
/****************************************************************************
5
** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
7
*****************************************************************************
9
** $JREEN_BEGIN_LICENSE$
10
** This program is free software: you can redistribute it and/or modify
11
** it under the terms of the GNU General Public License as published by
12
** the Free Software Foundation, either version 2 of the License, or
13
** (at your option) any later version.
15
** This program is distributed in the hope that it will be useful,
16
** but WITHOUT ANY WARRANTY; without even the implied warranty of
17
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
** See the GNU General Public License for more details.
20
** You should have received a copy of the GNU General Public License
21
** along with this program. If not, see http://www.gnu.org/licenses/.
22
** $JREEN_END_LICENSE$
24
****************************************************************************/
26
#include "bindfeature_p.h"
29
#include <QXmlStreamWriter>
30
#include <QStringList>
33
#define NS_BIND QLatin1String("urn:ietf:params:xml:ns:xmpp-bind")
37
class BindQuery : public Payload
39
J_PAYLOAD(Jreen::BindQuery)
41
BindQuery(const JID &jid, const QString &resource, bool bind = true)
42
: m_jid(jid), m_resource(resource), m_bind(bind) {}
43
JID jid() { return m_jid; }
44
QString resource() { return m_resource; }
45
bool isBind() { return m_bind; }
52
class JREEN_AUTOTEST_EXPORT BindQueryFactory : public PayloadFactory<BindQuery>
55
BindQueryFactory() : m_bind(true), m_depth(0), m_state(AtStart) {}
56
QStringList features() const { return QStringList(); }
57
bool canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
58
void handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes);
59
void handleEndElement(const QStringRef &name, const QStringRef &uri);
60
void handleCharacterData(const QStringRef &text);
61
void serialize(Payload *extension, QXmlStreamWriter *writer);
62
Payload::Ptr createPayload();
64
enum State { AtStart, AtResource, AtJid };
72
bool BindQueryFactory::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
75
return (name == QLatin1String("bind") || name == QLatin1String("unbind")) && uri == NS_BIND;
78
void BindQueryFactory::handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
85
m_bind = name == QLatin1String("bind");
88
} else if (m_depth == 2) {
89
if (name == QLatin1String("jid"))
91
else if (name == QLatin1String("resource"))
98
void BindQueryFactory::handleEndElement(const QStringRef &name, const QStringRef &uri)
107
void BindQueryFactory::handleCharacterData(const QStringRef &text)
109
if (m_depth == 2 && m_state == AtResource)
110
m_resource = text.toString();
111
else if (m_depth == 2 && m_state == AtJid)
112
m_jid = text.toString();
115
void BindQueryFactory::serialize(Payload *extension, QXmlStreamWriter *writer)
117
BindQuery *query = se_cast<BindQuery*>(extension);
118
writer->writeStartElement(QLatin1String(query->isBind() ? "bind" : "unbind"));
119
writer->writeDefaultNamespace(NS_BIND);
120
if (query->jid().isValid())
121
writer->writeTextElement(QLatin1String("jid"), query->jid());
122
else if (!query->resource().isEmpty())
123
writer->writeTextElement(QLatin1String("resource"), query->resource());
124
writer->writeEndElement();
127
Payload::Ptr BindQueryFactory::createPayload()
129
return Payload::Ptr(new BindQuery(m_jid, m_resource, m_bind));
132
BindFeature::BindFeature() : StreamFeature(Custom)
134
m_hasFeature = false;
137
void BindFeature::setStreamInfo(StreamInfo *info)
139
StreamFeature::setStreamInfo(info);
140
info->client()->registerPayload(new BindQueryFactory);
143
void BindFeature::reset()
145
m_hasFeature = false;
148
bool BindFeature::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
150
Q_UNUSED(attributes);
151
Logger::debug() << Q_FUNC_INFO;
152
return name == QLatin1String("bind") && uri == NS_BIND;
155
void BindFeature::handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
159
Q_UNUSED(attributes);
160
Logger::debug() << Q_FUNC_INFO;
164
void BindFeature::handleEndElement(const QStringRef &name, const QStringRef &uri)
170
void BindFeature::handleCharacterData(const QStringRef &text)
175
bool BindFeature::isActivatable()
180
bool BindFeature::activate()
182
IQ::Ptr iq(new ConnectionIQ(IQ::Set, JID()));
183
iq->addExtension(new BindQuery(JID(), m_info->jid().resource()));
184
m_info->client()->send(*iq.data(), this, SLOT(onIQResult(Jreen::IQ,int)), 0);
188
void BindFeature::onIQResult(const IQ &iq, int context)
190
Q_ASSERT(context == 0);
191
BindQuery::Ptr query = iq.payload<BindQuery>();
192
if (query && iq.subtype() == IQ::Result) {
193
m_info->setJID(query->jid());
194
m_info->completed(StreamInfo::ActivateNext);