bar can now toggle bluetooth power and discovery
This commit is contained in:
185
src/services/bluetooth.cpp
Normal file
185
src/services/bluetooth.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "services/bluetooth.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#include "glib.h"
|
||||
#include "sigc++/signal.h"
|
||||
|
||||
BluetoothService::BluetoothService() {
|
||||
GError *error = nullptr;
|
||||
|
||||
this->adapter_proxy = g_dbus_proxy_new_for_bus_sync(
|
||||
G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
nullptr,
|
||||
"org.bluez",
|
||||
"/org/bluez/hci0",
|
||||
"org.bluez.Adapter1",
|
||||
nullptr,
|
||||
&error);
|
||||
|
||||
if (error) {
|
||||
std::cerr << "Error creating Bluetooth adapter proxy: "
|
||||
<< error->message << std::endl;
|
||||
g_error_free(error);
|
||||
assert(false);
|
||||
} else {
|
||||
std::cout << "Bluetooth adapter proxy created successfully." << std::endl;
|
||||
}
|
||||
|
||||
this->powerState = this->getPowerState();
|
||||
this->isDiscovering = this->getIsDiscovering();
|
||||
|
||||
g_signal_connect(
|
||||
this->adapter_proxy,
|
||||
"g-properties-changed",
|
||||
G_CALLBACK(BluetoothService::onPropertyChangedStatic),
|
||||
this);
|
||||
}
|
||||
|
||||
bool BluetoothService::getPowerState() {
|
||||
GVariant *result = g_dbus_proxy_get_cached_property(
|
||||
this->adapter_proxy,
|
||||
"Powered");
|
||||
|
||||
if (!result) {
|
||||
std::cerr << "Error getting Powered property." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
gboolean powered;
|
||||
g_variant_get(result, "b", &powered);
|
||||
g_variant_unref(result);
|
||||
|
||||
return powered;
|
||||
}
|
||||
|
||||
bool BluetoothService::getIsDiscovering() {
|
||||
GVariant *result = g_dbus_proxy_get_cached_property(
|
||||
this->adapter_proxy,
|
||||
"Discovering");
|
||||
|
||||
if (!result) {
|
||||
std::cerr << "Error getting Discovering property." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
gboolean discovering;
|
||||
g_variant_get(result, "b", &discovering);
|
||||
g_variant_unref(result);
|
||||
|
||||
return discovering;
|
||||
}
|
||||
|
||||
void BluetoothService::setPowerState(bool state) {
|
||||
GError *error = nullptr;
|
||||
|
||||
GDBusConnection *connection = g_dbus_proxy_get_connection(this->adapter_proxy);
|
||||
GVariant *reply = g_dbus_connection_call_sync(
|
||||
connection,
|
||||
"org.bluez",
|
||||
"/org/bluez/hci0",
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"Set",
|
||||
g_variant_new(
|
||||
"(ssv)",
|
||||
"org.bluez.Adapter1",
|
||||
"Powered",
|
||||
g_variant_new_boolean(state)),
|
||||
nullptr,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
nullptr,
|
||||
&error);
|
||||
|
||||
if (error) {
|
||||
std::cerr << "Error setting Powered property: "
|
||||
<< error->message << std::endl;
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
if (reply) {
|
||||
g_variant_unref(reply);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
this->powerState = state;
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothService::setIsDiscovering(bool state) {
|
||||
const bool currently_discovering = this->getIsDiscovering();
|
||||
this->isDiscovering = currently_discovering;
|
||||
|
||||
if (currently_discovering == state) {
|
||||
return;
|
||||
}
|
||||
|
||||
GError *error = nullptr;
|
||||
|
||||
const char *method = state ? "StartDiscovery" : "StopDiscovery";
|
||||
GVariant *reply = g_dbus_proxy_call_sync(
|
||||
this->adapter_proxy,
|
||||
method,
|
||||
nullptr,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
nullptr,
|
||||
&error);
|
||||
|
||||
if (error) {
|
||||
std::cerr << "Error calling " << method << ": "
|
||||
<< error->message << std::endl;
|
||||
g_error_free(error);
|
||||
|
||||
if (reply) {
|
||||
g_variant_unref(reply);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this->isDiscovering = state;
|
||||
|
||||
if (reply) {
|
||||
g_variant_unref(reply);
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothService::onPropertyChanged(GDBusProxy *proxy,
|
||||
GVariant *changed_properties,
|
||||
const gchar *const *invalidated_properties,
|
||||
gpointer user_data) {
|
||||
|
||||
gboolean is_powered = FALSE;
|
||||
gboolean is_discovering = FALSE;
|
||||
|
||||
if (g_variant_lookup(changed_properties, "Powered", "b", &is_powered)) {
|
||||
|
||||
this->setIsDiscovering(false);
|
||||
isDiscoveringChangedSignal.emit(isDiscovering);
|
||||
|
||||
this->powerState = is_powered;
|
||||
powerStateChangedSignal.emit(powerState);
|
||||
}
|
||||
|
||||
if (g_variant_lookup(changed_properties, "Discovering", "b", &is_discovering)) {
|
||||
this->isDiscovering = is_discovering;
|
||||
isDiscoveringChangedSignal.emit(isDiscovering);
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothService::onPropertyChangedStatic(GDBusProxy *proxy,
|
||||
GVariant *changed_properties,
|
||||
const gchar *const *invalidated_properties,
|
||||
gpointer user_data) {
|
||||
BluetoothService *service = static_cast<BluetoothService *>(user_data);
|
||||
|
||||
if (service) {
|
||||
service->onPropertyChanged(proxy, changed_properties, invalidated_properties, user_data);
|
||||
} else {
|
||||
std::cerr << "Error: BluetoothService instance is null in static callback." << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user