Skip to content

Commit

Permalink
Updated to use bluez5
Browse files Browse the repository at this point in the history
 - normalized slots
 - moved update note from TransportTracker.h to TransportTracker.cpp
 - reworked onInterfacesAdded and onInterfacesRemoved using better logic and
   added addAdapterInterface() with a timer as commented by Slava Monich and Damien Caliste
 - follow up on \!39 discussions
 - removed InterfacesList from TransportTracker as it has no advantage over QStringList
 - remove btOn in TransportTracker and use string constant from TransportTracker in TransportTrackerTest
 - add HAVE_BLUEZ_5 and enable HAVE_BLUEZ_5 by default, use #ifdef instead of #if consistently
 - introducing BtCommon.h to hold BT related string
 - Update after commit fd1beef

Signed-off-by: Emanoil Kotsev <deloptes@gmail.com>
  • Loading branch information
deloptes authored and pvuorela committed May 7, 2021
1 parent 04ace1f commit 5365ff9
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 224 deletions.
41 changes: 41 additions & 0 deletions libbuteosyncfw/common/BtCommon.h
@@ -0,0 +1,41 @@
/*
* This file is part of buteo-syncfw package
*
* Copyright (C) 2020 as part of an update to use bluez5 by deloptes@gmail.com
*
*/

#ifndef BTCOMMON_H_
#define BTCOMMON_H_

#include <QtDBus>
#include <QMap>

#if HAVE_BLUEZ_5
namespace Buteo {

namespace BT {
static const QString BLUEZ_DEST = "org.bluez";
static const QString BLUEZ_MANAGER_INTERFACE = "org.freedesktop.DBus.ObjectManager";
static const QString BLUEZ_ADAPTER_INTERFACE = "org.bluez.Adapter1";
static const QString BLUEZ_DEVICE_INTERFACE = "org.bluez.Device1";
static const QString BLUEZ_PROPERTIES_INTERFACE = "org.freedesktop.DBus.Properties";
static const QString GETMANAGEDOBJECTS = "GetManagedObjects";
static const QString GETPROPERTIES = "GetAll";
static const QString PROPERTIESCHANGED = "PropertiesChanged";
static const QString INTERFACESADDED = "InterfacesAdded";
static const QString INTERFACESREMOVED = "InterfacesRemoved";

} // namespace BT

typedef QMap<QString,QVariantMap> InterfacesMap;
typedef QMap<QDBusObjectPath,InterfacesMap> ObjectsMap;

} // namespace Buteo

Q_DECLARE_METATYPE(Buteo::InterfacesMap)
Q_DECLARE_METATYPE(Buteo::ObjectsMap)

#endif /* HAVE_BLUEZ_5 */

#endif /* BTCOMMON_H_ */
200 changes: 145 additions & 55 deletions libbuteosyncfw/common/TransportTracker.cpp
Expand Up @@ -2,6 +2,7 @@
* This file is part of buteo-syncfw package
*
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
* 2019 Updated to use bluez5 by deloptes@gmail.com
*
* Contact: Sateesh Kavuri <sateesh.kavuri@nokia.com>
*
Expand Down Expand Up @@ -61,17 +62,44 @@ TransportTracker::TransportTracker(QObject *aParent) :
}
#endif

#if HAVE_BLUEZ_4
#ifdef HAVE_BLUEZ_5
// BT
// Set the bluetooth state
iTransportStates[Sync::CONNECTIVITY_BT] = btConnectivityStatus();
if (!iSystemBus.connect("org.bluez",
"",
"org.bluez.Adapter",
"PropertyChanged",
this,
SLOT(onBtStateChanged(QString, QDBusVariant)))) {
LOG_WARNING("Unable to connect to system bus for org.bluez.Adapter");
qDBusRegisterMetaType <InterfacesMap> ();
qDBusRegisterMetaType <ObjectsMap> ();

// listen for added interfaces
if (!iSystemBus.connect(BT::BLUEZ_DEST,
QString("/"),
BT::BLUEZ_MANAGER_INTERFACE,
BT::INTERFACESADDED,
this,
SLOT(onBtInterfacesAdded(QDBusObjectPath, InterfacesMap)))) {
LOG_WARNING("Failed to connect InterfacesAdded signal");
}

if (!iSystemBus.connect(BT::BLUEZ_DEST,
QString("/"),
BT::BLUEZ_MANAGER_INTERFACE,
BT::INTERFACESREMOVED,
this,
SLOT(onBtInterfacesRemoved(QDBusObjectPath, QStringList)))) {
LOG_WARNING("Failed to connect InterfacesRemoved signal");
}

// get the initial state
if (btConnectivityStatus()) {
if (!iSystemBus.connect(BT::BLUEZ_DEST,
iDefaultBtAdapter,
BT::BLUEZ_PROPERTIES_INTERFACE,
BT::PROPERTIESCHANGED,
this,
SLOT(onBtStateChanged(QString, QVariantMap, QStringList)))) {
LOG_WARNING("Failed to connect PropertiesChanged signal");
}
// Set the bluetooth state to on
iTransportStates[Sync::CONNECTIVITY_BT] = true;
} else {
LOG_WARNING("The BT adapter is powered off or missing");
}
#endif

Expand Down Expand Up @@ -107,17 +135,92 @@ void TransportTracker::onUsbStateChanged(bool aConnected)
updateState(Sync::CONNECTIVITY_USB, aConnected);
}

void TransportTracker::onBtStateChanged(QString aKey, QDBusVariant aValue)
#ifdef HAVE_BLUEZ_5
void TransportTracker::onBtStateChanged(QString interface, QVariantMap changed, QStringList invalidated)
{
FUNCTION_CALL_TRACE;

if (aKey == "Powered") {
bool btPowered = aValue.variant().toBool();
LOG_DEBUG("BT power state " << btPowered);
updateState(Sync::CONNECTIVITY_BT, btPowered);
Q_UNUSED(invalidated);

if (interface == BT::BLUEZ_ADAPTER_INTERFACE) {
for (QVariantMap::iterator i = changed.begin(); i != changed.end(); ++i) {
if (i.key() == "Powered") {
bool btOn = i.value().toBool();
LOG_INFO("BT power state " << btOn);
updateState(Sync::CONNECTIVITY_BT, btOn);
}
}
}
}

void TransportTracker::onBtInterfacesAdded(const QDBusObjectPath &path, const InterfacesMap interfaces)
{
FUNCTION_CALL_TRACE;

for (InterfacesMap::const_iterator i = interfaces.cbegin(); i != interfaces.cend(); ++i) {
if (i.key() == BT::BLUEZ_ADAPTER_INTERFACE) {

// do not process other interfaces after default one was selected
if (!iDefaultBtAdapter.isEmpty())
break;

iDefaultBtAdapter = path.path();
LOG_DEBUG(BT::BLUEZ_ADAPTER_INTERFACE << "interface" << iDefaultBtAdapter);

QDBusInterface adapter(BT::BLUEZ_DEST,
iDefaultBtAdapter,
BT::BLUEZ_ADAPTER_INTERFACE,
iSystemBus);

if (!iSystemBus.connect(BT::BLUEZ_DEST,
iDefaultBtAdapter,
BT::BLUEZ_PROPERTIES_INTERFACE,
BT::PROPERTIESCHANGED,
this,
SLOT(onBtStateChanged(QString, QVariantMap, QStringList)))) {
LOG_WARNING("Failed to connect PropertiesChanged signal");

}

if (adapter.isValid()) {
updateState(Sync::CONNECTIVITY_BT, adapter.property("Powered").toBool());
LOG_INFO("BT state changed" << adapter.property("Powered").toBool());
}
}
}
}

void TransportTracker::onBtInterfacesRemoved(const QDBusObjectPath &path, const QStringList interfaces)
{
FUNCTION_CALL_TRACE;

for (QStringList::const_iterator i = interfaces.cbegin(); i != interfaces.cend(); ++i) {
if (*i == BT::BLUEZ_ADAPTER_INTERFACE) {

if (path.path() != iDefaultBtAdapter)
continue;

LOG_DEBUG("DBus adapter path: " << iDefaultBtAdapter );

if (!iSystemBus.disconnect(BT::BLUEZ_DEST,
iDefaultBtAdapter,
BT::BLUEZ_PROPERTIES_INTERFACE,
BT::PROPERTIESCHANGED,
this,
SLOT(onBtStateChanged(QString,QVariantMap,QStringList)))) {
LOG_WARNING("Failed to disconnect PropertiesChanged signal");
} else {
LOG_DEBUG("'org.bluez.Adapter1' interface removed from " << path.path());
}

iDefaultBtAdapter = QString();

break;
}
}
}
#endif

void TransportTracker::onInternetStateChanged(bool aConnected, Sync::InternetConnectionType aType)
{
FUNCTION_CALL_TRACE;
Expand All @@ -127,8 +230,7 @@ void TransportTracker::onInternetStateChanged(bool aConnected, Sync::InternetCon
emit networkStateChanged(aConnected, aType);
}

void TransportTracker::updateState(Sync::ConnectivityType aType,
bool aState)
void TransportTracker::updateState(Sync::ConnectivityType aType, bool aState)
{
FUNCTION_CALL_TRACE;

Expand All @@ -146,55 +248,43 @@ void TransportTracker::updateState(Sync::ConnectivityType aType,
}
}

#ifdef HAVE_BLUEZ_5
bool TransportTracker::btConnectivityStatus()
{
#if HAVE_BLUEZ_4
FUNCTION_CALL_TRACE;

bool btOn = false;
QDBusMessage methodCallMsg = QDBusMessage::createMethodCall("org.bluez",
"/",
"org.bluez.Manager",
"DefaultAdapter");
QDBusInterface manager(BT::BLUEZ_DEST,
QString("/"),
BT::BLUEZ_MANAGER_INTERFACE,
iSystemBus);

QDBusMessage reply = iSystemBus.call(methodCallMsg);
if (reply.type() == QDBusMessage::ErrorMessage) {
LOG_WARNING("This device does not have a BT adapter");
return btOn;
QDBusReply<ObjectsMap> reply = manager.call(BT::GETMANAGEDOBJECTS);
if (!reply.isValid()) {
LOG_WARNING( "Failed to connect BT ObjectManager: " << reply.error().message() );
return false;
}

QList<QVariant> adapterList = reply.arguments();
// We will take the first adapter in the list
QString adapterPath = qdbus_cast<QDBusObjectPath>(adapterList.at(0)).path();

if (!adapterPath.isEmpty() || !adapterPath.isNull()) {
// Retrive the properties of the adapter and check for "Powered" key
methodCallMsg = QDBusMessage::createMethodCall("org.bluez",
adapterPath,
"org.bluez.Adapter",
"GetProperties");
reply = iSystemBus.call(methodCallMsg);
if (reply.type() == QDBusMessage::ErrorMessage) {
LOG_WARNING("Error in retrieving bluetooth properties");
return btOn;
}
ObjectsMap objects = reply.value();
for (ObjectsMap::iterator i = objects.begin(); i != objects.end(); ++i) {

QDBusArgument arg = reply.arguments().at(0).value<QDBusArgument>();
if (arg.currentType() == QDBusArgument::MapType) {
// Scan through the dict returned and check for "Powered" entry
QMap<QString, QVariant> dict = qdbus_cast<QMap<QString, QVariant> >(arg);
QMap<QString, QVariant>::iterator iter;
for (iter = dict.begin(); iter != dict.end(); ++iter) {
if (iter.key() == "Powered") {
btOn = iter.value().toBool();
LOG_DEBUG ("Bluetooth powered on? " << btOn);
break;
InterfacesMap ifaces = i.value();
for (InterfacesMap::const_iterator j = ifaces.cbegin(); j != ifaces.cend(); ++j) {

if (j.key() == BT::BLUEZ_ADAPTER_INTERFACE) {
if (iDefaultBtAdapter.isEmpty() || iDefaultBtAdapter != i.key().path()) {
iDefaultBtAdapter = i.key().path();
LOG_DEBUG ("Using adapter path: " << iDefaultBtAdapter);
}
QDBusInterface adapter(BT::BLUEZ_DEST,
iDefaultBtAdapter,
BT::BLUEZ_ADAPTER_INTERFACE,
iSystemBus);

return adapter.property("Powered").toBool(); // use first adapter
}
}
}
return btOn;
#else

return false;
#endif
}
#endif
18 changes: 16 additions & 2 deletions libbuteosyncfw/common/TransportTracker.h
Expand Up @@ -2,6 +2,7 @@
* This file is part of buteo-syncfw package
*
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
* 2019 Updated to use bluez5 by deloptes@gmail.com
*
* Contact: Sateesh Kavuri <sateesh.kavuri@nokia.com>
*
Expand Down Expand Up @@ -31,6 +32,10 @@
#include <QDBusVariant>
#include <QDBusConnection>

#ifdef HAVE_BLUEZ_5
#include <BtCommon.h>
#endif

namespace Buteo {

class USBModedProxy;
Expand Down Expand Up @@ -91,7 +96,13 @@ private slots:

void onUsbStateChanged(bool aConnected);

void onBtStateChanged(QString aKey, QDBusVariant aValue);
#ifdef HAVE_BLUEZ_5
void onBtStateChanged(QString interface, QVariantMap changed, QStringList invalidated);

void onBtInterfacesAdded(const QDBusObjectPath &path, const InterfacesMap interfaces);

void onBtInterfacesRemoved(const QDBusObjectPath &path, const QStringList interfaces);
#endif

void onInternetStateChanged(bool aConnected, Sync::InternetConnectionType aType);

Expand All @@ -103,6 +114,7 @@ private slots:

NetworkManager *iInternet;
QDBusConnection iSystemBus;
QString iDefaultBtAdapter;

mutable QMutex iMutex;

Expand All @@ -118,10 +130,12 @@ private slots:
friend class SynchronizerTest;
#endif

#ifdef HAVE_BLUEZ_5
bool btConnectivityStatus();
#endif

};

}
} // namespace Buteo

#endif /* TRANSPORTTRACKER_H_ */

0 comments on commit 5365ff9

Please sign in to comment.