#include "Swiften/Client/Client.h" #include #include "Swiften/Network/DomainNameResolver.h" #include "Swiften/Client/ClientSession.h" #include "Swiften/StreamStack/PlatformTLSLayerFactory.h" #include "Swiften/Network/BoostConnectionFactory.h" #include "Swiften/Network/DomainNameResolveException.h" #include "Swiften/TLS/PKCS12Certificate.h" namespace Swift { Client::Client(const JID& jid, const String& password) : IQRouter(this), jid_(jid), password_(password), session_(0) { connectionFactory_ = new BoostConnectionFactory(&boostIOServiceThread_.getIOService()); tlsLayerFactory_ = new PlatformTLSLayerFactory(); } Client::~Client() { delete session_; delete tlsLayerFactory_; delete connectionFactory_; } void Client::connect() { delete session_; session_ = 0; DomainNameResolver resolver; try { HostAddressPort remote = resolver.resolve(jid_.getDomain().getUTF8String()); connection_ = connectionFactory_->createConnection(); connection_->onConnectFinished.connect(boost::bind(&Client::handleConnectionConnectFinished, this, _1)); connection_->connect(remote); } catch (const DomainNameResolveException& e) { onError(ClientError::DomainNameResolveError); } } void Client::handleConnectionConnectFinished(bool error) { if (error) { onError(ClientError::ConnectionError); } else { session_ = new ClientSession(jid_, connection_, tlsLayerFactory_, &payloadParserFactories_, &payloadSerializers_); if (!certificate_.isEmpty()) { session_->setCertificate(PKCS12Certificate(certificate_, password_)); } session_->onSessionStarted.connect(boost::bind(boost::ref(onConnected))); session_->onError.connect(boost::bind(&Client::handleSessionError, this, _1)); session_->onNeedCredentials.connect(boost::bind(&Client::handleNeedCredentials, this)); session_->onDataRead.connect(boost::bind(&Client::handleDataRead, this, _1)); session_->onDataWritten.connect(boost::bind(&Client::handleDataWritten, this, _1)); session_->onElementReceived.connect(boost::bind(&Client::handleElement, this, _1)); session_->start(); } } void Client::disconnect() { if (session_) { session_->stop(); } } void Client::send(boost::shared_ptr stanza) { session_->sendElement(stanza); } void Client::sendIQ(boost::shared_ptr iq) { send(iq); } void Client::sendMessage(boost::shared_ptr message) { send(message); } void Client::sendPresence(boost::shared_ptr presence) { send(presence); } String Client::getNewIQID() { return idGenerator_.generateID(); } void Client::handleElement(boost::shared_ptr element) { boost::shared_ptr message = boost::dynamic_pointer_cast(element); if (message) { onMessageReceived(message); return; } boost::shared_ptr presence = boost::dynamic_pointer_cast(element); if (presence) { onPresenceReceived(presence); return; } boost::shared_ptr iq = boost::dynamic_pointer_cast(element); if (iq) { onIQReceived(iq); return; } } void Client::setCertificate(const String& certificate) { certificate_ = certificate; } void Client::handleSessionError(ClientSession::SessionError error) { ClientError clientError; switch (error) { case ClientSession::NoError: assert(false); break; case ClientSession::ConnectionReadError: clientError = ClientError(ClientError::ConnectionReadError); break; case ClientSession::ConnectionWriteError: clientError = ClientError(ClientError::ConnectionWriteError); break; case ClientSession::XMLError: clientError = ClientError(ClientError::XMLError); break; case ClientSession::AuthenticationFailedError: clientError = ClientError(ClientError::AuthenticationFailedError); break; case ClientSession::NoSupportedAuthMechanismsError: clientError = ClientError(ClientError::NoSupportedAuthMechanismsError); break; case ClientSession::UnexpectedElementError: clientError = ClientError(ClientError::UnexpectedElementError); break; case ClientSession::ResourceBindError: clientError = ClientError(ClientError::ResourceBindError); break; case ClientSession::SessionStartError: clientError = ClientError(ClientError::SessionStartError); break; case ClientSession::TLSError: clientError = ClientError(ClientError::TLSError); break; case ClientSession::ClientCertificateLoadError: clientError = ClientError(ClientError::ClientCertificateLoadError); break; case ClientSession::ClientCertificateError: clientError = ClientError(ClientError::ClientCertificateError); break; } onError(clientError); } void Client::handleNeedCredentials() { session_->sendCredentials(password_); } void Client::handleDataRead(const ByteArray& data) { onDataRead(String(data.getData(), data.getSize())); } void Client::handleDataWritten(const ByteArray& data) { onDataWritten(String(data.getData(), data.getSize())); } }