diff options
author | Andrzej J.R. Hunt <andrzej@ahunt.org> | 2012-08-22 12:44:42 +0200 |
---|---|---|
committer | Andrzej J.R. Hunt <andrzej@ahunt.org> | 2012-08-22 20:23:07 +0200 |
commit | 1db66c2a1a8ad5a60c68b09ddacc1bb6e021299f (patch) | |
tree | f4693b0a0c1a689783c9dbf956a56d8d350afb3a /sd | |
parent | 9d73597289be9049e8300ff92980fdffbe4d7040 (diff) |
Bluetooth connection working (Linux).
Change-Id: Iac77c3ce0ab0ea7bda3105c58859888e55e64d2d
Diffstat (limited to 'sd')
-rw-r--r-- | sd/source/ui/remotecontrol/BluetoothServer.cxx | 94 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/BluetoothServer.hxx | 8 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/BufferedStreamSocket.cxx | 41 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/BufferedStreamSocket.hxx | 23 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Communicator.cxx | 31 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Receiver.cxx | 2 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Server.cxx | 4 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Transmitter.cxx | 8 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/Transmitter.hxx | 6 |
9 files changed, 154 insertions, 63 deletions
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx index 0052397a64ef..bcff4addb44f 100644 --- a/sd/source/ui/remotecontrol/BluetoothServer.cxx +++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx @@ -22,29 +22,60 @@ #include "bluetooth/rfcomm.h" #endif + +#include "Communicator.hxx" + using namespace sd; -BluetoothServer::BluetoothServer(): - Thread( "BluetoothServer" ) +BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators ): + Thread( "BluetoothServer" ), + mpCommunicators( pCommunicators ) { - } BluetoothServer::~BluetoothServer() { } +struct oslSocketImpl { + int m_Socket; + int m_nLastError; + void* m_CloseCallback; + void* m_CallbackArg; + oslInterlockedCount m_nRefCount; +#if defined(LINUX) + sal_Bool m_bIsAccepting; + sal_Bool m_bIsInShutdown; +#endif +}; + + void BluetoothServer::execute() { #ifdef LINUX -// g_type_init(); -// GError* aError = NULL; -// GDBusConnection* aConnection = g_bus_get_sync( G_BUS_TYPE_SYSTEM, NULL, &aError ); -// if ( aError ) -// { -// fprintf( stderr, aError->message ); -// g_error_free( aError ); -// } + g_type_init(); + GError* aError = NULL; + GDBusConnection* aConnection = g_bus_get_sync( G_BUS_TYPE_SYSTEM, NULL, &aError ); + if ( aError ) + { + fprintf( stderr, aError->message ); + g_error_free( aError ); + } + + GVariant *aAdapter = g_dbus_connection_call_sync( aConnection, + "org.bluez", "/", "org.bluez.Manager", + "DefaultAdapter", NULL, + G_VARIANT_TYPE_TUPLE, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &aError); + GVariant *aAdapterName = g_variant_get_child_value( aAdapter, 0 ); + if ( aError ) + { + fprintf( stderr, aError->message ); + g_error_free( aError ); + } + fprintf( stderr, (const char*) g_variant_get_string( aAdapterName, NULL ) ); + + // GDBusObjectManager* aManager = g_dbus_object_manager_client_new_sync( aConnection, // G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, "org.bluez.Manager", "/org/bluez", // NULL, NULL, NULL, NULL, &aError ); @@ -53,14 +84,21 @@ void BluetoothServer::execute() // fprintf( stderr, aError->message ); // g_error_free( aError ); // } -// -// GVariant *aRet = g_dbus_connection_call_sync( aConnection, -// "org.bluez", "/", "org.bluez.Database", -// "AddServiceRecordFromXml", -// g_variant_new ("s", -// ""),, -// G_VARIANT_TYPE_UINT32, -// G_DBUS_CALL_FLAGS_NONE, -1, NULL, &aError); + + GVariant *aRecordHandle = g_dbus_connection_call_sync( aConnection, + "org.bluez", g_variant_get_string( aAdapterName, NULL ), "org.bluez.Service", + "AddRecord", + g_variant_new("(s)", + "<?xml version='1.0' encoding= 'UTF-8' ?><record><attribute id='0x0001'><sequence><uuid value='0x1101' /></sequence></attribute><attribute id='0x0004'><sequence><sequence><uuid value='0x0100' /></sequence><sequence><uuid value='0x0003' /><uint8 value='0x05' /></sequence></sequence></attribute><attribute id='0x0005'><sequence><uuid value='0x1002' /></sequence></attribute><attribute id='0x0006'><sequence><uint16 value='0x656e' /><uint16 value='0x006a' /><uint16 value='0x0100' /></sequence></attribute><attribute id='0x0009'><sequence><sequence><uuid value='0x1101' /><uint16 value='0x0100' /></sequence></sequence></attribute><attribute id='0x0100'><text value='Serial Port' /></attribute><attribute id='0x0101'><text value='COM Port' /></attribute></record>"), + G_VARIANT_TYPE_TUPLE, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &aError); + if ( aError ) + { + fprintf( stderr, aError->message ); + g_error_free( aError ); + } + (void) aRecordHandle; + // Remove handle again at some point // g_variant_unref( aRet ); // fprintf( stderr, "Manager gotten\n" ); // @@ -125,8 +163,8 @@ void BluetoothServer::execute() sockaddr_rc aAddr; aAddr.rc_family = AF_BLUETOOTH; -// aAddr.rc_bdaddr = *BDADDR_ANY; - aAddr.rc_channel = 1; + aAddr.rc_bdaddr = {{0, 0, 0, 0, 0, 0}}; // BDADDR_ANY is broken + aAddr.rc_channel = 5; if ( bind( aSocket, (sockaddr*) &aAddr, sizeof(aAddr)) < 0 ) { close( aSocket ); @@ -141,12 +179,18 @@ void BluetoothServer::execute() sockaddr_rc aRemoteAddr; socklen_t aRemoteAddrLen = sizeof(aRemoteAddr); - if ( accept(aSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen) < 0 ) + int bSocket; + if ( (bSocket = accept(aSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 ) { close( aSocket ); return; } else { fprintf( stderr, "Accepted Bluetooth\n" ); + + Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( bSocket) ); + mpCommunicators->push_back( pCommunicator ); + pCommunicator->launch(); + } #endif @@ -163,14 +207,14 @@ void BluetoothServer::execute() BluetoothServer *sd::BluetoothServer::spServer = NULL; -void BluetoothServer::setup() +void BluetoothServer::setup( std::vector<Communicator*>* pCommunicators ) { if (spServer) return; - spServer = new BluetoothServer(); + spServer = new BluetoothServer( pCommunicators ); spServer->launch(); } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
\ No newline at end of file diff --git a/sd/source/ui/remotecontrol/BluetoothServer.hxx b/sd/source/ui/remotecontrol/BluetoothServer.hxx index b95d86202e9a..163208ed1353 100644 --- a/sd/source/ui/remotecontrol/BluetoothServer.hxx +++ b/sd/source/ui/remotecontrol/BluetoothServer.hxx @@ -10,16 +10,19 @@ #define _SD_IMPRESSREMOTE_BLUETOOTHSERVER_HXX #include <salhelper/thread.hxx> +#include <vector> namespace sd { + class Communicator; + class BluetoothServer: public salhelper::Thread { public: - static void setup(); + static void setup( std::vector<Communicator*>* pCommunicators ); private: - BluetoothServer(); + BluetoothServer( std::vector<Communicator*>* pCommunicators ); ~BluetoothServer(); static BluetoothServer *spServer; @@ -27,6 +30,7 @@ namespace sd public: private: void execute(); + std::vector<Communicator*>* mpCommunicators; }; } diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx index 0e274c30295a..2b659705a6e4 100644 --- a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx +++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx @@ -11,6 +11,12 @@ #include <algorithm> +#ifdef WIN32 + #include <winsock2.h> +#else + #include <sys/socket.h> + #include <unistd.h> +#endif using namespace sd; using namespace std; using namespace osl; @@ -19,10 +25,36 @@ BufferedStreamSocket::BufferedStreamSocket( const osl::StreamSocket &aSocket ): StreamSocket( aSocket ), aRet( 0 ), aRead( 0 ), - aBuffer() + aBuffer(), + mSocket( 0 ), + usingCSocket( false) { } +BufferedStreamSocket::BufferedStreamSocket( int aSocket ): + StreamSocket(), + aRet( 0 ), + aRead( 0 ), + aBuffer(), + mSocket( aSocket ), + usingCSocket( true ) +{ +} + +void BufferedStreamSocket::getPeerAddr(osl::SocketAddr& rAddr) +{ + assert ( !usingCSocket ); + StreamSocket::getPeerAddr( rAddr ); +} + +sal_Int32 BufferedStreamSocket::write( const void* pBuffer, sal_uInt32 n ) +{ + if ( !usingCSocket ) + return StreamSocket::write( pBuffer, n ); + else + return ::write( mSocket, pBuffer, (size_t) n ); +} + sal_Int32 BufferedStreamSocket::readLine( OString& aLine ) { while ( true ) @@ -39,12 +71,15 @@ sal_Int32 BufferedStreamSocket::readLine( OString& aLine ) aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line aRead -= (aLocation + 1); - return aLine.getLength(); + return aLine.getLength() + 1; } // Then try and receive if nothing present aBuffer.resize( aRead + 100 ); - aRet = recv( &aBuffer[aRead], 100 ); + if ( !usingCSocket) + aRet = StreamSocket::recv( &aBuffer[aRead], 100 ); + else + aRet = ::read( mSocket, &aBuffer[aRead], 100 ); if ( aRet == 0 ) { diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx index 53b6e2aff29e..bf9a58aad7c0 100644 --- a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx +++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx @@ -20,14 +20,27 @@ namespace sd { /** - * A wrapper for an osl StreamSocket to allow reading lines. + * [A wrapper for an osl StreamSocket to allow reading lines.] + * + * Currently wraps either an osl StreamSocket or a standard c socket, + * allowing reading and writing for our purposes. Should eventually be + * returned to being a StreamSocket wrapper if/when Bluetooth is + * integrated into osl Sockets. */ class BufferedStreamSocket : - public ::osl::StreamSocket, + private ::osl::StreamSocket, private ::boost::noncopyable { public: + /** + * Create a BufferedStreamSocket on top of an + * osl::StreamSocket. + */ BufferedStreamSocket( const osl::StreamSocket &aSocket ); + /** + * Create a BufferedStreamSocket on top of a standard c socket. + */ + BufferedStreamSocket( int aSocket ); BufferedStreamSocket( const BufferedStreamSocket &aSocket ); /** * Blocks until a line is read. @@ -35,9 +48,15 @@ namespace sd * if there was a problem in communications. */ sal_Int32 readLine(OString& aLine); + + sal_Int32 write( const void* pBuffer, sal_uInt32 n ); + + void getPeerAddr(osl::SocketAddr&); private: sal_Int32 aRet, aRead; std::vector<char> aBuffer; + int mSocket; + bool usingCSocket; }; } diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx index 303f85a123a8..58f213071e5a 100644 --- a/sd/source/ui/remotecontrol/Communicator.cxx +++ b/sd/source/ui/remotecontrol/Communicator.cxx @@ -37,7 +37,7 @@ Communicator::~Communicator() // Run as a thread void Communicator::execute() { - pTransmitter = new Transmitter( *mpSocket ); + pTransmitter = new Transmitter( mpSocket ); pTransmitter->launch(); pTransmitter->addMessage( "LO_SERVER_SERVER_PAIRED\n\n", @@ -61,33 +61,24 @@ void Communicator::execute() { } - sal_uInt64 aRet, aRead; - vector<char> aBuffer; + sal_uInt64 aRet; vector<OString> aCommand; - aRead = 0; while ( true ) { - aBuffer.resize( aRead + 100 ); - aRet = mpSocket->recv( &aBuffer[aRead], 100 ); + OString aLine; + aRet = mpSocket->readLine( aLine ); if ( aRet == 0 ) { break; // I.e. transmission finished. } - aRead += aRet; - vector<char>::iterator aIt; - while ( (aIt = find( aBuffer.begin(), aBuffer.end(), '\n' )) - != aBuffer.end() ) + if ( aLine.getLength() ) { - sal_uInt64 aLocation = aIt - aBuffer.begin(); - - aCommand.push_back( OString( &(*aBuffer.begin()), aLocation ) ); - if ( aIt == aBuffer.begin() ) - { - aReceiver.parseCommand( aCommand ); - aCommand.clear(); - } - aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line - aRead -= (aLocation + 1); + aCommand.push_back( aLine ); + } + else + { + aReceiver.parseCommand( aCommand ); + aCommand.clear(); } } // TODO: deal with transmision errors gracefully. diff --git a/sd/source/ui/remotecontrol/Receiver.cxx b/sd/source/ui/remotecontrol/Receiver.cxx index b190a4502ce2..968fbb4e4ee7 100644 --- a/sd/source/ui/remotecontrol/Receiver.cxx +++ b/sd/source/ui/remotecontrol/Receiver.cxx @@ -55,8 +55,6 @@ void Receiver::parseCommand( std::vector<OString> aCommand ) } catch (uno::RuntimeException &) { - fprintf( stderr, "Error in retrieving Controller\n" ); - //return; } if ( aCommand[0].equals( "transition_next" ) ) diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx index d353a1b6b1ed..34f85b3aa0e5 100644 --- a/sd/source/ui/remotecontrol/Server.cxx +++ b/sd/source/ui/remotecontrol/Server.cxx @@ -83,7 +83,6 @@ void RemoteServer::execute() if ( ! pSocket->readLine( aLine ) ) delete pSocket; OString aPin( aLine ); - fprintf( stderr, "Pin:%s\n", aPin.getStr() ); SocketAddr aClientAddr; pSocket->getPeerAddr( aClientAddr ); @@ -117,6 +116,8 @@ void RemoteServer::setup() spServer = new RemoteServer(); spServer->launch(); + + sd::BluetoothServer::setup( &(spServer->mCommunicators) ); } @@ -211,7 +212,6 @@ void SdDLL::RegisterRemotes() sd::RemoteServer::setup(); sd::DiscoveryService::setup(); - sd::BluetoothServer::setup(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/remotecontrol/Transmitter.cxx b/sd/source/ui/remotecontrol/Transmitter.cxx index 209e46039f40..2b0eb1a6e7e9 100644 --- a/sd/source/ui/remotecontrol/Transmitter.cxx +++ b/sd/source/ui/remotecontrol/Transmitter.cxx @@ -13,9 +13,9 @@ using namespace std; using namespace osl; // Sockets etc. using namespace sd; -Transmitter::Transmitter( StreamSocket &aSocket ) +Transmitter::Transmitter( BufferedStreamSocket* aSocket ) : Thread( "TransmitterThread" ), - mStreamSocket( aSocket ), + pStreamSocket( aSocket ), mQueuesNotEmpty(), mFinishRequested(), mQueueMutex(), @@ -38,13 +38,13 @@ void Transmitter::execute() { OString aMessage( mHighPriority.front() ); mHighPriority.pop(); - mStreamSocket.write( aMessage.getStr(), aMessage.getLength() ); + pStreamSocket->write( aMessage.getStr(), aMessage.getLength() ); } else if ( !mLowPriority.empty() ) { OString aMessage( mLowPriority.front() ); mLowPriority.pop(); - mStreamSocket.write( aMessage.getStr(), aMessage.getLength() ); + pStreamSocket->write( aMessage.getStr(), aMessage.getLength() ); } if ( mLowPriority.empty() && mHighPriority.empty() ) diff --git a/sd/source/ui/remotecontrol/Transmitter.hxx b/sd/source/ui/remotecontrol/Transmitter.hxx index 1b83458b04cc..e227c577e2e7 100644 --- a/sd/source/ui/remotecontrol/Transmitter.hxx +++ b/sd/source/ui/remotecontrol/Transmitter.hxx @@ -11,7 +11,7 @@ #include <osl/conditn.hxx> #include <osl/mutex.hxx> -#include <osl/socket.hxx> +#include "BufferedStreamSocket.hxx" #include <salhelper/thread.hxx> #include <rtl/string.hxx> @@ -25,7 +25,7 @@ class Transmitter { public: enum Priority { PRIORITY_LOW = 1, PRIORITY_HIGH }; - Transmitter( osl::StreamSocket &aSocket ); + Transmitter( ::sd::BufferedStreamSocket* aSocket ); ~Transmitter(); void addMessage( const rtl::OString& aMessage, const Priority aPriority ); void notifyFinished(); @@ -33,7 +33,7 @@ public: private: void execute(); - ::osl::StreamSocket mStreamSocket; + ::sd::BufferedStreamSocket* pStreamSocket; ::osl::Condition mQueuesNotEmpty; ::osl::Condition mFinishRequested; |