gloox 1.0.24
capabilities.cpp
1/*
2 Copyright (c) 2007-2019 by Jakob Schröter <js@camaya.net>
3 This file is part of the gloox library. http://camaya.net/gloox
4
5 This software is distributed under a license. The full license
6 agreement can be found in the file LICENSE in this distribution.
7 This software may not be copied, modified, sold or distributed
8 other than expressed in the named license agreement.
9
10 This software is distributed without any warranty.
11*/
12
13
14#include "capabilities.h"
15
16#include "base64.h"
17#include "disco.h"
18#include "dataform.h"
19#include "sha.h"
20#include "tag.h"
21
22namespace gloox
23{
24
26 : StanzaExtension( ExtCaps ), m_disco( disco ), m_node( GLOOX_CAPS_NODE ),
27 m_hash( "sha-1" ), m_valid( false )
28 {
29 if( m_disco )
30 m_valid = true;
31 }
32
34 : StanzaExtension( ExtCaps ), m_disco( 0 ), m_valid( false )
35 {
36 if( !tag || tag->name() != "c" || !tag->hasAttribute( XMLNS, XMLNS_CAPS )
37 || !tag->hasAttribute( "node" ) || !tag->hasAttribute( "ver" ) )
38 return;
39
40 m_node = tag->findAttribute( "node" );
41 m_ver = tag->findAttribute( "ver" );
42 m_hash = tag->findAttribute( "hash" );
43 m_valid = true;
44 }
45
47 {
48 if( m_disco )
49 m_disco->removeNodeHandlers( const_cast<Capabilities*>( this ) );
50 }
51
52 const std::string Capabilities::ver() const
53 {
54 if( !m_disco )
55 return m_ver;
56
57 SHA sha;
58 sha.feed( generate( m_disco->identities(), m_disco->features( true ), m_disco->form() ) );
59 const std::string& hash = Base64::encode64( sha.binary() );
60 m_disco->removeNodeHandlers( const_cast<Capabilities*>( this ) );
61 m_disco->registerNodeHandler( const_cast<Capabilities*>( this ), m_node + '#' + hash );
62 return hash;
63 }
64
65 std::string Capabilities::generate( const Disco::IdentityList& il, const StringList& features, const DataForm* form )
66 {
67 StringList sl;
68 Disco::IdentityList::const_iterator it = il.begin();
69 for( ; it != il.end(); ++it )
70 {
71 std::string id = (*it)->category();
72 id += '/';
73 id += (*it)->type();
74 id += '/';
75 // FIXME add xml:lang caps here. see XEP-0115 Section 5
76 id += '/';
77 id += (*it)->name();
78 sl.push_back( id );
79 }
80 sl.sort();
81
82 std::string s;
83 StringList::const_iterator it2 = sl.begin();
84 for( ; it2 != sl.end(); ++it2 )
85 {
86 s += (*it2);
87 s += '<';
88 }
89
90 StringList f = features;
91 f.sort();
92 it2 = f.begin();
93 for( ; it2 != f.end(); ++it2 )
94 {
95 s += (*it2);
96 s += '<';
97 }
98
99 if( form )
100 {
101 DataForm::FieldList::const_iterator it3 = form->fields().begin();
102 typedef std::map<std::string, StringList> MapSSL;
103
104 MapSSL m;
105 for( ; it3 != form->fields().end(); ++it3 )
106 {
107 if( (*it3)->name() == "FORM_TYPE" )
108 {
109 s += (*it3)->value();
110 s += '<';
111 }
112 else
113 m.insert( std::make_pair( (*it3)->name(), (*it3)->values() ) );
114 }
115
116 MapSSL::iterator it4 = m.begin();
117 for( ; it4 != m.end(); ++it4 )
118 {
119 s += it4->first;
120 s += '<';
121 it2 = it4->second.begin();
122 for( ; it2 != it4->second.end(); ++it2 )
123 {
124 s += (*it2);
125 s += '<';
126 }
127 }
128 }
129 return s;
130 }
131
132 std::string Capabilities::generate( const Disco::Info* info )
133 {
134 return info ? generate( info->identities(), info->features(), info->form() ) : EmptyString;
135 }
136
137 std::string Capabilities::generate( const Disco* disco )
138 {
139 return disco ? generate( disco->identities(), disco->features(), disco->form() ) : EmptyString;
140 }
141
142 const std::string& Capabilities::filterString() const
143 {
144 static const std::string filter = "/presence/c[@xmlns='" + XMLNS_CAPS + "']";
145 return filter;
146 }
147
149 {
150 if( !m_valid || m_node.empty() )
151 return 0;
152
153 Tag* t = new Tag( "c" );
154 t->setXmlns( XMLNS_CAPS );
155 t->addAttribute( "hash", m_hash );
156 t->addAttribute( "node", m_node );
157 t->addAttribute( "ver", ver() );
158 return t;
159 }
160
162 {
163 return m_disco->features();
164 }
165
167 {
168 const Disco::IdentityList& il = m_disco->identities();
170 Disco::IdentityList::const_iterator it = il.begin();
171 for( ; it != il.end(); ++it )
172 {
173 ret.push_back( new Disco::Identity( *(*it) ) );
174 }
175 return ret;
176 }
177
178 Disco::ItemList Capabilities::handleDiscoNodeItems( const JID&, const JID&, const std::string& )
179 {
180 return Disco::ItemList();
181 }
182
183}
This is an implementation of XEP-0115 (Entity Capabilities).
Definition: capabilities.h:37
Capabilities(Disco *disco)
const std::string ver() const
virtual const std::string & filterString() const
virtual Disco::ItemList handleDiscoNodeItems(const JID &from, const JID &to, const std::string &node=EmptyString)
virtual Disco::IdentityList handleDiscoNodeIdentities(const JID &from, const std::string &node)
virtual StringList handleDiscoNodeFeatures(const JID &from, const std::string &node)
virtual Tag * tag() const
An abstraction of a XEP-0004 Data Form.
Definition: dataform.h:57
An abstraction of a Disco identity (Service Discovery, XEP-0030).
Definition: disco.h:197
This class implements XEP-0030 (Service Discovery) and XEP-0092 (Software Version).
Definition: disco.h:46
const DataForm * form() const
Definition: disco.h:544
const IdentityList & identities() const
Definition: disco.h:529
void removeNodeHandlers(DiscoNodeHandler *nh)
Definition: disco.cpp:513
void registerNodeHandler(DiscoNodeHandler *nh, const std::string &node)
Definition: disco.cpp:497
const StringList features(bool defaultFeatures=false) const
Definition: disco.cpp:524
std::list< Identity * > IdentityList
Definition: disco.h:56
std::list< Item * > ItemList
Definition: disco.h:266
An abstraction of a JID.
Definition: jid.h:31
An implementation of SHA1.
Definition: sha.h:30
void feed(const unsigned char *data, unsigned length)
Definition: sha.cpp:89
const std::string binary()
Definition: sha.cpp:68
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
This is an abstraction of an XML element.
Definition: tag.h:47
const std::string & name() const
Definition: tag.h:394
bool addAttribute(Attribute *attr)
Definition: tag.cpp:354
bool hasAttribute(const std::string &name, const std::string &value=EmptyString) const
Definition: tag.cpp:602
const std::string & findAttribute(const std::string &name) const
Definition: tag.cpp:589
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition: tag.cpp:522
const std::string encode64(const std::string &input)
Definition: base64.cpp:38
The namespace for the gloox library.
Definition: adhoc.cpp:28
std::list< std::string > StringList
Definition: gloox.h:1251
const std::string GLOOX_CAPS_NODE
Definition: gloox.cpp:120
const std::string EmptyString
Definition: gloox.cpp:124
const std::string XMLNS
Definition: gloox.cpp:122
const std::string XMLNS_CAPS
Definition: gloox.cpp:81