Archived
Initial commit
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
#include "bluetooth.h"
|
||||
#include "../util.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
static long long powered_devices = 0;
|
||||
|
||||
static GPtrArray *get_bluetooth_device_paths() {
|
||||
DIR *dir = opendir("/sys/class/bluetooth");
|
||||
if (!dir) {
|
||||
return NULL;
|
||||
}
|
||||
GPtrArray *arr = g_ptr_array_new();
|
||||
struct dirent *current;
|
||||
while ((current = readdir(dir))) {
|
||||
if (strcmp(current->d_name, ".") != 0 &&
|
||||
strcmp(current->d_name, "..") != 0) {
|
||||
char *path = g_strdup_printf("/org/bluez/%s", current->d_name);
|
||||
g_ptr_array_add(arr, path);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return arr;
|
||||
}
|
||||
|
||||
static void load_initial_device_states(GDBusConnection *dbus,
|
||||
GPtrArray *devices) {
|
||||
gsize i;
|
||||
for (i = 0; i < devices->len; ++i) {
|
||||
const char *path = g_ptr_array_index(devices, i);
|
||||
GError *err = NULL;
|
||||
GVariant *response = g_dbus_connection_call_sync(
|
||||
dbus, "org.bluez", path, "org.freedesktop.DBus.Properties", "Get",
|
||||
g_variant_new_parsed("('org.bluez.Adapter1', 'Powered')"),
|
||||
(GVariantType *)"(v)", G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
|
||||
if (response) {
|
||||
GVariant *wrapper = g_variant_get_child_value(response, 0);
|
||||
GVariant *value = g_variant_get_child_value(wrapper, 0);
|
||||
gboolean powered = g_variant_get_boolean(value);
|
||||
if (powered) {
|
||||
++powered_devices;
|
||||
} /* sice powered_devices is already 0, we dont have to increment it
|
||||
if the device is not powered */
|
||||
g_variant_unref(value);
|
||||
g_variant_unref(wrapper);
|
||||
g_variant_unref(response);
|
||||
}
|
||||
}
|
||||
qtb_signal_modules(4);
|
||||
}
|
||||
|
||||
static void device_changed_callback(GDBusConnection *dbus,
|
||||
const char *sender_name,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
const char *signal_name, GVariant *params,
|
||||
gpointer user_data) {
|
||||
GVariant *changed = g_variant_get_child_value(params, 1);
|
||||
GVariant *value_wrapper = g_variant_lookup_value(changed, "Powered", G_VARIANT_TYPE_BOOLEAN);
|
||||
if (value_wrapper) {
|
||||
gboolean powered = g_variant_get_boolean(value_wrapper);
|
||||
if (powered) {
|
||||
++powered_devices;
|
||||
} else {
|
||||
--powered_devices;
|
||||
}
|
||||
g_variant_unref(value_wrapper);
|
||||
}
|
||||
g_variant_unref(changed);
|
||||
qtb_signal_modules(4);
|
||||
}
|
||||
|
||||
static void subscribe_to_events(GDBusConnection *dbus, GPtrArray *devices) {
|
||||
gsize i;
|
||||
for (i = 0; i < devices->len; ++i) {
|
||||
const char *path = g_ptr_array_index(devices, i);
|
||||
g_dbus_connection_signal_subscribe(
|
||||
dbus, NULL, "org.freedesktop.DBus.Properties", "PropertiesChanged",
|
||||
path, "org.bluez.Adapter1", G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
&device_changed_callback, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void *thread_action() {
|
||||
GMainContext *context = g_main_context_new();
|
||||
g_main_context_push_thread_default(context);
|
||||
GError *err = NULL;
|
||||
GDBusConnection *dbus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
|
||||
if (err) {
|
||||
qtb_log("could not connect to bluez on the system bus: %s",
|
||||
err->message);
|
||||
qtb_die();
|
||||
}
|
||||
GPtrArray *devices = get_bluetooth_device_paths();
|
||||
load_initial_device_states(dbus, devices);
|
||||
subscribe_to_events(dbus, devices);
|
||||
gsize i;
|
||||
for (i = 0; i < devices->len; ++i) {
|
||||
g_free(g_ptr_array_index(devices, i));
|
||||
}
|
||||
g_ptr_array_free(devices, TRUE);
|
||||
GMainLoop *main_loop = g_main_loop_new(context, FALSE);
|
||||
g_main_loop_run(main_loop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void bluetooth_module_init() {
|
||||
g_thread_new("bluetooth-module", &thread_action, NULL);
|
||||
}
|
||||
|
||||
char *bluetooth_module_poll() {
|
||||
char *output = NULL;
|
||||
if (powered_devices != 0) {
|
||||
output = qtb_strdup(" ");
|
||||
}
|
||||
return output;
|
||||
}
|
||||
Reference in New Issue
Block a user