#pragma once #include #include #include #include #include #include #include #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; public: static std::shared_ptr getInstance() { if (!instance) { instance = std::shared_ptr(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 getDevices() const; std::vector getPairedDevices() const; // Signals sigc::signal &signalPoweredChanged(); sigc::signal &signalDiscoveringChanged(); sigc::signal &signalDeviceAdded(); sigc::signal &signalDeviceRemoved(); sigc::signal &signalDeviceChanged(); private: BluetoothController(); inline static std::shared_ptr instance = nullptr; bool m_powered = false; bool m_discovering = false; std::string m_adapter_path; Glib::RefPtr m_adapter_proxy; Glib::RefPtr m_object_manager_proxy; std::map m_devices; std::map> m_device_proxies; sigc::signal m_powered_signal; sigc::signal m_discovering_signal; sigc::signal m_device_added_signal; sigc::signal m_device_removed_signal; sigc::signal m_device_changed_signal; // Bus setup void onBusConnected(const Glib::RefPtr &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 &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 &invocation); // Adapter void setupAdapter(const std::string &path, const PropertiesMap &properties); void onAdapterPropertiesChanged(const Gio::DBus::Proxy::MapChangedProperties &changed, const std::vector &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 &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); };