diff options
author | Andrzej J.R. Hunt <andrzej@ahunt.org> | 2012-08-10 18:42:49 +0200 |
---|---|---|
committer | Andrzej J.R. Hunt <andrzej@ahunt.org> | 2012-08-10 18:43:44 +0200 |
commit | f4ab85cb44664a4c46c52d5a34eee300947e6069 (patch) | |
tree | 642112abdc63e9ba0765fd702c492f3241cea34f /sd | |
parent | fdo#48446 implement RTF_CPG (diff) | |
download | core-f4ab85cb44664a4c46c52d5a34eee300947e6069.tar.gz core-f4ab85cb44664a4c46c52d5a34eee300947e6069.zip |
Pairing implemented server side.
Change-Id: I542e563df68d38691f7c95cebf66aeb32071bd66
Diffstat (limited to 'sd')
-rw-r--r-- | sd/Library_sd.mk | 1 | ||||
-rw-r--r-- | sd/source/ui/inc/RemoteServer.hxx | 10 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/BufferedStreamSocket.cxx | 61 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/BufferedStreamSocket.hxx | 45 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Communicator.cxx | 13 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Communicator.hxx | 6 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Server.cxx | 66 |
7 files changed, 185 insertions, 17 deletions
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk index 92db929a067a..283971ca7656 100644 --- a/sd/Library_sd.mk +++ b/sd/Library_sd.mk @@ -327,6 +327,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\ sd/source/ui/presenter/PresenterPreviewCache \ sd/source/ui/presenter/PresenterTextView \ sd/source/ui/presenter/SlideRenderer \ + sd/source/ui/remotecontrol/BufferedStreamSocket \ sd/source/ui/remotecontrol/Communicator \ sd/source/ui/remotecontrol/DiscoveryService \ sd/source/ui/remotecontrol/ImagePreparer \ diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx index a77f5aba873c..c64bf94de3e7 100644 --- a/sd/source/ui/inc/RemoteServer.hxx +++ b/sd/source/ui/inc/RemoteServer.hxx @@ -38,6 +38,7 @@ namespace css = ::com::sun::star; namespace sd { class Communicator; + class BufferedStreamSocket; struct ClientInfo { @@ -53,14 +54,14 @@ namespace sd struct ClientInfoInternal: ClientInfo { - osl::StreamSocket mStreamSocket; + BufferedStreamSocket *mpStreamSocket; rtl::OUString mPin; ClientInfoInternal( const rtl::OUString rName, const rtl::OUString rAddress, - osl::StreamSocket &rSocket, rtl::OUString rPin ): + BufferedStreamSocket *pSocket, rtl::OUString rPin ): ClientInfo( rName, rAddress ), - mStreamSocket( rSocket ), + mpStreamSocket( pSocket ), mPin( rPin ) {} }; @@ -77,7 +78,8 @@ namespace sd // For the control dialog SD_DLLPUBLIC static std::vector<ClientInfo*> getClients(); - SD_DLLPUBLIC static void connectClient( ClientInfo aClient, rtl::OString aPin ); + SD_DLLPUBLIC static sal_Bool connectClient( ClientInfo *pClient, + rtl::OUString aPin ); // For the communicator static void removeCommunicator( Communicator* pCommunicator ); diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx new file mode 100644 index 000000000000..8232bd085a06 --- /dev/null +++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx @@ -0,0 +1,61 @@ +/* -*- 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/. + */ + +#include <BufferedStreamSocket.hxx> + +#include <algorithm> + +using namespace sd; +using namespace std; +using namespace osl; + +BufferedStreamSocket::BufferedStreamSocket( const osl::StreamSocket &aSocket ): + StreamSocket( aSocket ), + aRet( 0 ), + aRead( 0 ), + aBuffer() +{ +} + +sal_Int32 BufferedStreamSocket::readLine( OString& aLine ) +{ + while ( true ) + { + aBuffer.resize( aRead + 100 ); + aRet = recv( &aBuffer[aRead], 100 ); + if ( aRet == 0 ) + { + return aRet; + } + // Prevent buffer from growing massively large. + if ( aRead > MAX_LINE_LENGTH ) + { + aBuffer.erase( aBuffer.begin(), aBuffer.end() ); + return 0; + } + aRead += aRet; + vector<char>::iterator aIt; + while ( (aIt = find( aBuffer.begin(), aBuffer.end(), '\n' )) + != aBuffer.end() ) + { + sal_uInt64 aLocation = aIt - aBuffer.begin(); + + aLine = OString( &(*aBuffer.begin()), aLocation ); + + aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line + aRead -= (aLocation + 1); + + return aLine.getLength(); + } + } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx new file mode 100644 index 000000000000..53b6e2aff29e --- /dev/null +++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx @@ -0,0 +1,45 @@ +/* -*- 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/. + */ +#ifndef _SD_IMPRESSREMOTE_BUFFEREDSTREAMSOCKET_HXX +#define _SD_IMPRESSREMOTE_BUFFEREDSTREAMSOCKET_HXX + +#include <boost/noncopyable.hpp> +#include <osl/socket.hxx> +#include <vector> + +#define CHARSET RTL_TEXTENCODING_UTF8 +#define MAX_LINE_LENGTH 20000 + +namespace sd +{ + + /** + * A wrapper for an osl StreamSocket to allow reading lines. + */ + class BufferedStreamSocket : + public ::osl::StreamSocket, + private ::boost::noncopyable + { + public: + BufferedStreamSocket( const osl::StreamSocket &aSocket ); + BufferedStreamSocket( const BufferedStreamSocket &aSocket ); + /** + * Blocks until a line is read. + * Returns whatever the last call of recv returned, i.e. 0 or less + * if there was a problem in communications. + */ + sal_Int32 readLine(OString& aLine); + private: + sal_Int32 aRet, aRead; + std::vector<char> aBuffer; + }; +} + +#endif // _SD_IMPRESSREMOTE_BUFFEREDSTREAMSOCKET_HXX +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx index d4775f9264bf..303f85a123a8 100644 --- a/sd/source/ui/remotecontrol/Communicator.cxx +++ b/sd/source/ui/remotecontrol/Communicator.cxx @@ -22,9 +22,9 @@ using namespace std; using namespace com::sun::star; using namespace osl; -Communicator::Communicator( StreamSocket &aSocket ): +Communicator::Communicator( BufferedStreamSocket *pSocket ): Thread( "CommunicatorThread" ), - mSocket( aSocket ), + mpSocket( pSocket ), pTransmitter( 0 ), mListener( 0 ) { @@ -37,8 +37,11 @@ Communicator::~Communicator() // Run as a thread void Communicator::execute() { - pTransmitter = new Transmitter( mSocket ); + pTransmitter = new Transmitter( *mpSocket ); pTransmitter->launch(); + + pTransmitter->addMessage( "LO_SERVER_SERVER_PAIRED\n\n", + Transmitter::PRIORITY_HIGH ); Receiver aReceiver( pTransmitter ); try { uno::Reference< lang::XMultiServiceFactory > xServiceManager( @@ -65,7 +68,7 @@ void Communicator::execute() while ( true ) { aBuffer.resize( aRead + 100 ); - aRet = mSocket.recv( &aBuffer[aRead], 100 ); + aRet = mpSocket->recv( &aBuffer[aRead], 100 ); if ( aRet == 0 ) { break; // I.e. transmission finished. @@ -94,6 +97,8 @@ void Communicator::execute() pTransmitter->join(); pTransmitter = NULL; + delete mpSocket; + RemoteServer::removeCommunicator( this ); } diff --git a/sd/source/ui/remotecontrol/Communicator.hxx b/sd/source/ui/remotecontrol/Communicator.hxx index 089fffa7b3dd..d7ad796aa77a 100644 --- a/sd/source/ui/remotecontrol/Communicator.hxx +++ b/sd/source/ui/remotecontrol/Communicator.hxx @@ -22,6 +22,8 @@ #include <com/sun/star/presentation/XSlideShowController.hpp> +#include "BufferedStreamSocket.hxx" + #define CHARSET RTL_TEXTENCODING_UTF8 namespace css = ::com::sun::star; @@ -40,7 +42,7 @@ namespace sd class Communicator : public salhelper::Thread { public: - Communicator( osl::StreamSocket &aSocket ); + Communicator( BufferedStreamSocket *pSocket ); ~Communicator(); Transmitter* getTransmitter(); @@ -51,7 +53,7 @@ namespace sd private: void execute(); - osl::StreamSocket mSocket; + BufferedStreamSocket *mpSocket; Transmitter *pTransmitter; rtl::Reference<Listener> mListener; diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx index eb4adc13dc9f..af4170aed6dd 100644 --- a/sd/source/ui/remotecontrol/Server.cxx +++ b/sd/source/ui/remotecontrol/Server.cxx @@ -68,11 +68,39 @@ void RemoteServer::execute() while ( true ) { StreamSocket aSocket; - if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error ) { + if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error ) + { + 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(); + MutexGuard aGuard( mDataMutex ); - // FIXME: read one line in, parse the data. - mAvailableClients.push_back( new ClientInfoInternal( "A name", - "An address", aSocket, "0000" ) ); + mAvailableClients.push_back( new ClientInfoInternal( + OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ), + aAddress, pSocket, OStringToOUString( aPin, + RTL_TEXTENCODING_UTF8 ) ) ); + + // Read off any additional non-empty lines + do + { + pSocket->readLine( aLine ); + } + while ( aLine.getLength() > 0 ); + } else { + delete pSocket; } } @@ -141,10 +169,34 @@ std::vector<ClientInfo*> RemoteServer::getClients() return aClients; } -void RemoteServer::connectClient( ClientInfo aClient, rtl::OString aPin ) +sal_Bool RemoteServer::connectClient( ClientInfo* pClient, rtl::OUString aPin ) { - (void) aClient; - (void) aPin; + if ( !spServer ) + return false; + + ClientInfoInternal *apClient = (ClientInfoInternal*) pClient; + if ( apClient->mPin.equals( aPin ) ) + { + Communicator* pCommunicator = new Communicator( apClient->mpStreamSocket ); + MutexGuard aGuard( spServer->mDataMutex ); + + spServer->mCommunicators.push_back( pCommunicator ); + + for ( vector<ClientInfoInternal*>::iterator aIt = spServer->mAvailableClients.begin(); + aIt < spServer->mAvailableClients.end(); aIt++ ) + { + if ( pClient == *aIt ) + { + spServer->mAvailableClients.erase( aIt ); + break; + } + } + return true; + } + else + { + return false; + } } void SdDLL::RegisterRemotes() |