mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-01-31 15:19:11 +00:00
[Linux] Improve connection stability (#98)
This commit is contained in:
@@ -2,10 +2,16 @@
|
||||
#include "logger.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDBusObjectPath>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
BluetoothMonitor::BluetoothMonitor(QObject *parent)
|
||||
BluetoothMonitor::BluetoothMonitor(QObject *parent)
|
||||
: QObject(parent), m_dbus(QDBusConnection::systemBus())
|
||||
{
|
||||
// Register meta-types for D-Bus interaction
|
||||
qDBusRegisterMetaType<QDBusObjectPath>();
|
||||
qDBusRegisterMetaType<ManagedObjectList>();
|
||||
|
||||
if (!m_dbus.isConnected())
|
||||
{
|
||||
LOG_WARN("Failed to connect to system D-Bus");
|
||||
@@ -13,6 +19,7 @@ BluetoothMonitor::BluetoothMonitor(QObject *parent)
|
||||
}
|
||||
|
||||
registerDBusService();
|
||||
checkAlreadyConnectedDevices(); // Check for already connected devices on startup
|
||||
}
|
||||
|
||||
BluetoothMonitor::~BluetoothMonitor()
|
||||
@@ -23,18 +30,6 @@ BluetoothMonitor::~BluetoothMonitor()
|
||||
void BluetoothMonitor::registerDBusService()
|
||||
{
|
||||
// Match signals for PropertiesChanged on any BlueZ Device interface
|
||||
QString matchRule = QStringLiteral("type='signal',"
|
||||
"interface='org.freedesktop.DBus.Properties',"
|
||||
"member='PropertiesChanged',"
|
||||
"path_namespace='/org/bluez'");
|
||||
|
||||
m_dbus.connect("org.freedesktop.DBus",
|
||||
"/org/freedesktop/DBus",
|
||||
"org.freedesktop.DBus",
|
||||
"AddMatch",
|
||||
this,
|
||||
SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
|
||||
|
||||
if (!m_dbus.connect("", "", "org.freedesktop.DBus.Properties", "PropertiesChanged",
|
||||
this, SLOT(onPropertiesChanged(QString, QVariantMap, QStringList))))
|
||||
{
|
||||
@@ -42,6 +37,86 @@ void BluetoothMonitor::registerDBusService()
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothMonitor::isAirPodsDevice(const QString &devicePath)
|
||||
{
|
||||
QDBusInterface deviceInterface("org.bluez", devicePath, "org.freedesktop.DBus.Properties", m_dbus);
|
||||
|
||||
// Get UUIDs to check if it's an AirPods device
|
||||
QDBusReply<QVariant> uuidsReply = deviceInterface.call("Get", "org.bluez.Device1", "UUIDs");
|
||||
if (!uuidsReply.isValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList uuids = uuidsReply.value().toStringList();
|
||||
return uuids.contains("74ec2172-0bad-4d01-8f77-997b2be0722a");
|
||||
}
|
||||
|
||||
QString BluetoothMonitor::getDeviceName(const QString &devicePath)
|
||||
{
|
||||
QDBusInterface deviceInterface("org.bluez", devicePath, "org.freedesktop.DBus.Properties", m_dbus);
|
||||
QDBusReply<QVariant> nameReply = deviceInterface.call("Get", "org.bluez.Device1", "Name");
|
||||
if (nameReply.isValid())
|
||||
{
|
||||
return nameReply.value().toString();
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
bool BluetoothMonitor::checkAlreadyConnectedDevices()
|
||||
{
|
||||
QDBusInterface objectManager("org.bluez", "/", "org.freedesktop.DBus.ObjectManager", m_dbus);
|
||||
QDBusMessage reply = objectManager.call("GetManagedObjects");
|
||||
|
||||
if (reply.type() == QDBusMessage::ErrorMessage)
|
||||
{
|
||||
LOG_WARN("Failed to get managed objects: " << reply.errorMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant firstArg = reply.arguments().constFirst();
|
||||
QDBusArgument arg = firstArg.value<QDBusArgument>();
|
||||
ManagedObjectList managedObjects;
|
||||
arg >> managedObjects;
|
||||
|
||||
bool deviceFound = false;
|
||||
|
||||
for (auto it = managedObjects.constBegin(); it != managedObjects.constEnd(); ++it)
|
||||
{
|
||||
const QDBusObjectPath &objPath = it.key();
|
||||
const QMap<QString, QVariantMap> &interfaces = it.value();
|
||||
|
||||
if (interfaces.contains("org.bluez.Device1"))
|
||||
{
|
||||
const QVariantMap &deviceProps = interfaces.value("org.bluez.Device1");
|
||||
|
||||
// Check if the device has the necessary properties
|
||||
if (!deviceProps.contains("UUIDs") || !deviceProps.contains("Connected") ||
|
||||
!deviceProps.contains("Address") || !deviceProps.contains("Name"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QStringList uuids = deviceProps["UUIDs"].toStringList();
|
||||
bool isAirPods = uuids.contains("74ec2172-0bad-4d01-8f77-997b2be0722a");
|
||||
|
||||
if (isAirPods)
|
||||
{
|
||||
bool connected = deviceProps["Connected"].toBool();
|
||||
if (connected)
|
||||
{
|
||||
QString macAddress = deviceProps["Address"].toString();
|
||||
QString deviceName = deviceProps["Name"].toString();
|
||||
emit deviceConnected(macAddress, deviceName);
|
||||
LOG_DEBUG("Found already connected AirPods: " << macAddress << " Name: " << deviceName);
|
||||
deviceFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return deviceFound;
|
||||
}
|
||||
|
||||
void BluetoothMonitor::onPropertiesChanged(const QString &interface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
|
||||
{
|
||||
Q_UNUSED(invalidatedProps);
|
||||
@@ -56,8 +131,13 @@ void BluetoothMonitor::onPropertiesChanged(const QString &interface, const QVari
|
||||
bool connected = changedProps["Connected"].toBool();
|
||||
QString path = QDBusContext::message().path();
|
||||
|
||||
if (!isAirPodsDevice(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusInterface deviceInterface("org.bluez", path, "org.freedesktop.DBus.Properties", m_dbus);
|
||||
|
||||
|
||||
// Get the device address
|
||||
QDBusReply<QVariant> addrReply = deviceInterface.call("Get", "org.bluez.Device1", "Address");
|
||||
if (!addrReply.isValid())
|
||||
@@ -65,29 +145,17 @@ void BluetoothMonitor::onPropertiesChanged(const QString &interface, const QVari
|
||||
return;
|
||||
}
|
||||
QString macAddress = addrReply.value().toString();
|
||||
|
||||
// Get UUIDs to check if it's an AirPods device
|
||||
QDBusReply<QVariant> uuidsReply = deviceInterface.call("Get", "org.bluez.Device1", "UUIDs");
|
||||
if (!uuidsReply.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList uuids = uuidsReply.value().toStringList();
|
||||
if (!uuids.contains("74ec2172-0bad-4d01-8f77-997b2be0722a"))
|
||||
{
|
||||
return; // Not an AirPods device
|
||||
}
|
||||
QString deviceName = getDeviceName(path);
|
||||
|
||||
if (connected)
|
||||
{
|
||||
emit deviceConnected(macAddress);
|
||||
LOG_DEBUG("AirPods device connected:" << macAddress);
|
||||
emit deviceConnected(macAddress, deviceName);
|
||||
LOG_DEBUG("AirPods device connected:" << macAddress << " Name:" << deviceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit deviceDisconnected(macAddress);
|
||||
LOG_DEBUG("AirPods device disconnected:" << macAddress);
|
||||
emit deviceDisconnected(macAddress, deviceName);
|
||||
LOG_DEBUG("AirPods device disconnected:" << macAddress << " Name:" << deviceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user