[Libreoffice-commits] core.git: Branch 'libreoffice-4-0' - 6 commits - sd/source
Michael Meeks
michael.meeks at suse.com
Tue Feb 19 04:01:36 PST 2013
sd/source/ui/dlg/RemoteDialog.cxx | 21
sd/source/ui/dlg/RemoteDialog.hxx | 2
sd/source/ui/inc/RemoteServer.hxx | 6
sd/source/ui/remotecontrol/BluetoothServer.cxx | 720 +++++++++++++-------
sd/source/ui/remotecontrol/BluetoothServer.hxx | 19
sd/source/ui/remotecontrol/BufferedStreamSocket.cxx | 13
sd/source/ui/remotecontrol/BufferedStreamSocket.hxx | 2
sd/source/ui/remotecontrol/Communicator.cxx | 8
sd/source/ui/remotecontrol/Communicator.hxx | 1
sd/source/ui/remotecontrol/IBluetoothSocket.hxx | 2
sd/source/ui/remotecontrol/Server.cxx | 14
11 files changed, 547 insertions(+), 261 deletions(-)
New commits:
commit 156be5f435bcaddfeaffa1055c9be9be8aa3b27a
Author: Michael Meeks <michael.meeks at suse.com>
Date: Tue Feb 19 10:07:29 2013 +0000
sdremote: fix linux conditional.
Change-Id: I911863f07b08e771d78a4a98d9a4f82c93a7d55e
(cherry picked from commit da8cf16796b916552e4aa0ab294359f91a9b8c0e)
Signed-off-by: Thorsten Behrens <tbehrens at suse.com>
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index 69cc593..8706e67 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -633,11 +633,11 @@ void BluetoothServer::restoreDiscoverable()
void BluetoothServer::doEnsureDiscoverable()
{
+#ifdef LINUX_BLUETOOTH
if (!spServer->mpImpl->mpConnection ||
spServer->meWasDiscoverable != UNKNOWN )
return;
-#ifdef LINUX_BLUETOOTH
// Find out if we are discoverable already ...
DBusObject *pAdapter = spServer->mpImpl->getAdapter();
if( !pAdapter )
commit 4a7f9c7da446aeb6a5a9010ed7f44ffc40fc67ca
Author: Michael Meeks <michael.meeks at suse.com>
Date: Mon Feb 18 14:40:24 2013 +0000
sdremote: listening to dynamic changes to adapters.
Allows LibreOffice to start with no bluetooth, and for it to
appear and disappear dynamically at run-time, cleaning up stale
bluetooth sockets, and re-binding successfully each time.
Change-Id: Ifa04c8cc1859c98adca94ac0e57c7ebd85f2f31f
(cherry picked from commit 93abe8688a4700c04b5ab045eb296298e1b49031)
Signed-off-by: Thorsten Behrens <tbehrens at suse.com>
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index a4cad7b..69cc593 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -222,15 +222,17 @@ bluezRegisterServiceRecord( DBusConnection *pConnection, DBusObject *pAdapter,
return true;
}
-static int
-bluezCreateListeningSocket()
+static void
+bluezCreateAttachListeningSocket( GMainContext *pContext, GPollFD *pSocketFD )
{
int nSocket;
+ pSocketFD->fd = -1;
+
if( ( nSocket = socket( AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM ) ) < 0 )
{
SAL_WARN( "sdremote.bluetooth", "failed to open bluetooth socket with error " << nSocket );
- return -1;
+ return;
}
sockaddr_rc aAddr;
@@ -243,24 +245,39 @@ bluezCreateListeningSocket()
if ( ( a = bind( nSocket, (sockaddr*) &aAddr, sizeof(aAddr) ) ) < 0 ) {
SAL_WARN( "sdremote.bluetooth", "bind failed with error" << a );
close( nSocket );
- return -1;
+ return;
}
if ( ( a = listen( nSocket, 1 ) ) < 0 )
{
SAL_WARN( "sdremote.bluetooth", "listen failed with error" << a );
close( nSocket );
- return -1;
+ return;
}
// set non-blocking behaviour ...
if( fcntl( nSocket, F_SETFL, O_NONBLOCK) < 0 )
{
close( nSocket );
- return -1;
+ return;
}
- return nSocket;
+ pSocketFD->fd = nSocket;
+ pSocketFD->events = G_IO_IN | G_IO_PRI;
+ pSocketFD->revents = 0;
+
+ g_main_context_add_poll( pContext, pSocketFD, G_PRIORITY_DEFAULT );
+}
+
+static void
+bluezDetachCloseSocket( GMainContext *pContext, GPollFD *pSocketFD )
+{
+ if( pSocketFD->fd >= 0 )
+ {
+ close( pSocketFD->fd );
+ g_main_context_remove_poll( pContext, pSocketFD );
+ pSocketFD->fd = -1;
+ }
}
#endif // LINUX_BLUETOOTH
@@ -552,6 +569,24 @@ setDiscoverable( DBusConnection *pConnection, DBusObject *pAdapter, bool bDiscov
dbus_message_unref( pMsg );
}
+static DBusObject *
+registerWithDefaultAdapter( DBusConnection *pConnection )
+{
+ DBusObject *pService;
+ pService = bluezGetDefaultService( pConnection );
+ if( !pService )
+ return NULL;
+
+ if( !bluezRegisterServiceRecord( pConnection, pService,
+ bluetooth_service_record ) )
+ {
+ delete pService;
+ return NULL;
+ }
+
+ return pService;
+}
+
#endif // LINUX_BLUETOOTH
BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators )
@@ -636,6 +671,17 @@ void BluetoothServer::doRestoreDiscoverable()
spServer->meWasDiscoverable = UNKNOWN;
}
+// We have to have all our clients shut otherwise we can't
+// re-bind to the same port number it appears.
+void BluetoothServer::cleanupCommunicators()
+{
+ for (std::vector<Communicator *>::iterator it = mpCommunicators->begin();
+ it != mpCommunicators->end(); it++)
+ (*it)->forceClose();
+ // the hope is that all the threads then terminate cleanly and
+ // clean themselves up.
+}
+
void SAL_CALL BluetoothServer::run()
{
SAL_INFO( "sdremote.bluetooth", "BluetoothServer::run called" );
@@ -645,33 +691,20 @@ void SAL_CALL BluetoothServer::run()
if( !pConnection )
return;
- mpImpl->mpService = bluezGetDefaultService( pConnection );
- if( !mpImpl->mpService )
- {
- dbus_connection_unref( pConnection );
- return;
- }
-
- if( !bluezRegisterServiceRecord( pConnection, mpImpl->mpService,
- bluetooth_service_record ) )
- return;
-
- int nSocket = bluezCreateListeningSocket();
- if( nSocket < 0 )
- return;
-
- // ---------------- Socket code ----------------
-
- sockaddr_rc aRemoteAddr;
- socklen_t aRemoteAddrLen = sizeof(aRemoteAddr);
+ // listen for connection state and power changes - we need to close
+ // and re-create our socket code on suspend / resume, enable/disable
+ DBusError aError;
+ dbus_error_init( &aError );
+ dbus_bus_add_match( pConnection, "type='signal',interface='org.bluez.Manager'", &aError );
+ dbus_connection_flush( pConnection );
- // Avoid using GSources where we can
+ // Try to setup the default adapter, otherwise wait for add/remove signal
+ mpImpl->mpService = registerWithDefaultAdapter( pConnection );
- // poll on our socket
+ // poll on our bluetooth socket - if we can.
GPollFD aSocketFD;
- aSocketFD.fd = nSocket;
- aSocketFD.events = G_IO_IN | G_IO_PRI;
- g_main_context_add_poll( mpImpl->mpContext, &aSocketFD, G_PRIORITY_DEFAULT );
+ if( mpImpl->mpService )
+ bluezCreateAttachListeningSocket( mpImpl->mpContext, &aSocketFD );
// also poll on our dbus connection
int fd = -1;
@@ -696,13 +729,45 @@ void SAL_CALL BluetoothServer::run()
SAL_INFO( "sdremote.bluetooth", "main-loop spin "
<< aDBusFD.revents << " " << aSocketFD.revents );
if( aDBusFD.revents )
- dbus_connection_read_write_dispatch( pConnection, 0 );
+ {
+ dbus_connection_read_write( pConnection, 0 );
+ DBusMessage *pMsg = dbus_connection_pop_message( pConnection );
+ if( pMsg )
+ {
+ if( dbus_message_is_signal( pMsg, "org.bluez.Manager", "AdapterRemoved" ) )
+ {
+ SAL_WARN( "sdremote.bluetooth", "lost adapter - cleaning up sockets" );
+ bluezDetachCloseSocket( mpImpl->mpContext, &aSocketFD );
+ cleanupCommunicators();
+ }
+ else if( dbus_message_is_signal( pMsg, "org.bluez.Manager", "AdapterAdded" ) ||
+ dbus_message_is_signal( pMsg, "org.bluez.Manager", "DefaultAdapterChanged" ) )
+ {
+ SAL_WARN( "sdremote.bluetooth", "gained adapter - re-generating sockets" );
+ bluezDetachCloseSocket( mpImpl->mpContext, &aSocketFD );
+ cleanupCommunicators();
+ mpImpl->mpService = registerWithDefaultAdapter( pConnection );
+ if( mpImpl->mpService )
+ bluezCreateAttachListeningSocket( mpImpl->mpContext, &aSocketFD );
+ }
+ else
+ SAL_INFO( "sdremote.bluetooth", "unknown incoming dbus message, "
+ << " type: " << dbus_message_get_type( pMsg )
+ << " path: '" << dbus_message_get_path( pMsg )
+ << "' interface: '" << dbus_message_get_interface( pMsg )
+ << "' member: '" << dbus_message_get_member( pMsg ) );
+ }
+ dbus_message_unref( pMsg );
+ }
if( aSocketFD.revents )
{
+ sockaddr_rc aRemoteAddr;
+ socklen_t aRemoteAddrLen = sizeof(aRemoteAddr);
+
int nClient;
SAL_INFO( "sdremote.bluetooth", "performing accept" );
- if ( ( nClient = accept( nSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 &&
+ if ( ( nClient = accept( aSocketFD.fd, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 &&
errno != EAGAIN )
{
SAL_WARN( "sdremote.bluetooth", "accept failed with errno " << errno );
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.hxx b/sd/source/ui/remotecontrol/BluetoothServer.hxx
index 24b8dec..8078ede 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.hxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.hxx
@@ -43,6 +43,7 @@ namespace sd
BluetoothServerImpl *mpImpl;
virtual void SAL_CALL run();
+ void cleanupCommunicators();
std::vector<Communicator*>* mpCommunicators;
};
}
diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
index d35b606..c4f7f611 100644
--- a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
+++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
@@ -27,7 +27,7 @@ BufferedStreamSocket::BufferedStreamSocket( const osl::StreamSocket &aSocket ):
aRead( 0 ),
aBuffer(),
mSocket( 0 ),
- usingCSocket( false)
+ usingCSocket( false )
{
}
@@ -55,6 +55,17 @@ sal_Int32 BufferedStreamSocket::write( const void* pBuffer, sal_uInt32 n )
return ::send( mSocket, (const char *) pBuffer, (size_t) n, 0 );
}
+void BufferedStreamSocket::close()
+{
+ if( usingCSocket )
+ {
+ ::close( mSocket );
+ mSocket = -1;
+ }
+ else
+ close();
+}
+
sal_Int32 BufferedStreamSocket::readLine( OString& aLine )
{
while ( true )
diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx
index 0e6b99a..005cc73 100644
--- a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx
+++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx
@@ -51,6 +51,8 @@ namespace sd
virtual sal_Int32 write( const void* pBuffer, sal_uInt32 n );
+ virtual void close();
+
void getPeerAddr(osl::SocketAddr&);
private:
sal_Int32 aRet, aRead;
diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx
index 7f01334..de73dcc 100644
--- a/sd/source/ui/remotecontrol/Communicator.cxx
+++ b/sd/source/ui/remotecontrol/Communicator.cxx
@@ -33,6 +33,14 @@ Communicator::~Communicator()
{
}
+/// Close the underlying socket from another thread to force
+/// an early exit / termination
+void Communicator::forceClose()
+{
+ if( mpSocket )
+ mpSocket->close();
+}
+
// Run as a thread
void Communicator::execute()
{
diff --git a/sd/source/ui/remotecontrol/Communicator.hxx b/sd/source/ui/remotecontrol/Communicator.hxx
index a783bac..7883401 100644
--- a/sd/source/ui/remotecontrol/Communicator.hxx
+++ b/sd/source/ui/remotecontrol/Communicator.hxx
@@ -43,6 +43,7 @@ namespace sd
css::presentation::XSlideShowController > &rController );
void informListenerDestroyed();
void disposeListener();
+ void forceClose();
private:
void execute();
diff --git a/sd/source/ui/remotecontrol/IBluetoothSocket.hxx b/sd/source/ui/remotecontrol/IBluetoothSocket.hxx
index 1949367..0359807 100644
--- a/sd/source/ui/remotecontrol/IBluetoothSocket.hxx
+++ b/sd/source/ui/remotecontrol/IBluetoothSocket.hxx
@@ -33,6 +33,8 @@ namespace sd
@return number of bytes actually written
*/
virtual sal_Int32 write( const void* pBuffer, sal_uInt32 n ) = 0;
+
+ virtual void close() {};
};
}
commit 25819137fe00afa6ec5cb900a742fa9368a52a16
Author: Michael Meeks <michael.meeks at suse.com>
Date: Mon Feb 18 13:31:21 2013 +0000
sdremote: re-work discoverable property get/set to use libdbus.
Change-Id: I5e11a0fcfd8db648a40c738cbc8181889cb36136
(cherry picked from commit 618fe83d6e8aeabc309540fae998aeb78465bb4d)
Signed-off-by: Thorsten Behrens <tbehrens at suse.com>
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index 5229e9d..a4cad7b 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -21,20 +21,12 @@
#ifdef LINUX_BLUETOOTH
#include <glib.h>
#include <dbus/dbus.h>
- #include <dbus/dbus-glib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
- #define DBUS_TYPE_G_STRING_ANY_HASHTABLE (dbus_g_type_get_map( "GHashTable", G_TYPE_STRING, G_TYPE_VALUE ))
- #ifndef G_VALUE_INIT
- #define G_VALUE_INIT {0,{{0}}} // G_VALUE_INIT only present in glib >= 2.30
- #endif
- #ifndef DBusGObjectPath
- #define DBusGObjectPath char // DBusGObjectPath is only present in newer version of dbus-glib
- #endif
#include "BluetoothServiceRecord.hxx"
#include "BufferedStreamSocket.hxx"
#endif
@@ -83,26 +75,52 @@ using namespace sd;
#ifdef LINUX_BLUETOOTH
-struct sd::BluetoothServerImpl {
- // the glib mainloop running in the thread
- GMainContext *mpContext;
- volatile bool mbExitMainloop;
-};
-
struct DBusObject {
OString maBusName;
OString maPath;
OString maInterface;
+ DBusObject() { }
DBusObject( const char *pBusName, const char *pPath, const char *pInterface )
- : maBusName( pBusName ), maPath( pPath ), maInterface( pInterface )
- { }
+ : maBusName( pBusName ), maPath( pPath ), maInterface( pInterface ) { }
DBusMessage *getMethodCall( const char *pName )
{
return dbus_message_new_method_call( maBusName.getStr(), maPath.getStr(),
maInterface.getStr(), pName );
}
+ DBusObject *cloneForInterface( const char *pInterface )
+ {
+ DBusObject *pObject = new DBusObject();
+
+ pObject->maBusName = maBusName;
+ pObject->maPath = maPath;
+ pObject->maInterface = pInterface;
+
+ return pObject;
+ }
+};
+
+struct sd::BluetoothServerImpl {
+ // the glib mainloop running in the thread
+ GMainContext *mpContext;
+ DBusConnection *mpConnection;
+ DBusObject *mpService;
+ volatile bool mbExitMainloop;
+
+ BluetoothServerImpl() :
+ mpContext( g_main_context_new() ),
+ mpConnection( NULL ),
+ mpService( NULL ),
+ mbExitMainloop( false )
+ { }
+
+ DBusObject *getAdapter()
+ {
+ if( !mpService )
+ return NULL;
+ return mpService->cloneForInterface( "org.bluez.Adapter" );
+ }
};
static DBusConnection *
@@ -124,19 +142,15 @@ dbusConnectToNameOnBus()
return pConnection;
}
-static DBusObject *
-bluezGetDefaultAdapter( DBusConnection *pConnection,
- const gchar* pInterfaceType = "org.bluez.Adapter" )
+static DBusMessage *
+sendUnrefAndWaitForReply( DBusConnection *pConnection, DBusMessage *pMsg )
{
- DBusMessage *pMsg;
- DBusMessageIter it;
- DBusPendingCall *pPending;
+ DBusPendingCall *pPending = NULL;
- pMsg = DBusObject( "org.bluez", "/", "org.bluez.Manager" ).getMethodCall( "DefaultAdapter" );
if( !pMsg || !dbus_connection_send_with_reply( pConnection, pMsg, &pPending,
-1 /* default timeout */ ) )
{
- SAL_WARN( "sdremote.bluetooth", "Memory allocation failed on message" );
+ SAL_WARN( "sdremote.bluetooth", "Memory allocation failed on message send" );
dbus_message_unref( pMsg );
return NULL;
}
@@ -146,14 +160,25 @@ bluezGetDefaultAdapter( DBusConnection *pConnection,
dbus_pending_call_block( pPending ); // block for reply
pMsg = dbus_pending_call_steal_reply( pPending );
- if( !pMsg || !dbus_message_iter_init( pMsg, &it ) )
- {
+ if( !pMsg )
SAL_WARN( "sdremote.bluetooth", "no valid reply / timeout" );
- dbus_pending_call_unref( pPending );
- return NULL;
- }
+
dbus_pending_call_unref( pPending );
+ return pMsg;
+}
+
+static DBusObject *
+bluezGetDefaultService( DBusConnection *pConnection )
+{
+ DBusMessage *pMsg;
+ DBusMessageIter it;
+ const gchar* pInterfaceType = "org.bluez.Service";
+ pMsg = DBusObject( "org.bluez", "/", "org.bluez.Manager" ).getMethodCall( "DefaultAdapter" );
+ pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+
+ if(!pMsg || !dbus_message_iter_init( pMsg, &it ) )
+ return NULL;
if( DBUS_TYPE_OBJECT_PATH != dbus_message_iter_get_arg_type( &it ) )
SAL_WARN( "sdremote.bluetooth", "invalid type of reply to DefaultAdapter: '"
@@ -177,25 +202,13 @@ bluezRegisterServiceRecord( DBusConnection *pConnection, DBusObject *pAdapter,
{
DBusMessage *pMsg;
DBusMessageIter it;
- DBusPendingCall *pPending;
pMsg = pAdapter->getMethodCall( "AddRecord" );
dbus_message_iter_init_append( pMsg, &it );
dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pServiceRecord );
- if(!dbus_connection_send_with_reply( pConnection, pMsg, &pPending,
- -1 /* default timeout */ ) )
- if( !dbus_connection_send( pConnection, pMsg, NULL ) )
- {
- SAL_WARN( "sdremote.bluetooth", "failed to send service record" );
- return false;
- }
- dbus_connection_flush( pConnection );
- dbus_message_unref( pMsg );
-
- dbus_pending_call_block( pPending ); // block for reply
+ pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
- pMsg = dbus_pending_call_steal_reply( pPending );
if( !pMsg || !dbus_message_iter_init( pMsg, &it ) ||
dbus_message_iter_get_arg_type( &it ) != DBUS_TYPE_UINT32 )
{
@@ -206,8 +219,6 @@ bluezRegisterServiceRecord( DBusConnection *pConnection, DBusObject *pAdapter,
// We ignore the uint de-registration handle we get back:
// bluez will clean us up automatically on exit
- dbus_pending_call_unref( pPending );
-
return true;
}
@@ -252,7 +263,12 @@ bluezCreateListeningSocket()
return nSocket;
}
-#endif // defined(LINUX) && defined(ENABLE_DBUS)
+#endif // LINUX_BLUETOOTH
+
+void BluetoothServer::addCommunicator( Communicator* pCommunicator )
+{
+ mpCommunicators->push_back( pCommunicator );
+}
#if defined(MACOSX)
@@ -402,195 +418,222 @@ void incomingCallback( void *userRefCon,
#endif // MACOSX
-
-BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators )
- : meWasDiscoverable( UNKNOWN ),
- mpImpl( NULL ),
- mpCommunicators( pCommunicators )
-{
#ifdef LINUX_BLUETOOTH
- g_type_init();
- mpImpl = new BluetoothServerImpl();
- mpImpl->mpContext = g_main_context_new();
- mpImpl->mbExitMainloop = false;
-#endif
-}
-
-BluetoothServer::~BluetoothServer()
-{
-}
-
-
-void BluetoothServer::ensureDiscoverable()
-{
- if( !spServer || spServer->meWasDiscoverable != UNKNOWN )
- return;
- bool bDiscoverable = spServer->isDiscoverable();
- spServer->meWasDiscoverable = bDiscoverable ? DISCOVERABLE : NOT_DISCOVERABLE;
- spServer->setDiscoverable( true );
-}
-
-void BluetoothServer::restoreDiscoverable()
-{
- if(!spServer)
- return;
-
- if ( spServer->meWasDiscoverable == NOT_DISCOVERABLE )
- spServer->setDiscoverable( false );
- spServer->meWasDiscoverable = UNKNOWN;
+extern "C" {
+ static gboolean ensureDiscoverable_cb(gpointer)
+ {
+ BluetoothServer::doEnsureDiscoverable();
+ return FALSE; // remove source
+ }
+ static gboolean restoreDiscoverable_cb(gpointer)
+ {
+ BluetoothServer::doRestoreDiscoverable();
+ return FALSE; // remove source
+ }
}
-bool BluetoothServer::isDiscoverable()
+static bool
+getBooleanProperty( DBusConnection *pConnection, DBusObject *pAdapter,
+ const char *pPropertyName, bool *pBoolean )
{
-#if 0 // (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
- SAL_INFO( "sdremote.bluetooth", "BluetoothServer::isDiscoverable called" );
- g_type_init();
- gboolean aResult;
+ *pBoolean = false;
- GError *aError = NULL;
+ if( !pAdapter )
+ return false;
- DBusGConnection *aConnection = NULL;
- aConnection = dbus_g_bus_get( DBUS_BUS_SYSTEM, &aError );
+ DBusMessage *pMsg;
+ pMsg = sendUnrefAndWaitForReply( pConnection,
+ pAdapter->getMethodCall( "GetProperties" ) );
- if ( aError != NULL ) {
- g_error_free (aError);
- SAL_INFO( "sdremote.bluetooth", "did not get DBusGConnection" );
+ DBusMessageIter it;
+ if( !pMsg || !dbus_message_iter_init( pMsg, &it ) )
+ {
+ SAL_WARN( "sdremote.bluetooth", "no valid reply / timeout" );
return false;
}
- DBusGProxy* aAdapter = bluezGetDefaultAdapter( pConnection );
- if ( aAdapter == NULL )
+ if( DBUS_TYPE_ARRAY != dbus_message_iter_get_arg_type( &it ) )
{
- dbus_g_connection_unref( aConnection );
- SAL_INFO( "sdremote.bluetooth", "did not get default adaptor" );
+ SAL_WARN( "sdremote.bluetooth", "no valid reply / timeout" );
return false;
}
- GHashTable* aProperties = NULL;
- aResult = dbus_g_proxy_call( aAdapter, "GetProperties", &aError,
- G_TYPE_INVALID,
- DBUS_TYPE_G_STRING_ANY_HASHTABLE, &aProperties,
- G_TYPE_INVALID);
- g_object_unref( G_OBJECT( aAdapter ));
- dbus_g_connection_unref( aConnection );
- if ( !aResult || aError )
+ DBusMessageIter arrayIt;
+ dbus_message_iter_recurse( &it, &arrayIt );
+
+ while( dbus_message_iter_get_arg_type( &arrayIt ) == DBUS_TYPE_DICT_ENTRY )
{
- if ( aError )
- g_error_free( aError );
- SAL_INFO( "sdremote.bluetooth", "did not get properties" );
- return false;
- }
+ DBusMessageIter dictIt;
+ dbus_message_iter_recurse( &arrayIt, &dictIt );
- gboolean aIsDiscoverable = g_value_get_boolean( (GValue*) g_hash_table_lookup(
- aProperties, "Discoverable" ) );
+ const char *pName = NULL;
+ if( dbus_message_iter_get_arg_type( &dictIt ) == DBUS_TYPE_STRING )
+ {
+ dbus_message_iter_get_basic( &dictIt, &pName );
+ if( pName != NULL && !strcmp( pName, pPropertyName ) )
+ {
+ SAL_INFO( "sdremote.bluetooth", "hit " << pPropertyName << " property" );
+ dbus_message_iter_next( &dictIt );
+ dbus_bool_t bBool = false;
- g_hash_table_unref( aProperties );
+ if( dbus_message_iter_get_arg_type( &dictIt ) == DBUS_TYPE_VARIANT )
+ {
+ DBusMessageIter variantIt;
+ dbus_message_iter_recurse( &dictIt, &variantIt );
+
+ if( dbus_message_iter_get_arg_type( &variantIt ) == DBUS_TYPE_BOOLEAN )
+ {
+ dbus_message_iter_get_basic( &variantIt, &bBool );
+ SAL_INFO( "sdremote.bluetooth", "" << pPropertyName << " is " << bBool );
+ *pBoolean = bBool;
+ return true;
+ }
+ else
+ SAL_WARN( "sdremote.bluetooth", "" << pPropertyName << " type " <<
+ dbus_message_iter_get_arg_type( &variantIt ) );
+ }
+ else
+ SAL_WARN( "sdremote.bluetooth", "variant type ? " <<
+ dbus_message_iter_get_arg_type( &dictIt ) );
+ }
+ else
+ {
+ const char *pStr = pName ? pName : "<null>";
+ SAL_INFO( "sdremote.bluetooth", "property '" << pStr << "'" );
+ }
+ }
+ else
+ SAL_WARN( "sdremote.bluetooth", "unexpected property key type "
+ << dbus_message_iter_get_arg_type( &dictIt ) );
+ dbus_message_iter_next( &arrayIt );
+ }
+ dbus_message_unref( pMsg );
- SAL_INFO( "sdremote.bluetooth", "BluetoothServer::isDiscoverable() returns " << static_cast< bool >( aIsDiscoverable ) );
- return aIsDiscoverable;
-#else // defined(LINUX) && defined(ENABLE_DBUS)
return false;
-#endif
}
-void BluetoothServer::setDiscoverable( bool bDiscoverable )
+static void
+setDiscoverable( DBusConnection *pConnection, DBusObject *pAdapter, bool bDiscoverable )
{
-#if 0 // (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
- SAL_INFO( "sdremote.bluetooth", "BluetoothServer::setDiscoverable called" );
- g_type_init();
- gboolean aResult;
+ SAL_INFO( "sdremote.bluetooth", "setDiscoverable to " << bDiscoverable );
- GError *aError = NULL;
+ bool bPowered = false;
+ if( !getBooleanProperty( pConnection, pAdapter, "Powered", &bPowered ) || !bPowered )
+ return; // nothing to do
- DBusGConnection *aConnection = NULL;
- aConnection = dbus_g_bus_get( DBUS_BUS_SYSTEM, &aError );
+ DBusMessage *pMsg;
+ DBusMessageIter it, varIt;
- if ( aError != NULL )
- {
- g_error_free (aError);
- return;
- }
+ // set timeout to zero
+ pMsg = pAdapter->getMethodCall( "SetProperty" );
+ dbus_message_iter_init_append( pMsg, &it );
+ const char *pTimeoutStr = "DiscoverableTimeout";
+ dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pTimeoutStr );
+ dbus_message_iter_open_container( &it, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_UINT32_AS_STRING, &varIt );
+ dbus_uint32_t nTimeout = 0;
+ dbus_message_iter_append_basic( &varIt, DBUS_TYPE_UINT32, &nTimeout );
+ dbus_message_iter_close_container( &it, &varIt );
+ dbus_connection_send( pConnection, pMsg, NULL ); // async send - why not ?
+ dbus_message_unref( pMsg );
- DBusGProxy* aAdapter = bluezGetDefaultAdapter( pConnection );
- if ( aAdapter == NULL )
- {
- dbus_g_connection_unref( aConnection );
- return;
- }
+ // set discoverable value
+ pMsg = pAdapter->getMethodCall( "SetProperty" );
+ dbus_message_iter_init_append( pMsg, &it );
+ const char *pDiscoverableStr = "Discoverable";
+ dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pDiscoverableStr );
+ dbus_message_iter_open_container( &it, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_BOOLEAN_AS_STRING, &varIt );
+ dbus_bool_t bValue = bDiscoverable;
+ dbus_message_iter_append_basic( &varIt, DBUS_TYPE_BOOLEAN, &bValue );
+ dbus_message_iter_close_container( &it, &varIt ); // async send - why not ?
+ dbus_connection_send( pConnection, pMsg, NULL );
+ dbus_message_unref( pMsg );
+}
- GHashTable* aProperties;
- aResult = dbus_g_proxy_call( aAdapter, "GetProperties", &aError,
- G_TYPE_INVALID,
- DBUS_TYPE_G_STRING_ANY_HASHTABLE, &aProperties,
- G_TYPE_INVALID);
+#endif // LINUX_BLUETOOTH
- if ( !aResult || aError )
- {
- SAL_WARN( "sdremote.bluetooth", "GetProperties failed" );
- if ( aError )
- {
- g_error_free( aError );
- SAL_WARN( "sdremote.bluetooth", "with error " << aError->message );
- }
+BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators )
+ : meWasDiscoverable( UNKNOWN ),
+ mpImpl( NULL ),
+ mpCommunicators( pCommunicators )
+{
+#ifdef LINUX_BLUETOOTH
+ mpImpl = new BluetoothServerImpl();
+#endif
+}
+
+BluetoothServer::~BluetoothServer()
+{
+}
+
+void BluetoothServer::ensureDiscoverable()
+{
+#ifdef LINUX_BLUETOOTH
+ // Push it all across into our mainloop
+ if( !spServer )
return;
- }
+ GSource *pIdle = g_idle_source_new();
+ g_source_set_callback( pIdle, ensureDiscoverable_cb, NULL, NULL );
+ g_source_set_priority( pIdle, G_PRIORITY_DEFAULT );
+ g_source_attach( pIdle, spServer->mpImpl->mpContext );
+ g_source_unref( pIdle );
+#endif
+}
- gboolean aPowered = g_value_get_boolean( (GValue*) g_hash_table_lookup(
- aProperties, "Powered" ) );
+void BluetoothServer::restoreDiscoverable()
+{
+#ifdef LINUX_BLUETOOTH
+ // Push it all across into our mainloop
+ if( !spServer )
+ return;
+ GSource *pIdle = g_idle_source_new();
+ g_source_set_callback( pIdle, restoreDiscoverable_cb, NULL, NULL );
+ g_source_set_priority( pIdle, G_PRIORITY_DEFAULT_IDLE );
+ g_source_attach( pIdle, spServer->mpImpl->mpContext );
+ g_source_unref( pIdle );
+#endif
+}
- g_hash_table_unref( aProperties );
- if ( !aPowered )
- {
- SAL_INFO( "sdremote.bluetooth", "Bluetooth adapter not powered, returning" );
- g_object_unref( G_OBJECT( aAdapter ));
+void BluetoothServer::doEnsureDiscoverable()
+{
+ if (!spServer->mpImpl->mpConnection ||
+ spServer->meWasDiscoverable != UNKNOWN )
return;
- }
- GValue aTimeout = G_VALUE_INIT;
- g_value_init( &aTimeout, G_TYPE_UINT );
- g_value_set_uint( &aTimeout, 0 );
- aResult = dbus_g_proxy_call( aAdapter, "SetProperty", &aError,
- G_TYPE_STRING, "DiscoverableTimeout",
- G_TYPE_VALUE, &aTimeout, G_TYPE_INVALID, G_TYPE_INVALID);
- if ( !aResult || aError )
- {
- SAL_WARN( "sdremote.bluetooth", "SetProperty(DiscoverableTimeout) failed" );
- if ( aError )
- {
- g_error_free( aError );
- SAL_WARN( "sdremote.bluetooth", "with error " << aError->message );
- }
+#ifdef LINUX_BLUETOOTH
+ // Find out if we are discoverable already ...
+ DBusObject *pAdapter = spServer->mpImpl->getAdapter();
+ if( !pAdapter )
return;
- }
- GValue bDiscoverableGValue = G_VALUE_INIT;
- g_value_init( &bDiscoverableGValue, G_TYPE_BOOLEAN );
- g_value_set_boolean( &bDiscoverableGValue, bDiscoverable );
- aResult = dbus_g_proxy_call( aAdapter, "SetProperty", &aError,
- G_TYPE_STRING, "Discoverable",
- G_TYPE_VALUE, &bDiscoverableGValue, G_TYPE_INVALID, G_TYPE_INVALID);
- if ( !aResult || aError )
+ bool bDiscoverable;
+ if( getBooleanProperty( spServer->mpImpl->mpConnection, pAdapter,
+ "Discoverable", &bDiscoverable ) )
{
- SAL_WARN( "sdremote.bluetooth", "SetProperty(Discoverable) failed" );
- if ( aError )
- {
- g_error_free( aError );
- SAL_WARN( "sdremote.bluetooth", "with error " << aError->message );
- }
- return;
+ spServer->meWasDiscoverable = bDiscoverable ? DISCOVERABLE : NOT_DISCOVERABLE;
+ if( !bDiscoverable )
+ setDiscoverable( spServer->mpImpl->mpConnection, pAdapter, true );
}
- g_object_unref( G_OBJECT( aAdapter ));
- dbus_g_connection_unref( aConnection );
-#else // defined(LINUX) && defined(ENABLE_DBUS)
- (void) bDiscoverable; // avoid warnings
+ delete pAdapter;
#endif
}
-void BluetoothServer::addCommunicator( Communicator* pCommunicator )
+void BluetoothServer::doRestoreDiscoverable()
{
- mpCommunicators->push_back( pCommunicator );
+ if( spServer->meWasDiscoverable == NOT_DISCOVERABLE )
+ {
+#ifdef LINUX_BLUETOOTH
+ DBusObject *pAdapter = spServer->mpImpl->getAdapter();
+ if( !pAdapter )
+ return;
+ setDiscoverable( spServer->mpImpl->mpConnection, pAdapter, false );
+ delete pAdapter;
+#endif
+ }
+ spServer->meWasDiscoverable = UNKNOWN;
}
void SAL_CALL BluetoothServer::run()
@@ -602,14 +645,15 @@ void SAL_CALL BluetoothServer::run()
if( !pConnection )
return;
- DBusObject *pService = bluezGetDefaultAdapter( pConnection, "org.bluez.Service" );
- if( !pService )
+ mpImpl->mpService = bluezGetDefaultService( pConnection );
+ if( !mpImpl->mpService )
{
dbus_connection_unref( pConnection );
return;
}
- if( !bluezRegisterServiceRecord( pConnection, pService, bluetooth_service_record ) )
+ if( !bluezRegisterServiceRecord( pConnection, mpImpl->mpService,
+ bluetooth_service_record ) )
return;
int nSocket = bluezCreateListeningSocket();
@@ -641,6 +685,8 @@ void SAL_CALL BluetoothServer::run()
else
SAL_WARN( "sdremote.bluetooth", "failed to poll for incoming dbus signals" );
+ mpImpl->mpConnection = pConnection;
+
while( !mpImpl->mbExitMainloop )
{
aDBusFD.revents = 0;
@@ -669,6 +715,10 @@ void SAL_CALL BluetoothServer::run()
}
}
+ g_main_context_unref( mpImpl->mpContext );
+ mpImpl->mpConnection = NULL;
+ mpImpl->mpContext = NULL;
+
#elif defined(WIN32)
WORD wVersionRequested;
WSADATA wsaData;
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.hxx b/sd/source/ui/remotecontrol/BluetoothServer.hxx
index b922d60..24b8dec 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.hxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.hxx
@@ -28,15 +28,15 @@ namespace sd
/// restore the state of discoverability from before ensureDiscoverable
static void restoreDiscoverable();
- void addCommunicator( Communicator* pCommunicator );
+ // called by C / idle callbacks
+ static void doEnsureDiscoverable();
+ static void doRestoreDiscoverable();
+ void addCommunicator( Communicator* pCommunicator );
private:
BluetoothServer( std::vector<Communicator*>* pCommunicators );
~BluetoothServer();
- bool isDiscoverable();
- void setDiscoverable( bool bDiscoverable );
-
enum { UNKNOWN, DISCOVERABLE, NOT_DISCOVERABLE } meWasDiscoverable;
static BluetoothServer *spServer;
commit 7848b97462a088521986ba200ee2fd55982667bb
Author: Michael Meeks <michael.meeks at suse.com>
Date: Mon Feb 18 11:30:54 2013 +0000
sdremote: switch to a non-blocking socket, and polling glib mainloop.
Conflicts:
sd/source/ui/remotecontrol/BluetoothServer.cxx
Change-Id: I84c0a522fe16fbc8fc86a8e4bccb84aec0a1acd1
(cherry picked from commit 0d89d814055d5c267a2cc57e302a23e9f0b521e3)
Signed-off-by: Thorsten Behrens <tbehrens at suse.com>
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index 2ccfc87..5229e9d 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -15,9 +15,15 @@
#include <sal/log.hxx>
#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
+# define LINUX_BLUETOOTH
+#endif
+
+#ifdef LINUX_BLUETOOTH
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
+ #include <errno.h>
+ #include <fcntl.h>
#include <sys/unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
@@ -75,7 +81,13 @@
using namespace sd;
-#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
+#ifdef LINUX_BLUETOOTH
+
+struct sd::BluetoothServerImpl {
+ // the glib mainloop running in the thread
+ GMainContext *mpContext;
+ volatile bool mbExitMainloop;
+};
struct DBusObject {
OString maBusName;
@@ -230,6 +242,13 @@ bluezCreateListeningSocket()
return -1;
}
+ // set non-blocking behaviour ...
+ if( fcntl( nSocket, F_SETFL, O_NONBLOCK) < 0 )
+ {
+ close( nSocket );
+ return -1;
+ }
+
return nSocket;
}
@@ -386,8 +405,15 @@ void incomingCallback( void *userRefCon,
BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators )
: meWasDiscoverable( UNKNOWN ),
+ mpImpl( NULL ),
mpCommunicators( pCommunicators )
{
+#ifdef LINUX_BLUETOOTH
+ g_type_init();
+ mpImpl = new BluetoothServerImpl();
+ mpImpl->mpContext = g_main_context_new();
+ mpImpl->mbExitMainloop = false;
+#endif
}
BluetoothServer::~BluetoothServer()
@@ -569,10 +595,9 @@ void BluetoothServer::addCommunicator( Communicator* pCommunicator )
void SAL_CALL BluetoothServer::run()
{
- SAL_INFO( "sdremote.bluetooth", "BluetoothServer::execute called" );
-#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
- g_type_init();
+ SAL_INFO( "sdremote.bluetooth", "BluetoothServer::run called" );
+#ifdef LINUX_BLUETOOTH
DBusConnection *pConnection = dbusConnectToNameOnBus();
if( !pConnection )
return;
@@ -587,8 +612,8 @@ void SAL_CALL BluetoothServer::run()
if( !bluezRegisterServiceRecord( pConnection, pService, bluetooth_service_record ) )
return;
- int aSocket = bluezCreateListeningSocket();
- if( aSocket < 0 )
+ int nSocket = bluezCreateListeningSocket();
+ if( nSocket < 0 )
return;
// ---------------- Socket code ----------------
@@ -596,22 +621,51 @@ void SAL_CALL BluetoothServer::run()
sockaddr_rc aRemoteAddr;
socklen_t aRemoteAddrLen = sizeof(aRemoteAddr);
- // FIXME: use a glib main-loop [!] ...
- // FIXME: fixme ! ...
- while ( true )
+ // Avoid using GSources where we can
+
+ // poll on our socket
+ GPollFD aSocketFD;
+ aSocketFD.fd = nSocket;
+ aSocketFD.events = G_IO_IN | G_IO_PRI;
+ g_main_context_add_poll( mpImpl->mpContext, &aSocketFD, G_PRIORITY_DEFAULT );
+
+ // also poll on our dbus connection
+ int fd = -1;
+ GPollFD aDBusFD;
+ if( dbus_connection_get_unix_fd( pConnection, &fd ) && fd >= 0 )
{
- int bSocket;
- SAL_INFO( "sdremote.bluetooth", "waiting on accept" );
- if ( (bSocket = accept(aSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 )
+ aDBusFD.fd = fd;
+ aDBusFD.events = G_IO_IN | G_IO_PRI;
+ g_main_context_add_poll( mpImpl->mpContext, &aDBusFD, G_PRIORITY_DEFAULT );
+ }
+ else
+ SAL_WARN( "sdremote.bluetooth", "failed to poll for incoming dbus signals" );
+
+ while( !mpImpl->mbExitMainloop )
+ {
+ aDBusFD.revents = 0;
+ aSocketFD.revents = 0;
+ g_main_context_iteration( mpImpl->mpContext, TRUE );
+
+ SAL_INFO( "sdremote.bluetooth", "main-loop spin "
+ << aDBusFD.revents << " " << aSocketFD.revents );
+ if( aDBusFD.revents )
+ dbus_connection_read_write_dispatch( pConnection, 0 );
+
+ if( aSocketFD.revents )
{
- SAL_WARN( "sdremote.bluetooth", "accept failed with error" << bSocket );
- close( aSocket );
- return;
- } else {
- SAL_INFO( "sdremote.bluetooth", "connection accepted" );
- Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( bSocket) );
- mpCommunicators->push_back( pCommunicator );
- pCommunicator->launch();
+ int nClient;
+ SAL_INFO( "sdremote.bluetooth", "performing accept" );
+ if ( ( nClient = accept( nSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 &&
+ errno != EAGAIN )
+ {
+ SAL_WARN( "sdremote.bluetooth", "accept failed with errno " << errno );
+ } else {
+ SAL_INFO( "sdremote.bluetooth", "connection accepted " << nClient );
+ Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( nClient ) );
+ mpCommunicators->push_back( pCommunicator );
+ pCommunicator->launch();
+ }
}
}
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.hxx b/sd/source/ui/remotecontrol/BluetoothServer.hxx
index 5b986fa..b922d60 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.hxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.hxx
@@ -16,6 +16,7 @@ namespace sd
{
class Communicator;
+ struct BluetoothServerImpl;
class BluetoothServer:
public osl::Thread
{
@@ -39,7 +40,9 @@ namespace sd
enum { UNKNOWN, DISCOVERABLE, NOT_DISCOVERABLE } meWasDiscoverable;
static BluetoothServer *spServer;
+ BluetoothServerImpl *mpImpl;
virtual void SAL_CALL run();
+
std::vector<Communicator*>* mpCommunicators;
};
}
commit 84f1c87936fa13ea937cd02ec79a3b29ed26c5d1
Author: Michael Meeks <michael.meeks at suse.com>
Date: Mon Feb 18 10:55:31 2013 +0000
sdremote: re-write SDP registration to use raw dbus-1 not dbus-glib.
Conflicts:
sd/source/ui/remotecontrol/BluetoothServer.cxx
Change-Id: I65ff5e603b6719df69b3c2aef7ff438ad54d23e2
(cherry picked from commit 5a90716b802d281c111e1f4f43f3fefded2c1f81)
Signed-off-by: Thorsten Behrens <tbehrens at suse.com>
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index d140c1e..2ccfc87 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -16,6 +16,7 @@
#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
#include <glib.h>
+ #include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <sys/unistd.h>
#include <sys/socket.h>
@@ -75,46 +76,163 @@
using namespace sd;
#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
-DBusGProxy* bluezGetDefaultAdapter( DBusGConnection* aConnection,
- const gchar* aInterfaceType = "org.bluez.Adapter" )
+
+struct DBusObject {
+ OString maBusName;
+ OString maPath;
+ OString maInterface;
+
+ DBusObject( const char *pBusName, const char *pPath, const char *pInterface )
+ : maBusName( pBusName ), maPath( pPath ), maInterface( pInterface )
+ { }
+
+ DBusMessage *getMethodCall( const char *pName )
+ {
+ return dbus_message_new_method_call( maBusName.getStr(), maPath.getStr(),
+ maInterface.getStr(), pName );
+ }
+};
+
+static DBusConnection *
+dbusConnectToNameOnBus()
{
- GError *aError = NULL;
+ DBusError aError;
+ DBusConnection *pConnection;
- DBusGProxy *aManager = NULL;
- aManager = dbus_g_proxy_new_for_name( aConnection, "org.bluez", "/",
- "org.bluez.Manager" );
+ dbus_error_init( &aError );
- if ( aManager == NULL )
+ pConnection = dbus_bus_get( DBUS_BUS_SYSTEM, &aError );
+ if( !pConnection || dbus_error_is_set( &aError ))
{
- SAL_WARN( "sdremote.bluetooth", "getting org.bluez.Manager failed" );
- dbus_g_connection_unref( aConnection );
+ SAL_WARN( "sdremote.bluetooth", "failed to get dbus system bus: " << aError.message );
+ dbus_error_free( &aError );
return NULL;
}
- gboolean aResult;
- DBusGObjectPath* aAdapterPath = NULL;
- aResult = dbus_g_proxy_call( aManager, "DefaultAdapter", &aError,
- G_TYPE_INVALID,
- DBUS_TYPE_G_OBJECT_PATH, &aAdapterPath,
- G_TYPE_INVALID);
+ return pConnection;
+}
- g_object_unref( G_OBJECT( aManager ));
- if ( !aResult || aError )
+static DBusObject *
+bluezGetDefaultAdapter( DBusConnection *pConnection,
+ const gchar* pInterfaceType = "org.bluez.Adapter" )
+{
+ DBusMessage *pMsg;
+ DBusMessageIter it;
+ DBusPendingCall *pPending;
+
+ pMsg = DBusObject( "org.bluez", "/", "org.bluez.Manager" ).getMethodCall( "DefaultAdapter" );
+ if( !pMsg || !dbus_connection_send_with_reply( pConnection, pMsg, &pPending,
+ -1 /* default timeout */ ) )
{
- SAL_WARN( "sdremote.bluetooth", "getting DefaultAdapter path failed" );
- if ( aError )
- g_error_free( aError );
+ SAL_WARN( "sdremote.bluetooth", "Memory allocation failed on message" );
+ dbus_message_unref( pMsg );
+ return NULL;
+ }
+ dbus_connection_flush( pConnection );
+ dbus_message_unref( pMsg );
+
+ dbus_pending_call_block( pPending ); // block for reply
+
+ pMsg = dbus_pending_call_steal_reply( pPending );
+ if( !pMsg || !dbus_message_iter_init( pMsg, &it ) )
+ {
+ SAL_WARN( "sdremote.bluetooth", "no valid reply / timeout" );
+ dbus_pending_call_unref( pPending );
return NULL;
}
+ dbus_pending_call_unref( pPending );
- DBusGProxy *aAdapter = NULL;
- aAdapter = dbus_g_proxy_new_for_name( aConnection, "org.bluez",
- aAdapterPath, aInterfaceType );
- g_free( aAdapterPath );
- SAL_INFO( "sdremote.bluetooth", "DefaultAdapter retrieved" );
- return aAdapter;
+ if( DBUS_TYPE_OBJECT_PATH != dbus_message_iter_get_arg_type( &it ) )
+ SAL_WARN( "sdremote.bluetooth", "invalid type of reply to DefaultAdapter: '"
+ << dbus_message_iter_get_arg_type( &it ) << "'" );
+ else
+ {
+ const char *pObjectPath = NULL;
+ dbus_message_iter_get_basic( &it, &pObjectPath );
+ SAL_INFO( "sdremote.bluetooth", "DefaultAdapter retrieved: '"
+ << pObjectPath << "' '" << pInterfaceType << "'" );
+ return new DBusObject( "org.bluez", pObjectPath, pInterfaceType );
+ }
+ dbus_message_unref( pMsg );
+
+ return NULL;
}
+
+static bool
+bluezRegisterServiceRecord( DBusConnection *pConnection, DBusObject *pAdapter,
+ const char *pServiceRecord )
+{
+ DBusMessage *pMsg;
+ DBusMessageIter it;
+ DBusPendingCall *pPending;
+
+ pMsg = pAdapter->getMethodCall( "AddRecord" );
+ dbus_message_iter_init_append( pMsg, &it );
+ dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pServiceRecord );
+
+ if(!dbus_connection_send_with_reply( pConnection, pMsg, &pPending,
+ -1 /* default timeout */ ) )
+ if( !dbus_connection_send( pConnection, pMsg, NULL ) )
+ {
+ SAL_WARN( "sdremote.bluetooth", "failed to send service record" );
+ return false;
+ }
+ dbus_connection_flush( pConnection );
+ dbus_message_unref( pMsg );
+
+ dbus_pending_call_block( pPending ); // block for reply
+
+ pMsg = dbus_pending_call_steal_reply( pPending );
+ if( !pMsg || !dbus_message_iter_init( pMsg, &it ) ||
+ dbus_message_iter_get_arg_type( &it ) != DBUS_TYPE_UINT32 )
+ {
+ SAL_WARN( "sdremote.bluetooth", "SDP registration failed" );
+ return false;
+ }
+
+ // We ignore the uint de-registration handle we get back:
+ // bluez will clean us up automatically on exit
+
+ dbus_pending_call_unref( pPending );
+
+ return true;
+}
+
+static int
+bluezCreateListeningSocket()
+{
+ int nSocket;
+
+ if( ( nSocket = socket( AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM ) ) < 0 )
+ {
+ SAL_WARN( "sdremote.bluetooth", "failed to open bluetooth socket with error " << nSocket );
+ return -1;
+ }
+
+ sockaddr_rc aAddr;
+ aAddr.rc_family = AF_BLUETOOTH;
+ // BDADDR_ANY is broken, so use memset to set to 0.
+ memset( &aAddr.rc_bdaddr, 0, sizeof( aAddr.rc_bdaddr ) );
+ aAddr.rc_channel = 5;
+
+ int a;
+ if ( ( a = bind( nSocket, (sockaddr*) &aAddr, sizeof(aAddr) ) ) < 0 ) {
+ SAL_WARN( "sdremote.bluetooth", "bind failed with error" << a );
+ close( nSocket );
+ return -1;
+ }
+
+ if ( ( a = listen( nSocket, 1 ) ) < 0 )
+ {
+ SAL_WARN( "sdremote.bluetooth", "listen failed with error" << a );
+ close( nSocket );
+ return -1;
+ }
+
+ return nSocket;
+}
+
#endif // defined(LINUX) && defined(ENABLE_DBUS)
#if defined(MACOSX)
@@ -299,7 +417,7 @@ void BluetoothServer::restoreDiscoverable()
bool BluetoothServer::isDiscoverable()
{
-#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
+#if 0 // (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
SAL_INFO( "sdremote.bluetooth", "BluetoothServer::isDiscoverable called" );
g_type_init();
gboolean aResult;
@@ -315,7 +433,7 @@ bool BluetoothServer::isDiscoverable()
return false;
}
- DBusGProxy* aAdapter = bluezGetDefaultAdapter( aConnection );
+ DBusGProxy* aAdapter = bluezGetDefaultAdapter( pConnection );
if ( aAdapter == NULL )
{
dbus_g_connection_unref( aConnection );
@@ -352,8 +470,8 @@ bool BluetoothServer::isDiscoverable()
void BluetoothServer::setDiscoverable( bool bDiscoverable )
{
-#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
- SAL_INFO( "sdremote.bluetooth", "BluetoothServer::isDiscoverable called" );
+#if 0 // (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
+ SAL_INFO( "sdremote.bluetooth", "BluetoothServer::setDiscoverable called" );
g_type_init();
gboolean aResult;
@@ -368,7 +486,7 @@ void BluetoothServer::setDiscoverable( bool bDiscoverable )
return;
}
- DBusGProxy* aAdapter = bluezGetDefaultAdapter( aConnection );
+ DBusGProxy* aAdapter = bluezGetDefaultAdapter( pConnection );
if ( aAdapter == NULL )
{
dbus_g_connection_unref( aConnection );
@@ -455,72 +573,31 @@ void SAL_CALL BluetoothServer::run()
#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
g_type_init();
- GError *aError = NULL;
-
- DBusGConnection *aConnection = NULL;
- aConnection = dbus_g_bus_get( DBUS_BUS_SYSTEM, &aError );
-
- if ( aError != NULL ) {
- SAL_WARN( "sdremote.bluetooth", "failed to get dbus system bus" );
- g_error_free (aError);
- return;
- }
-
- DBusGProxy* aAdapter = bluezGetDefaultAdapter( aConnection, "org.bluez.Service" );
- if ( aAdapter == NULL )
- {
- SAL_WARN( "sdremote.bluetooth", "failed to retrieve default adapter" );
- dbus_g_connection_unref( aConnection );
+ DBusConnection *pConnection = dbusConnectToNameOnBus();
+ if( !pConnection )
return;
- }
- // Add the record -- the handle can be used to release it again, but we
- // don't bother as the record is automatically released when LO exits.
- guint aHandle;
- gboolean aResult = dbus_g_proxy_call( aAdapter, "AddRecord", &aError,
- G_TYPE_STRING, bluetooth_service_record,
- G_TYPE_INVALID,
- G_TYPE_UINT, &aHandle,
- G_TYPE_INVALID);
-
- g_object_unref( G_OBJECT( aAdapter ));
- dbus_g_connection_unref( aConnection );
- if ( !aResult)
+ DBusObject *pService = bluezGetDefaultAdapter( pConnection, "org.bluez.Service" );
+ if( !pService )
{
- SAL_WARN( "sdremote.bluetooth", "SDP registration failed" );
+ dbus_connection_unref( pConnection );
return;
}
- // ---------------- Socket code
- int aSocket;
- if ( (aSocket = socket( AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM )) < 0 )
- {
- SAL_WARN( "sdremote.bluetooth", "failed to open bluetooth socket with error " << aSocket );
+ if( !bluezRegisterServiceRecord( pConnection, pService, bluetooth_service_record ) )
return;
- }
- sockaddr_rc aAddr;
- aAddr.rc_family = AF_BLUETOOTH;
- // BDADDR_ANY is broken, so use memset to set to 0.
- memset( &aAddr.rc_bdaddr, 0, sizeof( aAddr.rc_bdaddr ) );
- aAddr.rc_channel = 5;
-
- int a;
- if ( ( a = bind( aSocket, (sockaddr*) &aAddr, sizeof(aAddr) ) ) < 0 ) {
- SAL_WARN( "sdremote.bluetooth", "bind failed with error" << a );
- close( aSocket );
+ int aSocket = bluezCreateListeningSocket();
+ if( aSocket < 0 )
return;
- }
- if ( ( a = listen( aSocket, 1 ) ) < 0 )
- {
- SAL_WARN( "sdremote.bluetooth", "listen failed with error" << a );
- close( aSocket );
- return;
- }
+ // ---------------- Socket code ----------------
sockaddr_rc aRemoteAddr;
socklen_t aRemoteAddrLen = sizeof(aRemoteAddr);
+
+ // FIXME: use a glib main-loop [!] ...
+ // FIXME: fixme ! ...
while ( true )
{
int bSocket;
commit 943fd58a4fce2a1009060f2f8907e806983721e7
Author: Michael Meeks <michael.meeks at suse.com>
Date: Mon Feb 18 09:24:23 2013 +0000
improve bluetooth discoverability toggling API.
Change-Id: I289d43fcb173b64b01183a41f780bc74d2ba0abe
(cherry picked from commit 21979643e47e503a20113b1e8e98814717c71ac5)
Signed-off-by: Thorsten Behrens <tbehrens at suse.com>
diff --git a/sd/source/ui/dlg/RemoteDialog.cxx b/sd/source/ui/dlg/RemoteDialog.cxx
index fd60895..f9cff1b 100644
--- a/sd/source/ui/dlg/RemoteDialog.cxx
+++ b/sd/source/ui/dlg/RemoteDialog.cxx
@@ -22,22 +22,12 @@ RemoteDialog::RemoteDialog( Window *pWindow ) :
ModalDialog( pWindow, SdResId( DLG_PAIR_REMOTE ) ),
mButtonConnect( this, SdResId( BTN_CONNECT ) ),
mButtonCancel( this, SdResId( BTN_CANCEL ) ),
- mClientBox( this, NULL, SdResId( LB_SERVERS ) ),
- mPreviouslyDiscoverable()
+ mClientBox( this, NULL, SdResId( LB_SERVERS ) )
{
- (void) mPreviouslyDiscoverable; // avoid warnings about unused member
-
FreeResource();
#ifdef ENABLE_SDREMOTE
-
-#ifdef ENABLE_SDREMOTE_BLUETOOTH
- mPreviouslyDiscoverable = RemoteServer::isBluetoothDiscoverable();
- if ( !mPreviouslyDiscoverable )
- RemoteServer::setBluetoothDiscoverable( true );
-#else
- RemoteServer::setBluetoothDiscoverable( false );
-#endif
+ RemoteServer::ensureDiscoverable();
vector<ClientInfo*> aClients( RemoteServer::getClients() );
@@ -80,12 +70,7 @@ IMPL_LINK_NOARG(RemoteDialog, HandleConnectButton)
IMPL_LINK_NOARG( RemoteDialog, CloseHdl )
{
-#if defined(ENABLE_SDREMOTE) && defined(ENABLE_SDREMOTE_BLUETOOTH)
- if ( !mPreviouslyDiscoverable )
- {
- RemoteServer::setBluetoothDiscoverable( false );
- }
-#endif
+ RemoteServer::restoreDiscoverable();
Close();
return 0;
}
diff --git a/sd/source/ui/dlg/RemoteDialog.hxx b/sd/source/ui/dlg/RemoteDialog.hxx
index bc4831b..882b9c2 100644
--- a/sd/source/ui/dlg/RemoteDialog.hxx
+++ b/sd/source/ui/dlg/RemoteDialog.hxx
@@ -27,8 +27,6 @@ private:
OKButton mButtonConnect;
CancelButton mButtonCancel;
ClientBox mClientBox;
- // Whether discoverability was enabled befor the dialog started.
- bool mPreviouslyDiscoverable;
DECL_DLLPRIVATE_LINK( HandleConnectButton, void * );
DECL_LINK( CloseHdl, void * );
diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx
index 740465c..f209561 100644
--- a/sd/source/ui/inc/RemoteServer.hxx
+++ b/sd/source/ui/inc/RemoteServer.hxx
@@ -66,8 +66,10 @@ namespace sd
SD_DLLPUBLIC static sal_Bool connectClient( ClientInfo *pClient,
rtl::OUString aPin );
- SD_DLLPUBLIC static bool isBluetoothDiscoverable();
- SD_DLLPUBLIC static void setBluetoothDiscoverable( bool aDiscoverable );
+ /// ensure that discoverability (eg. for Bluetooth) is enabled
+ SD_DLLPUBLIC static void ensureDiscoverable();
+ /// restore the state of discoverability from before ensureDiscoverable
+ SD_DLLPUBLIC static void restoreDiscoverable();
// For the communicator
static void removeCommunicator( Communicator* pCommunicator );
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index 4d94866..d140c1e 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -267,7 +267,8 @@ void incomingCallback( void *userRefCon,
BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators )
- : mpCommunicators( pCommunicators )
+ : meWasDiscoverable( UNKNOWN ),
+ mpCommunicators( pCommunicators )
{
}
@@ -275,6 +276,27 @@ BluetoothServer::~BluetoothServer()
{
}
+
+void BluetoothServer::ensureDiscoverable()
+{
+ if( !spServer || spServer->meWasDiscoverable != UNKNOWN )
+ return;
+
+ bool bDiscoverable = spServer->isDiscoverable();
+ spServer->meWasDiscoverable = bDiscoverable ? DISCOVERABLE : NOT_DISCOVERABLE;
+ spServer->setDiscoverable( true );
+}
+
+void BluetoothServer::restoreDiscoverable()
+{
+ if(!spServer)
+ return;
+
+ if ( spServer->meWasDiscoverable == NOT_DISCOVERABLE )
+ spServer->setDiscoverable( false );
+ spServer->meWasDiscoverable = UNKNOWN;
+}
+
bool BluetoothServer::isDiscoverable()
{
#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
@@ -328,7 +350,7 @@ bool BluetoothServer::isDiscoverable()
#endif
}
-void BluetoothServer::setDiscoverable( bool aDiscoverable )
+void BluetoothServer::setDiscoverable( bool bDiscoverable )
{
#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
SAL_INFO( "sdremote.bluetooth", "BluetoothServer::isDiscoverable called" );
@@ -398,12 +420,12 @@ void BluetoothServer::setDiscoverable( bool aDiscoverable )
return;
}
- GValue aDiscoverableGValue = G_VALUE_INIT;
- g_value_init( &aDiscoverableGValue, G_TYPE_BOOLEAN );
- g_value_set_boolean( &aDiscoverableGValue, aDiscoverable );
+ GValue bDiscoverableGValue = G_VALUE_INIT;
+ g_value_init( &bDiscoverableGValue, G_TYPE_BOOLEAN );
+ g_value_set_boolean( &bDiscoverableGValue, bDiscoverable );
aResult = dbus_g_proxy_call( aAdapter, "SetProperty", &aError,
G_TYPE_STRING, "Discoverable",
- G_TYPE_VALUE, &aDiscoverableGValue, G_TYPE_INVALID, G_TYPE_INVALID);
+ G_TYPE_VALUE, &bDiscoverableGValue, G_TYPE_INVALID, G_TYPE_INVALID);
if ( !aResult || aError )
{
SAL_WARN( "sdremote.bluetooth", "SetProperty(Discoverable) failed" );
@@ -418,7 +440,7 @@ void BluetoothServer::setDiscoverable( bool aDiscoverable )
g_object_unref( G_OBJECT( aAdapter ));
dbus_g_connection_unref( aConnection );
#else // defined(LINUX) && defined(ENABLE_DBUS)
- (void) aDiscoverable; // avoid warnings
+ (void) bDiscoverable; // avoid warnings
#endif
}
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.hxx b/sd/source/ui/remotecontrol/BluetoothServer.hxx
index d8c9879..5b986fa 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.hxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.hxx
@@ -22,18 +22,25 @@ namespace sd
public:
static void setup( std::vector<Communicator*>* pCommunicators );
- static bool isDiscoverable();
- static void setDiscoverable( bool aDiscoverable );
+ /// ensure that Bluetooth discoverability is on
+ static void ensureDiscoverable();
+ /// restore the state of discoverability from before ensureDiscoverable
+ static void restoreDiscoverable();
+
void addCommunicator( Communicator* pCommunicator );
private:
BluetoothServer( std::vector<Communicator*>* pCommunicators );
~BluetoothServer();
+
+ bool isDiscoverable();
+ void setDiscoverable( bool bDiscoverable );
+
+ enum { UNKNOWN, DISCOVERABLE, NOT_DISCOVERABLE } meWasDiscoverable;
static BluetoothServer *spServer;
virtual void SAL_CALL run();
std::vector<Communicator*>* mpCommunicators;
-
};
}
diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx
index 9989ed0..561dac1 100644
--- a/sd/source/ui/remotecontrol/Server.cxx
+++ b/sd/source/ui/remotecontrol/Server.cxx
@@ -318,21 +318,19 @@ void SdDLL::RegisterRemotes()
sd::DiscoveryService::setup();
}
-bool RemoteServer::isBluetoothDiscoverable()
+void RemoteServer::ensureDiscoverable()
{
+ // FIXME: we could also enable listening on our WiFi
+ // socket here to significantly reduce the attack surface.
#ifdef ENABLE_SDREMOTE_BLUETOOTH
- return BluetoothServer::isDiscoverable();
-#else
- return false;
+ BluetoothServer::ensureDiscoverable();
#endif
}
-void RemoteServer::setBluetoothDiscoverable( bool aDiscoverable )
+void RemoteServer::restoreDiscoverable()
{
#ifdef ENABLE_SDREMOTE_BLUETOOTH
- BluetoothServer::setDiscoverable( aDiscoverable );
-#else
- (void) aDiscoverable;
+ BluetoothServer::restoreDiscoverable();
#endif
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list