capabilities.cpp
/*
Copyright (c) 2007-2023 by Jakob Schröter <js@camaya.net>
This file is part of the gloox library. http://camaya.net/gloox
This software is distributed under a license. The full license
agreement can be found in the file LICENSE in this distribution.
This software may not be copied, modified, sold or distributed
other than expressed in the named license agreement.
This software is distributed without any warranty.
*/
#include "capabilities.h"
#include "base64.h"
#include "disco.h"
#include "dataform.h"
#include "sha.h"
#include "tag.h"
namespace gloox
{
Capabilities::Capabilities( Disco* disco )
: StanzaExtension( ExtCaps ), m_disco( disco ), m_node( GLOOX_CAPS_NODE ),
m_hash( "sha-1" ), m_valid( false )
{
if( m_disco )
m_valid = true;
}
Capabilities::Capabilities( const Tag* tag )
: StanzaExtension( ExtCaps ), m_disco( 0 ), m_valid( false )
{
if( !tag || tag->name() != "c" || !tag->hasAttribute( XMLNS, XMLNS_CAPS )
|| !tag->hasAttribute( "node" ) || !tag->hasAttribute( "ver" ) )
return;
m_node = tag->findAttribute( "node" );
m_ver = tag->findAttribute( "ver" );
m_hash = tag->findAttribute( "hash" );
m_valid = true;
}
Capabilities::~Capabilities()
{
if( m_disco )
m_disco->removeNodeHandlers( const_cast<Capabilities*>( this ) );
}
const std::string Capabilities::ver() const
{
if( !m_disco )
return m_ver;
SHA sha;
sha.feed( generate( m_disco->identities(), m_disco->features( true ), m_disco->form() ) );
const std::string& hash = Base64::encode64( sha.binary() );
m_disco->removeNodeHandlers( const_cast<Capabilities*>( this ) );
m_disco->registerNodeHandler( const_cast<Capabilities*>( this ), m_node + '#' + hash );
return hash;
}
std::string Capabilities::generate( const Disco::IdentityList& il, const StringList& features, const DataForm* form )
{
StringList sl;
Disco::IdentityList::const_iterator it = il.begin();
for( ; it != il.end(); ++it )
{
std::string id = (*it)->category();
id += '/';
id += (*it)->type();
id += '/';
// FIXME add xml:lang caps here. see XEP-0115 Section 5
id += '/';
id += (*it)->name();
sl.push_back( id );
}
sl.sort();
std::string s;
StringList::const_iterator it2 = sl.begin();
for( ; it2 != sl.end(); ++it2 )
{
s += (*it2);
s += '<';
}
StringList f = features;
f.sort();
it2 = f.begin();
for( ; it2 != f.end(); ++it2 )
{
s += (*it2);
s += '<';
}
if( form )
{
DataForm::FieldList::const_iterator it3 = form->fields().begin();
typedef std::map<std::string, StringList> MapSSL;
MapSSL m;
for( ; it3 != form->fields().end(); ++it3 )
{
if( (*it3)->name() == "FORM_TYPE" )
{
s += (*it3)->value();
s += '<';
}
else
m.insert( std::make_pair( (*it3)->name(), (*it3)->values() ) );
}
MapSSL::iterator it4 = m.begin();
for( ; it4 != m.end(); ++it4 )
{
s += it4->first;
s += '<';
it2 = it4->second.begin();
for( ; it2 != it4->second.end(); ++it2 )
{
s += (*it2);
s += '<';
}
}
}
return s;
}
std::string Capabilities::generate( const Disco::Info* info )
{
return info ? generate( info->identities(), info->features(), info->form() ) : EmptyString;
}
std::string Capabilities::generate( const Disco* disco )
{
return disco ? generate( disco->identities(), disco->features(), disco->form() ) : EmptyString;
}
const std::string& Capabilities::filterString() const
{
static const std::string filter = "/presence/c[@xmlns='" + XMLNS_CAPS + "']";
return filter;
}
Tag* Capabilities::tag() const
{
if( !m_valid || m_node.empty() )
return 0;
Tag* t = new Tag( "c" );
t->setXmlns( XMLNS_CAPS );
t->addAttribute( "hash", m_hash );
t->addAttribute( "node", m_node );
t->addAttribute( "ver", ver() );
return t;
}
StringList Capabilities::handleDiscoNodeFeatures( const JID&, const std::string& )
{
return m_disco->features();
}
Disco::IdentityList Capabilities::handleDiscoNodeIdentities( const JID&, const std::string& )
{
const Disco::IdentityList& il = m_disco->identities();
Disco::IdentityList ret;
Disco::IdentityList::const_iterator it = il.begin();
for( ; it != il.end(); ++it )
{
ret.push_back( new Disco::Identity( *(*it) ) );
}
return ret;
}
Disco::ItemList Capabilities::handleDiscoNodeItems( const JID&, const JID&, const std::string& )
{
return Disco::ItemList();
}
}
gloox::Capabilities::Capabilities
Capabilities(Disco *disco)
Definition capabilities.cpp:25
gloox::Capabilities::ver
const std::string ver() const
Definition capabilities.cpp:52
gloox::Capabilities::filterString
virtual const std::string & filterString() const
Definition capabilities.cpp:142
gloox::Capabilities::handleDiscoNodeItems
virtual Disco::ItemList handleDiscoNodeItems(const JID &from, const JID &to, const std::string &node=EmptyString)
Definition capabilities.cpp:178
gloox::Capabilities::~Capabilities
virtual ~Capabilities()
Definition capabilities.cpp:46
gloox::Capabilities::handleDiscoNodeIdentities
virtual Disco::IdentityList handleDiscoNodeIdentities(const JID &from, const std::string &node)
Definition capabilities.cpp:166
gloox::Capabilities::handleDiscoNodeFeatures
virtual StringList handleDiscoNodeFeatures(const JID &from, const std::string &node)
Definition capabilities.cpp:161
gloox::Capabilities::tag
virtual Tag * tag() const
Definition capabilities.cpp:148
gloox::DataFormFieldContainer::fields
FieldList & fields()
Definition dataformfieldcontainer.h:79
gloox::DataForm
An abstraction of a XEP-0004 Data Form.
Definition dataform.h:57
gloox::Disco::Identity
An abstraction of a Disco identity (Service Discovery, XEP-0030).
Definition disco.h:197
gloox::Disco::Info
An abstraction of a Disco Info element (from Service Discovery, XEP-0030) as a StanzaExtension.
Definition disco.h:66
gloox::Disco
This class implements XEP-0030 (Service Discovery) and XEP-0092 (Software Version).
Definition disco.h:46
gloox::Disco::IdentityList
std::list< Identity * > IdentityList
Definition disco.h:56
gloox::Disco::ItemList
std::list< Item * > ItemList
Definition disco.h:266
gloox::JID
An abstraction of a JID.
Definition jid.h:31
gloox::SHA
An implementation of SHA1.
Definition sha.h:30
gloox::SHA::feed
void feed(const unsigned char *data, unsigned length)
Definition sha.cpp:89
gloox::SHA::binary
const std::string binary()
Definition sha.cpp:68
gloox::StanzaExtension::StanzaExtension
StanzaExtension(int type)
Definition stanzaextension.h:211
gloox::Tag
This is an abstraction of an XML element.
Definition tag.h:47
gloox::Tag::addAttribute
bool addAttribute(Attribute *attr)
Definition tag.cpp:354
gloox::Tag::setXmlns
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition tag.cpp:522
gloox::Base64::encode64
const std::string encode64(const std::string &input)
Definition base64.cpp:38
gloox
The namespace for the gloox library.
Definition adhoc.cpp:28
gloox::StringList
std::list< std::string > StringList
Definition gloox.h:1251
gloox::GLOOX_CAPS_NODE
const std::string GLOOX_CAPS_NODE
Definition gloox.cpp:120
gloox::EmptyString
const std::string EmptyString
Definition gloox.cpp:124
gloox::XMLNS
const std::string XMLNS
Definition gloox.cpp:122
gloox::XMLNS_CAPS
const std::string XMLNS_CAPS
Definition gloox.cpp:81
gloox::ExtCaps
@ ExtCaps
Definition stanzaextension.h:48