SceneSwitcher/plugins/mqtt/mqtt-helpers.hpp
WarmUpTill 84f7d0d214 Add SSL support to MQTT connections
Also fixes crash on startup if SSL was used while there was no support
for encrypted connections yet
2025-10-28 19:20:52 +01:00

149 lines
4.0 KiB
C++

#pragma once
#include "message-dispatcher.hpp"
#include "file-selection.hpp"
#include "item-selection-helpers.hpp"
#include "topic-selection.hpp"
#include <condition_variable>
#include <obs-data.h>
#include <QCheckBox>
#include <QComboBox>
#include <QLayout>
#include <QPushButton>
#include <QSpinBox>
#include <string>
#include <thread>
#include <mqtt/async_client.h>
namespace advss {
using MqttMessageBuffer = std::shared_ptr<MessageBuffer<std::string>>;
using MqttMessageDispatcher = MessageDispatcher<std::string>;
class MqttConnection : public Item {
public:
MqttConnection() = default;
~MqttConnection();
MqttConnection(const MqttConnection &other);
MqttConnection(const std::string &name, const std::string &uri,
const std::string &username, const std::string &password,
const std::string &trustStore,
const std::string &keyStore,
const std::string &privateKey, bool verifyServerCert,
bool connectOnStart, bool reconnect, int reconnectDelay);
static std::shared_ptr<Item> Create()
{
return std::make_shared<MqttConnection>();
}
void Connect();
bool SendMessage(const std::string &topic, const std::string &payload,
int qos, bool retained);
void Load(obs_data_t *data);
void Save(obs_data_t *data) const;
MqttMessageBuffer RegisterForEvents();
bool ConnectOnStartup() const { return _connectOnStart; }
QString GetURI() const { return QString::fromStdString(_uri); }
int GetTopicSubscriptionCount() const { return _topics.size(); }
QString GetStatus() const;
private:
void ConnectThread();
void Disconnect();
std::string _uri = "mqtt://localhost:1883";
std::string _username = "user";
std::string _password = "password";
std::string _trustStore = "";
std::string _keyStore = "";
std::string _privateKey = "";
bool _verifyServerCert = false;
std::vector<std::string> _topics = {"/example"};
std::vector<int> _qos = {1};
std::thread _thread;
bool _connectOnStart = true;
bool _reconnect = true;
int _reconnectDelay = 3;
std::shared_ptr<mqtt::async_client> _client;
std::atomic_bool _disconnect{false};
std::atomic_bool _connected{false};
std::atomic_bool _connecting{false};
std::mutex _clientMtx;
std::mutex _waitMtx;
std::condition_variable _cv;
std::string _lastError = "";
MqttMessageDispatcher _dispatcher;
friend class MqttConnectionSettingsDialog;
};
class MqttConnectionSettingsDialog : public ItemSettingsDialog {
Q_OBJECT
public:
MqttConnectionSettingsDialog(QWidget *parent, const MqttConnection &);
static bool AskForSettings(QWidget *parent, MqttConnection &settings);
private slots:
void ShowPassword();
void HidePassword();
void ReconnectChanged(int state);
void TestConnection();
private:
QLineEdit *_uri;
QLineEdit *_username;
QLineEdit *_password;
QPushButton *_showPassword;
FileSelection *_trustStore;
FileSelection *_keyStore;
FileSelection *_privateKey;
QCheckBox *_verifyServerCert;
MqttTopicListWidget *_topics;
QCheckBox *_connectOnStart;
QCheckBox *_reconnect;
QSpinBox *_reconnectDelay;
QLabel *_status;
QPushButton *_test;
QGridLayout *_layout;
QTimer *_updateStatusTimer = nullptr;
};
class MqttConnectionSelection : public ItemSelection {
Q_OBJECT
public:
MqttConnectionSelection(QWidget *parent = 0);
void SetConnection(const std::weak_ptr<MqttConnection> &);
};
class MqttConnectionSignalManager : public QObject {
Q_OBJECT
public:
MqttConnectionSignalManager(QObject *parent = nullptr);
static MqttConnectionSignalManager *Instance();
private slots:
void OpenNewConnection(const QString &);
signals:
void Rename(const QString &, const QString &);
void Add(const QString &);
void Remove(const QString &);
};
std::deque<std::shared_ptr<Item>> &GetMqttConnections();
MqttConnection *GetMqttConnectionByName(const QString &);
MqttConnection *GetMqttConnectionByName(const std::string &);
std::weak_ptr<MqttConnection>
GetWeakMqttConnectionByName(const std::string &name);
std::weak_ptr<MqttConnection>
GetWeakMqttConnectionByQString(const QString &name);
std::string GetWeakMqttConnectionName(const std::weak_ptr<MqttConnection> &);
} // namespace advss