/* * Copyright (c) 2012 Yoann Blein * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ #include #include #include #include #include #include #include #include #include #include namespace Swift { OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory) : ScreenSharing(session, udpSocketFactory), contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)), canceled(false), sessionAccepted(false), socketConnected(false), rtpSession(0), timerFactory(timerFactory) { session->onSessionAcceptReceived.connect(boost::bind(&OutgoingScreenSharing::handleSessionAcceptReceived, this, _1, _2, _3)); } OutgoingScreenSharing::~OutgoingScreenSharing() { } void OutgoingScreenSharing::cancel() { canceled = true; session->sendTerminate(JinglePayload::Reason::Cancel); onStateChange(ScreenSharing::Canceled); } void OutgoingScreenSharing::start() { //onStateChange(ScreenSharing::WaitingForStart); SWIFT_LOG(debug) << "Screen sharing: start" << std::endl; JingleRTPDescription::ref desc = boost::make_shared(JingleRTPDescription::Video); payloadTypeUsed = RTPPayloadType(98, "VP8", 90000); desc->addPayloadType(payloadTypeUsed); JingleRawUDPTransportPayload::ref transport = boost::make_shared(); addBestCandidate(transport); session->sendInitiate(contentID, desc, transport); onStateChange(ScreenSharing::WaitingForAccept); serverSocket->onConnected.connect(boost::bind(&OutgoingScreenSharing::handleSocketConnected, this)); serverSocket->connectToFirstIncoming(); } void OutgoingScreenSharing::handleSocketConnected() { if (canceled) return; SWIFT_LOG(debug) << "Screen sharing: UDP socket connected" << std::endl; socketConnected = true; if (sessionAccepted) startRTPSession(); } void OutgoingScreenSharing::handleSessionAcceptReceived(const JingleContentID& /*id*/, boost::shared_ptr /*desc*/, boost::shared_ptr /*transport*/) { if (canceled) return; SWIFT_LOG(debug) << "Screen sharing: accepted" << std::endl; // TODO: check desc and transport sessionAccepted = true; if (socketConnected) { startRTPSession(); } else { connectionTimer = timerFactory->createTimer(1000); connectionTimer->onTick.connect(boost::bind(&OutgoingScreenSharing::handleConnectionFailed, this)); connectionTimer->start(); onStateChange(ScreenSharing::Connecting); } } void OutgoingScreenSharing::handleConnectionFailed() { SWIFT_LOG(debug) << "Screen sharing: unable to connect" << std::endl; session->sendTerminate(JinglePayload::Reason::ConnectivityError); canceled = true; onStateChange(ScreenSharing::Failed); } void OutgoingScreenSharing::startRTPSession() { SWIFT_LOG(debug) << "Screen sharing: accepted and connected, start sharing" << std::endl; // Session accepted and socket connected, we can start the rtp session rtpSession = new RTPSessionImpl(serverSocket, payloadTypeUsed); } }