Files
fastfetch/src/detection/bluetooth/bluetooth_linux.c
T

204 lines
6.4 KiB
C
Raw Normal View History

2023-01-24 10:39:33 +01:00
#include "bluetooth.h"
#include "util/stringUtils.h"
2023-01-24 10:39:33 +01:00
#ifdef FF_HAVE_DBUS
#include "common/dbus.h"
/* Example dbus reply, striped to only the relevant parts:
array [ //root
dict entry( //object
object path "/org/bluez/hci0/dev_03_21_8B_91_16_4D"
array [
2023-01-27 18:03:57 +01:00
dict entry( //property
string "org.bluez.Device1"
array [
2023-01-27 18:21:42 +01:00
dict entry( //value
2023-01-27 18:03:57 +01:00
string "Address"
variant string "03:21:8B:91:16:4D"
)
2023-01-27 18:21:42 +01:00
dict entry( //value
2023-01-27 18:03:57 +01:00
string "Name"
variant string "JBL TUNE160BT"
)
2023-01-27 18:21:42 +01:00
dict entry( //value
2023-01-27 18:03:57 +01:00
string "Icon"
variant string "audio-headset"
)
2023-01-27 18:21:42 +01:00
dict entry( //value
2023-01-27 18:03:57 +01:00
string "Connected"
variant boolean true
)
]
)
dict entry( //property
string "org.bluez.Battery1"
array [
2023-01-27 18:21:42 +01:00
dict entry( //value
2023-01-27 18:03:57 +01:00
string "Percentage"
variant byte 100
)
]
)
2023-01-24 10:39:33 +01:00
]
)
]
*/
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
2023-01-27 18:21:42 +01:00
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
const char* deviceProperty;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty);
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(ffStrEquals(deviceProperty, "Address"))
2023-01-27 18:21:42 +01:00
ffDBusGetValue(dbus, &dictIter, &device->address);
else if(ffStrEquals(deviceProperty, "Name"))
2023-01-27 18:21:42 +01:00
ffDBusGetValue(dbus, &dictIter, &device->name);
else if(ffStrEquals(deviceProperty, "Icon"))
2023-01-27 18:21:42 +01:00
ffDBusGetValue(dbus, &dictIter, &device->type);
else if(ffStrEquals(deviceProperty, "Percentage"))
2023-01-27 18:21:42 +01:00
ffDBusGetByte(dbus, &dictIter, &device->battery);
else if(ffStrEquals(deviceProperty, "Connected"))
2023-01-27 18:21:42 +01:00
ffDBusGetBool(dbus, &dictIter, &device->connected);
}
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
2023-01-24 10:39:33 +01:00
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
const char* propertyType;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &propertyType);
if(strstr(propertyType, "Device") == NULL && strstr(propertyType, "Battery") == NULL)
return; //We don't care about other properties
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
return;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
while(true)
{
2023-01-27 18:21:42 +01:00
detectBluetoothValue(dbus, &arrayIter, device);
2023-01-24 10:39:33 +01:00
FF_DBUS_ITER_CONTINUE(dbus, &arrayIter);
}
}
2023-06-12 21:50:25 +08:00
static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
2023-01-24 10:39:33 +01:00
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
2023-01-24 12:02:20 +01:00
return;
2023-01-24 10:39:33 +01:00
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH)
2023-01-24 12:02:20 +01:00
return;
2023-01-24 10:39:33 +01:00
const char* objectPath;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath);
//We don't want adapter objects
if(strstr(objectPath, "dev_") == NULL)
2023-01-24 12:02:20 +01:00
return;
2023-01-24 10:39:33 +01:00
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
2023-01-24 12:02:20 +01:00
return;
2023-01-24 10:39:33 +01:00
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
FFBluetoothResult* device = ffListAdd(devices);
2023-01-24 12:02:20 +01:00
ffStrbufInit(&device->name);
ffStrbufInit(&device->address);
ffStrbufInit(&device->type);
device->battery = 0;
device->connected = false;
2023-01-24 10:39:33 +01:00
while(true)
{
2023-01-24 12:02:20 +01:00
detectBluetoothProperty(dbus, &arrayIter, device);
2023-01-24 10:39:33 +01:00
FF_DBUS_ITER_CONTINUE(dbus, &arrayIter);
}
2023-01-24 12:02:20 +01:00
if(device->name.length == 0)
2023-01-24 10:39:33 +01:00
{
2023-01-24 12:02:20 +01:00
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->address);
ffStrbufDestroy(&device->type);
2023-06-12 21:50:25 +08:00
--devices->length;
2023-01-24 10:39:33 +01:00
}
}
2023-06-12 21:50:25 +08:00
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
2023-01-24 10:39:33 +01:00
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
return;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &arrayIter);
while(true)
{
2023-06-12 21:50:25 +08:00
detectBluetoothObject(devices, dbus, &arrayIter);
2023-01-24 10:39:33 +01:00
FF_DBUS_ITER_CONTINUE(dbus, &arrayIter);
}
}
static const char* detectBluetooth(FFlist* devices)
2023-01-24 10:39:33 +01:00
{
FFDBusData dbus;
const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus);
2023-01-24 10:39:33 +01:00
if(error)
return error;
DBusMessage* managedObjects = ffDBusGetMethodReply(&dbus, "org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
if(!managedObjects)
return "Failed to call GetManagedObjects";
DBusMessageIter rootIter;
if(!dbus.lib->ffdbus_message_iter_init(managedObjects, &rootIter))
{
dbus.lib->ffdbus_message_unref(managedObjects);
return "Failed to get root iterator of GetManagedObjects";
}
2023-06-12 21:50:25 +08:00
detectBluetoothRoot(devices, &dbus, &rootIter);
2023-01-24 10:39:33 +01:00
dbus.lib->ffdbus_message_unref(managedObjects);
return NULL;
}
#endif
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
2023-01-24 10:39:33 +01:00
{
#ifdef FF_HAVE_DBUS
return detectBluetooth(devices);
2023-01-24 10:39:33 +01:00
#else
2023-06-12 21:50:25 +08:00
return "Fastfetch was compiled without DBus support";
2023-01-24 10:39:33 +01:00
#endif
}