sd/source/ui/remotecontrol/BluetoothServer.cxx | 673 +---
sd/source/ui/remotecontrol/BufferedStreamSocket.cxx |2
sd/source/ui/remotecontrol/Communicator.cxx |2
3 files changed, 605 insertions(+), 72 deletions(-)
New commits:
commit d337b9a3c5ab41e4dc956e7fe1b36704426dc123
Author: Andrzej Hunt
Date: Thu Apr 10 21:58:29 2014 +0100
fdo#74697 Add Bluez 5 support for impress remote.
This time we:
- Don't break SAL_WARN with an fprintf like syntax.
- Replace DBUS_TYPE_UNIX_FD with it's definition 'h' as we might
be building on dbus-glib versions that do not support it (however
presumably anyone running bluez 5 will have a dbus version that is
new enough to support this, i.e. purely a build-time issue).
- Remove various C++11'isms.
Reviewed-on: https://gerrit.libreoffice.org/8924
Tested-by: Andrzej Hunt
Reviewed-by: Andrzej Hunt
(cherry picked from commit b15666fd7582729c75bd0dd1bd0cb5d7c5a77f0c)
Conflicts:
sd/source/ui/remotecontrol/BluetoothServer.cxx
Change-Id: I736cad2122cd3789a5c7fb62c39e409d41fc1e32
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx
b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index 836c73e..db0ce7f 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -12,6 +12,8 @@
#include
#include
+#include
+
#include
#ifdef LINUX_BLUETOOTH
@@ -89,25 +91,40 @@ struct DBusObject {
}
};
+static DBusObject* getBluez5Adapter(DBusConnection *pConnection);
+
struct sd::BluetoothServer::Impl {
// the glib mainloop running in the thread
GMainContext *mpContext;
DBusConnection *mpConnection;
DBusObject *mpService;
volatile bool mbExitMainloop;
+enum BluezVersion { BLUEZ4, BLUEZ5, UNKNOWN };
+BluezVersion maBluezVersion;
Impl()
: mpContext( g_main_context_new() )
, mpConnection( NULL )
, mpService( NULL )
, mbExitMainloop( false )
+, maBluezVersion( UNKNOWN )
{ }
DBusObject *getAdapter()
{
-if( !mpService )
+if (mpService)
+{
+DBusObject* pAdapter = mpService->cloneForInterface(
"org.bluez.Adapter" );
+return pAdapter;
+}
+else if (spServer->mpImpl->maBluezVersion == BLUEZ5)
+{
+return getBluez5Adapter(mpConnection);
+}
+else
+{
return NULL;
-return mpService->cloneForInterface( "org.bluez.Adapter" );
+}
}
};
@@ -155,37 +172,181 @@ sendUnrefAndWaitForReply( DBusConnection *pConnection,
DBusMessage *pMsg )
return pMsg;
}
+static bool
+isBluez5Available(DBusConnection *pConnection)
+{
+DBusMessage *pMsg;
+
+// Simplest wasy to check whether we have Bluez 5+ is to check
+// that we can obtain adapters using the new interfaces.
+// The first two error checks however don't tell us anything as they should
+// succeed as long as dbus is working correctly.
+pMsg = DBusObject( "org.bluez", "/", "org.freedesktop.DBus.ObjectManager"
).getMethodCall( "GetManagedObjects" );
+if (!pMsg)
+{
+SAL_INFO("sdremote.bluetooth", "No GetManagedObjects call created");
+return false;
+}
+
+pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+if (!pMsg)
+{
+SAL_INFO("sdremote.bluetooth", "No reply received");
+return false;
+}
+
+// If dbus is working correctly and we aren't on bluez 5 this is where we
+// should actually get the error.
+if (dbus_message_get_error_name( pMsg ))
+{
+SAL_INFO( "sdremote.bluetooth", "GetManagedObjects call failed with \""
+<< dbus_message_get_error_name( pMsg )
+<< "\" -- we don't seem to have Bluez 5 available");
+return false;
+}
+SAL_INFO("sdremote.bluetooth", "GetManagedObjects call seems to have
succeeded -- we must be on Bluez 5");
+dbus_message_unref(pMsg);
+return true;
+}
+
+
+static DBusObject*
+getBluez5Adapter(DBusConnection *pConnection)
+{
+DBusMessage *pMsg;
+// This returns a list of objects where we need to find the first
+// org.bluez.Adapter1 .
+pMsg = DBusObject( "org.bluez", "/", "org.freedesktop.DBus.ObjectManager"
).getMethodCall( "GetManagedObjects" );
+if (!pMsg)
+return NULL;
+
+const gchar* pInterfaceType = "org.bluez.Adapter1";
+
+pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+
+DBusMessageIter aObjectIterator;
+if (pMsg && dbus_message_iter_init(pMsg, &aObjectIterator))
+{
+if (DBUS_TYPE_ARRAY ==
dbus_message_iter_get_arg_type(&aObjectIterator))
+{
+DBusMessageIter aObject;
+dbus_message_iter_recurse(&aObjectIterator, &aObject);
+do
+{
+if (DBUS_TYPE_DICT_ENTRY ==
dbus_message_it