summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorAndrzej J.R. Hunt <andrzej@ahunt.org>2012-08-10 18:42:49 +0200
committerAndrzej J.R. Hunt <andrzej@ahunt.org>2012-08-10 18:43:44 +0200
commitf4ab85cb44664a4c46c52d5a34eee300947e6069 (patch)
tree642112abdc63e9ba0765fd702c492f3241cea34f /sd
parentf6a24ace5ad12e79f0cc90709a290a30e3758781 (diff)
Pairing implemented server side.
Change-Id: I542e563df68d38691f7c95cebf66aeb32071bd66
Diffstat (limited to 'sd')
-rw-r--r--sd/Library_sd.mk1
-rw-r--r--sd/source/ui/inc/RemoteServer.hxx10
-rw-r--r--sd/source/ui/remotecontrol/BufferedStreamSocket.cxx61
-rw-r--r--sd/source/ui/remotecontrol/BufferedStreamSocket.hxx45
-rw-r--r--sd/source/ui/remotecontrol/Communicator.cxx13
-rw-r--r--sd/source/ui/remotecontrol/Communicator.hxx6
-rw-r--r--sd/source/ui/remotecontrol/Server.cxx66
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()