diff options
Diffstat (limited to 'Swiften/Component/CoreComponent.cpp')
-rw-r--r-- | Swiften/Component/CoreComponent.cpp | 253 |
1 files changed, 133 insertions, 120 deletions
diff --git a/Swiften/Component/CoreComponent.cpp b/Swiften/Component/CoreComponent.cpp index d2cc7aa..ef7d3a4 100644 --- a/Swiften/Component/CoreComponent.cpp +++ b/Swiften/Component/CoreComponent.cpp @@ -1,164 +1,177 @@ /* - * Copyright (c) 2010-2013 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2019 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ #include <Swiften/Component/CoreComponent.h> #include <boost/bind.hpp> -#include <iostream> +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/Base/Log.h> #include <Swiften/Component/ComponentSession.h> +#include <Swiften/Component/ComponentSessionStanzaChannel.h> #include <Swiften/Network/Connector.h> #include <Swiften/Network/NetworkFactories.h> -#include <Swiften/TLS/PKCS12Certificate.h> -#include <Swiften/Session/BasicSessionStream.h> #include <Swiften/Queries/IQRouter.h> -#include <Swiften/Base/IDGenerator.h> -#include <Swiften/Component/ComponentSessionStanzaChannel.h> +#include <Swiften/Session/BasicSessionStream.h> +#include <Swiften/TLS/PKCS12Certificate.h> +#include <Swiften/TLS/TLSOptions.h> namespace Swift { CoreComponent::CoreComponent(const JID& jid, const std::string& secret, NetworkFactories* networkFactories) : networkFactories(networkFactories), jid_(jid), secret_(secret), disconnectRequested_(false) { - stanzaChannel_ = new ComponentSessionStanzaChannel(); - stanzaChannel_->onMessageReceived.connect(boost::ref(onMessageReceived)); - stanzaChannel_->onPresenceReceived.connect(boost::ref(onPresenceReceived)); - stanzaChannel_->onAvailableChanged.connect(boost::bind(&CoreComponent::handleStanzaChannelAvailableChanged, this, _1)); + stanzaChannel_ = new ComponentSessionStanzaChannel(); + stanzaChannel_->onMessageReceived.connect(boost::ref(onMessageReceived)); + stanzaChannel_->onPresenceReceived.connect(boost::ref(onPresenceReceived)); + stanzaChannel_->onAvailableChanged.connect(boost::bind(&CoreComponent::handleStanzaChannelAvailableChanged, this, _1)); - iqRouter_ = new IQRouter(stanzaChannel_); - iqRouter_->setFrom(jid); + iqRouter_ = new IQRouter(stanzaChannel_); + iqRouter_->setFrom(jid); } CoreComponent::~CoreComponent() { - if (session_ || connection_) { - std::cerr << "Warning: Component not disconnected properly" << std::endl; - } - delete iqRouter_; - - stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&CoreComponent::handleStanzaChannelAvailableChanged, this, _1)); - stanzaChannel_->onMessageReceived.disconnect(boost::ref(onMessageReceived)); - stanzaChannel_->onPresenceReceived.disconnect(boost::ref(onPresenceReceived)); - delete stanzaChannel_; + if (session_ || connection_) { + SWIFT_LOG(warning) << "Component not disconnected properly"; + } + delete iqRouter_; + + stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&CoreComponent::handleStanzaChannelAvailableChanged, this, _1)); + stanzaChannel_->onMessageReceived.disconnect(boost::ref(onMessageReceived)); + stanzaChannel_->onPresenceReceived.disconnect(boost::ref(onPresenceReceived)); + delete stanzaChannel_; } -void CoreComponent::connect(const std::string& host, int port) { - assert(!connector_); - connector_ = ComponentConnector::create(host, port, networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory()); - connector_->onConnectFinished.connect(boost::bind(&CoreComponent::handleConnectorFinished, this, _1)); - connector_->setTimeoutMilliseconds(60*1000); - connector_->start(); +void CoreComponent::connect(const std::string& host, unsigned short port) { + assert(!connector_); + connector_ = ComponentConnector::create(host, port, networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory()); + connector_->onConnectFinished.connect(boost::bind(&CoreComponent::handleConnectorFinished, this, _1)); + connector_->setTimeoutMilliseconds(60*1000); + connector_->start(); } -void CoreComponent::handleConnectorFinished(boost::shared_ptr<Connection> connection) { - connector_->onConnectFinished.disconnect(boost::bind(&CoreComponent::handleConnectorFinished, this, _1)); - connector_.reset(); - if (!connection) { - if (!disconnectRequested_) { - onError(ComponentError::ConnectionError); - } - } - else { - assert(!connection_); - connection_ = connection; - - assert(!sessionStream_); - sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(ComponentStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), NULL, networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory())); - sessionStream_->onDataRead.connect(boost::bind(&CoreComponent::handleDataRead, this, _1)); - sessionStream_->onDataWritten.connect(boost::bind(&CoreComponent::handleDataWritten, this, _1)); - - session_ = ComponentSession::create(jid_, secret_, sessionStream_, networkFactories->getCryptoProvider()); - stanzaChannel_->setSession(session_); - session_->onFinished.connect(boost::bind(&CoreComponent::handleSessionFinished, this, _1)); - session_->start(); - } +void CoreComponent::handleConnectorFinished(std::shared_ptr<Connection> connection) { + connector_->onConnectFinished.disconnect(boost::bind(&CoreComponent::handleConnectorFinished, this, _1)); + connector_.reset(); + if (!connection) { + if (!disconnectRequested_) { + onError(ComponentError::ConnectionError); + } + } + else { + assert(!connection_); + connection_ = connection; + + assert(!sessionStream_); + sessionStream_ = std::make_shared<BasicSessionStream>(ComponentStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), nullptr, networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory(), TLSOptions()); + sessionStream_->onDataRead.connect(boost::bind(&CoreComponent::handleDataRead, this, _1)); + sessionStream_->onDataWritten.connect(boost::bind(&CoreComponent::handleDataWritten, this, _1)); + + session_ = ComponentSession::create(jid_, secret_, sessionStream_, networkFactories->getCryptoProvider()); + stanzaChannel_->setSession(session_); + session_->onFinished.connect(boost::bind(&CoreComponent::handleSessionFinished, this, _1)); + session_->start(); + } } void CoreComponent::disconnect() { - // FIXME: We should be able to do without this boolean. We just have to make sure we can tell the difference between - // connector finishing without a connection due to an error or because of a disconnect. - disconnectRequested_ = true; - if (session_) { - session_->finish(); - } - else if (connector_) { - connector_->stop(); - assert(!session_); - } - //assert(!session_); /* commenting out until we have time to refactor to be like CoreClient */ - //assert(!sessionStream_); - //assert(!connector_); - disconnectRequested_ = false; + // FIXME: We should be able to do without this boolean. We just have to make sure we can tell the difference between + // connector finishing without a connection due to an error or because of a disconnect. + disconnectRequested_ = true; + if (session_) { + session_->finish(); + } + else if (connector_) { + connector_->stop(); + assert(!session_); + } + //assert(!session_); /* commenting out until we have time to refactor to be like CoreClient */ + //assert(!sessionStream_); + //assert(!connector_); + disconnectRequested_ = false; } -void CoreComponent::handleSessionFinished(boost::shared_ptr<Error> error) { - session_->onFinished.disconnect(boost::bind(&CoreComponent::handleSessionFinished, this, _1)); - session_.reset(); - - sessionStream_->onDataRead.disconnect(boost::bind(&CoreComponent::handleDataRead, this, _1)); - sessionStream_->onDataWritten.disconnect(boost::bind(&CoreComponent::handleDataWritten, this, _1)); - sessionStream_.reset(); - - connection_->disconnect(); - connection_.reset(); - - if (error) { - ComponentError componentError; - if (boost::shared_ptr<ComponentSession::Error> actualError = boost::dynamic_pointer_cast<ComponentSession::Error>(error)) { - switch(actualError->type) { - case ComponentSession::Error::AuthenticationFailedError: - componentError = ComponentError(ComponentError::AuthenticationFailedError); - break; - case ComponentSession::Error::UnexpectedElementError: - componentError = ComponentError(ComponentError::UnexpectedElementError); - break; - } - } - else if (boost::shared_ptr<SessionStream::SessionStreamError> actualError = boost::dynamic_pointer_cast<SessionStream::SessionStreamError>(error)) { - switch(actualError->type) { - case SessionStream::SessionStreamError::ParseError: - componentError = ComponentError(ComponentError::XMLError); - break; - case SessionStream::SessionStreamError::TLSError: - assert(false); - componentError = ComponentError(ComponentError::UnknownError); - break; - case SessionStream::SessionStreamError::InvalidTLSCertificateError: - assert(false); - componentError = ComponentError(ComponentError::UnknownError); - break; - case SessionStream::SessionStreamError::ConnectionReadError: - componentError = ComponentError(ComponentError::ConnectionReadError); - break; - case SessionStream::SessionStreamError::ConnectionWriteError: - componentError = ComponentError(ComponentError::ConnectionWriteError); - break; - } - } - onError(componentError); - } +void CoreComponent::handleSessionFinished(std::shared_ptr<Error> error) { + session_->onFinished.disconnect(boost::bind(&CoreComponent::handleSessionFinished, this, _1)); + session_.reset(); + + sessionStream_->onDataRead.disconnect(boost::bind(&CoreComponent::handleDataRead, this, _1)); + sessionStream_->onDataWritten.disconnect(boost::bind(&CoreComponent::handleDataWritten, this, _1)); + sessionStream_.reset(); + + connection_->disconnect(); + connection_.reset(); + + if (error) { + ComponentError componentError; + if (std::shared_ptr<ComponentSession::Error> actualError = std::dynamic_pointer_cast<ComponentSession::Error>(error)) { + switch(actualError->type) { + case ComponentSession::Error::AuthenticationFailedError: + componentError = ComponentError(ComponentError::AuthenticationFailedError); + break; + case ComponentSession::Error::UnexpectedElementError: + componentError = ComponentError(ComponentError::UnexpectedElementError); + break; + } + } + else if (std::shared_ptr<SessionStream::SessionStreamError> actualError = std::dynamic_pointer_cast<SessionStream::SessionStreamError>(error)) { + switch(actualError->type) { + case SessionStream::SessionStreamError::ParseError: + componentError = ComponentError(ComponentError::XMLError); + break; + case SessionStream::SessionStreamError::TLSError: + assert(false); + componentError = ComponentError(ComponentError::UnknownError); + break; + case SessionStream::SessionStreamError::InvalidTLSCertificateError: + assert(false); + componentError = ComponentError(ComponentError::UnknownError); + break; + case SessionStream::SessionStreamError::ConnectionReadError: + componentError = ComponentError(ComponentError::ConnectionReadError); + break; + case SessionStream::SessionStreamError::ConnectionWriteError: + componentError = ComponentError(ComponentError::ConnectionWriteError); + break; + } + } + onError(componentError); + } } void CoreComponent::handleDataRead(const SafeByteArray& data) { - onDataRead(data); + onDataRead(data); } void CoreComponent::handleDataWritten(const SafeByteArray& data) { - onDataWritten(data); + onDataWritten(data); } void CoreComponent::handleStanzaChannelAvailableChanged(bool available) { - if (available) { - onConnected(); - } + if (available) { + onConnected(); + } +} + +void CoreComponent::sendMessage(std::shared_ptr<Message> message) { + stanzaChannel_->sendMessage(message); +} + +void CoreComponent::sendPresence(std::shared_ptr<Presence> presence) { + stanzaChannel_->sendPresence(presence); +} + +void CoreComponent::sendData(const std::string& data) { + sessionStream_->writeData(data); } -void CoreComponent::sendMessage(boost::shared_ptr<Message> message) { - stanzaChannel_->sendMessage(message); +bool CoreComponent::isActive() const { + return session_ || connector_; } -void CoreComponent::sendPresence(boost::shared_ptr<Presence> presence) { - stanzaChannel_->sendPresence(presence); +bool CoreComponent::isAvailable() const { + return stanzaChannel_->isAvailable(); } } |