/* * 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 namespace Swift { ScreenSharing::ScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory) : rtpSession(0), jingleSession(session), udpSocketFactory(udpSocketFactory) { jingleSession->onSessionTerminateReceived.connect(boost::bind(&ScreenSharing::handleSessionTerminateReceived, this, _1)); } ScreenSharing::~ScreenSharing() { jingleSession->onSessionTerminateReceived.disconnect(boost::bind(&ScreenSharing::handleSessionTerminateReceived, this, _1)); } void ScreenSharing::stop() { jingleSession->sendTerminate(JinglePayload::Reason::Success); if (rtpSession) rtpSession->stop(); onStateChange(ScreenSharing::Finished); onFinished(); } bool ScreenSharing::addBestCandidate(boost::shared_ptr transport) { // TODO: NAT traversal JingleRawUDPTransportPayload::Candidate candidate; candidate.cid = idGenerator.generateID(); candidate.component = 1; candidate.generation = 0; PlatformNetworkEnvironment env; std::vector interfaces = env.getNetworkInterfaces(); serverSocket = udpSocketFactory->createUDPSocket(); // Find the first ip which is not loopback /*foreach (const NetworkInterface& interface, interfaces) { if (!interface.isLoopback() && !interface.getAddresses().empty()) { // exclude loopback serverSocket->bindOnAvailablePort(interface.getAddresses().front()); candidate.hostAddressPort = serverSocket->getLocalAddress(); candidate.type = JingleRawUDPTransportPayload::Candidate::Host; transport->addCandidate(candidate); return true; } }*/ SWIFT_LOG(debug) << "Screen sharing: Addresses available: " << std::endl; foreach (const NetworkInterface& interface, interfaces) { SWIFT_LOG(debug) << "\tInterface: " << interface.getName() << std::endl; foreach (const HostAddress& addr, interface.getAddresses()) { SWIFT_LOG(debug) << "\t\t" << addr.getRawAddress().to_string() << std::endl; } } std::string scopeLinkBeginning("fe80"); foreach (const NetworkInterface& interface, interfaces) { if (!interface.isLoopback()) { // exclude loopback foreach (const HostAddress& addr, interface.getAddresses()) { // Disable ipv6 for now if (addr.getRawAddress().is_v6()) continue; // Ignore link scope ipv6 addr if (addr.getRawAddress().is_v6() && addr.toString().compare(2, scopeLinkBeginning.length(), scopeLinkBeginning) == 0) continue; int port = serverSocket->bindOnAvailablePort(addr); // int port = serverSocket->bind(HostAddressPort(addr, 29999)); if (!port) continue; candidate.hostAddressPort = serverSocket->getLocalAddress(); candidate.type = JingleRawUDPTransportPayload::Candidate::Host; transport->addCandidate(candidate); return true; } } } /* int port = serverSocket->bind(HostAddressPort(HostAddress("0.0.0.0"), 29999)); if (!port) return false; candidate.hostAddressPort = HostAddressPort(HostAddress("82.225.14.174"), 29999); candidate.type = JingleRawUDPTransportPayload::Candidate::Host; transport->addCandidate(candidate); return true; */ // else loopback for self sharing /*if (!interfaces.empty() && !interfaces.front().getAddresses().empty()) { int port = serverSocket->bindOnAvailablePort(interfaces.front().getAddresses().front()); if (port) { candidate.hostAddressPort = serverSocket->getLocalAddress(); candidate.type = JingleRawUDPTransportPayload::Candidate::Host; transport->addCandidate(candidate); return true; } }*/ return false; } void ScreenSharing::handleSessionTerminateReceived(boost::optional reason) { if (rtpSession) rtpSession->stop(); if (reason.is_initialized() && reason.get().type == JinglePayload::Reason::Cancel) { onStateChange(ScreenSharing::Canceled); } else if (reason.is_initialized() && reason.get().type == JinglePayload::Reason::Success) { onStateChange(ScreenSharing::Finished); } else { onStateChange(ScreenSharing::Failed); } onFinished(); } }