jinglesession.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 "jinglesession.h"
#include "clientbase.h"
#include "error.h"
#include "jinglecontent.h"
#include "jinglesessionhandler.h"
#include "tag.h"
#include "util.h"
namespace gloox
{
namespace Jingle
{
static const char* actionValues [] = {
"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 inline Action actionType( const std::string& type )
{
return static_cast<Action>( util::lookup( type, actionValues ) );
}
// ---- Session::Reason ----
static const char* reasonValues [] = {
"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 inline Session::Reason::Reasons reasonType( const std::string& type )
{
return static_cast<Session::Reason::Reasons>( util::lookup( type, reasonValues ) );
}
Session::Reason::Reason( Reasons reason,
const std::string& sid,
const std::string& text)
: Plugin( PluginReason ), m_reason( reason ), m_sid( sid ), m_text( text )
{
}
Session::Reason::Reason( const Tag* tag )
: Plugin( PluginReason )
{
if( !tag || tag->name() != "reason" )
return;
const TagList& l = tag->children();
TagList::const_iterator it = l.begin();
for( ; it != l.end(); ++it )
{
if( (*it)->name() == "text" )
m_text = (*it)->cdata();
else if( (*it)->xmlns() == XMLNS_JINGLE )
m_reason = reasonType( (*it)->name() );
}
}
Session::Reason::~Reason()
{
}
const std::string& Session::Reason::filterString() const
{
static const std::string filter = "jingle/reason";
return filter;
}
Tag* Session::Reason::tag() const
{
if( m_reason == InvalidReason )
return 0;
Tag* t = new Tag( "reason" );
Tag* r = new Tag( t, util::lookup( m_reason, reasonValues ) );
if( m_reason == AlternativeSession && !m_sid.empty() )
new Tag( r, "sid", m_sid );
if( !m_text.empty() )
new Tag( t, "text", m_text );
return t;
}
Plugin* Session::Reason::clone() const
{
return new Reason( *this );
}
// ---- ~Session::Reason ----
// ---- Session::Jingle ----
Session::Jingle::Jingle( Action action, const JID& initiator, const JID& responder,
const PluginList& plugins, const std::string& sid )
: StanzaExtension( ExtJingle ), m_action( action ), m_sid( sid ),
m_initiator( initiator ), m_responder( responder ), m_plugins( plugins ), m_tag( 0 )
{
}
#ifdef JINGLE_TEST
Session::Jingle::Jingle( Action action, const JID& initiator, const JID& responder,
const Plugin* plugin, const std::string& sid )
: StanzaExtension( ExtJingle ), m_action( action ), m_sid( sid ),
m_initiator( initiator ), m_responder( responder ), m_tag( 0 )
{
if( plugin )
m_plugins.push_back( plugin );
}
#endif
Session::Jingle::Jingle( const Tag* tag )
: StanzaExtension( ExtJingle ), m_action( InvalidAction ), m_tag( 0 )
{
if( !tag || tag->name() != "jingle" )
return;
m_action = actionType( tag->findAttribute( "action" ) );
m_initiator.setJID( tag->findAttribute( "initiator" ) );
m_responder.setJID( tag->findAttribute( "responder" ) );
m_sid = tag->findAttribute( "sid" );
m_tag = tag->clone();
}
// Session::Jingle::Jingle( const Jingle& right )
// : StanzaExtension( ExtJingle ), m_action( right.m_action ),
// m_sid( right.m_sid ), m_initiator( right.m_initiator ),
// m_responder( right.m_responder )
// {
// PluginList::const_iterator it = right.m_plugins.begin();
// for( ; it != right.m_plugins.end(); ++it )
// m_plugins.push_back( (*it)->clone() );
// }
Session::Jingle::~Jingle()
{
util::clearList( m_plugins );
}
const std::string& Session::Jingle::filterString() const
{
static const std::string filter = "/iq/jingle[@xmlns='" + XMLNS_JINGLE + "']";
return filter;
}
Tag* Session::Jingle::tag() const
{
if( m_action == InvalidAction || m_sid.empty() )
return 0;
Tag* t = new Tag( "jingle" );
t->setXmlns( XMLNS_JINGLE );
t->addAttribute( "action", util::lookup( m_action, actionValues ) );
if( m_initiator && m_action == SessionInitiate )
t->addAttribute( "initiator", m_initiator.full() );
if( m_responder && m_action == SessionAccept )
t->addAttribute( "responder", m_responder.full() );
t->addAttribute( "sid", m_sid );
PluginList::const_iterator it = m_plugins.begin();
for( ; it != m_plugins.end(); ++it )
t->addChild( (*it)->tag() );
return t;
}
StanzaExtension* Session::Jingle::clone() const
{
return new Jingle( *this );
}
// ---- ~Session::Jingle ----
// ---- Session ----
Session::Session( ClientBase* parent, const JID& callee, SessionHandler* jsh )
: m_parent( parent ), m_state( Ended ), m_remote( callee ),
m_handler( jsh ), m_valid( false )
{
if( !m_parent || !m_handler || !m_remote )
return;
m_initiator = m_parent->jid();
m_sid = m_parent->getID();
m_valid = true;
}
Session::Session( ClientBase* parent, const JID& callee, const Session::Jingle* jingle, SessionHandler* jsh )
: m_parent( parent ), m_state( Ended ), m_handler( jsh ), m_valid( false )
{
if( !m_parent || !m_handler || !callee /*|| jingle->action() != SessionInitiate*/ )
return;
m_remote = callee;
m_sid = jingle->sid();
m_valid = true;
}
Session::~Session()
{
if( m_parent )
m_parent->removeIDHandler( this );
}
bool Session::contentAccept( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( ContentAccept, content );
}
bool Session::contentAdd( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( ContentAdd, content );
}
bool Session::contentAdd( const PluginList& contents )
{
if( m_state < Pending )
return false;
return doAction( ContentAdd, contents );
}
bool Session::contentModify( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( ContentModify, content );
}
bool Session::contentReject( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( ContentReject, content );
}
bool Session::contentRemove( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( ContentRemove, content );
}
bool Session::descriptionInfo( const Plugin* info )
{
if( m_state < Pending )
return false;
return doAction( DescriptionInfo, info );
}
bool Session::securityInfo( const Plugin* info )
{
if( m_state < Pending )
return false;
return doAction( SecurityInfo, info );
}
bool Session::sessionAccept( const Content* content )
{
if( !content || m_state > Pending )
return false;
m_state = Active;
return doAction( SessionAccept, content );
}
bool Session::sessionAccept( const PluginList& plugins )
{
if( plugins.empty() || m_state != Pending )
return false;
m_state = Active;
return doAction( SessionAccept, plugins );
}
bool Session::sessionInfo( const Plugin* info )
{
if( m_state < Pending )
return false;
return doAction( SessionInfo, info );
}
bool Session::sessionInitiate( const Content* content )
{
if( !content || !m_initiator || m_state >= Pending )
return false;
m_state = Pending;
return doAction( SessionInitiate, content );
}
bool Session::sessionInitiate( const PluginList& plugins )
{
if( plugins.empty() || !m_initiator || m_state >= Pending )
return false;
m_state = Pending;
return doAction( SessionInitiate, plugins );
}
bool Session::sessionTerminate( Session::Reason* reason )
{
if( m_state < Pending /*|| !m_initiator*/ )
return false;
m_state = Ended;
return doAction( SessionTerminate, reason );
}
bool Session::transportAccept( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( TransportAccept, content );
}
bool Session::transportInfo( const Plugin* info )
{
if( m_state < Pending )
return false;
return doAction( TransportInfo, info );
}
bool Session::transportReject( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( TransportReject, content );
}
bool Session::transportReplace( const Content* content )
{
if( m_state < Pending )
return false;
return doAction( TransportReplace, content );
}
bool Session::doAction( Action action, const Plugin* plugin )
{
PluginList pl;
pl.push_back( plugin );
return doAction( action, pl );
}
bool Session::doAction( Action action, const PluginList& plugins )
{
if( !m_valid || !m_parent )
return false;
IQ init( IQ::Set, m_remote, m_parent->getID() );
init.addExtension( new Jingle( action, m_initiator, m_responder, plugins, m_sid ) );
m_parent->send( init, this, action );
return true;
}
bool Session::handleIq( const IQ& iq )
{
const Jingle* j = iq.findExtension<Jingle>( ExtJingle );
if( !j || j->sid() != m_sid || !m_handler || !m_parent )
return false;
switch( j->action() )
{
case SessionAccept:
m_state = Active;
m_responder = j->responder();
break;
case SessionInitiate:
m_state = Pending;
m_initiator = j->initiator();
if( !m_responder )
m_responder = m_parent->jid();
break;
case SessionTerminate:
m_state = Ended;
break;
default:
break;
}
IQ re( IQ::Result, iq.from(), iq.id() );
m_parent->send( re );
m_handler->handleSessionAction( j->action(), this, j );
return true;
}
void Session::handleIqID( const IQ& iq, int context )
{
if( iq.subtype() == IQ::Error )
{
const Error* e = iq.findExtension<Error>( ExtError );
m_handler->handleSessionActionError( static_cast<Action>( context ), this, e );
switch( context )
{
case ContentAccept:
break;
case ContentAdd:
break;
case ContentModify:
break;
case ContentReject:
break;
case ContentRemove:
break;
case DescriptionInfo:
break;
case SessionAccept:
break;
case SessionInfo:
break;
case SessionInitiate:
m_state = Ended;
break;
case SessionTerminate:
break;
case TransportAccept:
break;
case TransportInfo:
break;
case TransportReject:
break;
case TransportReplace:
break;
case InvalidAction:
break;
default:
break;
}
}
}
}
}
gloox::ClientBase
This is the common base class for a Jabber/XMPP Client and a Jabber Component.
Definition clientbase.h:79
gloox::ClientBase::getID
const std::string getID()
Definition clientbase.cpp:1168
gloox::ClientBase::send
void send(Tag *tag)
Definition clientbase.cpp:1004
gloox::Error
A stanza error abstraction implemented as a StanzaExtension.
Definition error.h:35
gloox::IQ
An abstraction of an IQ stanza.
Definition iq.h:34
gloox::IQ::subtype
IqType subtype() const
Definition iq.h:74
gloox::IQ::Set
@ Set
Definition iq.h:46
gloox::IQ::Error
@ Error
Definition iq.h:49
gloox::IQ::Result
@ Result
Definition iq.h:48
gloox::JID
An abstraction of a JID.
Definition jid.h:31
gloox::Jingle::Content
An abstraction of a Jingle Content Type. This is part of Jingle (XEP-0166).
Definition jinglecontent.h:42
gloox::Jingle::Plugin
An abstraction of a Jingle plugin. This is part of Jingle (XEP-0166 et al.).
Definition jingleplugin.h:68
gloox::Jingle::Plugin::Plugin
Plugin(JinglePluginType type)
Definition jingleplugin.h:76
gloox::Jingle::SessionHandler
A Jingle session handler.
Definition jinglesessionhandler.h:33
gloox::Jingle::Session::Jingle
This is an abstraction of Jingle's (XEP-0166) <jingle> element as a StanzaExtension.
Definition jinglesession.h:199
gloox::Jingle::Session::Jingle::clone
virtual StanzaExtension * clone() const
Definition jinglesession.cpp:212
gloox::Jingle::Session::Jingle::filterString
virtual const std::string & filterString() const
Definition jinglesession.cpp:182
gloox::Jingle::Session::Jingle::~Jingle
virtual ~Jingle()
Definition jinglesession.cpp:177
gloox::Jingle::Session::Jingle::sid
const std::string & sid() const
Definition jinglesession.h:219
gloox::Jingle::Session::Jingle::Jingle
Jingle(const Tag *tag=0)
Definition jinglesession.cpp:153
gloox::Jingle::Session::Jingle::tag
virtual Tag * tag() const
Definition jinglesession.cpp:188
gloox::Jingle::Session::Reason
An abstraction of a Jingle (XEP-0166) session terminate reason.
Definition jinglesession.h:105
gloox::Jingle::Session::Reason::~Reason
virtual ~Reason()
Definition jinglesession.cpp:102
gloox::Jingle::Session::Reason::Reason
Reason(Reasons reason, const std::string &sid=EmptyString, const std::string &text=EmptyString)
Definition jinglesession.cpp:78
gloox::Jingle::Session::Reason::Reasons
Reasons
Definition jinglesession.h:111
gloox::Jingle::Session::Reason::AlternativeSession
@ AlternativeSession
Definition jinglesession.h:112
gloox::Jingle::Session::Reason::InvalidReason
@ InvalidReason
Definition jinglesession.h:129
gloox::Jingle::Session::Reason::clone
virtual Plugin * clone() const
Definition jinglesession.cpp:128
gloox::Jingle::Session::Reason::reason
Reasons reason() const
Definition jinglesession.h:156
gloox::Jingle::Session::Reason::filterString
virtual const std::string & filterString() const
Definition jinglesession.cpp:106
gloox::Jingle::Session::Reason::sid
const std::string & sid() const
Definition jinglesession.h:163
gloox::Jingle::Session::Reason::text
const std::string & text() const
Definition jinglesession.h:170
gloox::Jingle::Session::Reason::tag
virtual Tag * tag() const
Definition jinglesession.cpp:112
gloox::Jingle::Session::contentReject
bool contentReject(const Content *content)
Definition jinglesession.cpp:282
gloox::Jingle::Session::transportReplace
bool transportReplace(const Content *content)
Definition jinglesession.cpp:392
gloox::Jingle::Session::sessionAccept
bool sessionAccept(const Content *content)
Definition jinglesession.cpp:314
gloox::Jingle::Session::contentRemove
bool contentRemove(const Content *content)
Definition jinglesession.cpp:290
gloox::Jingle::Session::~Session
virtual ~Session()
Definition jinglesession.cpp:244
gloox::Jingle::Session::sessionInfo
bool sessionInfo(const Plugin *info)
Definition jinglesession.cpp:332
gloox::Jingle::Session::transportReject
bool transportReject(const Content *content)
Definition jinglesession.cpp:384
gloox::Jingle::Session::transportInfo
bool transportInfo(const Plugin *info)
Definition jinglesession.cpp:376
gloox::Jingle::Session::contentAdd
bool contentAdd(const Content *content)
Definition jinglesession.cpp:258
gloox::Jingle::Session::sessionInitiate
bool sessionInitiate(const Content *content)
Definition jinglesession.cpp:340
gloox::Jingle::Session::transportAccept
bool transportAccept(const Content *content)
Definition jinglesession.cpp:368
gloox::Jingle::Session::handleIqID
virtual void handleIqID(const IQ &iq, int context)
Definition jinglesession.cpp:452
gloox::Jingle::Session::handleIq
virtual bool handleIq(const IQ &iq)
Definition jinglesession.cpp:419
gloox::Jingle::Session::contentModify
bool contentModify(const Content *content)
Definition jinglesession.cpp:274
gloox::Jingle::Session::Pending
@ Pending
Definition jinglesession.h:92
gloox::Jingle::Session::Active
@ Active
Definition jinglesession.h:93
gloox::Jingle::Session::Ended
@ Ended
Definition jinglesession.h:91
gloox::Jingle::Session::responder
const JID & responder() const
Definition jinglesession.h:343
gloox::Jingle::Session::sid
const std::string & sid() const
Definition jinglesession.h:525
gloox::Jingle::Session::securityInfo
bool securityInfo(const Plugin *info)
Definition jinglesession.cpp:306
gloox::Jingle::Session::descriptionInfo
bool descriptionInfo(const Plugin *info)
Definition jinglesession.cpp:298
gloox::Jingle::Session::initiator
const JID & initiator() const
Definition jinglesession.h:336
gloox::Jingle::Session::contentAccept
bool contentAccept(const Content *content)
Definition jinglesession.cpp:250
gloox::Jingle::Session::sessionTerminate
bool sessionTerminate(Session::Reason *reason)
Definition jinglesession.cpp:358
gloox::StanzaExtension
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
Definition stanzaextension.h:204
gloox::StanzaExtension::StanzaExtension
StanzaExtension(int type)
Definition stanzaextension.h:211
gloox::Stanza::id
const std::string & id() const
Definition stanza.h:63
gloox::Stanza::from
const JID & from() const
Definition stanza.h:51
gloox::Stanza::findExtension
const StanzaExtension * findExtension(int type) const
Definition stanza.cpp:57
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::addChild
void addChild(Tag *child)
Definition tag.cpp:424
gloox::Tag::setXmlns
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition tag.cpp:522
gloox::Jingle
The namespace containing Jingle-related (XEP-0166 et. al.) classes.
Definition jinglecontent.cpp:22
gloox::Jingle::PluginReason
@ PluginReason
Definition jingleplugin.h:43
gloox::Jingle::Action
Action
Definition jinglesession.h:50
gloox::Jingle::ContentAdd
@ ContentAdd
Definition jinglesession.h:52
gloox::Jingle::ContentModify
@ ContentModify
Definition jinglesession.h:53
gloox::Jingle::ContentRemove
@ ContentRemove
Definition jinglesession.h:55
gloox::Jingle::DescriptionInfo
@ DescriptionInfo
Definition jinglesession.h:56
gloox::Jingle::InvalidAction
@ InvalidAction
Definition jinglesession.h:66
gloox::Jingle::TransportReject
@ TransportReject
Definition jinglesession.h:64
gloox::Jingle::ContentAccept
@ ContentAccept
Definition jinglesession.h:51
gloox::Jingle::SessionInfo
@ SessionInfo
Definition jinglesession.h:59
gloox::Jingle::SessionAccept
@ SessionAccept
Definition jinglesession.h:58
gloox::Jingle::SessionInitiate
@ SessionInitiate
Definition jinglesession.h:60
gloox::Jingle::ContentReject
@ ContentReject
Definition jinglesession.h:54
gloox::Jingle::TransportReplace
@ TransportReplace
Definition jinglesession.h:65
gloox::Jingle::SecurityInfo
@ SecurityInfo
Definition jinglesession.h:57
gloox::Jingle::TransportInfo
@ TransportInfo
Definition jinglesession.h:63
gloox::Jingle::TransportAccept
@ TransportAccept
Definition jinglesession.h:62
gloox::Jingle::SessionTerminate
@ SessionTerminate
Definition jinglesession.h:61
gloox::Jingle::PluginList
std::list< const Plugin * > PluginList
Definition jingleplugin.h:52
gloox::util::clearList
void clearList(std::list< T * > &L)
Definition util.h:152
gloox
The namespace for the gloox library.
Definition adhoc.cpp:28
gloox::TagList
std::list< Tag * > TagList
Definition tag.h:31
gloox::XMLNS_JINGLE
const std::string XMLNS_JINGLE
Definition gloox.cpp:101
gloox::ExtJingle
@ ExtJingle
Definition stanzaextension.h:77
gloox::ExtError
@ ExtError
Definition stanzaextension.h:47