129 lines
4.6 KiB
C++
129 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <giomm.h>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <sigc++/sigc++.h>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "connection/dbus/dbus.hpp"
|
|
|
|
struct BluetoothDevice {
|
|
std::string object_path;
|
|
std::string address;
|
|
std::string name;
|
|
std::string icon;
|
|
bool paired = false;
|
|
bool connected = false;
|
|
bool trusted = false;
|
|
int16_t rssi = 0;
|
|
};
|
|
|
|
class BluetoothController : public DbusConnection {
|
|
using PropertiesMap = std::map<Glib::ustring, Glib::VariantBase>;
|
|
|
|
public:
|
|
static std::shared_ptr<BluetoothController> getInstance() {
|
|
if (!instance) {
|
|
instance = std::shared_ptr<BluetoothController>(new BluetoothController());
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
// Adapter control
|
|
void setPowered(bool powered);
|
|
bool isPowered() const;
|
|
|
|
// Discovery
|
|
void startDiscovery();
|
|
void stopDiscovery();
|
|
bool isDiscovering() const;
|
|
|
|
// Device actions (identified by object_path)
|
|
void pairDevice(const std::string &object_path);
|
|
void unpairDevice(const std::string &object_path);
|
|
void connectDevice(const std::string &object_path);
|
|
void disconnectDevice(const std::string &object_path);
|
|
void trustDevice(const std::string &object_path, bool trusted);
|
|
|
|
// Queries
|
|
std::vector<BluetoothDevice> getDevices() const;
|
|
std::vector<BluetoothDevice> getPairedDevices() const;
|
|
|
|
// Signals
|
|
sigc::signal<void(bool)> &signalPoweredChanged();
|
|
sigc::signal<void(bool)> &signalDiscoveringChanged();
|
|
sigc::signal<void(const BluetoothDevice &)> &signalDeviceAdded();
|
|
sigc::signal<void(const std::string &)> &signalDeviceRemoved();
|
|
sigc::signal<void(const BluetoothDevice &)> &signalDeviceChanged();
|
|
|
|
private:
|
|
BluetoothController();
|
|
|
|
inline static std::shared_ptr<BluetoothController> instance = nullptr;
|
|
|
|
bool m_powered = false;
|
|
bool m_discovering = false;
|
|
|
|
std::string m_adapter_path;
|
|
Glib::RefPtr<Gio::DBus::Proxy> m_adapter_proxy;
|
|
Glib::RefPtr<Gio::DBus::Proxy> m_object_manager_proxy;
|
|
|
|
std::map<std::string, BluetoothDevice> m_devices;
|
|
std::map<std::string, Glib::RefPtr<Gio::DBus::Proxy>> m_device_proxies;
|
|
|
|
sigc::signal<void(bool)> m_powered_signal;
|
|
sigc::signal<void(bool)> m_discovering_signal;
|
|
sigc::signal<void(const BluetoothDevice &)> m_device_added_signal;
|
|
sigc::signal<void(const std::string &)> m_device_removed_signal;
|
|
sigc::signal<void(const BluetoothDevice &)> m_device_changed_signal;
|
|
|
|
// Bus setup
|
|
void onBusConnected(const Glib::RefPtr<Gio::AsyncResult> &result);
|
|
void enumerateObjects();
|
|
void parseInterfaces(const std::string &object_path, const Glib::VariantBase &interfaces_var);
|
|
|
|
// ObjectManager signals
|
|
void onObjectManagerSignal(const Glib::ustring &sender_name,
|
|
const Glib::ustring &signal_name,
|
|
const Glib::VariantContainerBase ¶meters);
|
|
|
|
// Agent
|
|
guint m_agent_id = 0;
|
|
void registerAgent();
|
|
void on_agent_method_call(const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
|
const Glib::ustring &sender,
|
|
const Glib::ustring &object_path,
|
|
const Glib::ustring &interface_name,
|
|
const Glib::ustring &method_name,
|
|
const Glib::VariantContainerBase ¶meters,
|
|
const Glib::RefPtr<Gio::DBus::MethodInvocation> &invocation);
|
|
|
|
// Adapter
|
|
void setupAdapter(const std::string &path, const PropertiesMap &properties);
|
|
void onAdapterPropertiesChanged(const Gio::DBus::Proxy::MapChangedProperties &changed,
|
|
const std::vector<Glib::ustring> &invalidated);
|
|
|
|
// Devices
|
|
void addDevice(const std::string &path, const PropertiesMap &properties);
|
|
void removeDevice(const std::string &path);
|
|
void onDevicePropertiesChanged(const std::string &object_path,
|
|
const Gio::DBus::Proxy::MapChangedProperties &changed,
|
|
const std::vector<Glib::ustring> &invalidated);
|
|
|
|
// Helpers
|
|
static BluetoothDevice parseDeviceProperties(const std::string &path, const PropertiesMap &properties);
|
|
void setDbusProperty(const std::string &object_path,
|
|
const std::string &interface,
|
|
const std::string &property,
|
|
const Glib::VariantBase &value);
|
|
|
|
// HID Authorization handler
|
|
void authorizeHIDDevice(const std::string &object_path);
|
|
|
|
Glib::RefPtr<Gio::DBus::NodeInfo> m_node_info;
|
|
std::shared_ptr<Gio::DBus::InterfaceVTable> m_interface_vtable;
|
|
};
|