/* * Copyright (c) 2010 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swiften/Jingle/JingleSessionImpl.h> #include <boost/smart_ptr/make_shared.hpp> #include <Swiften/Parser/PayloadParsers/JingleParser.h> #include <Swiften/Jingle/JingleContentID.h> #include <Swiften/Elements/JingleContentPayload.h> #include <Swiften/Queries/Request.h> #include <Swiften/Queries/GenericRequest.h> #include <Swiften/Base/Log.h> #include "Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h" #include "Swiften/FileTransfer/JingleTransport.h" namespace Swift { JingleSessionImpl::JingleSessionImpl(const JID& initiator, const JID& peerJID, const std::string& id, IQRouter* router) : JingleSession(initiator, id), iqRouter(router), peerJID(peerJID) { SWIFT_LOG(debug) << "initiator: " << initiator << ", peerJID: " << peerJID << std::endl; } void JingleSessionImpl::handleIncomingAction(JinglePayload::ref action) { if (action->getAction() == JinglePayload::SessionTerminate) { onSessionTerminateReceived(action->getReason()); return; } if (action->getAction() == JinglePayload::SessionInfo) { onSessionInfoReceived(action); return; } JingleContentPayload::ref content = action->getPayload<JingleContentPayload>(); if (!content) { SWIFT_LOG(debug) << "no content payload!" << std::endl; return; } JingleContentID contentID(content->getName(), content->getCreator()); JingleDescription::ref description = content->getDescriptions().empty() ? JingleDescription::ref() : content->getDescriptions()[0]; JingleTransportPayload::ref transport = content->getTransports().empty() ? JingleTransportPayload::ref() : content->getTransports()[0]; switch(action->getAction()) { case JinglePayload::SessionAccept: onSessionAcceptReceived(contentID, description, transport); return; case JinglePayload::TransportAccept: onTransportAcceptReceived(contentID, transport); return; case JinglePayload::TransportInfo: onTransportInfoReceived(contentID, transport); return; case JinglePayload::TransportReject: onTransportRejectReceived(contentID, transport); return; case JinglePayload::TransportReplace: onTransportReplaceReceived(contentID, transport); return; // following unused Jingle actions case JinglePayload::ContentAccept: case JinglePayload::ContentAdd: case JinglePayload::ContentModify: case JinglePayload::ContentReject: case JinglePayload::ContentRemove: case JinglePayload::DescriptionInfo: case JinglePayload::SecurityInfo: // handled elsewhere case JinglePayload::SessionInitiate: case JinglePayload::SessionInfo: case JinglePayload::SessionTerminate: case JinglePayload::UnknownAction: return; } std::cerr << "Unhandled Jingle action!!! ACTION: " << action->getAction() << std::endl; } void JingleSessionImpl::sendInitiate(const JingleContentID& id, JingleDescription::ref description, JingleTransportPayload::ref transport) { JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionInitiate, getID()); payload->setInitiator(getInitiator()); JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); content->setCreator(id.getCreator()); content->setName(id.getName()); content->addDescription(description); content->addTransport(transport); payload->addPayload(content); sendSetRequest(payload); } void JingleSessionImpl::sendTerminate(JinglePayload::Reason::Type reason) { JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionTerminate, getID()); payload->setReason(JinglePayload::Reason(reason)); payload->setInitiator(getInitiator()); sendSetRequest(payload); } void JingleSessionImpl::sendInfo(boost::shared_ptr<Payload> info) { JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionInfo, getID()); payload->addPayload(info); sendSetRequest(payload); } void JingleSessionImpl::sendAccept(const JingleContentID& id, JingleDescription::ref description, JingleTransportPayload::ref transPayload) { JinglePayload::ref payload = createPayload(); JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); content->setCreator(id.getCreator()); content->setName(id.getName()); content->addTransport(transPayload); content->addDescription(description); payload->setAction(JinglePayload::SessionAccept); payload->addPayload(content); // put into IQ:set and send it away sendSetRequest(payload); } void JingleSessionImpl::sendTransportAccept(const JingleContentID& id, JingleTransportPayload::ref transPayload) { JinglePayload::ref payload = createPayload(); JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); content->setCreator(id.getCreator()); content->setName(id.getName()); content->addTransport(transPayload); payload->setAction(JinglePayload::TransportAccept); payload->addPayload(content); // put into IQ:set and send it away sendSetRequest(payload); } void JingleSessionImpl::sendTransportInfo(const JingleContentID& id, JingleTransportPayload::ref transPayload) { JinglePayload::ref payload = createPayload(); JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); content->setCreator(id.getCreator()); content->setName(id.getName()); content->addTransport(transPayload); payload->setAction(JinglePayload::TransportInfo); payload->addPayload(content); sendSetRequest(payload); } void JingleSessionImpl::sendTransportReject(const JingleContentID& /* id */, JingleTransportPayload::ref /* transPayload */) { SWIFT_LOG(debug) << "NOT IMPLEMENTED YET!!!!" << std::endl; } void JingleSessionImpl::sendTransportReplace(const JingleContentID& id, JingleTransportPayload::ref transPayload) { JinglePayload::ref payload = createPayload(); JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); content->setCreator(id.getCreator()); content->setName(id.getName()); content->addTransport(transPayload); payload->setAction(JinglePayload::TransportReplace); payload->addContent(content); sendSetRequest(payload); } void JingleSessionImpl::sendSetRequest(JinglePayload::ref payload) { boost::shared_ptr<GenericRequest<JinglePayload> > request = boost::make_shared<GenericRequest<JinglePayload> >(IQ::Set, peerJID, payload, iqRouter); request->send(); } JinglePayload::ref JingleSessionImpl::createPayload() const { JinglePayload::ref payload = boost::make_shared<JinglePayload>(); payload->setSessionID(getID()); payload->setInitiator(getInitiator()); return payload; } }