summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2013-02-18 10:55:31 +0000
committerThorsten Behrens <tbehrens@suse.com>2013-02-19 13:00:14 +0100
commit84f1c87936fa13ea937cd02ec79a3b29ed26c5d1 (patch)
tree6f00756df3399babe609a465827b7d8df58a9eba
parent943fd58a4fce2a1009060f2f8907e806983721e7 (diff)
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@suse.com>
-rw-r--r--sd/source/ui/remotecontrol/BluetoothServer.cxx245
1 files changed, 161 insertions, 84 deletions
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index d140c1e523d1..2ccfc8738195 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;