22#include " logger.h"
33
44#include < QDebug>
5+ #include < QDBusObjectPath>
6+ #include < QDBusMetaType>
57
6- BluetoothMonitor::BluetoothMonitor (QObject *parent)
8+ BluetoothMonitor::BluetoothMonitor (QObject *parent)
79 : QObject(parent), m_dbus(QDBusConnection::systemBus())
810{
11+ // Register meta-types for D-Bus interaction
12+ qDBusRegisterMetaType<QDBusObjectPath>();
13+ qDBusRegisterMetaType<ManagedObjectList>();
14+
915 if (!m_dbus.isConnected ())
1016 {
1117 LOG_WARN (" Failed to connect to system D-Bus" );
1218 return ;
1319 }
1420
1521 registerDBusService ();
22+ checkAlreadyConnectedDevices (); // Check for already connected devices on startup
1623}
1724
1825BluetoothMonitor::~BluetoothMonitor ()
@@ -23,25 +30,93 @@ BluetoothMonitor::~BluetoothMonitor()
2330void BluetoothMonitor::registerDBusService ()
2431{
2532 // Match signals for PropertiesChanged on any BlueZ Device interface
26- QString matchRule = QStringLiteral (" type='signal',"
27- " interface='org.freedesktop.DBus.Properties',"
28- " member='PropertiesChanged',"
29- " path_namespace='/org/bluez'" );
30-
31- m_dbus.connect (" org.freedesktop.DBus" ,
32- " /org/freedesktop/DBus" ,
33- " org.freedesktop.DBus" ,
34- " AddMatch" ,
35- this ,
36- SLOT (onPropertiesChanged (QString, QVariantMap, QStringList)));
37-
3833 if (!m_dbus.connect (" " , " " , " org.freedesktop.DBus.Properties" , " PropertiesChanged" ,
3934 this , SLOT (onPropertiesChanged (QString, QVariantMap, QStringList))))
4035 {
4136 LOG_WARN (" Failed to connect to D-Bus PropertiesChanged signal" );
4237 }
4338}
4439
40+ bool BluetoothMonitor::isAirPodsDevice (const QString &devicePath)
41+ {
42+ QDBusInterface deviceInterface (" org.bluez" , devicePath, " org.freedesktop.DBus.Properties" , m_dbus);
43+
44+ // Get UUIDs to check if it's an AirPods device
45+ QDBusReply<QVariant> uuidsReply = deviceInterface.call (" Get" , " org.bluez.Device1" , " UUIDs" );
46+ if (!uuidsReply.isValid ())
47+ {
48+ return false ;
49+ }
50+
51+ QStringList uuids = uuidsReply.value ().toStringList ();
52+ return uuids.contains (" 74ec2172-0bad-4d01-8f77-997b2be0722a" );
53+ }
54+
55+ QString BluetoothMonitor::getDeviceName (const QString &devicePath)
56+ {
57+ QDBusInterface deviceInterface (" org.bluez" , devicePath, " org.freedesktop.DBus.Properties" , m_dbus);
58+ QDBusReply<QVariant> nameReply = deviceInterface.call (" Get" , " org.bluez.Device1" , " Name" );
59+ if (nameReply.isValid ())
60+ {
61+ return nameReply.value ().toString ();
62+ }
63+ return " Unknown" ;
64+ }
65+
66+ bool BluetoothMonitor::checkAlreadyConnectedDevices ()
67+ {
68+ QDBusInterface objectManager (" org.bluez" , " /" , " org.freedesktop.DBus.ObjectManager" , m_dbus);
69+ QDBusMessage reply = objectManager.call (" GetManagedObjects" );
70+
71+ if (reply.type () == QDBusMessage::ErrorMessage)
72+ {
73+ LOG_WARN (" Failed to get managed objects: " << reply.errorMessage ());
74+ return false ;
75+ }
76+
77+ QVariant firstArg = reply.arguments ().constFirst ();
78+ QDBusArgument arg = firstArg.value <QDBusArgument>();
79+ ManagedObjectList managedObjects;
80+ arg >> managedObjects;
81+
82+ bool deviceFound = false ;
83+
84+ for (auto it = managedObjects.constBegin (); it != managedObjects.constEnd (); ++it)
85+ {
86+ const QDBusObjectPath &objPath = it.key ();
87+ const QMap<QString, QVariantMap> &interfaces = it.value ();
88+
89+ if (interfaces.contains (" org.bluez.Device1" ))
90+ {
91+ const QVariantMap &deviceProps = interfaces.value (" org.bluez.Device1" );
92+
93+ // Check if the device has the necessary properties
94+ if (!deviceProps.contains (" UUIDs" ) || !deviceProps.contains (" Connected" ) ||
95+ !deviceProps.contains (" Address" ) || !deviceProps.contains (" Name" ))
96+ {
97+ continue ;
98+ }
99+
100+ QStringList uuids = deviceProps[" UUIDs" ].toStringList ();
101+ bool isAirPods = uuids.contains (" 74ec2172-0bad-4d01-8f77-997b2be0722a" );
102+
103+ if (isAirPods)
104+ {
105+ bool connected = deviceProps[" Connected" ].toBool ();
106+ if (connected)
107+ {
108+ QString macAddress = deviceProps[" Address" ].toString ();
109+ QString deviceName = deviceProps[" Name" ].toString ();
110+ emit deviceConnected (macAddress, deviceName);
111+ LOG_DEBUG (" Found already connected AirPods: " << macAddress << " Name: " << deviceName);
112+ deviceFound = true ;
113+ }
114+ }
115+ }
116+ }
117+ return deviceFound;
118+ }
119+
45120void BluetoothMonitor::onPropertiesChanged (const QString &interface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
46121{
47122 Q_UNUSED (invalidatedProps);
@@ -56,38 +131,31 @@ void BluetoothMonitor::onPropertiesChanged(const QString &interface, const QVari
56131 bool connected = changedProps[" Connected" ].toBool ();
57132 QString path = QDBusContext::message ().path ();
58133
134+ if (!isAirPodsDevice (path))
135+ {
136+ return ;
137+ }
138+
59139 QDBusInterface deviceInterface (" org.bluez" , path, " org.freedesktop.DBus.Properties" , m_dbus);
60-
140+
61141 // Get the device address
62142 QDBusReply<QVariant> addrReply = deviceInterface.call (" Get" , " org.bluez.Device1" , " Address" );
63143 if (!addrReply.isValid ())
64144 {
65145 return ;
66146 }
67147 QString macAddress = addrReply.value ().toString ();
68-
69- // Get UUIDs to check if it's an AirPods device
70- QDBusReply<QVariant> uuidsReply = deviceInterface.call (" Get" , " org.bluez.Device1" , " UUIDs" );
71- if (!uuidsReply.isValid ())
72- {
73- return ;
74- }
75-
76- QStringList uuids = uuidsReply.value ().toStringList ();
77- if (!uuids.contains (" 74ec2172-0bad-4d01-8f77-997b2be0722a" ))
78- {
79- return ; // Not an AirPods device
80- }
148+ QString deviceName = getDeviceName (path);
81149
82150 if (connected)
83151 {
84- emit deviceConnected (macAddress);
85- LOG_DEBUG (" AirPods device connected:" << macAddress);
152+ emit deviceConnected (macAddress, deviceName );
153+ LOG_DEBUG (" AirPods device connected:" << macAddress << " Name: " << deviceName );
86154 }
87155 else
88156 {
89- emit deviceDisconnected (macAddress);
90- LOG_DEBUG (" AirPods device disconnected:" << macAddress);
157+ emit deviceDisconnected (macAddress, deviceName );
158+ LOG_DEBUG (" AirPods device disconnected:" << macAddress << " Name: " << deviceName );
91159 }
92160 }
93161}
0 commit comments