/*! * * Copyright (c) 2026 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * \file MqttClient.h * \author (original) Stephen Quong * \date (original) 30-Jul-2026 * */ #pragma once #include #include #include #include #include #include #include class QMqttClient; /*! * \brief Encrypted client MQTT connection to a broker for message sending and receiving. * Lifecycle: init() -> open() -> close(). */ class MqttClient : public QObject { Q_OBJECT public: /*! * \brief Parameters for one MQTT session. */ struct Config { QString endpoint; // Broker FQDN or address; no scheme or trailing slash. quint16 port = 8883; // Broker port; the session is always TLS. QString certPath; // Client certificate for mTLS, PEM; optional. QString keyPath; // Unencrypted private key matching certPath, PEM; required. QString caPath; // CA bundle to verify the broker, PEM; optional, falls back // to the system CA set. QString clientId; // Must equal the IoT Thing name; the device policy scopes iot:Connect to it. quint16 keepAliveSecs = 30; // MQTT keep-alive interval; PINGREQ is QMqttClient's job. bool cleanSession = true; // No broker-side queue; durability is the device's job. }; explicit MqttClient(QObject *parent = nullptr); ~MqttClient() override; bool init(const Config &config); bool open(); void close(); bool publish(const QString &topic, const QByteArray &payload, qint32 &msgId, quint8 qos=1); bool subscribe(const QString &topicFilter, quint8 qos=1); Q_SIGNALS: /*! * \brief Emitted when the state of the session changes (i.e. connect, disconnect) * \note Subscriptions belong to the QMqttClient that gets destroyed on disconnect, * so re-subscription is required on every new connection. * \note Not emitted for a caller-initiated close() */ void didStateChanged(QMqttClient::ClientState state); /*! * \brief Emitted for status change of every sent message. */ void didMessageStatusChanged(quint32 id, QMqtt::MessageStatus status, const QMqttMessageStatusProperties &properties); /*! * \brief Emitted for every message the broker delivers to this client. * \details Covers all active subscriptions; the receiver demultiplexes by topic. */ void didMessageReceived(const QByteArray &message, const QMqttTopicName &topic); private Q_SLOTS: void onStateChanged(); private: QMqttClient *_client = nullptr; Config _config; QSslConfiguration _sslConfig; };