2012-07-11 17:44:41 +01:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*/
|
2012-07-09 10:57:32 +01:00
|
|
|
#include <stdlib.h>
|
2012-07-12 22:10:33 +01:00
|
|
|
#include <algorithm>
|
2012-07-09 10:57:32 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2013-02-07 22:46:05 +01:00
|
|
|
#include <officecfg/Office/Common.hxx>
|
|
|
|
#include <officecfg/Office/Impress.hxx>
|
2012-08-28 22:17:35 +02:00
|
|
|
|
|
|
|
#include <com/sun/star/container/XNameAccess.hpp>
|
|
|
|
#include <com/sun/star/container/XNameContainer.hpp>
|
|
|
|
#include <com/sun/star/uno/Sequence.hxx>
|
|
|
|
|
2012-07-17 23:03:31 +02:00
|
|
|
#include <comphelper/processfactory.hxx>
|
2012-08-28 22:17:35 +02:00
|
|
|
#include <comphelper/configuration.hxx>
|
2012-09-20 12:02:05 +02:00
|
|
|
#include <sal/log.hxx>
|
2012-07-17 23:03:31 +02:00
|
|
|
|
2012-07-09 12:20:45 +01:00
|
|
|
#include "sddll.hxx"
|
2012-07-09 15:53:03 +01:00
|
|
|
|
2012-08-02 11:28:38 +02:00
|
|
|
#include "DiscoveryService.hxx"
|
2012-07-19 18:43:18 +02:00
|
|
|
#include "Listener.hxx"
|
|
|
|
#include "Receiver.hxx"
|
2012-07-30 08:34:41 +02:00
|
|
|
#include "RemoteServer.hxx"
|
2012-08-20 11:18:35 +02:00
|
|
|
#include "BluetoothServer.hxx"
|
2012-11-27 16:35:45 +01:00
|
|
|
#include "Communicator.hxx"
|
2013-02-14 17:07:01 +02:00
|
|
|
#include "BufferedStreamSocket.hxx"
|
2012-07-18 22:04:09 +02:00
|
|
|
|
2012-07-09 10:57:32 +01:00
|
|
|
using namespace std;
|
2012-07-09 15:53:03 +01:00
|
|
|
using namespace sd;
|
2012-07-17 17:48:07 +02:00
|
|
|
using namespace ::com::sun::star;
|
2012-08-28 22:17:35 +02:00
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
using namespace ::com::sun::star::beans;
|
|
|
|
using namespace ::com::sun::star::container;
|
|
|
|
using namespace ::com::sun::star::lang;
|
2012-07-12 22:10:33 +01:00
|
|
|
using rtl::OString;
|
2012-08-10 17:20:16 +02:00
|
|
|
using namespace ::osl;
|
2012-08-28 22:17:35 +02:00
|
|
|
using namespace ::comphelper;
|
2012-08-10 17:20:16 +02:00
|
|
|
|
2012-09-06 09:55:38 +02:00
|
|
|
namespace sd {
|
|
|
|
/**
|
|
|
|
* Used to keep track of clients that have attempted to connect, but haven't
|
|
|
|
* yet been approved.
|
|
|
|
*/
|
|
|
|
struct ClientInfoInternal:
|
|
|
|
ClientInfo
|
|
|
|
{
|
|
|
|
BufferedStreamSocket *mpStreamSocket;
|
|
|
|
rtl::OUString mPin;
|
|
|
|
|
|
|
|
ClientInfoInternal( const rtl::OUString rName,
|
|
|
|
const rtl::OUString rAddress,
|
|
|
|
BufferedStreamSocket *pSocket, rtl::OUString rPin ):
|
|
|
|
ClientInfo( rName, rAddress ),
|
|
|
|
mpStreamSocket( pSocket ),
|
|
|
|
mPin( rPin ) {}
|
|
|
|
};
|
|
|
|
}
|
2012-08-10 17:20:16 +02:00
|
|
|
|
|
|
|
RemoteServer::RemoteServer() :
|
|
|
|
Thread( "RemoteServerThread" ),
|
|
|
|
mSocket(),
|
|
|
|
mAvailableClients()
|
2012-07-09 10:57:32 +01:00
|
|
|
{
|
2013-02-07 22:49:35 +01:00
|
|
|
SAL_INFO( "sdremote", "Instantiated RemoteServer" );
|
2012-07-09 10:57:32 +01:00
|
|
|
}
|
|
|
|
|
2012-07-30 08:34:41 +02:00
|
|
|
RemoteServer::~RemoteServer()
|
2012-07-09 10:57:32 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-07-30 08:34:41 +02:00
|
|
|
void RemoteServer::execute()
|
2012-07-09 15:53:03 +01:00
|
|
|
{
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_INFO( "sdremote", "RemoteServer::execute called" );
|
2012-11-27 16:35:45 +01:00
|
|
|
uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
|
|
|
|
if (!xContext.is() || !officecfg::Office::Common::Misc::ExperimentalMode::get(xContext))
|
|
|
|
{
|
|
|
|
SAL_INFO("sdremote", "not in experimental mode, disabling TCP server");
|
|
|
|
return;
|
|
|
|
}
|
2012-07-10 16:36:04 +01:00
|
|
|
osl::SocketAddr aAddr( "0", PORT );
|
2012-07-09 15:53:03 +01:00
|
|
|
if ( !mSocket.bind( aAddr ) )
|
|
|
|
{
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_WARN( "sdremote", "bind failed" << mSocket.getErrorAsString() );
|
2012-09-06 09:55:38 +02:00
|
|
|
return;
|
2012-07-09 15:53:03 +01:00
|
|
|
}
|
|
|
|
|
2012-07-10 16:36:04 +01:00
|
|
|
if ( !mSocket.listen(3) )
|
2012-07-09 15:53:03 +01:00
|
|
|
{
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_WARN( "sdremote", "listen failed" << mSocket.getErrorAsString() );
|
2012-09-06 09:55:38 +02:00
|
|
|
return;
|
2012-07-09 15:53:03 +01:00
|
|
|
}
|
|
|
|
while ( true )
|
|
|
|
{
|
2012-08-10 17:20:16 +02:00
|
|
|
StreamSocket aSocket;
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_INFO( "sdremote", "waiting on accept" );
|
2012-08-10 18:42:49 +02:00
|
|
|
if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error )
|
|
|
|
{
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_WARN( "sdremote", "accept failed" << mSocket.getErrorAsString() );
|
2012-08-10 18:42:49 +02:00
|
|
|
return; // Closed, or other issue.
|
|
|
|
}
|
|
|
|
BufferedStreamSocket *pSocket = new BufferedStreamSocket( aSocket);
|
|
|
|
OString aLine;
|
|
|
|
if ( pSocket->readLine( aLine)
|
|
|
|
&& aLine.equals( "LO_SERVER_CLIENT_PAIR" ) &&
|
|
|
|
pSocket->readLine( aLine ) )
|
|
|
|
{
|
|
|
|
OString aName( aLine );
|
|
|
|
|
|
|
|
if ( ! pSocket->readLine( aLine ) ) delete pSocket;
|
|
|
|
OString aPin( aLine );
|
|
|
|
|
|
|
|
SocketAddr aClientAddr;
|
|
|
|
pSocket->getPeerAddr( aClientAddr );
|
|
|
|
OUString aAddress = aClientAddr.getHostname();
|
|
|
|
|
2012-11-27 16:35:45 +01:00
|
|
|
MutexGuard aGuard( sDataMutex );
|
2012-08-28 22:17:35 +02:00
|
|
|
ClientInfoInternal* pClient = new ClientInfoInternal(
|
2012-08-10 18:42:49 +02:00
|
|
|
OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ),
|
|
|
|
aAddress, pSocket, OStringToOUString( aPin,
|
2012-08-28 22:17:35 +02:00
|
|
|
RTL_TEXTENCODING_UTF8 ) );
|
|
|
|
mAvailableClients.push_back( pClient );
|
2012-08-10 18:42:49 +02:00
|
|
|
|
|
|
|
// Read off any additional non-empty lines
|
2012-09-06 09:55:38 +02:00
|
|
|
// We know that we at least have the empty termination line to read.
|
2012-08-10 18:42:49 +02:00
|
|
|
do
|
|
|
|
{
|
|
|
|
pSocket->readLine( aLine );
|
|
|
|
}
|
|
|
|
while ( aLine.getLength() > 0 );
|
2012-08-28 22:17:35 +02:00
|
|
|
|
|
|
|
// Check if we already have this server.
|
2012-09-19 12:11:01 +02:00
|
|
|
Reference< XNameAccess > const xConfig = officecfg::Office::Impress::Misc::AuthorisedRemotes::get();
|
2012-08-28 22:17:35 +02:00
|
|
|
Sequence< OUString > aNames = xConfig->getElementNames();
|
2012-09-18 11:16:45 +02:00
|
|
|
bool aFound = false;
|
2012-08-28 22:17:35 +02:00
|
|
|
for ( int i = 0; i < aNames.getLength(); i++ )
|
|
|
|
{
|
|
|
|
if ( aNames[i].equals( pClient->mName ) )
|
|
|
|
{
|
|
|
|
Reference<XNameAccess> xSetItem( xConfig->getByName(aNames[i]), UNO_QUERY );
|
|
|
|
Any axPin(xSetItem->getByName("PIN"));
|
|
|
|
OUString sPin;
|
|
|
|
axPin >>= sPin;
|
|
|
|
|
2012-09-06 09:55:38 +02:00
|
|
|
if ( sPin.equals( pClient->mPin ) ) {
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_INFO( "sdremote", "client found on validated list -- connecting" );
|
2012-09-06 09:55:38 +02:00
|
|
|
connectClient( pClient, sPin );
|
2012-09-18 11:16:45 +02:00
|
|
|
aFound = true;
|
|
|
|
break;
|
2012-08-28 22:17:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2012-09-18 11:16:45 +02:00
|
|
|
// Pin not found so inform the client.
|
|
|
|
if ( !aFound )
|
2012-09-20 12:02:05 +02:00
|
|
|
{
|
|
|
|
SAL_INFO( "sdremote", "client not found on validated list" );
|
2012-09-18 11:16:45 +02:00
|
|
|
pSocket->write( "LO_SERVER_VALIDATING_PIN\n\n",
|
2012-09-17 17:20:08 +02:00
|
|
|
strlen( "LO_SERVER_VALIDATING_PIN\n\n" ) );
|
2012-09-20 12:02:05 +02:00
|
|
|
}
|
2012-08-10 18:42:49 +02:00
|
|
|
} else {
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_INFO( "sdremote", "client failed to send LO_SERVER_CLIENT_PAIR, ignoring" );
|
2012-08-10 18:42:49 +02:00
|
|
|
delete pSocket;
|
2012-08-07 09:29:35 +02:00
|
|
|
}
|
2012-07-09 15:53:03 +01:00
|
|
|
}
|
2012-09-20 12:02:05 +02:00
|
|
|
spServer = NULL; // Object is destroyed when Thread::execute() ends.
|
2012-07-09 15:53:03 +01:00
|
|
|
}
|
2012-07-09 12:20:45 +01:00
|
|
|
|
2012-08-10 17:20:16 +02:00
|
|
|
RemoteServer *sd::RemoteServer::spServer = NULL;
|
2012-11-27 16:35:45 +01:00
|
|
|
::osl::Mutex sd::RemoteServer::sDataMutex;
|
|
|
|
::std::vector<Communicator*> sd::RemoteServer::sCommunicators;
|
2012-08-10 17:20:16 +02:00
|
|
|
|
|
|
|
void RemoteServer::setup()
|
2012-07-19 13:02:03 +02:00
|
|
|
{
|
2012-08-10 17:20:16 +02:00
|
|
|
if (spServer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
spServer = new RemoteServer();
|
|
|
|
spServer->launch();
|
2012-08-22 12:44:42 +02:00
|
|
|
|
2012-11-16 00:00:58 +01:00
|
|
|
#ifdef ENABLE_SDREMOTE_BLUETOOTH
|
2012-11-27 16:35:45 +01:00
|
|
|
sd::BluetoothServer::setup( &sCommunicators );
|
2012-10-21 14:54:53 +02:00
|
|
|
#endif
|
2012-07-19 13:02:03 +02:00
|
|
|
}
|
2012-07-17 16:44:46 +02:00
|
|
|
|
2012-08-10 17:20:16 +02:00
|
|
|
|
2012-07-30 08:34:41 +02:00
|
|
|
void RemoteServer::presentationStarted( const css::uno::Reference<
|
2012-08-10 17:20:16 +02:00
|
|
|
css::presentation::XSlideShowController > &rController )
|
2012-07-17 16:44:46 +02:00
|
|
|
{
|
2012-08-10 17:20:16 +02:00
|
|
|
if ( !spServer )
|
|
|
|
return;
|
2012-11-27 16:35:45 +01:00
|
|
|
MutexGuard aGuard( sDataMutex );
|
|
|
|
for ( vector<Communicator*>::const_iterator aIt = sCommunicators.begin();
|
|
|
|
aIt != sCommunicators.end(); ++aIt )
|
2012-07-18 16:14:52 +02:00
|
|
|
{
|
2012-08-10 17:20:16 +02:00
|
|
|
(*aIt)->presentationStarted( rController );
|
2012-07-18 16:14:52 +02:00
|
|
|
}
|
2012-07-17 16:44:46 +02:00
|
|
|
}
|
2012-07-30 08:34:41 +02:00
|
|
|
void RemoteServer::presentationStopped()
|
2012-07-20 12:02:54 +02:00
|
|
|
{
|
2012-08-10 17:20:16 +02:00
|
|
|
if ( !spServer )
|
|
|
|
return;
|
2012-11-27 16:35:45 +01:00
|
|
|
MutexGuard aGuard( sDataMutex );
|
|
|
|
for ( vector<Communicator*>::const_iterator aIt = sCommunicators.begin();
|
|
|
|
aIt != sCommunicators.end(); ++aIt )
|
2012-07-20 12:02:54 +02:00
|
|
|
{
|
2012-08-10 17:20:16 +02:00
|
|
|
(*aIt)->disposeListener();
|
2012-07-20 12:02:54 +02:00
|
|
|
}
|
|
|
|
}
|
2012-07-17 16:44:46 +02:00
|
|
|
|
2012-08-10 17:20:16 +02:00
|
|
|
void RemoteServer::removeCommunicator( Communicator* mCommunicator )
|
2012-07-09 17:26:27 +01:00
|
|
|
{
|
2012-08-10 17:20:16 +02:00
|
|
|
if ( !spServer )
|
|
|
|
return;
|
2012-11-27 16:35:45 +01:00
|
|
|
MutexGuard aGuard( sDataMutex );
|
|
|
|
for ( vector<Communicator*>::iterator aIt = sCommunicators.begin();
|
|
|
|
aIt != sCommunicators.end(); ++aIt )
|
2012-08-10 17:20:16 +02:00
|
|
|
{
|
|
|
|
if ( mCommunicator == *aIt )
|
|
|
|
{
|
2012-11-27 16:35:45 +01:00
|
|
|
sCommunicators.erase( aIt );
|
2012-08-10 17:20:16 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-07-09 17:26:27 +01:00
|
|
|
}
|
|
|
|
|
2012-08-10 17:20:16 +02:00
|
|
|
std::vector<ClientInfo*> RemoteServer::getClients()
|
2012-08-10 13:27:40 +02:00
|
|
|
{
|
2013-02-07 22:49:35 +01:00
|
|
|
SAL_INFO( "sdremote", "RemoteServer::getClients() called" );
|
2012-09-11 03:19:26 +02:00
|
|
|
std::vector<ClientInfo*> aClients;
|
2012-08-10 17:20:16 +02:00
|
|
|
if ( !spServer )
|
2013-02-07 22:49:35 +01:00
|
|
|
{
|
|
|
|
SAL_INFO( "sdremote", "No remote server instance => no clients" );
|
2012-09-11 03:19:26 +02:00
|
|
|
return aClients;
|
2013-02-07 22:49:35 +01:00
|
|
|
}
|
2012-09-11 03:19:26 +02:00
|
|
|
|
2012-11-27 16:35:45 +01:00
|
|
|
MutexGuard aGuard( sDataMutex );
|
2012-08-10 17:20:16 +02:00
|
|
|
aClients.assign( spServer->mAvailableClients.begin(),
|
|
|
|
spServer->mAvailableClients.end() );
|
|
|
|
return aClients;
|
2012-08-10 13:27:40 +02:00
|
|
|
}
|
|
|
|
|
2012-08-10 18:42:49 +02:00
|
|
|
sal_Bool RemoteServer::connectClient( ClientInfo* pClient, rtl::OUString aPin )
|
2012-08-10 13:27:40 +02:00
|
|
|
{
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_INFO( "sdremote", "RemoteServer::connectClient called" );
|
2012-08-10 18:42:49 +02:00
|
|
|
if ( !spServer )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ClientInfoInternal *apClient = (ClientInfoInternal*) pClient;
|
|
|
|
if ( apClient->mPin.equals( aPin ) )
|
|
|
|
{
|
2012-08-28 22:17:35 +02:00
|
|
|
// Save in settings first
|
|
|
|
boost::shared_ptr< ConfigurationChanges > aChanges = ConfigurationChanges::create();
|
2012-09-19 12:11:01 +02:00
|
|
|
Reference< XNameContainer > const xConfig = officecfg::Office::Impress::Misc::AuthorisedRemotes::get( aChanges );
|
2012-08-28 22:17:35 +02:00
|
|
|
|
|
|
|
Reference<XSingleServiceFactory> xChildFactory (
|
|
|
|
xConfig, UNO_QUERY);
|
|
|
|
Reference<XNameReplace> xChild( xChildFactory->createInstance(), UNO_QUERY);
|
|
|
|
Any aValue;
|
|
|
|
if (xChild.is())
|
|
|
|
{
|
|
|
|
// Check whether the client is already saved
|
2012-09-04 11:48:55 +02:00
|
|
|
bool aSaved = false;
|
2012-08-28 22:17:35 +02:00
|
|
|
Sequence< OUString > aNames = xConfig->getElementNames();
|
|
|
|
for ( int i = 0; i < aNames.getLength(); i++ )
|
|
|
|
{
|
|
|
|
if ( aNames[i].equals( apClient->mName ) )
|
2012-09-04 11:48:55 +02:00
|
|
|
{
|
2012-08-28 22:17:35 +02:00
|
|
|
xConfig->replaceByName( apClient->mName, makeAny( xChild ) );
|
2012-09-04 11:48:55 +02:00
|
|
|
aSaved = true;
|
|
|
|
break;
|
|
|
|
}
|
2012-08-28 22:17:35 +02:00
|
|
|
}
|
2012-09-04 11:48:55 +02:00
|
|
|
if ( !aSaved )
|
|
|
|
xConfig->insertByName( apClient->mName, makeAny( xChild ) );
|
2012-08-28 22:17:35 +02:00
|
|
|
aValue <<= OUString( apClient->mPin );
|
|
|
|
xChild->replaceByName("PIN", aValue);
|
|
|
|
aChanges->commit();
|
|
|
|
}
|
|
|
|
|
2012-08-10 18:42:49 +02:00
|
|
|
Communicator* pCommunicator = new Communicator( apClient->mpStreamSocket );
|
2012-11-27 16:35:45 +01:00
|
|
|
MutexGuard aGuard( sDataMutex );
|
2012-08-10 18:42:49 +02:00
|
|
|
|
2012-11-27 16:35:45 +01:00
|
|
|
sCommunicators.push_back( pCommunicator );
|
2012-08-10 18:42:49 +02:00
|
|
|
|
|
|
|
for ( vector<ClientInfoInternal*>::iterator aIt = spServer->mAvailableClients.begin();
|
2012-10-13 16:06:44 +02:00
|
|
|
aIt != spServer->mAvailableClients.end(); ++aIt )
|
2012-08-10 18:42:49 +02:00
|
|
|
{
|
|
|
|
if ( pClient == *aIt )
|
|
|
|
{
|
|
|
|
spServer->mAvailableClients.erase( aIt );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-08-13 21:39:12 +02:00
|
|
|
pCommunicator->launch();
|
2012-08-10 18:42:49 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2012-08-10 13:27:40 +02:00
|
|
|
}
|
|
|
|
|
2012-07-09 12:20:45 +01:00
|
|
|
void SdDLL::RegisterRemotes()
|
|
|
|
{
|
2012-08-07 13:12:06 +02:00
|
|
|
// Disable unless in experimental mode for now
|
2012-09-20 12:02:05 +02:00
|
|
|
SAL_INFO( "sdremote", "SdDLL::RegisterRemotes called" );
|
2012-08-07 13:12:06 +02:00
|
|
|
uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
|
2013-02-07 22:46:05 +01:00
|
|
|
if ( xContext.is() && !officecfg::Office::Impress::Misc::Start::EnableSdremote::get( xContext ) )
|
2012-08-07 13:12:06 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
sd::RemoteServer::setup();
|
|
|
|
sd::DiscoveryService::setup();
|
2012-07-09 12:20:45 +01:00
|
|
|
}
|
2012-09-18 18:22:12 +02:00
|
|
|
|
|
|
|
bool RemoteServer::isBluetoothDiscoverable()
|
|
|
|
{
|
2012-11-16 00:00:58 +01:00
|
|
|
#ifdef ENABLE_SDREMOTE_BLUETOOTH
|
2012-09-18 18:22:12 +02:00
|
|
|
return BluetoothServer::isDiscoverable();
|
2012-10-21 14:54:53 +02:00
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
2012-09-18 18:22:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void RemoteServer::setBluetoothDiscoverable( bool aDiscoverable )
|
|
|
|
{
|
2012-11-16 00:00:58 +01:00
|
|
|
#ifdef ENABLE_SDREMOTE_BLUETOOTH
|
2012-09-18 18:22:12 +02:00
|
|
|
BluetoothServer::setDiscoverable( aDiscoverable );
|
2012-10-22 09:23:22 +03:00
|
|
|
#else
|
|
|
|
(void) aDiscoverable;
|
2012-10-21 14:54:53 +02:00
|
|
|
#endif
|
2012-09-18 18:22:12 +02:00
|
|
|
}
|
2012-07-12 17:59:08 +01:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|