├── .tag ├── examples ├── examples.pro ├── mqtt │ ├── quickpublication │ │ ├── qmldir │ │ ├── main.cpp │ │ ├── CMakeLists.txt │ │ ├── quickpublication.pro │ │ ├── qmlmqttclient.h │ │ └── qmlmqttclient.cpp │ ├── quicksubscription │ │ ├── qmldir │ │ ├── main.cpp │ │ ├── CMakeLists.txt │ │ ├── quicksubscription.pro │ │ ├── qmlmqttclient.h │ │ ├── qmlmqttclient.cpp │ │ └── Main.qml │ ├── doc │ │ ├── images │ │ │ ├── simpleclient.png │ │ │ ├── subscriptions.png │ │ │ ├── quickpublication.png │ │ │ └── quicksubscription.png │ │ ├── examples.qdoc │ │ ├── quicksubscription.qdoc │ │ ├── quickpublication.qdoc │ │ ├── websocketsubscription.qdoc │ │ ├── subscriptions.qdoc │ │ └── simpleclient.qdoc │ ├── mqtt.pro │ ├── simpleclient │ │ ├── main.cpp │ │ ├── simpleclient.pro │ │ ├── mainwindow.h │ │ ├── CMakeLists.txt │ │ └── mainwindow.cpp │ ├── subscriptions │ │ ├── main.cpp │ │ ├── subscriptionwindow.h │ │ ├── mainwindow.h │ │ ├── subscriptions.pro │ │ ├── CMakeLists.txt │ │ ├── subscriptionwindow.cpp │ │ ├── subscriptionwindow.ui │ │ └── mainwindow.cpp │ ├── CMakeLists.txt │ └── websocketsubscription │ │ ├── clientsubscription.h │ │ ├── websocketsubscription.pro │ │ ├── websocketiodevice.h │ │ ├── CMakeLists.txt │ │ ├── websocketiodevice.cpp │ │ ├── main.cpp │ │ └── clientsubscription.cpp └── CMakeLists.txt ├── tests ├── benchmarks │ ├── benchmarks.pro │ └── qmqttclient │ │ ├── qmqttclient.pro │ │ └── tst_qmqttclient.cpp ├── libfuzzer │ └── mqtt │ │ └── data_receive │ │ ├── data_receive.pro │ │ └── main.cpp ├── auto │ ├── cmake │ │ └── CMakeLists.txt │ ├── qmqtttopicname │ │ ├── CMakeLists.txt │ │ └── tst_qmqtttopicname.cpp │ ├── qmqtttopicfilter │ │ └── CMakeLists.txt │ ├── qmqttcontrolpacket │ │ ├── CMakeLists.txt │ │ └── tst_qmqttcontrolpacket.cpp │ ├── CMakeLists.txt │ ├── conformance │ │ └── CMakeLists.txt │ ├── qmqttclient │ │ └── CMakeLists.txt │ ├── qmqttsubscription │ │ └── CMakeLists.txt │ ├── qmqttpublishproperties │ │ └── CMakeLists.txt │ ├── qmqttlastwillproperties │ │ └── CMakeLists.txt │ ├── qmqttconnectionproperties │ │ └── CMakeLists.txt │ └── qmqttsubscriptionproperties │ │ ├── CMakeLists.txt │ │ └── tst_qmqttsubscriptionproperties.cpp ├── manual │ ├── sslconfiguration │ │ ├── sslconfiguration.pro │ │ ├── CMakeLists.txt │ │ └── main.cpp │ └── consolepubsub │ │ ├── CMakeLists.txt │ │ ├── main_pub.cpp │ │ └── main_sub.cpp ├── README.txt ├── certificate │ ├── cert.crt │ └── cert.key └── CMakeLists.txt ├── .gitreview ├── src ├── mqtt │ ├── doc │ │ ├── images │ │ │ └── mqtt.png │ │ ├── src │ │ │ ├── external-resources.qdoc │ │ │ ├── module.qdoc │ │ │ └── index.qdoc │ │ ├── qtmqtt.qdocconf │ │ └── style │ │ │ └── style.css │ ├── qmqttglobal_p.h │ ├── qmqttsubscription_p.h │ ├── qmqtttype.h │ ├── qmqttmessage_p.h │ ├── qmqttauthenticationproperties.h │ ├── transportLayers │ │ ├── mqtt_websocket_io.cpp │ │ ├── mqtt_websocket_io_p.h │ │ ├── mqtt_secure_websocket_io.cpp │ │ ├── mqtt_secure_websocket_io_p.h │ │ ├── mqtt_websocket_io_base_p.h │ │ └── mqtt_websocket_io_base.cpp │ ├── qmqttpublishproperties_p.h │ ├── qmqttmessage.h │ ├── qmqttsubscriptionproperties.h │ ├── CMakeLists.txt │ ├── qmqttglobal.h │ ├── qmqttclient_p.h │ ├── qmqttcontrolpacket_p.h │ ├── qmqttconnectionproperties_p.h │ ├── qmqtttopicname.h │ ├── qmqttsubscription.h │ ├── qmqtttopicfilter.h │ ├── qmqttpublishproperties.h │ ├── qmqttcontrolpacket.cpp │ ├── qmqttauthenticationproperties.cpp │ ├── qmqttsubscriptionproperties.cpp │ └── qmqttmessage.cpp └── CMakeLists.txt ├── .cmake.conf ├── dist ├── REUSE.toml ├── changes-5.15.0 ├── changes-5.14.1 ├── changes-5.15.1 ├── changes-5.14.2 ├── changes-5.11.0 ├── changes-5.11.2 ├── changes-5.14.0 ├── changes-5.15.2 ├── changes-5.12.0 ├── changes-5.12.10 └── changes-5.13.1 ├── dependencies.yaml ├── LICENSES ├── LicenseRef-Qt-Commercial.txt └── BSD-3-Clause.txt ├── CMakeLists.txt ├── coin ├── module_config.yaml └── axivion │ └── ci_config_linux.json ├── REUSE.toml └── licenseRule.json /.tag: -------------------------------------------------------------------------------- 1 | c588c20e662714237bed6ca8b098639ab0933d23 2 | -------------------------------------------------------------------------------- /examples/examples.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | SUBDIRS += mqtt 3 | -------------------------------------------------------------------------------- /tests/benchmarks/benchmarks.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | SUBDIRS += qmqttclient 3 | 4 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=codereview.qt-project.org 3 | project=qt/qtmqtt 4 | defaultbranch=dev 5 | -------------------------------------------------------------------------------- /src/mqtt/doc/images/mqtt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qt/qtmqtt/dev/src/mqtt/doc/images/mqtt.png -------------------------------------------------------------------------------- /examples/mqtt/quickpublication/qmldir: -------------------------------------------------------------------------------- 1 | module publication 2 | 3 | prefer :/qt/qml/publication/ 4 | Main 1.0 Main.qml 5 | -------------------------------------------------------------------------------- /examples/mqtt/quicksubscription/qmldir: -------------------------------------------------------------------------------- 1 | module subscription 2 | 3 | prefer :/qt/qml/subscription/ 4 | Main 1.0 Main.qml 5 | -------------------------------------------------------------------------------- /examples/mqtt/doc/images/simpleclient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qt/qtmqtt/dev/examples/mqtt/doc/images/simpleclient.png -------------------------------------------------------------------------------- /examples/mqtt/doc/images/subscriptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qt/qtmqtt/dev/examples/mqtt/doc/images/subscriptions.png -------------------------------------------------------------------------------- /examples/mqtt/doc/images/quickpublication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qt/qtmqtt/dev/examples/mqtt/doc/images/quickpublication.png -------------------------------------------------------------------------------- /examples/mqtt/doc/images/quicksubscription.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qt/qtmqtt/dev/examples/mqtt/doc/images/quicksubscription.png -------------------------------------------------------------------------------- /tests/libfuzzer/mqtt/data_receive/data_receive.pro: -------------------------------------------------------------------------------- 1 | QT -= gui 2 | QT += mqtt testlib 3 | QT += mqtt-private 4 | 5 | SOURCES += \ 6 | main.cpp 7 | 8 | LIBS += -fsanitize=fuzzer 9 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | set(QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES "QT_COMMERCIAL_OR_GPL3") 5 | 6 | add_subdirectory(mqtt) 7 | -------------------------------------------------------------------------------- /.cmake.conf: -------------------------------------------------------------------------------- 1 | set(QT_REPO_MODULE_VERSION "6.12.0") 2 | set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") 3 | set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_QASCONST=1") 4 | list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_FOREACH=1") 5 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | qt_examples_build_begin(EXTERNAL_BUILD) 5 | 6 | add_subdirectory(mqtt) 7 | 8 | qt_examples_build_end() 9 | -------------------------------------------------------------------------------- /src/mqtt/doc/src/external-resources.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | /*! 5 | \externalpage https://www.mqtt.org 6 | \title MQTT 7 | */ 8 | -------------------------------------------------------------------------------- /dist/REUSE.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[annotations]] 4 | path = ["*"] 5 | precedence = "override" 6 | comment = "Licensed as documentation." 7 | SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." 8 | SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only" 9 | -------------------------------------------------------------------------------- /dependencies.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | ../qtbase: 3 | ref: df1292e2b96aab02ad6df778d8336e7958ad5d1c 4 | required: true 5 | ../qtdeclarative: 6 | ref: 7ef1d06ce70fa360613dca0b5ff03365ebbc9883 7 | required: true 8 | ../qtwebsockets: 9 | ref: ecf7bc43c93b4edd49e11e342a9beae900bd0680 10 | required: false 11 | -------------------------------------------------------------------------------- /examples/mqtt/mqtt.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | qtHaveModule(gui):qtHaveModule(widgets): SUBDIRS += \ 4 | simpleclient \ 5 | subscriptions 6 | 7 | qtHaveModule(quick): SUBDIRS += quicksubscription 8 | qtHaveModule(quick): SUBDIRS += quickpublication 9 | qtHaveModule(websockets): SUBDIRS += websocketsubscription 10 | -------------------------------------------------------------------------------- /examples/mqtt/simpleclient/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "mainwindow.h" 5 | #include 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | QApplication a(argc, argv); 10 | MainWindow w; 11 | w.show(); 12 | 13 | return a.exec(); 14 | } 15 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "mainwindow.h" 5 | #include 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | QApplication a(argc, argv); 10 | MainWindow w; 11 | w.show(); 12 | 13 | return a.exec(); 14 | } 15 | -------------------------------------------------------------------------------- /tests/auto/cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | 6 | project(qtmqtt_cmake_tests) 7 | 8 | enable_testing() 9 | 10 | find_package(Qt6Core REQUIRED) 11 | 12 | include("${_Qt6CTestMacros}") 13 | 14 | _qt_internal_test_module_includes( 15 | Mqtt QMqttClient 16 | ) 17 | -------------------------------------------------------------------------------- /examples/mqtt/doc/examples.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | 5 | /*! 6 | \group qtmqtt-examples 7 | \title Qt MQTT Examples 8 | \brief List of Qt MQTT examples 9 | 10 | The Qt MQTT examples demonstrate the functionality provided by the 11 | \l{Qt MQTT} module. 12 | */ 13 | -------------------------------------------------------------------------------- /tests/benchmarks/qmqttclient/qmqttclient.pro: -------------------------------------------------------------------------------- 1 | CONFIG += benchmark 2 | QT += network testlib mqtt 3 | QT -= gui 4 | QT_PRIVATE += mqtt-private 5 | 6 | TARGET = tst_qmqttclient 7 | 8 | SOURCES += \ 9 | tst_qmqttclient.cpp 10 | 11 | HEADERS += \ 12 | $$PWD/../../common/broker_connection.h 13 | 14 | INCLUDEPATH += \ 15 | $$PWD/../../common 16 | 17 | DEFINES += SRCDIR=\\\"$$PWD/\\\" 18 | -------------------------------------------------------------------------------- /tests/manual/sslconfiguration/sslconfiguration.pro: -------------------------------------------------------------------------------- 1 | QT -= gui 2 | QT += network mqtt 3 | 4 | CONFIG += c++11 console 5 | CONFIG -= app_bundle 6 | 7 | DEFINES += QT_DEPRECATED_WARNINGS 8 | 9 | SOURCES += \ 10 | main.cpp 11 | 12 | # Default rules for deployment. 13 | qnx: target.path = /tmp/$${TARGET}/bin 14 | else: unix:!android: target.path = /opt/$${TARGET}/bin 15 | !isEmpty(target.path): INSTALLS += target 16 | -------------------------------------------------------------------------------- /src/mqtt/doc/src/module.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | 5 | /*! 6 | \module QtMqtt 7 | \title Qt MQTT C++ Classes 8 | \ingroup modules 9 | \qtcmakepackage Mqtt 10 | \qtvariable mqtt 11 | \brief Provides classes that enable sending messages via the MQTT protocol. 12 | 13 | The \l{Qt MQTT} page contains information about how to use the module. 14 | */ 15 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-Qt-Commercial.txt: -------------------------------------------------------------------------------- 1 | Licensees holding valid commercial Qt licenses may use this software in 2 | accordance with the the terms contained in a written agreement between 3 | you and The Qt Company. Alternatively, the terms and conditions that were 4 | accepted by the licensee when buying and/or downloading the 5 | software do apply. 6 | 7 | For the latest licensing terms and conditions, see https://www.qt.io/terms-conditions. 8 | For further information use the contact form at https://www.qt.io/contact-us. 9 | -------------------------------------------------------------------------------- /tests/manual/sslconfiguration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## sslconfiguration Binary: 6 | ##################################################################### 7 | 8 | qt_add_manual_test(sslconfiguration 9 | SOURCES 10 | main.cpp 11 | DEFINES 12 | QT_DEPRECATED_WARNINGS 13 | LIBRARIES 14 | Qt::Mqtt 15 | Qt::Network 16 | ) 17 | -------------------------------------------------------------------------------- /examples/mqtt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | if(TARGET Qt::Gui AND TARGET Qt::Widgets) 5 | qt_internal_add_example(simpleclient) 6 | qt_internal_add_example(subscriptions) 7 | endif() 8 | if(TARGET Qt::Quick) 9 | qt_internal_add_example(quicksubscription) 10 | qt_internal_add_example(quickpublication) 11 | endif() 12 | if(TARGET Qt::WebSockets) 13 | qt_internal_add_example(websocketsubscription) 14 | endif() 15 | -------------------------------------------------------------------------------- /tests/auto/qmqtttopicname/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqtttopicname Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqtttopicname 11 | SOURCES 12 | tst_qmqtttopicname.cpp 13 | DEFINES 14 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 15 | LIBRARIES 16 | Qt::MqttPrivate 17 | Qt::Mqtt 18 | ) 19 | -------------------------------------------------------------------------------- /tests/auto/qmqtttopicfilter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqtttopicfilter Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqtttopicfilter 11 | SOURCES 12 | tst_qmqtttopicfilter.cpp 13 | DEFINES 14 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 15 | LIBRARIES 16 | Qt::MqttPrivate 17 | Qt::Mqtt 18 | ) 19 | -------------------------------------------------------------------------------- /tests/auto/qmqttcontrolpacket/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqttcontrolpacket Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqttcontrolpacket 11 | SOURCES 12 | tst_qmqttcontrolpacket.cpp 13 | DEFINES 14 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 15 | LIBRARIES 16 | Qt::MqttPrivate 17 | Qt::Mqtt 18 | Qt::Network 19 | ) 20 | -------------------------------------------------------------------------------- /tests/auto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | if(WIN32 OR (LINUX AND NOT CMAKE_CROSSCOMPILING)) 5 | add_subdirectory(cmake) 6 | add_subdirectory(conformance) 7 | add_subdirectory(qmqttconnectionproperties) 8 | add_subdirectory(qmqttcontrolpacket) 9 | add_subdirectory(qmqttclient) 10 | add_subdirectory(qmqttlastwillproperties) 11 | add_subdirectory(qmqttpublishproperties) 12 | add_subdirectory(qmqttsubscription) 13 | add_subdirectory(qmqttsubscriptionproperties) 14 | add_subdirectory(qmqtttopicname) 15 | add_subdirectory(qmqtttopicfilter) 16 | endif() 17 | -------------------------------------------------------------------------------- /tests/auto/conformance/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_conformance Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_conformance 11 | SOURCES 12 | ../../common/broker_connection.h 13 | tst_conformance.cpp 14 | DEFINES 15 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 16 | INCLUDE_DIRECTORIES 17 | ../../common 18 | LIBRARIES 19 | Qt::MqttPrivate 20 | Qt::Mqtt 21 | Qt::Network 22 | ) 23 | -------------------------------------------------------------------------------- /tests/auto/qmqttclient/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqttclient Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqttclient 11 | SOURCES 12 | ../../common/broker_connection.h 13 | tst_qmqttclient.cpp 14 | DEFINES 15 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 16 | INCLUDE_DIRECTORIES 17 | ../../common 18 | LIBRARIES 19 | Qt::MqttPrivate 20 | Qt::Mqtt 21 | Qt::Network 22 | ) 23 | -------------------------------------------------------------------------------- /tests/auto/qmqttsubscription/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqttsubscription Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqttsubscription 11 | SOURCES 12 | ../../common/broker_connection.h 13 | tst_qmqttsubscription.cpp 14 | DEFINES 15 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 16 | INCLUDE_DIRECTORIES 17 | ../../common 18 | LIBRARIES 19 | Qt::MqttPrivate 20 | Qt::Mqtt 21 | Qt::Network 22 | ) 23 | -------------------------------------------------------------------------------- /examples/mqtt/quickpublication/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include 5 | #include 6 | 7 | using namespace Qt::StringLiterals; 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | QGuiApplication app(argc, argv); 12 | QQmlApplicationEngine engine; 13 | 14 | QObject::connect( 15 | &engine, &QQmlApplicationEngine::objectCreationFailed, &app, 16 | []() { QCoreApplication::exit(EXIT_FAILURE); }, Qt::QueuedConnection); 17 | 18 | engine.loadFromModule(u"publication"_s, u"Main"_s); 19 | 20 | return QGuiApplication::exec(); 21 | } 22 | -------------------------------------------------------------------------------- /tests/auto/qmqttpublishproperties/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqttpublishproperties Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqttpublishproperties 11 | SOURCES 12 | ../../common/broker_connection.h 13 | tst_qmqttpublishproperties.cpp 14 | DEFINES 15 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 16 | INCLUDE_DIRECTORIES 17 | ../../common 18 | LIBRARIES 19 | Qt::MqttPrivate 20 | Qt::Mqtt 21 | Qt::Network 22 | ) 23 | -------------------------------------------------------------------------------- /examples/mqtt/quicksubscription/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include 5 | #include 6 | 7 | using namespace Qt::StringLiterals; 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | QGuiApplication app(argc, argv); 12 | QQmlApplicationEngine engine; 13 | 14 | QObject::connect( 15 | &engine, &QQmlApplicationEngine::objectCreationFailed, &app, 16 | []() { QCoreApplication::exit(EXIT_FAILURE); }, Qt::QueuedConnection); 17 | 18 | engine.loadFromModule(u"subscription"_s, u"Main"_s); 19 | 20 | return QGuiApplication::exec(); 21 | } 22 | -------------------------------------------------------------------------------- /tests/auto/qmqttlastwillproperties/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqttlastwillproperties Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqttlastwillproperties 11 | SOURCES 12 | ../../common/broker_connection.h 13 | tst_qmqttlastwillproperties.cpp 14 | DEFINES 15 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 16 | INCLUDE_DIRECTORIES 17 | ../../common 18 | LIBRARIES 19 | Qt::MqttPrivate 20 | Qt::Mqtt 21 | Qt::Network 22 | ) 23 | -------------------------------------------------------------------------------- /tests/auto/qmqttconnectionproperties/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqttconnectionproperties Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqttconnectionproperties 11 | SOURCES 12 | ../../common/broker_connection.h 13 | tst_qmqttconnectionproperties.cpp 14 | DEFINES 15 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 16 | INCLUDE_DIRECTORIES 17 | ../../common 18 | LIBRARIES 19 | Qt::MqttPrivate 20 | Qt::Mqtt 21 | Qt::Network 22 | ) 23 | -------------------------------------------------------------------------------- /tests/auto/qmqttsubscriptionproperties/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## tst_qmqttsubscriptionproperties Test: 6 | ##################################################################### 7 | 8 | qtmqtt_add_test( 9 | TARGET 10 | tst_qmqttsubscriptionproperties 11 | SOURCES 12 | ../../common/broker_connection.h 13 | tst_qmqttsubscriptionproperties.cpp 14 | DEFINES 15 | SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" 16 | INCLUDE_DIRECTORIES 17 | ../../common 18 | LIBRARIES 19 | Qt::MqttPrivate 20 | Qt::Mqtt 21 | Qt::Network 22 | ) 23 | -------------------------------------------------------------------------------- /src/mqtt/qmqttglobal_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QTQMQTTGLOBAL_P_H 6 | #define QTQMQTTGLOBAL_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | #include 21 | 22 | QT_BEGIN_NAMESPACE 23 | 24 | Q_DECLARE_LOGGING_CATEGORY(lcMqttClient) 25 | 26 | QT_END_NAMESPACE 27 | 28 | #endif // QTQMQTTGLOBAL_P_H 29 | -------------------------------------------------------------------------------- /dist/changes-5.15.0: -------------------------------------------------------------------------------- 1 | Qt 5.15 introduces many new features and improvements as well as bugfixes 2 | over the 5.14.x series. For more details, refer to the online documentation 3 | included in this distribution. The documentation is also available online: 4 | 5 | https://doc.qt.io/qt-5/index.html 6 | 7 | The Qt version 5.15 series is binary compatible with the 5.14.x series. 8 | Applications compiled for 5.14 will continue to run with 5.15. 9 | 10 | Some of the changes listed in this file include issue tracking numbers 11 | corresponding to tasks in the Qt Bug Tracker: 12 | 13 | https://bugreports.qt.io/ 14 | 15 | Each of these identifiers can be entered in the bug tracker to obtain more 16 | information about a particular change. 17 | 18 | - This release contains only minor code improvements. 19 | -------------------------------------------------------------------------------- /dist/changes-5.14.1: -------------------------------------------------------------------------------- 1 | Qt 5.14.1 is a bug-fix release. It maintains both forward and backward 2 | compatibility (source and binary) with Qt 5.14.0. 3 | 4 | For more details, refer to the online documentation included in this 5 | distribution. The documentation is also available online: 6 | 7 | https://doc.qt.io/qt-5/index.html 8 | 9 | The Qt version 5.14 series is binary compatible with the 5.13.x series. 10 | Applications compiled for 5.13 will continue to run with 5.14. 11 | 12 | Some of the changes listed in this file include issue tracking numbers 13 | corresponding to tasks in the Qt Bug Tracker: 14 | 15 | https://bugreports.qt.io/ 16 | 17 | Each of these identifiers can be entered in the bug tracker to obtain more 18 | information about a particular change. 19 | 20 | - This release contains only minor code improvements. 21 | -------------------------------------------------------------------------------- /dist/changes-5.15.1: -------------------------------------------------------------------------------- 1 | Qt 5.15.1 is a bug-fix release. It maintains both forward and backward 2 | compatibility (source and binary) with Qt 5.15.0. 3 | 4 | For more details, refer to the online documentation included in this 5 | distribution. The documentation is also available online: 6 | 7 | https://doc.qt.io/qt-5/index.html 8 | 9 | The Qt version 5.15 series is binary compatible with the 5.14.x series. 10 | Applications compiled for 5.14 will continue to run with 5.15. 11 | 12 | Some of the changes listed in this file include issue tracking numbers 13 | corresponding to tasks in the Qt Bug Tracker: 14 | 15 | https://bugreports.qt.io/ 16 | 17 | Each of these identifiers can be entered in the bug tracker to obtain more 18 | information about a particular change. 19 | 20 | - This release contains only minor code improvements. 21 | -------------------------------------------------------------------------------- /dist/changes-5.14.2: -------------------------------------------------------------------------------- 1 | Qt 5.14.2 is a bug-fix release. It maintains both forward and backward 2 | compatibility (source and binary) with Qt 5.14.0 through 5.14.1. 3 | 4 | For more details, refer to the online documentation included in this 5 | distribution. The documentation is also available online: 6 | 7 | https://doc.qt.io/qt-5/index.html 8 | 9 | The Qt version 5.14 series is binary compatible with the 5.13.x series. 10 | Applications compiled for 5.13 will continue to run with 5.14. 11 | 12 | Some of the changes listed in this file include issue tracking numbers 13 | corresponding to tasks in the Qt Bug Tracker: 14 | 15 | https://bugreports.qt.io/ 16 | 17 | Each of these identifiers can be entered in the bug tracker to obtain more 18 | information about a particular change. 19 | 20 | - This release contains only minor code improvements. 21 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | 6 | include(.cmake.conf) 7 | project(QtMqtt 8 | VERSION "${QT_REPO_MODULE_VERSION}" 9 | DESCRIPTION "Qt Mqtt Libraries" 10 | HOMEPAGE_URL "https://qt.io/" 11 | LANGUAGES CXX C 12 | ) 13 | 14 | find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals) 15 | 16 | # This should be called as early as possible, just after find_package(BuildInternals) where it is 17 | # defined. 18 | qt_internal_project_setup() 19 | 20 | find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core Network) 21 | find_package(Qt6 ${PROJECT_VERSION} CONFIG OPTIONAL_COMPONENTS Quick # For tests 22 | Gui Widgets WebSockets) # For examples 23 | 24 | qt_build_repo() 25 | -------------------------------------------------------------------------------- /coin/module_config.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | accept_configuration: 3 | condition: property 4 | property: features 5 | not_contains_value: Disable 6 | 7 | instructions: 8 | Build: 9 | - type: EnvironmentVariable 10 | variableName: VERIFY_SOURCE_SBOM 11 | variableValue: "ON" 12 | - type: EnvironmentVariable 13 | variableName: COIN_NO_MOSQUITTO 14 | variableValue: "1" 15 | enable_if: 16 | condition: and 17 | conditions: 18 | - condition: property 19 | property: host.os 20 | equals_value: Windows 21 | - condition: property 22 | property: target.arch 23 | in_values: ["AARCH64", "ARM64"] 24 | - !include "{{qt/qtbase}}/coin_module_build_template_v2.yaml" 25 | 26 | Test: 27 | - !include "{{qt/qtbase}}/coin_module_test_template_v2.yaml" 28 | - !include "{{qt/qtbase}}/coin_module_test_docs.yaml" 29 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/subscriptionwindow.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #ifndef SUBSCRIPTIONWINDOW_H 5 | #define SUBSCRIPTIONWINDOW_H 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | QT_BEGIN_NAMESPACE 12 | namespace Ui { 13 | class SubscriptionWindow; 14 | } 15 | QT_END_NAMESPACE 16 | 17 | class SubscriptionWindow : public QWidget 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | explicit SubscriptionWindow(QMqttSubscription *sub, QWidget *parent = nullptr); 23 | ~SubscriptionWindow(); 24 | 25 | public slots: 26 | void updateMessage(const QMqttMessage &msg); 27 | void updateStatus(QMqttSubscription::SubscriptionState state); 28 | private: 29 | Ui::SubscriptionWindow *ui; 30 | QMqttSubscription *m_sub; 31 | }; 32 | 33 | #endif // SUBSCRIPTIONWINDOW_H 34 | -------------------------------------------------------------------------------- /tests/README.txt: -------------------------------------------------------------------------------- 1 | The tests included in the subdirectories check for functionality and 2 | conformance of the Qt MQTT module. 3 | 4 | To be able to run the tests successfully, a broker needs to be available and 5 | reachable. 6 | 7 | The continuous integration utilized the paho conformance test broker. It can 8 | be obtained at this location: 9 | https://github.com/eclipse/paho.mqtt.testing 10 | 11 | For the unit tests being able to locate this script, use the 12 | MQTT_TEST_BROKER_LOCATION environment variable and set it 13 | to “/interoperability/startbroker.py”. 14 | 15 | Alternatively, any broker can be instantiated and passed to the auto tests 16 | by using the environment variable MQTT_TEST_BROKER. This must point to a 17 | valid url. The broker must run on the standardized port 1883. 18 | 19 | Note, that the unit tests verify functionality against the MQTT 3.1.1 version 20 | of the standard, hence the broker needs to be compliant to the adherent 21 | specifications. 22 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/mainwindow.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #ifndef MAINWINDOW_H 5 | #define MAINWINDOW_H 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | QT_BEGIN_NAMESPACE 12 | namespace Ui { 13 | class MainWindow; 14 | } 15 | QT_END_NAMESPACE 16 | 17 | class MainWindow : public QMainWindow 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | explicit MainWindow(QWidget *parent = nullptr); 23 | ~MainWindow(); 24 | 25 | public slots: 26 | void setClientPort(int p); 27 | 28 | private slots: 29 | void on_buttonConnect_clicked(); 30 | void on_buttonQuit_clicked(); 31 | void updateLogStateChange(); 32 | 33 | void brokerDisconnected(); 34 | 35 | void on_buttonPublish_clicked(); 36 | 37 | void on_buttonSubscribe_clicked(); 38 | 39 | private: 40 | Ui::MainWindow *ui; 41 | QMqttClient *m_client; 42 | }; 43 | 44 | #endif // MAINWINDOW_H 45 | -------------------------------------------------------------------------------- /examples/mqtt/simpleclient/simpleclient.pro: -------------------------------------------------------------------------------- 1 | QT += core gui network mqtt 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 | 5 | TARGET = simplemqttclient 6 | TEMPLATE = app 7 | 8 | # The following define makes your compiler emit warnings if you use 9 | # any feature of Qt which as been marked as deprecated (the exact warnings 10 | # depend on your compiler). Please consult the documentation of the 11 | # deprecated API in order to know how to port your code away from it. 12 | DEFINES += QT_DEPRECATED_WARNINGS 13 | 14 | # You can also make your code fail to compile if you use deprecated APIs. 15 | # In order to do so, uncomment the following line. 16 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 17 | #DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x060000 # disables all APIs deprecated in Qt 6.0.0 and earlier 18 | 19 | 20 | SOURCES += main.cpp\ 21 | mainwindow.cpp 22 | 23 | HEADERS += mainwindow.h 24 | FORMS += mainwindow.ui 25 | 26 | target.path = $$[QT_INSTALL_EXAMPLES]/mqtt/simpleclient 27 | INSTALLS += target 28 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/subscriptions.pro: -------------------------------------------------------------------------------- 1 | QT += core gui network widgets mqtt 2 | 3 | TARGET = mqttsubscriptions 4 | 5 | # The following define makes your compiler emit warnings if you use 6 | # any feature of Qt which as been marked as deprecated (the exact warnings 7 | # depend on your compiler). Please consult the documentation of the 8 | # deprecated API in order to know how to port your code away from it. 9 | DEFINES += QT_DEPRECATED_WARNINGS 10 | 11 | # You can also make your code fail to compile if you use deprecated APIs. 12 | # In order to do so, uncomment the following line. 13 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 14 | #DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x060000 # disables all APIs deprecated in Qt 6.0.0 and earlier 15 | 16 | 17 | SOURCES += main.cpp\ 18 | mainwindow.cpp \ 19 | subscriptionwindow.cpp 20 | 21 | HEADERS += mainwindow.h \ 22 | subscriptionwindow.h 23 | FORMS += mainwindow.ui \ 24 | subscriptionwindow.ui 25 | 26 | target.path = $$[QT_INSTALL_EXAMPLES]/mqtt/subscriptions 27 | INSTALLS += target 28 | -------------------------------------------------------------------------------- /dist/changes-5.11.0: -------------------------------------------------------------------------------- 1 | Qt 5.11 introduces many new features and improvements as well as bugfixes 2 | over the 5.10.x series. For more details, refer to the online documentation 3 | included in this distribution. The documentation is also available online: 4 | 5 | http://doc.qt.io/qt-5/index.html 6 | 7 | The Qt version 5.11 series is binary compatible with the 5.10.x series. 8 | Applications compiled for 5.10 will continue to run with 5.11. 9 | 10 | Some of the changes listed in this file include issue tracking numbers 11 | corresponding to tasks in the Qt Bug Tracker: 12 | 13 | https://bugreports.qt.io/ 14 | 15 | Each of these identifiers can be entered in the bug tracker to obtain more 16 | information about a particular change. 17 | 18 | **************************************************************************** 19 | * Qt 5.11.0 Changes * 20 | **************************************************************************** 21 | 22 | QtMQTT 23 | ----------- 24 | 25 | - [QTBUG-66955] Fixed connection for already opened QIODevice based 26 | transport layers. 27 | -------------------------------------------------------------------------------- /examples/mqtt/websocketsubscription/clientsubscription.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #ifndef CLIENTSUBSCRIPTION_H 5 | #define CLIENTSUBSCRIPTION_H 6 | 7 | #include "websocketiodevice.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class ClientSubscription : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | ClientSubscription(QObject *parent = nullptr); 18 | 19 | void setUrl(const QUrl &url); // ie ws://broker.hivemq.com:8000/mqtt 20 | void setTopic(const QString &topic); 21 | void setVersion(int v); 22 | signals: 23 | void messageReceived(QByteArray); 24 | void errorOccured(); 25 | 26 | public slots: 27 | void connectAndSubscribe(); 28 | void handleMessage(const QByteArray &msgContent); 29 | 30 | private: 31 | QMqttClient m_client; 32 | QMqttSubscription *m_subscription; 33 | QUrl m_url; 34 | QString m_topic; 35 | WebSocketIODevice m_device; 36 | int m_version; 37 | }; 38 | 39 | #endif // CLIENTSUBSCRIPTION_H 40 | -------------------------------------------------------------------------------- /dist/changes-5.11.2: -------------------------------------------------------------------------------- 1 | Qt 5.11.2 is a bug-fix release. It maintains both forward and backward 2 | compatibility (source and binary) with Qt 5.11.0 through 5.11.1. 3 | 4 | For more details, refer to the online documentation included in this 5 | distribution. The documentation is also available online: 6 | 7 | http://doc.qt.io/qt-5/index.html 8 | 9 | The Qt version 5.11 series is binary compatible with the 5.10.x series. 10 | Applications compiled for 5.10 will continue to run with 5.11. 11 | 12 | Some of the changes listed in this file include issue tracking numbers 13 | corresponding to tasks in the Qt Bug Tracker: 14 | 15 | https://bugreports.qt.io/ 16 | 17 | Each of these identifiers can be entered in the bug tracker to obtain more 18 | information about a particular change. 19 | 20 | **************************************************************************** 21 | * Qt 5.11.2 Changes * 22 | **************************************************************************** 23 | 24 | - [QTBUG-68343] Fixed CMake unit tests 25 | - [QTBUG-68614] Fixed connection problems for manual secure transports 26 | -------------------------------------------------------------------------------- /dist/changes-5.14.0: -------------------------------------------------------------------------------- 1 | Qt 5.14 introduces many new features and improvements as well as bugfixes 2 | over the 5.13.x series. For more details, refer to the online documentation 3 | included in this distribution. The documentation is also available online: 4 | 5 | https://doc.qt.io/qt-5/index.html 6 | 7 | The Qt version 5.14 series is binary compatible with the 5.13.x series. 8 | Applications compiled for 5.13 will continue to run with 5.14. 9 | 10 | Some of the changes listed in this file include issue tracking numbers 11 | corresponding to tasks in the Qt Bug Tracker: 12 | 13 | https://bugreports.qt.io/ 14 | 15 | Each of these identifiers can be entered in the bug tracker to obtain more 16 | information about a particular change. 17 | 18 | **************************************************************************** 19 | * QMqttClient * 20 | **************************************************************************** 21 | 22 | - [QTBUG-73378] Added secure connection with QSslConfiguration 23 | - [QTBUG-76783] Added support for empty last will messages 24 | - Introduce autoKeepAlive property 25 | -------------------------------------------------------------------------------- /examples/mqtt/websocketsubscription/websocketsubscription.pro: -------------------------------------------------------------------------------- 1 | QT += core websockets mqtt 2 | QT -= gui 3 | 4 | CONFIG += c++11 5 | 6 | TARGET = websocketsubscription 7 | CONFIG += console 8 | CONFIG -= app_bundle 9 | 10 | TEMPLATE = app 11 | 12 | SOURCES += main.cpp \ 13 | clientsubscription.cpp \ 14 | websocketiodevice.cpp 15 | 16 | # The following define makes your compiler emit warnings if you use 17 | # any feature of Qt which as been marked deprecated (the exact warnings 18 | # depend on your compiler). Please consult the documentation of the 19 | # deprecated API in order to know how to port your code away from it. 20 | DEFINES += QT_DEPRECATED_WARNINGS 21 | 22 | # You can also make your code fail to compile if you use deprecated APIs. 23 | # In order to do so, uncomment the following line. 24 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 25 | #DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x060000 # disables all APIs deprecated in Qt 6.0.0 and earlier 26 | 27 | target.path = $$[QT_INSTALL_EXAMPLES]/mqtt/websocketsubscription 28 | INSTALLS += target 29 | 30 | HEADERS += \ 31 | clientsubscription.h \ 32 | websocketiodevice.h 33 | -------------------------------------------------------------------------------- /examples/mqtt/websocketsubscription/websocketiodevice.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #ifndef WEBSOCKETIODEVICE_H 5 | #define WEBSOCKETIODEVICE_H 6 | 7 | #include 8 | #include 9 | 10 | class WebSocketIODevice : public QIODevice 11 | { 12 | Q_OBJECT 13 | public: 14 | WebSocketIODevice(QObject *parent = nullptr); 15 | 16 | bool isSequential() const override; 17 | qint64 bytesAvailable() const override; 18 | 19 | bool open(OpenMode mode) override; 20 | void close() override; 21 | 22 | qint64 readData(char *data, qint64 maxlen) override; 23 | qint64 writeData(const char *data, qint64 len) override; 24 | 25 | void setUrl(const QUrl &url); 26 | void setProtocol(const QByteArray &data); 27 | Q_SIGNALS: 28 | void socketConnected(); 29 | 30 | public slots: 31 | void handleBinaryMessage(const QByteArray &msg); 32 | void onSocketConnected(); 33 | 34 | private: 35 | QByteArray m_protocol; 36 | QByteArray m_buffer; 37 | QWebSocket m_socket; 38 | QUrl m_url; 39 | }; 40 | 41 | #endif // WEBSOCKETIODEVICE_H 42 | -------------------------------------------------------------------------------- /coin/axivion/ci_config_linux.json: -------------------------------------------------------------------------------- 1 | { 2 | "Project": { 3 | "BuildSystemIntegration": { 4 | "child_order": [ 5 | "GCCSetup", 6 | "CMake", 7 | "LinkLibraries" 8 | ] 9 | }, 10 | "CMake": { 11 | "_active": true, 12 | "_copy_from": "CMakeIntegration", 13 | "build_environment": {}, 14 | "build_options": "-j4", 15 | "generate_options": "--fresh", 16 | "generator": "Ninja" 17 | }, 18 | "GCCSetup": { 19 | "_active": true, 20 | "_copy_from": "Command", 21 | "build_command": "gccsetup --cc gcc --cxx g++ --config ../../../axivion/" 22 | }, 23 | "LinkLibraries": { 24 | "_active": true, 25 | "_copy_from": "AxivionLinker", 26 | "input_files": [ 27 | "build/lib/lib*.so*.ir" 28 | ], 29 | "ir": "build/$(env:TESTED_MODULE_COIN).ir" 30 | } 31 | }, 32 | "_Format": "1.0", 33 | "_Version": "7.6.2", 34 | "_VersionNum": [ 35 | 7, 36 | 6, 37 | 2, 38 | 12725 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /dist/changes-5.15.2: -------------------------------------------------------------------------------- 1 | Qt 5.15.2 is a bug-fix release. It maintains both forward and backward 2 | compatibility (source and binary) with Qt 5.15.1. 3 | 4 | For more details, refer to the online documentation included in this 5 | distribution. The documentation is also available online: 6 | 7 | https://doc.qt.io/qt-5.15/index.html 8 | 9 | The Qt version 5.15 series is binary compatible with the 5.14.x series. 10 | Applications compiled for 5.14 will continue to run with 5.15. 11 | 12 | Some of the changes listed in this file include issue tracking numbers 13 | corresponding to tasks in the Qt Bug Tracker: 14 | 15 | https://bugreports.qt.io/ 16 | 17 | Each of these identifiers can be entered in the bug tracker to obtain more 18 | information about a particular change. 19 | 20 | **************************************************************************** 21 | * Important Behavior Changes * 22 | **************************************************************************** 23 | 24 | **************************************************************************** 25 | * Library * 26 | **************************************************************************** 27 | 28 | 29 | -------------------------------------------------------------------------------- /dist/changes-5.12.0: -------------------------------------------------------------------------------- 1 | Qt 5.12 introduces many new features and improvements as well as bugfixes 2 | over the 5.11.x series. For more details, refer to the online documentation 3 | included in this distribution. The documentation is also available online: 4 | 5 | http://doc.qt.io/qt-5/index.html 6 | 7 | The Qt version 5.12 series is binary compatible with the 5.11.x series. 8 | Applications compiled for 5.11 will continue to run with 5.12. 9 | 10 | Some of the changes listed in this file include issue tracking numbers 11 | corresponding to tasks in the Qt Bug Tracker: 12 | 13 | https://bugreports.qt.io/ 14 | 15 | Each of these identifiers can be entered in the bug tracker to obtain more 16 | information about a particular change. 17 | 18 | **************************************************************************** 19 | * Qt 5.12.0 Changes * 20 | **************************************************************************** 21 | 22 | QtMQTT 23 | ----------- 24 | 25 | - Added support for MQTT protocol level 5. 26 | - [QTBUG-67176] Fixed property overwrite during established connection. 27 | - [QTBUG-68614] Fixed management of manually specified secure connection. 28 | - [QTBUG-69642] Fixed buffer reading for string data. 29 | -------------------------------------------------------------------------------- /dist/changes-5.12.10: -------------------------------------------------------------------------------- 1 | Qt 5.12.10 is a bug-fix release. It maintains both forward and backward 2 | compatibility (source and binary) with Qt 5.12.9. 3 | 4 | For more details, refer to the online documentation included in this 5 | distribution. The documentation is also available online: 6 | 7 | https://doc.qt.io/qt-5.12/index.html 8 | 9 | The Qt version 5.12 series is binary compatible with the 5.11.x series. 10 | Applications compiled for 5.11 will continue to run with 5.12. 11 | 12 | Some of the changes listed in this file include issue tracking numbers 13 | corresponding to tasks in the Qt Bug Tracker: 14 | 15 | https://bugreports.qt.io/ 16 | 17 | Each of these identifiers can be entered in the bug tracker to obtain more 18 | information about a particular change. 19 | 20 | **************************************************************************** 21 | * Important Behavior Changes * 22 | **************************************************************************** 23 | 24 | **************************************************************************** 25 | * Library * 26 | **************************************************************************** 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/mqtt/websocketsubscription/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | project(websocketsubscription LANGUAGES CXX) 6 | 7 | set(CMAKE_AUTOMOC ON) 8 | 9 | if(NOT DEFINED INSTALL_EXAMPLESDIR) 10 | set(INSTALL_EXAMPLESDIR "examples") 11 | endif() 12 | 13 | set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/mqtt/websocketsubscription") 14 | 15 | find_package(Qt6 REQUIRED COMPONENTS Core Mqtt WebSockets) 16 | 17 | qt_add_executable(websocketsubscription 18 | clientsubscription.cpp clientsubscription.h 19 | main.cpp 20 | websocketiodevice.cpp websocketiodevice.h 21 | ) 22 | 23 | set_target_properties(websocketsubscription PROPERTIES 24 | WIN32_EXECUTABLE FALSE 25 | MACOSX_BUNDLE FALSE 26 | ) 27 | 28 | target_compile_definitions(websocketsubscription PUBLIC 29 | QT_DEPRECATED_WARNINGS 30 | ) 31 | 32 | target_link_libraries(websocketsubscription PUBLIC 33 | Qt::Core 34 | Qt::Mqtt 35 | Qt::WebSockets 36 | ) 37 | 38 | install(TARGETS websocketsubscription 39 | RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" 40 | BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" 41 | LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" 42 | ) 43 | -------------------------------------------------------------------------------- /examples/mqtt/simpleclient/mainwindow.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #ifndef MAINWINDOW_H 5 | #define MAINWINDOW_H 6 | 7 | #include 8 | #include 9 | 10 | QT_BEGIN_NAMESPACE 11 | namespace Ui { 12 | class MainWindow; 13 | } 14 | QT_END_NAMESPACE 15 | 16 | class MainWindow : public QMainWindow 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit MainWindow(QWidget *parent = nullptr); 22 | ~MainWindow(); 23 | 24 | public slots: 25 | void setClientPort(int p); 26 | void setSecure(bool s); 27 | void setWebSockets(bool ws); 28 | void setProtocol(QMqttClient::ProtocolVersion p); 29 | private slots: 30 | void on_buttonConnect_clicked(); 31 | void on_buttonQuit_clicked(); 32 | void updateLogStateChange(); 33 | 34 | void brokerDisconnected(); 35 | 36 | void on_buttonPublish_clicked(); 37 | 38 | void on_buttonSubscribe_clicked(); 39 | 40 | private: 41 | Ui::MainWindow *ui = nullptr; 42 | QMqttClient *m_client = nullptr; 43 | bool m_secure = false; 44 | bool m_webSockets = false; 45 | QMqttClient::ProtocolVersion m_protocol = QMqttClient::ProtocolVersion::MQTT_3_1_1; 46 | }; 47 | 48 | #endif // MAINWINDOW_H 49 | -------------------------------------------------------------------------------- /examples/mqtt/quicksubscription/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | project(quicksubscription LANGUAGES CXX) 6 | 7 | if(NOT DEFINED INSTALL_EXAMPLESDIR) 8 | set(INSTALL_EXAMPLESDIR "examples") 9 | endif() 10 | 11 | set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/mqtt/quicksubscription") 12 | 13 | find_package(Qt6 REQUIRED COMPONENTS Core Gui Mqtt Qml Quick) 14 | 15 | qt_standard_project_setup(REQUIRES 6.5) 16 | 17 | qt_add_executable(quicksubscription 18 | WIN32 19 | MACOSX_BUNDLE 20 | main.cpp 21 | ) 22 | 23 | target_compile_definitions(quicksubscription PUBLIC 24 | QT_DEPRECATED_WARNINGS 25 | ) 26 | 27 | target_link_libraries(quicksubscription PRIVATE 28 | Qt::Core 29 | Qt::Gui 30 | Qt::Mqtt 31 | Qt::Qml 32 | Qt::Quick 33 | ) 34 | 35 | qt_add_qml_module(quicksubscription 36 | URI subscription 37 | QML_FILES 38 | "Main.qml" 39 | SOURCES 40 | qmlmqttclient.cpp qmlmqttclient.h 41 | ) 42 | 43 | install(TARGETS quicksubscription 44 | RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" 45 | BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" 46 | LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" 47 | ) 48 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | project(mqttsubscriptions LANGUAGES CXX) 6 | 7 | set(CMAKE_AUTOMOC ON) 8 | set(CMAKE_AUTOUIC ON) 9 | 10 | if(NOT DEFINED INSTALL_EXAMPLESDIR) 11 | set(INSTALL_EXAMPLESDIR "examples") 12 | endif() 13 | 14 | set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/mqtt/subscriptions") 15 | 16 | find_package(Qt6 REQUIRED COMPONENTS Core Gui Mqtt Network Widgets) 17 | 18 | qt_add_executable(mqttsubscriptions 19 | main.cpp 20 | mainwindow.cpp mainwindow.h mainwindow.ui 21 | subscriptionwindow.cpp subscriptionwindow.h subscriptionwindow.ui 22 | ) 23 | 24 | set_target_properties(mqttsubscriptions PROPERTIES 25 | WIN32_EXECUTABLE TRUE 26 | MACOSX_BUNDLE TRUE 27 | ) 28 | 29 | target_compile_definitions(mqttsubscriptions PUBLIC 30 | QT_DEPRECATED_WARNINGS 31 | ) 32 | 33 | target_link_libraries(mqttsubscriptions PUBLIC 34 | Qt::Core 35 | Qt::Gui 36 | Qt::Mqtt 37 | Qt::Network 38 | Qt::Widgets 39 | ) 40 | 41 | install(TARGETS mqttsubscriptions 42 | RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" 43 | BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" 44 | LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" 45 | ) 46 | -------------------------------------------------------------------------------- /src/mqtt/qmqttsubscription_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTSUBSCRIPTION_P_H 6 | #define QMQTTSUBSCRIPTION_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include "qmqttsubscription.h" 20 | #include 21 | 22 | QT_BEGIN_NAMESPACE 23 | 24 | class QMqttSubscriptionPrivate : public QObjectPrivate 25 | { 26 | Q_DECLARE_PUBLIC(QMqttSubscription) 27 | public: 28 | QMqttSubscriptionPrivate(); 29 | ~QMqttSubscriptionPrivate() override = default; 30 | QMqttClient *m_client{nullptr}; 31 | QMqttTopicFilter m_topic; 32 | QString m_reasonString; 33 | QMqttUserProperties m_userProperties; 34 | QString m_sharedSubscriptionName; 35 | QMqttSubscription::SubscriptionState m_state{QMqttSubscription::Unsubscribed}; 36 | QMqtt::ReasonCode m_reasonCode{QMqtt::ReasonCode::Success}; 37 | quint8 m_qos{0}; 38 | bool m_shared{false}; 39 | }; 40 | 41 | QT_END_NAMESPACE 42 | 43 | #endif // QMQTTSUBSCRIPTION_P_H 44 | -------------------------------------------------------------------------------- /examples/mqtt/quickpublication/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | project(quickpublication LANGUAGES CXX) 6 | 7 | if(NOT DEFINED INSTALL_EXAMPLESDIR) 8 | set(INSTALL_EXAMPLESDIR "examples") 9 | endif() 10 | 11 | set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/mqtt/quickpublication") 12 | 13 | find_package(Qt6 REQUIRED COMPONENTS Core Gui Mqtt Qml Quick) 14 | 15 | qt_standard_project_setup(REQUIRES 6.5) 16 | 17 | qt_add_executable(quickpublication 18 | WIN32 19 | MACOSX_BUNDLE 20 | main.cpp 21 | ) 22 | 23 | set_target_properties(quickpublication PROPERTIES 24 | WIN32_EXECUTABLE TRUE 25 | MACOSX_BUNDLE TRUE 26 | ) 27 | 28 | target_compile_definitions(quickpublication PUBLIC 29 | QT_DEPRECATED_WARNINGS 30 | ) 31 | 32 | target_link_libraries(quickpublication PRIVATE 33 | Qt::Core 34 | Qt::Gui 35 | Qt::Mqtt 36 | Qt::Qml 37 | Qt::Quick 38 | ) 39 | 40 | qt_add_qml_module(quickpublication 41 | URI publication 42 | QML_FILES 43 | "Main.qml" 44 | SOURCES 45 | qmlmqttclient.cpp qmlmqttclient.h 46 | ) 47 | 48 | install(TARGETS quickpublication 49 | RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" 50 | BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" 51 | LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" 52 | ) 53 | -------------------------------------------------------------------------------- /dist/changes-5.13.1: -------------------------------------------------------------------------------- 1 | Qt 5.13.1 is a bug-fix release. It maintains both forward and backward 2 | compatibility (source and binary) with Qt 5.13.0. 3 | 4 | For more details, refer to the online documentation included in this 5 | distribution. The documentation is also available online: 6 | 7 | https://doc.qt.io/qt-5/index.html 8 | 9 | The Qt version 5.13 series is binary compatible with the 5.12.x series. 10 | Applications compiled for 5.12 will continue to run with 5.13. 11 | 12 | Some of the changes listed in this file include issue tracking numbers 13 | corresponding to tasks in the Qt Bug Tracker: 14 | 15 | https://bugreports.qt.io/ 16 | 17 | Each of these identifiers can be entered in the bug tracker to obtain more 18 | information about a particular change. 19 | 20 | **************************************************************************** 21 | * General * 22 | **************************************************************************** 23 | - [QTBUG-76783] Allow will messages with an empty payload. 24 | 25 | **************************************************************************** 26 | * Documentation * 27 | **************************************************************************** 28 | - Improve documentation about keepAlive interval granularity. 29 | - Improve documentation on maximumReceive 30 | -------------------------------------------------------------------------------- /examples/mqtt/simpleclient/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | project(simplemqttclient LANGUAGES CXX) 6 | 7 | set(CMAKE_AUTOMOC ON) 8 | set(CMAKE_AUTOUIC ON) 9 | 10 | if(NOT DEFINED INSTALL_EXAMPLESDIR) 11 | set(INSTALL_EXAMPLESDIR "examples") 12 | endif() 13 | 14 | set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/mqtt/simpleclient") 15 | 16 | find_package(Qt6 REQUIRED COMPONENTS Core Gui Mqtt Network Widgets) 17 | 18 | qt_add_executable(simplemqttclient 19 | main.cpp 20 | mainwindow.cpp mainwindow.h mainwindow.ui 21 | ) 22 | 23 | set_target_properties(simplemqttclient PROPERTIES 24 | WIN32_EXECUTABLE TRUE 25 | MACOSX_BUNDLE TRUE 26 | ) 27 | 28 | target_compile_definitions(simplemqttclient PUBLIC 29 | QT_DEPRECATED_WARNINGS 30 | ) 31 | 32 | target_link_libraries(simplemqttclient PUBLIC 33 | Qt::Core 34 | Qt::Gui 35 | Qt::Mqtt 36 | Qt::Network 37 | ) 38 | 39 | target_link_libraries(simplemqttclient PUBLIC Qt::Widgets) 40 | 41 | if((QT_MAJOR_VERSION GREATER 4)) 42 | target_link_libraries(simplemqttclient PUBLIC 43 | Qt::Widgets 44 | ) 45 | endif() 46 | 47 | install(TARGETS simplemqttclient 48 | RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" 49 | BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" 50 | LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" 51 | ) 52 | -------------------------------------------------------------------------------- /src/mqtt/qmqtttype.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTTYPE_H 6 | #define QMQTTTYPE_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | QT_BEGIN_NAMESPACE 17 | 18 | class QMqttStringPairData; 19 | class Q_MQTT_EXPORT QMqttStringPair 20 | { 21 | public: 22 | QMqttStringPair(); 23 | QMqttStringPair(const QString &name, const QString &value); 24 | QMqttStringPair(const QMqttStringPair &); 25 | ~QMqttStringPair(); 26 | 27 | QString name() const; 28 | void setName(const QString &n); 29 | 30 | QString value() const; 31 | void setValue(const QString &v); 32 | 33 | bool operator==(const QMqttStringPair &other) const; 34 | bool operator!=(const QMqttStringPair &other) const; 35 | QMqttStringPair &operator=(const QMqttStringPair &); 36 | private: 37 | QSharedDataPointer data; 38 | }; 39 | 40 | #ifndef QT_NO_DEBUG_STREAM 41 | Q_MQTT_EXPORT QDebug operator<<(QDebug d, const QMqttStringPair &s); 42 | #endif 43 | 44 | class Q_MQTT_EXPORT QMqttUserProperties : public QList 45 | { 46 | public: 47 | }; 48 | 49 | QT_END_NAMESPACE 50 | 51 | #endif // QMQTTTYPE_H 52 | -------------------------------------------------------------------------------- /examples/mqtt/quickpublication/quickpublication.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = quickpublication 3 | 4 | QT += qml quick mqtt 5 | CONFIG += qmltypes 6 | 7 | SOURCES += main.cpp \ 8 | qmlmqttclient.cpp 9 | 10 | HEADERS += \ 11 | qmlmqttclient.h 12 | 13 | qml_resources.files = Main.qml qmldir 14 | qml_resources.prefix = /qt/qml/publication 15 | 16 | RESOURCES += qml_resources 17 | 18 | # Additional import path used to resolve QML modules in Qt Creator's code model 19 | QML_IMPORT_PATH = $$pwd/. 20 | QML_IMPORT_NAME = publication 21 | QML_IMPORT_MAJOR_VERSION = 1 22 | 23 | # Additional import path used to resolve QML modules just for Qt Quick Designer 24 | QML_DESIGNER_IMPORT_PATH = 25 | 26 | # The following define makes your compiler emit warnings if you use 27 | # any feature of Qt which as been marked deprecated (the exact warnings 28 | # depend on your compiler). Please consult the documentation of the 29 | # deprecated API in order to know how to port your code away from it. 30 | DEFINES += QT_DEPRECATED_WARNINGS 31 | 32 | # You can also make your code fail to compile if you use deprecated APIs. 33 | # In order to do so, uncomment the following line. 34 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 35 | #DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x060000 # disables all APIs deprecated in Qt 6.0.0 and earlier 36 | 37 | target.path = $$[QT_INSTALL_EXAMPLES]/mqtt/quickpublication 38 | INSTALLS += target 39 | -------------------------------------------------------------------------------- /examples/mqtt/quicksubscription/quicksubscription.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = quicksubscription 3 | 4 | QT += qml quick mqtt 5 | CONFIG += qmltypes 6 | 7 | SOURCES += main.cpp \ 8 | qmlmqttclient.cpp 9 | 10 | HEADERS += \ 11 | qmlmqttclient.h 12 | 13 | qml_resources.files = Main.qml qmldir 14 | qml_resources.prefix = /qt/qml/subscription 15 | 16 | RESOURCES += qml_resources 17 | 18 | # Additional import path used to resolve QML modules in Qt Creator's code model 19 | QML_IMPORT_PATH = $$pwd/. 20 | QML_IMPORT_NAME = subscription 21 | QML_IMPORT_MAJOR_VERSION = 1 22 | 23 | # Additional import path used to resolve QML modules just for Qt Quick Designer 24 | QML_DESIGNER_IMPORT_PATH = 25 | 26 | # The following define makes your compiler emit warnings if you use 27 | # any feature of Qt which as been marked deprecated (the exact warnings 28 | # depend on your compiler). Please consult the documentation of the 29 | # deprecated API in order to know how to port your code away from it. 30 | DEFINES += QT_DEPRECATED_WARNINGS 31 | 32 | # You can also make your code fail to compile if you use deprecated APIs. 33 | # In order to do so, uncomment the following line. 34 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 35 | #DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x060000 # disables all APIs deprecated in Qt 6.0.0 and earlier 36 | 37 | target.path = $$[QT_INSTALL_EXAMPLES]/mqtt/quicksubscription 38 | INSTALLS += target 39 | -------------------------------------------------------------------------------- /LICENSES/BSD-3-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 7 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /src/mqtt/qmqttmessage_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTMESSAGE_P_H 6 | #define QMQTTMESSAGE_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include "qmqttglobal.h" 20 | #include "qmqtttopicname.h" 21 | #include "qmqttpublishproperties.h" 22 | 23 | #include 24 | #include 25 | 26 | QT_BEGIN_NAMESPACE 27 | 28 | class QMqttMessagePrivate : public QSharedData 29 | { 30 | public: 31 | bool operator==(const QMqttMessagePrivate &other) const { 32 | return m_topic == other.m_topic 33 | && m_payload == other.m_payload 34 | && m_id == other.m_id 35 | && m_qos == other.m_qos 36 | && m_duplicate == other.m_duplicate 37 | && m_retain == other.m_retain; 38 | } 39 | QMqttTopicName m_topic; 40 | QByteArray m_payload; 41 | quint16 m_id{0}; 42 | quint8 m_qos{0}; 43 | bool m_duplicate{false}; 44 | bool m_retain{false}; 45 | QMqttPublishProperties m_publishProperties; 46 | }; 47 | 48 | QT_END_NAMESPACE 49 | 50 | #endif // QMQTTMESSAGE_P_H 51 | -------------------------------------------------------------------------------- /src/mqtt/qmqttauthenticationproperties.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTAUTHENTICATIONPROPERTIES_H 6 | #define QMQTTAUTHENTICATIONPROPERTIES_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | QT_BEGIN_NAMESPACE 17 | 18 | class QMqttAuthenticationPropertiesData; 19 | 20 | class Q_MQTT_EXPORT QMqttAuthenticationProperties 21 | { 22 | public: 23 | QMqttAuthenticationProperties(); 24 | QMqttAuthenticationProperties(const QMqttAuthenticationProperties &); 25 | QMqttAuthenticationProperties &operator=(const QMqttAuthenticationProperties &); 26 | ~QMqttAuthenticationProperties(); 27 | 28 | QString authenticationMethod() const; 29 | void setAuthenticationMethod(const QString &method); 30 | 31 | QByteArray authenticationData() const; 32 | void setAuthenticationData(const QByteArray &adata); 33 | 34 | QString reason() const; 35 | void setReason(const QString &r); 36 | 37 | QMqttUserProperties userProperties() const; 38 | void setUserProperties(const QMqttUserProperties &user); 39 | 40 | private: 41 | QSharedDataPointer data; 42 | }; 43 | 44 | QT_END_NAMESPACE 45 | 46 | #endif // QMQTTAUTHENTICATIONPROPERTIES_H 47 | -------------------------------------------------------------------------------- /src/mqtt/transportLayers/mqtt_websocket_io.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | #include "mqtt_websocket_io_p.h" 5 | 6 | #ifdef QT_MQTT_WITH_WEBSOCKETS 7 | 8 | QMqttWebSocketIO::~QMqttWebSocketIO() 9 | { 10 | disconnect(m_socket.get(), &QWebSocket::connected, this, &QMqttWebSocketIO::doSocketConnected); 11 | } 12 | 13 | QMqttWebSocketIO::QMqttWebSocketIO(QObject *parent, QWebSocket *webSocket) 14 | : 15 | QMqttWebSocketIOBase(parent, webSocket) 16 | { 17 | connect(m_socket.get(), &QWebSocket::connected, this, &QMqttWebSocketIO::doSocketConnected); 18 | } 19 | 20 | void QMqttWebSocketIO::connectToHost(const QString &hostname, quint16 port, QMqttClient::ProtocolVersion version) 21 | { 22 | setProtocol(version); 23 | if (!isExternalSocket()) { 24 | QUrl url(QString(u"ws://") + hostname + u":" + QString().setNum(port)); 25 | QWebSocketHandshakeOptions options; 26 | options.setSubprotocols(QStringList{ QString::fromUtf8(m_protocol) }); 27 | m_socket->open(url, options); 28 | } 29 | open(QIODevice::ReadWrite); 30 | } 31 | 32 | void QMqttWebSocketIO::close() 33 | { 34 | m_socket->close(); 35 | QMqttWebSocketIOBase::close(); 36 | } 37 | 38 | void QMqttWebSocketIO::doSocketConnected() 39 | { 40 | emit connected(); 41 | } 42 | 43 | #include "moc_mqtt_websocket_io_p.cpp" 44 | 45 | #endif /* QT_MQTT_WITH_WEBSOCKETS */ 46 | -------------------------------------------------------------------------------- /examples/mqtt/quickpublication/qmlmqttclient.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #ifndef QMLMQTTCLIENT_H 5 | #define QMLMQTTCLIENT_H 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | class QmlMqttClient : public QObject 13 | { 14 | Q_OBJECT 15 | Q_PROPERTY(QString hostname READ hostname WRITE setHostname NOTIFY hostnameChanged) 16 | Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged) 17 | Q_PROPERTY(QMqttClient::ClientState state READ state WRITE setState NOTIFY stateChanged) 18 | QML_NAMED_ELEMENT(MqttClient) 19 | QML_EXTENDED_NAMESPACE(QMqttClient) 20 | public: 21 | 22 | QmlMqttClient(QObject *parent = nullptr); 23 | 24 | Q_INVOKABLE void connectToHost(); 25 | Q_INVOKABLE void disconnectFromHost(); 26 | Q_INVOKABLE int publish(const QString &topic, const QString &message, int qos = 0, bool retain = false); 27 | 28 | const QString hostname() const; 29 | void setHostname(const QString &newHostname); 30 | 31 | int port() const; 32 | void setPort(int newPort); 33 | 34 | const QMqttClient::ClientState state() const; 35 | void setState(const QMqttClient::ClientState &newState); 36 | 37 | signals: 38 | void hostnameChanged(); 39 | void portChanged(); 40 | 41 | void stateChanged(); 42 | 43 | private: 44 | Q_DISABLE_COPY(QmlMqttClient) 45 | QMqttClient m_client; 46 | }; 47 | 48 | #endif // QMLMQTTCLIENT_H 49 | -------------------------------------------------------------------------------- /src/mqtt/transportLayers/mqtt_websocket_io_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QTMQTTCLIENT_WEBSOCKET_IODEVICE_H 6 | #define QTMQTTCLIENT_WEBSOCKET_IODEVICE_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #ifdef QT_MQTT_WITH_WEBSOCKETS 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "transportLayers/mqtt_websocket_io_base_p.h" 26 | #include "qmqttclient.h" 27 | 28 | QT_BEGIN_NAMESPACE 29 | 30 | class QMqttWebSocketIO : public QMqttWebSocketIOBase 31 | { 32 | Q_OBJECT 33 | public: 34 | Q_DISABLE_COPY_MOVE(QMqttWebSocketIO) 35 | 36 | ~QMqttWebSocketIO() override; 37 | QMqttWebSocketIO(QObject *parent = nullptr, QWebSocket *webSocket = nullptr); 38 | 39 | void close() override; 40 | 41 | void connectToHost(const QString &hostname, quint16 port, QMqttClient::ProtocolVersion version); 42 | 43 | Q_SIGNALS: 44 | void connected(); 45 | 46 | public slots: 47 | void doSocketConnected(); 48 | }; 49 | 50 | QT_END_NAMESPACE 51 | 52 | #endif /* QT_MQTT_WITH_WEBSOCKETS */ 53 | 54 | #endif /* QTMQTTCLIENT_WEBSOCKET_IODEVICE_H */ 55 | -------------------------------------------------------------------------------- /src/mqtt/transportLayers/mqtt_secure_websocket_io.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | #include "mqtt_secure_websocket_io_p.h" 5 | 6 | #ifdef QT_MQTT_WITH_WEBSOCKETS 7 | 8 | QMqttSecureWebSocketIO::~QMqttSecureWebSocketIO() 9 | { 10 | disconnect(m_socket.get(), &QWebSocket::connected, this, &QMqttSecureWebSocketIO::doSocketEncrypted); 11 | } 12 | 13 | QMqttSecureWebSocketIO::QMqttSecureWebSocketIO(QObject *parent, QWebSocket *webSocket) 14 | : 15 | QMqttWebSocketIOBase(parent, webSocket) 16 | { 17 | connect(m_socket.get(), &QWebSocket::connected, this, &QMqttSecureWebSocketIO::doSocketEncrypted); 18 | } 19 | 20 | void QMqttSecureWebSocketIO::connectToHostEncrypted(const QString &hostname, quint16 port, QMqttClient::ProtocolVersion version) 21 | { 22 | setProtocol(version); 23 | if (!isExternalSocket()) { 24 | QUrl url(QString(u"wss://") + hostname + u":" + QString().setNum(port)); 25 | QWebSocketHandshakeOptions options; 26 | options.setSubprotocols(QStringList{ QString::fromUtf8(m_protocol) }); 27 | m_socket->open(url, options); 28 | } 29 | open(QIODevice::ReadWrite); 30 | } 31 | 32 | void QMqttSecureWebSocketIO::close() 33 | { 34 | m_socket->close(); 35 | QMqttWebSocketIOBase::close(); 36 | } 37 | 38 | void QMqttSecureWebSocketIO::doSocketEncrypted() 39 | { 40 | emit encrypted(); 41 | } 42 | 43 | #include "moc_mqtt_secure_websocket_io_p.cpp" 44 | 45 | #endif /* QT_MQTT_WITH_WEBSOCKETS */ 46 | -------------------------------------------------------------------------------- /src/mqtt/qmqttpublishproperties_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTPUBLISHPROPERTIES_P_H 6 | #define QMQTTPUBLISHPROPERTIES_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include "qmqttglobal_p.h" 20 | #include "qmqttpublishproperties.h" 21 | 22 | #include 23 | #include 24 | 25 | QT_BEGIN_NAMESPACE 26 | 27 | class QMqttPublishPropertiesData : public QSharedData 28 | { 29 | public: 30 | QString responseTopic; 31 | QString contentType; 32 | QByteArray correlationData; 33 | quint32 messageExpiry{0}; 34 | QList subscriptionIdentifier; 35 | QMqttPublishProperties::PublishPropertyDetails details{QMqttPublishProperties::None}; 36 | quint16 topicAlias{0}; 37 | QMqtt::PayloadFormatIndicator payloadIndicator{QMqtt::PayloadFormatIndicator::Unspecified}; 38 | QMqttUserProperties userProperties; 39 | }; 40 | 41 | class QMqttMessageStatusPropertiesData : public QSharedData 42 | { 43 | public: 44 | QMqttUserProperties userProperties; 45 | QString reasonString; 46 | QMqtt::ReasonCode reasonCode{QMqtt::ReasonCode::Success}; 47 | }; 48 | 49 | QT_END_NAMESPACE 50 | 51 | #endif // QMQTTPUBLISHPROPERTIES_P_H 52 | -------------------------------------------------------------------------------- /src/mqtt/transportLayers/mqtt_secure_websocket_io_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QTMQTTCLIENT_SECURE_WEBSOCKET_IODEVICE_H 6 | #define QTMQTTCLIENT_SECURE_WEBSOCKET_IODEVICE_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | #ifdef QT_MQTT_WITH_WEBSOCKETS 19 | 20 | #include 21 | #include 22 | #include 23 | #include "transportLayers/mqtt_websocket_io_base_p.h" 24 | #include "qmqttclient.h" 25 | 26 | QT_BEGIN_NAMESPACE 27 | 28 | class QMqttSecureWebSocketIO : public QMqttWebSocketIOBase 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | Q_DISABLE_COPY_MOVE(QMqttSecureWebSocketIO) 34 | 35 | ~QMqttSecureWebSocketIO() override; 36 | QMqttSecureWebSocketIO(QObject *parent = nullptr, QWebSocket *webSocket = nullptr); 37 | 38 | void close() override; 39 | 40 | void connectToHostEncrypted(const QString &hostname, quint16 port, QMqttClient::ProtocolVersion version); 41 | 42 | Q_SIGNALS: 43 | void encrypted(); 44 | 45 | public slots: 46 | void doSocketEncrypted(); 47 | }; 48 | 49 | QT_END_NAMESPACE 50 | 51 | #endif /* QT_MQTT_WITH_WEBSOCKETS */ 52 | 53 | #endif /* QTMQTTCLIENT_SECURE_WEBSOCKET_IODEVICE_H */ 54 | -------------------------------------------------------------------------------- /tests/certificate/cert.crt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | -----BEGIN CERTIFICATE----- 5 | MIID6zCCAtOgAwIBAgIUbbY+pKEPOOytRZ3RujmmdriEAKcwDQYJKoZIhvcNAQEL 6 | BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv 7 | MQswCQYDVQQKDAJRdDELMAkGA1UECwwCUXQxEjAQBgNVBAMMCWxvY2FsaG9zdDEo 8 | MCYGCSqGSIb3DQEJARYZZXZlbi5vc2Nhci5hbmRlcnNlbkBxdC5pbzAgFw0yNDEw 9 | MzExMTMyNDdaGA8yMTI0MTAwNzExMzI0N1owgYMxCzAJBgNVBAYTAk5PMQ0wCwYD 10 | VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMQswCQYDVQQKDAJRdDELMAkGA1UECwwC 11 | UXQxEjAQBgNVBAMMCWxvY2FsaG9zdDEoMCYGCSqGSIb3DQEJARYZZXZlbi5vc2Nh 12 | ci5hbmRlcnNlbkBxdC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 13 | AJzWmpWU9f/baRi/Fhn362W488HzC2/MUdbTZGIQUqt1TwTLyYMEqkr6WMy/NdYL 14 | 8X5oXW0uz8LttbFp98wJTkNirYBMxowxwWWePnqbK0iKaZTBvBzUh0vWvmtFzHUW 15 | E93K1NtKyL76Zj/EZv0I0CpkWMobpzEW/zquPj83Wxki0xp2rr/HHynqFv8KFMoJ 16 | pR1A6uWtly12V1aQyXZIyMoIUPgDPmsHtNZKBCcz7IsAYHjjfvEIJ+r4lOOsgTXj 17 | cdMU+0hHfyNCy1/6xmBwnchSqDZf3bTyFRu6GK+zzFKBSyt4MB7zQ2P29qYwoNJO 18 | buJkPRfqiQJJRLkwyu59TB0CAwEAAaNTMFEwHQYDVR0OBBYEFGGxHowwihBbJlM5 19 | 2wzicQa2sCfwMB8GA1UdIwQYMBaAFGGxHowwihBbJlM52wzicQa2sCfwMA8GA1Ud 20 | EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACf4lUaBpw65tOZk32EpMD0D 21 | M0ilx1AwfUqliKdhVvkFJ6jN5h17YhVjFoGtSzE7ry5Rg5J07tUK5Xkjcfk39UWV 22 | RofVnRhrtiticXs0eXQkDXqao0aMjUjsWiokr4/cTNT5R3h9jmjzyjA6pWf2oSjT 23 | GTzZAHdcuBTUfvPy/Ff4M5AVNsI6geUqrUd6XzFwQsDWTT86sdWQIC8j+FMghhss 24 | 9XRNOmhWtWGSRbP0HqlWOz5hFRPP/faI/FGTknzkkVYoWaB1CR+ThFK9jYi0FnFL 25 | 2fIcJPt+6g6d01Ws5cb9HpL9joUloCjsZ+w6PXYNVyHTaG3Lg5o4nT1Oizvrq1k= 26 | -----END CERTIFICATE----- 27 | 28 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[annotations]] 4 | path = [".cmake.conf", "**.yaml", "**/ci_config_linux.json", "**.pro", ".tag"] 5 | precedence = "closest" 6 | comment = "build system" 7 | SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." 8 | SPDX-License-Identifier = "BSD-3-Clause" 9 | 10 | [[annotations]] 11 | path = ["**/.gitattributes", "**.gitignore", "**.gitreview"] 12 | precedence = "closest" 13 | comment = "version control system. Infrastructure" 14 | SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." 15 | SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" 16 | 17 | [[annotations]] 18 | path = ["**/doc/images/**", "examples/**"] 19 | comment = "this must be after the build system table because example and snippets take precedence over build system" 20 | precedence = "closest" 21 | SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." 22 | SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" 23 | 24 | [[annotations]] 25 | path = ["**.qdocconf", "src/mqtt/doc/style/style.css", "tests/README.txt"] 26 | comment = "documentation" 27 | precedence = "closest" 28 | SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." 29 | SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only" 30 | 31 | [[annotations]] 32 | path = ["**.toml", "licenseRule.json"] 33 | comment = "infrastructure" 34 | precedence = "override" 35 | SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." 36 | SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" 37 | 38 | [[annotations]] 39 | path = ["**/qt_attribution.json"] 40 | comment = "currently not needed, but ready if such file is added. documentation." 41 | precedence = "override" 42 | SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd." 43 | SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only" 44 | -------------------------------------------------------------------------------- /tests/manual/consolepubsub/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.16) 5 | project(qtmqtt_pub_sub LANGUAGES CXX) 6 | 7 | if (ANDROID) 8 | message(FATAL_ERROR "This project cannot be built on Android.") 9 | endif() 10 | 11 | set(CMAKE_AUTOMOC ON) 12 | 13 | if(NOT DEFINED INSTALL_EXAMPLESDIR) 14 | set(INSTALL_EXAMPLESDIR "examples") 15 | endif() 16 | 17 | set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/mqtt/consolepubsub") 18 | 19 | if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) 20 | find_package(Qt6 REQUIRED COMPONENTS Mqtt) 21 | end() 22 | 23 | # 24 | # Pub 25 | # 26 | 27 | qt_add_executable(qtmqtt_pub 28 | configuration.h 29 | main_pub.cpp 30 | ) 31 | 32 | set_target_properties(qtmqtt_pub PROPERTIES 33 | WIN32_EXECUTABLE FALSE 34 | MACOSX_BUNDLE FALSE 35 | ) 36 | 37 | target_compile_definitions(qtmqtt_pub PUBLIC 38 | QT_DEPRECATED_WARNINGS 39 | ) 40 | 41 | target_link_libraries(qtmqtt_pub PUBLIC 42 | Qt::Mqtt 43 | ) 44 | 45 | install(TARGETS qtmqtt_pub 46 | RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" 47 | BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" 48 | LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" 49 | ) 50 | 51 | # 52 | # Sub 53 | # 54 | 55 | qt_add_executable(qtmqtt_sub 56 | configuration.h 57 | main_sub.cpp 58 | ) 59 | 60 | set_target_properties(qtmqtt_sub PROPERTIES 61 | WIN32_EXECUTABLE FALSE 62 | MACOSX_BUNDLE FALSE 63 | ) 64 | 65 | target_compile_definitions(qtmqtt_sub PUBLIC 66 | QT_DEPRECATED_WARNINGS 67 | ) 68 | 69 | target_link_libraries(qtmqtt_sub PUBLIC 70 | Qt::Mqtt 71 | ) 72 | 73 | install(TARGETS qtmqtt_sub 74 | RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" 75 | BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" 76 | LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" 77 | ) 78 | -------------------------------------------------------------------------------- /src/mqtt/qmqttmessage.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTMESSAGE_H 6 | #define QMQTTMESSAGE_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | QT_BEGIN_NAMESPACE 16 | 17 | class QMqttMessagePrivate; 18 | 19 | class Q_MQTT_EXPORT QMqttMessage 20 | { 21 | Q_GADGET 22 | Q_PROPERTY(QMqttTopicName topic READ topic CONSTANT) 23 | Q_PROPERTY(QByteArray payload READ payload CONSTANT) 24 | Q_PROPERTY(quint16 id READ id CONSTANT) 25 | Q_PROPERTY(quint8 qos READ qos CONSTANT) 26 | Q_PROPERTY(bool duplicate READ duplicate CONSTANT) 27 | Q_PROPERTY(bool retain READ retain CONSTANT) 28 | 29 | public: 30 | QMqttMessage(); 31 | QMqttMessage(const QMqttMessage& other); 32 | ~QMqttMessage(); 33 | 34 | QMqttMessage& operator=(const QMqttMessage &other); 35 | bool operator==(const QMqttMessage &other) const; 36 | inline bool operator!=(const QMqttMessage &other) const; 37 | 38 | const QByteArray &payload() const; 39 | quint8 qos() const; 40 | quint16 id() const; 41 | QMqttTopicName topic() const; 42 | bool duplicate() const; 43 | bool retain() const; 44 | 45 | QMqttPublishProperties publishProperties() const; 46 | private: 47 | friend class QMqttConnection; 48 | QMqttMessage(const QMqttTopicName &topic, const QByteArray &payload, 49 | quint16 id, quint8 qos, 50 | bool dup, bool retain); 51 | QExplicitlySharedDataPointer d; 52 | }; 53 | 54 | QT_END_NAMESPACE 55 | 56 | Q_DECLARE_METATYPE(QMqttMessage) 57 | 58 | #endif // QMQTTMESSAGE_H 59 | -------------------------------------------------------------------------------- /examples/mqtt/quickpublication/qmlmqttclient.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "qmlmqttclient.h" 5 | #include 6 | #include 7 | 8 | QmlMqttClient::QmlMqttClient(QObject *parent) 9 | : QObject(parent) 10 | { 11 | connect(&m_client, &QMqttClient::hostnameChanged, this, &QmlMqttClient::hostnameChanged); 12 | connect(&m_client, &QMqttClient::portChanged, this, &QmlMqttClient::portChanged); 13 | connect(&m_client, &QMqttClient::stateChanged, this, &QmlMqttClient::stateChanged); 14 | } 15 | 16 | void QmlMqttClient::connectToHost() 17 | { 18 | m_client.connectToHost(); 19 | } 20 | 21 | void QmlMqttClient::disconnectFromHost() 22 | { 23 | m_client.disconnectFromHost(); 24 | } 25 | 26 | const QString QmlMqttClient::hostname() const 27 | { 28 | return m_client.hostname(); 29 | } 30 | 31 | void QmlMqttClient::setHostname(const QString &newHostname) 32 | { 33 | m_client.setHostname(newHostname); 34 | } 35 | 36 | int QmlMqttClient::port() const 37 | { 38 | return m_client.port(); 39 | } 40 | 41 | void QmlMqttClient::setPort(int newPort) 42 | { 43 | if (newPort < 0 || newPort > std::numeric_limits::max()) { 44 | qWarning() << "Trying to set invalid port number"; 45 | return; 46 | } 47 | m_client.setPort(static_cast(newPort)); 48 | } 49 | 50 | const QMqttClient::ClientState QmlMqttClient::state() const 51 | { 52 | return m_client.state(); 53 | } 54 | 55 | void QmlMqttClient::setState(const QMqttClient::ClientState &newState) 56 | { 57 | m_client.setState(newState); 58 | } 59 | 60 | int QmlMqttClient::publish(const QString &topic, const QString &message, int qos, bool retain) 61 | { 62 | auto result = m_client.publish(QMqttTopicName(topic), message.toUtf8(), qos, retain); 63 | return result; 64 | } 65 | -------------------------------------------------------------------------------- /tests/certificate/cert.key: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 The Qt Company Ltd. 2 | # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | -----BEGIN PRIVATE KEY----- 5 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCc1pqVlPX/22kY 6 | vxYZ9+tluPPB8wtvzFHW02RiEFKrdU8Ey8mDBKpK+ljMvzXWC/F+aF1tLs/C7bWx 7 | affMCU5DYq2ATMaMMcFlnj56mytIimmUwbwc1IdL1r5rRcx1FhPdytTbSsi++mY/ 8 | xGb9CNAqZFjKG6cxFv86rj4/N1sZItMadq6/xx8p6hb/ChTKCaUdQOrlrZctdldW 9 | kMl2SMjKCFD4Az5rB7TWSgQnM+yLAGB4437xCCfq+JTjrIE143HTFPtIR38jQstf 10 | +sZgcJ3IUqg2X9208hUbuhivs8xSgUsreDAe80Nj9vamMKDSTm7iZD0X6okCSUS5 11 | MMrufUwdAgMBAAECggEAKs2u9q/my2M4NZbBE2lEB0kIzZ/lOSfMFhMvTEwkI8Mq 12 | Q6bSYj19tGTKo2Zz7OzphZQ6GzgxX4O8mKTRChBoGZ/uths9/Lj/jRo49wEuOOf9 13 | lKmjC0M9gYckBObRvArAdUGMAiVQ0D5KdZDGgrxLA6bLTK1rXcxm777qIhqbdCpN 14 | i9RwW9wp9rMV53J8mmWWUDVpfbIKHAmp50JknXj07onPEqN6IKdZY7sYACfYiz/8 15 | l31rKfR/P5j/aRBOFwBnq7Z3JGfOEQPmE8bxQ2Vt3ZXPK2ekreDx4j2Tz+gSZmF3 16 | Ee8DonQtA1DTOlhMyb6FhJrEFmDr38jGQqDK4qV8iQKBgQDLoOSYzX0xcyK2dPMD 17 | woPGcKymI+XYx0Q6cVZo1GttNarhBN0w0ms9a4SYoTMhAI9tzjJw/sU5t9kLan6n 18 | m11PqQVK+Vbh1v2YICJW89LcOFYwyO6IAiMN1LUdy8las4GwcXRwBWWnXAnE+YJK 19 | AiXcmB1ZX3j8pgStCF9VApC50wKBgQDFLP87pGtWW3nvkxoDpgVb1CwpO1T1EsFF 20 | Yzv7eIkFQGUkqF7OlslhMCOERE8pj4dr4CoTIvVsYW+lYfBnFPpQ0pQ+BZ2meZ0u 21 | GfWBDYpNGTGrxEDBc923glb2oegQQirHpiWtlinp5nciOn/rqpUwJR3b46drFlNy 22 | 26CTKA+8TwKBgQDKv8qdMo2i/QblMRD+/2CB55KgYkHrVI1ku5DUFB1awgMAxf0P 23 | LZRFtZZy+p6UD6DALn0e8S2jSKE9sq2laRbByINSoW2WtKAQJn7KoT+kshtvu8F1 24 | fts0XERyBITaYL2S14SePWF4ADZiACVwVy8ns/YVFPC8bvlc6Gczl7hOrQKBgQCP 25 | BUmJSIT3GdlDlq7q8JS4fBkgO0IvldAM9aL/j/nLjl8PDPXf4e3mihVpDmdhXRO8 26 | gtfiE5xzZeWmz3iiPMworeYLauVkaJhDZV73ogusStcFoY/bAqFTR76unNgIWwZO 27 | 1MxFskNqvtmxQT+igJRAXNvgsKuyeHpFONurggaP7wKBgCj25sAxVcOuOcANQGcO 28 | wCNvt1pHDJengrzaKooCJqm5YxNhrcKlJsdQcQ1Mu+KyhcMY/WF/0UaJZytlHMWf 29 | aDlF7zKqhQFqFY7nk/C7+fED7Kg3XJR54qtweVNzD6k4yTeSsvBeTd2aaepzZvJI 30 | IOQ3RPVQNsdgjn3VTGs/rmrR 31 | -----END PRIVATE KEY----- 32 | 33 | -------------------------------------------------------------------------------- /src/mqtt/qmqttsubscriptionproperties.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTSUBSCRIPTIONPROPERTIES_H 6 | #define QMQTTSUBSCRIPTIONPROPERTIES_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | QT_BEGIN_NAMESPACE 17 | 18 | class QMqttSubscriptionPropertiesData; 19 | class QMqttUnsubscriptionPropertiesData; 20 | 21 | class Q_MQTT_EXPORT QMqttSubscriptionProperties 22 | { 23 | public: 24 | QMqttSubscriptionProperties(); 25 | QMqttSubscriptionProperties(const QMqttSubscriptionProperties &); 26 | QMqttSubscriptionProperties &operator=(const QMqttSubscriptionProperties &); 27 | ~QMqttSubscriptionProperties(); 28 | 29 | QMqttUserProperties userProperties() const; 30 | void setUserProperties(const QMqttUserProperties &user); 31 | 32 | quint32 subscriptionIdentifier() const; 33 | void setSubscriptionIdentifier(quint32 id); 34 | 35 | bool noLocal() const; 36 | void setNoLocal(bool noloc); 37 | private: 38 | QSharedDataPointer data; 39 | }; 40 | 41 | class Q_MQTT_EXPORT QMqttUnsubscriptionProperties 42 | { 43 | public: 44 | QMqttUnsubscriptionProperties(); 45 | QMqttUnsubscriptionProperties(const QMqttUnsubscriptionProperties &); 46 | QMqttUnsubscriptionProperties &operator=(const QMqttUnsubscriptionProperties &rhs); 47 | ~QMqttUnsubscriptionProperties(); 48 | 49 | QMqttUserProperties userProperties() const; 50 | void setUserProperties(const QMqttUserProperties &user); 51 | 52 | private: 53 | QSharedDataPointer data; 54 | }; 55 | 56 | QT_END_NAMESPACE 57 | 58 | #endif // QMQTTSUBSCRIPTIONPROPERTIES_H 59 | -------------------------------------------------------------------------------- /src/mqtt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ##################################################################### 5 | ## Mqtt Module: 6 | ##################################################################### 7 | 8 | qt_internal_add_module(Mqtt 9 | SOURCES 10 | qmqttauthenticationproperties.cpp qmqttauthenticationproperties.h 11 | qmqttclient.cpp qmqttclient.h qmqttclient_p.h 12 | qmqttconnection.cpp qmqttconnection_p.h 13 | qmqttconnectionproperties.cpp qmqttconnectionproperties.h qmqttconnectionproperties_p.h 14 | qmqttcontrolpacket.cpp qmqttcontrolpacket_p.h 15 | qmqttglobal.h qmqttglobal_p.h 16 | qmqttmessage.cpp qmqttmessage.h qmqttmessage_p.h 17 | qmqttpublishproperties.cpp qmqttpublishproperties.h qmqttpublishproperties_p.h 18 | qmqttsubscription.cpp qmqttsubscription.h qmqttsubscription_p.h 19 | qmqttsubscriptionproperties.cpp qmqttsubscriptionproperties.h 20 | qmqtttopicfilter.cpp qmqtttopicfilter.h 21 | qmqtttopicname.cpp qmqtttopicname.h 22 | qmqtttype.cpp qmqtttype.h 23 | LIBRARIES 24 | Qt::CorePrivate 25 | PUBLIC_LIBRARIES 26 | Qt::Core 27 | Qt::Network 28 | PRIVATE_MODULE_INTERFACE 29 | Qt::CorePrivate 30 | ) 31 | 32 | qt_internal_extend_target(Mqtt 33 | CONDITION 34 | TARGET Qt::WebSockets 35 | DEFINES 36 | QT_MQTT_WITH_WEBSOCKETS 37 | PUBLIC_LIBRARIES 38 | Qt::WebSockets 39 | SOURCES 40 | transportLayers/mqtt_websocket_io_base.cpp 41 | transportLayers/mqtt_websocket_io_base_p.h 42 | transportLayers/mqtt_websocket_io.cpp 43 | transportLayers/mqtt_websocket_io_p.h 44 | transportLayers/mqtt_secure_websocket_io.cpp 45 | transportLayers/mqtt_secure_websocket_io_p.h 46 | ) 47 | 48 | qt_internal_add_docs(Mqtt 49 | doc/qtmqtt.qdocconf 50 | ) 51 | -------------------------------------------------------------------------------- /examples/mqtt/doc/quicksubscription.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | /*! 5 | \example quicksubscription 6 | \title Qt Quick Subscription 7 | \examplecategory {Connectivity} 8 | \ingroup qtmqtt-examples 9 | \brief Use Qt Quick Controls to create an application that can subscribe to MQTT 10 | topics. 11 | 12 | \image quicksubscription.png 13 | 14 | \e {Qt Quick Subscription} demonstrates how to register QMqttClient as a QML type and 15 | use it in a Qt Quick application. 16 | 17 | \l {Qt MQTT} does not provide a QML API in its current version. However, 18 | you can make the C++ classes of the module available to QML. 19 | 20 | \section1 Creating a Client 21 | 22 | Connect to QMqttSubscription::messageReceived( ) to receive all messages 23 | sent to the broker: 24 | 25 | \quotefromfile quicksubscription/qmlmqttclient.cpp 26 | \skipto QmlMqttSubscription 27 | \printuntil } 28 | 29 | Create a \c QmlMqttClient class with the QMqttClient class as a base 30 | class: 31 | 32 | \skipto QmlMqttClient( 33 | \printuntil } 34 | 35 | Use the \c subscribe() function to create a subscription object: 36 | \skipto subscribe 37 | \printuntil } 38 | 39 | Use a QMqttMessage object to store the payload of a received 40 | message: 41 | 42 | \skipto handleMessage 43 | \printuntil } 44 | 45 | \section1 Registering Classes in QML 46 | 47 | In the \c main.cpp file, load the QML type Main from the module 48 | subscription: 49 | 50 | \quotefromfile quicksubscription/main.cpp 51 | \skipto (argc 52 | \printuntil loadFromModule 53 | 54 | Now use the MqttClient type in the \c Main.qml file to create an 55 | MQTT client: 56 | 57 | \quotefromfile quicksubscription/Main.qml 58 | \skipto MqttClient { 59 | \printuntil } 60 | */ 61 | -------------------------------------------------------------------------------- /src/mqtt/doc/qtmqtt.qdocconf: -------------------------------------------------------------------------------- 1 | include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) 2 | 3 | project = QtMqtt 4 | description = Qt MQTT Reference Documentation 5 | version = $QT_VERSION 6 | 7 | examplesinstallpath = mqtt 8 | 9 | qhp.projects = QtMqtt 10 | 11 | qhp.QtMqtt.file = qtmqtt.qhp 12 | qhp.QtMqtt.namespace = org.qt-project.qtmqtt.$QT_VERSION_TAG 13 | qhp.QtMqtt.virtualFolder = qtmqtt 14 | qhp.QtMqtt.indexTitle = Qt MQTT 15 | qhp.QtMqtt.indexRoot = 16 | 17 | qhp.QtMqtt.subprojects = overview classes examples 18 | 19 | qhp.QtMqtt.subprojects.overview.title = Overview 20 | qhp.QtMqtt.subprojects.overview.indexTitle = Qt MQTT Overview 21 | qhp.QtMqtt.subprojects.overview.selectors = group:none 22 | 23 | qhp.QtMqtt.subprojects.classes.title = C++ Classes 24 | qhp.QtMqtt.subprojects.classes.indexTitle = Qt MQTT C++ Classes 25 | qhp.QtMqtt.subprojects.classes.selectors = class fake:headerfile 26 | qhp.QtMqtt.subprojects.classes.sortPages = true 27 | 28 | qhp.QtMqtt.subprojects.examples.title = Examples 29 | qhp.QtMqtt.subprojects.examples.indexTitle = Qt MQTT Examples 30 | qhp.QtMqtt.subprojects.examples.selectors = example 31 | qhp.QtMqtt.subprojects.examples.sortPages = true 32 | 33 | headerdirs += .. 34 | sourcedirs += .. 35 | exampledirs = ../../../examples/mqtt \ 36 | snippets 37 | imagedirs += images \ 38 | ../../../examples/mqtt/doc/images 39 | excludedirs += ../qt4support 40 | 41 | depends += qtcore qtdoc qtnetwork qmake qtwebsockets qtcmake 42 | 43 | #add generic thumbnail images for example documentation that does not have an image. 44 | manifestmeta.thumbnail.names += "QtMqtt/WebSockets MQTT Subscription*" 45 | 46 | navigation.landingpage = "Qt MQTT" 47 | navigation.cppclassespage = "Qt MQTT C++ Classes" 48 | 49 | # Allow zero warnings when testing documentation in CI 50 | warninglimit = 0 51 | -------------------------------------------------------------------------------- /src/mqtt/doc/src/index.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | 5 | /*! 6 | \page qtmqtt-index.html 7 | \title Qt MQTT 8 | \brief Provides classes and functions to make MQTT programming simple and 9 | portable. 10 | 11 | \l{MQTT} is a machine-to-machine (M2M) protocol utilizing the 12 | publish-and-subscribe paradigm. Its purpose is to provide a channel with 13 | minimal communication overhead. 14 | 15 | Generally, MQTT is used on top of a TCP connection. However, the base 16 | requirement is defined as an ordered, lossless, bidirectional connection. 17 | 18 | The Qt MQTT module provides a standard compliant implementation of the MQTT 19 | protocol specification. It enables applications to act as telemetry displays 20 | and devices to publish telemetry data. The supported versions are MQTT 3.1, 21 | MQTT 3.1.1, and MQTT 5.0. 22 | 23 | \include module-use.qdocinc using qt module 24 | 25 | \code 26 | find_package(Qt6 REQUIRED COMPONENTS Mqtt) 27 | target_link_libraries(mytarget PRIVATE Qt6::Mqtt) 28 | \endcode 29 | 30 | See also the \l {Build with CMake} overview. 31 | 32 | \include module-use.qdocinc building with qmake 33 | 34 | \code 35 | QT += mqtt 36 | \endcode 37 | 38 | \section1 Articles and Guides 39 | 40 | \list 41 | \li \l{Qt MQTT Overview}{Overview} 42 | \endlist 43 | 44 | \section1 Examples 45 | 46 | \list 47 | \li \l{Qt MQTT Examples} 48 | \endlist 49 | 50 | \section1 Reference 51 | 52 | \list 53 | \li \l{Qt MQTT C++ Classes}{C++ Classes} 54 | \endlist 55 | 56 | \section1 Licenses and Attributions 57 | 58 | Qt MQTT is available under commercial licenses from \l{The Qt Company}. 59 | In addition, it is available under the 60 | \l{GNU General Public License, version 3}. 61 | 62 | \annotatedlist attributions-qtmqtt 63 | */ 64 | -------------------------------------------------------------------------------- /src/mqtt/qmqttglobal.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QTQMQTTGLOBAL_H 6 | #define QTQMQTTGLOBAL_H 7 | 8 | #include 9 | #include 10 | 11 | QT_BEGIN_NAMESPACE 12 | 13 | namespace QMqtt 14 | { 15 | enum class PayloadFormatIndicator : quint8 { 16 | Unspecified = 0, 17 | UTF8Encoded = 1 18 | }; 19 | 20 | enum class MessageStatus : quint8 { 21 | Unknown = 0, 22 | Published, 23 | Acknowledged, 24 | Received, 25 | Released, 26 | Completed 27 | }; 28 | 29 | enum class ReasonCode : quint8 { 30 | Success = 0, 31 | SubscriptionQoSLevel0 = 0, 32 | SubscriptionQoSLevel1 = 0x01, 33 | SubscriptionQoSLevel2 = 0x02, 34 | NoMatchingSubscriber = 0x10, 35 | NoSubscriptionExisted = 0x11, 36 | ContinueAuthentication = 0x18, 37 | ReAuthenticate = 0x19, 38 | UnspecifiedError = 0x80, 39 | MalformedPacket = 0x81, 40 | ProtocolError = 0x82, 41 | ImplementationSpecificError = 0x83, 42 | UnsupportedProtocolVersion = 0x84, 43 | InvalidClientId = 0x85, 44 | InvalidUserNameOrPassword = 0x86, 45 | NotAuthorized = 0x87, 46 | ServerNotAvailable = 0x88, 47 | ServerBusy = 0x89, 48 | ClientBanned = 0x8A, 49 | InvalidAuthenticationMethod = 0x8C, 50 | InvalidTopicFilter = 0x8F, 51 | InvalidTopicName = 0x90, 52 | MessageIdInUse = 0x91, 53 | MessageIdNotFound = 0x92, 54 | PacketTooLarge = 0x95, 55 | QuotaExceeded = 0x97, 56 | InvalidPayloadFormat = 0x99, 57 | RetainNotSupported = 0x9A, 58 | QoSNotSupported = 0x9B, 59 | UseAnotherServer = 0x9C, 60 | ServerMoved = 0x9D, 61 | SharedSubscriptionsNotSupported = 0x9E, 62 | ExceededConnectionRate = 0x9F, 63 | SubscriptionIdsNotSupported = 0xA1, 64 | WildCardSubscriptionsNotSupported = 0xA2 65 | }; 66 | } 67 | QT_END_NAMESPACE 68 | 69 | #endif //QTQMQTTGLOBAL_H 70 | -------------------------------------------------------------------------------- /tests/manual/sslconfiguration/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | QCoreApplication a(argc, argv); 11 | 12 | const bool support = QSslSocket::supportsSsl(); 13 | if (!support) { 14 | qWarning() << "This test requires a Qt build with SSL support."; 15 | return -1; 16 | } 17 | 18 | QSslConfiguration sslConfig; 19 | 20 | // You must download the current certificate from the mosquitto test page 21 | // http://test.mosquitto.org and place it next to the binary. 22 | const auto certs = QSslCertificate::fromPath("mosquitto.org.crt"); 23 | 24 | if (certs.isEmpty()) { 25 | qWarning() << "Could not load certificates"; 26 | return -2; 27 | } 28 | 29 | sslConfig.setCaCertificates(certs); 30 | 31 | QMqttClient client; 32 | 33 | client.setHostname("test.mosquitto.org"); 34 | client.setPort(8883); 35 | 36 | a.connect(&client, &QMqttClient::connected, [&client]() { 37 | qDebug() << "MQTT Client connected, subscribing"; 38 | auto sub = client.subscribe(QLatin1String("some/Topic/foo"), 1); 39 | client.connect(sub, &QMqttSubscription::stateChanged, [] (QMqttSubscription::SubscriptionState s) { 40 | qDebug() << "MQTT Subscription new state:" << s; 41 | if (s == QMqttSubscription::Subscribed) 42 | qInfo() << "Connection and Subscription succeeded, test done."; 43 | }); 44 | }); 45 | 46 | a.connect(&client, &QMqttClient::stateChanged, [](QMqttClient::ClientState s) { 47 | qDebug() << "MQTT State:" << s; 48 | }); 49 | a.connect(&client, &QMqttClient::errorChanged, [](QMqttClient::ClientError e) { 50 | qDebug() << "MQTT Error:" << e; 51 | }); 52 | 53 | client.connectToHostEncrypted(sslConfig); 54 | 55 | return a.exec(); 56 | } 57 | -------------------------------------------------------------------------------- /src/mqtt/qmqttclient_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTCLIENT_P_H 6 | #define QMQTTCLIENT_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include "qmqttglobal_p.h" 20 | #include "qmqttclient.h" 21 | #include "qmqttconnection_p.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | QT_BEGIN_NAMESPACE 28 | 29 | class QMqttClientPrivate : public QObjectPrivate 30 | { 31 | Q_DECLARE_PUBLIC(QMqttClient) 32 | public: 33 | QMqttClientPrivate(QMqttClient *c); 34 | ~QMqttClientPrivate() override; 35 | void setStateAndError(QMqttClient::ClientState s, QMqttClient::ClientError e = QMqttClient::NoError); 36 | void setClientId(const QString &id); 37 | QMqttClient *m_client{nullptr}; 38 | QString m_hostname; 39 | quint16 m_port{0}; 40 | QMqttConnection m_connection; 41 | QString m_clientId; // auto-generated 42 | quint16 m_keepAlive{60}; 43 | QMqttClient::ProtocolVersion m_protocolVersion{QMqttClient::MQTT_3_1_1}; 44 | QMqttClient::ClientState m_state{QMqttClient::Disconnected}; 45 | QMqttClient::ClientError m_error{QMqttClient::NoError}; 46 | QString m_willTopic; 47 | QByteArray m_willMessage; 48 | quint8 m_willQoS{0}; 49 | bool m_willRetain{false}; 50 | bool m_autoKeepAlive{true}; 51 | QString m_username; 52 | QString m_password; 53 | bool m_cleanSession{true}; 54 | QMqttConnectionProperties m_connectionProperties; 55 | QMqttLastWillProperties m_lastWillProperties; 56 | QMqttServerConnectionProperties m_serverConnectionProperties; 57 | }; 58 | 59 | QT_END_NAMESPACE 60 | #endif // QMQTTCLIENT_P_H 61 | -------------------------------------------------------------------------------- /examples/mqtt/doc/quickpublication.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | /*! 5 | \example quickpublication 6 | \title Qt Quick Publication 7 | \examplecategory {Connectivity} 8 | \ingroup qtmqtt-examples 9 | \brief Use Qt Quick Controls to create an application that can publish on MQTT 10 | topics. 11 | 12 | \image quickpublication.png 13 | 14 | \e {Qt Quick Publication} demonstrates how to register QMqttClient as a QML type and 15 | use it in a Qt Quick application. 16 | 17 | \l {Qt MQTT} does not provide a QML API in its current version. However, 18 | you can make the C++ classes of the module available to QML. 19 | 20 | \section1 Creating a Client 21 | 22 | Create the wrapper class \c QmlMqttClient that has QMqttClient as a member: 23 | \quotefromfile quickpublication/qmlmqttclient.h 24 | \skipto private 25 | \printuntil } 26 | 27 | Connect the wrapper methods to the methods of QMqttClient in the constructor: 28 | \quotefromfile quickpublication/qmlmqttclient.cpp 29 | \skipto QmlMqttClient 30 | \printuntil } 31 | 32 | A wrapper method has the same name as the wrapped method. In the simplest case, 33 | it is just a single method call: 34 | 35 | \skipto connectToHost 36 | \printuntil } 37 | 38 | It is also possible to customize a wrapper method by extending it with some additional 39 | functionality: 40 | 41 | \skipto setPort 42 | \printuntil ); 43 | 44 | \section1 Registering Classes in QML 45 | 46 | In the \c main.cpp file, load the QML type Main from the module 47 | publication: 48 | 49 | \quotefromfile quickpublication/main.cpp 50 | \skipto (argc 51 | \printuntil loadFromModule 52 | 53 | 54 | Now use the MqttClient type in the \c Main.qml file to create an 55 | MQTT client: 56 | 57 | \quotefromfile quickpublication/Main.qml 58 | \skipto MqttClient { 59 | \printuntil } 60 | */ 61 | -------------------------------------------------------------------------------- /examples/mqtt/quicksubscription/qmlmqttclient.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #ifndef QMLMQTTCLIENT_H 5 | #define QMLMQTTCLIENT_H 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | class QmlMqttClient; 14 | 15 | class QmlMqttSubscription : public QObject 16 | { 17 | Q_OBJECT 18 | QML_UNCREATABLE("Not intended to be creatable") 19 | public: 20 | QmlMqttSubscription(QMqttSubscription *s, QmlMqttClient *c); 21 | ~QmlMqttSubscription(); 22 | 23 | Q_SIGNALS: 24 | void messageReceived(const QString &msg); 25 | 26 | public slots: 27 | void handleMessage(const QMqttMessage &qmsg); 28 | 29 | private: 30 | Q_DISABLE_COPY(QmlMqttSubscription) 31 | QMqttSubscription *sub; 32 | QmlMqttClient *client; 33 | }; 34 | 35 | class QmlMqttClient : public QObject 36 | { 37 | Q_OBJECT 38 | Q_PROPERTY(QString hostname READ hostname WRITE setHostname NOTIFY hostnameChanged) 39 | Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged) 40 | Q_PROPERTY(QMqttClient::ClientState state READ state WRITE setState NOTIFY stateChanged) 41 | QML_NAMED_ELEMENT(MqttClient) 42 | QML_EXTENDED_NAMESPACE(QMqttClient) 43 | public: 44 | 45 | QmlMqttClient(QObject *parent = nullptr); 46 | 47 | Q_INVOKABLE void connectToHost(); 48 | Q_INVOKABLE void disconnectFromHost(); 49 | Q_INVOKABLE QmlMqttSubscription *subscribe(const QString &topic); 50 | 51 | const QString hostname() const; 52 | void setHostname(const QString &newHostname); 53 | 54 | int port() const; 55 | void setPort(int newPort); 56 | 57 | QMqttClient::ClientState state() const; 58 | void setState(const QMqttClient::ClientState &newState); 59 | 60 | signals: 61 | void hostnameChanged(); 62 | void portChanged(); 63 | 64 | void stateChanged(); 65 | 66 | private: 67 | Q_DISABLE_COPY(QmlMqttClient) 68 | QMqttClient m_client; 69 | }; 70 | 71 | #endif // QMLMQTTCLIENT_H 72 | -------------------------------------------------------------------------------- /src/mqtt/qmqttcontrolpacket_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTCONTROLPACKET_P_H 6 | #define QMQTTCONTROLPACKET_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | #include "qmqttglobal_p.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | QT_BEGIN_NAMESPACE 25 | 26 | class Q_AUTOTEST_EXPORT QMqttControlPacket 27 | { 28 | public: 29 | enum PacketType { 30 | UNKNOWN = 0x00, 31 | CONNECT = 0x10, 32 | CONNACK = 0x20, 33 | PUBLISH = 0x30, 34 | PUBACK = 0x40, 35 | PUBREC = 0x50, 36 | PUBREL = 0x60, 37 | PUBCOMP = 0x70, 38 | SUBSCRIBE = 0x80, 39 | SUBACK = 0x90, 40 | UNSUBSCRIBE = 0xA0, 41 | UNSUBACK = 0xB0, 42 | PINGREQ = 0xC0, 43 | PINGRESP = 0xD0, 44 | DISCONNECT = 0xE0, 45 | AUTH = 0xF0, 46 | }; 47 | 48 | QMqttControlPacket(); 49 | QMqttControlPacket(quint8 header); 50 | QMqttControlPacket(quint8 header, const QByteArray &pay); 51 | 52 | void clear(); 53 | 54 | void setHeader(quint8 h); 55 | inline quint8 header() const { return m_header; } 56 | 57 | void append(char value); 58 | void append(quint16 value); 59 | void append(quint32 value); 60 | void append(const QByteArray &data); 61 | void appendRaw(const QByteArray &data); 62 | void appendRawVariableInteger(quint32 value); 63 | 64 | QByteArray serialize() const; 65 | QByteArray serializePayload() const; 66 | inline QByteArray payload() const { return m_payload; } 67 | private: 68 | quint8 m_header{UNKNOWN}; 69 | QByteArray m_payload; 70 | }; 71 | 72 | QT_END_NAMESPACE 73 | 74 | #endif // QMQTTCONTROLPACKET_P_H 75 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/subscriptionwindow.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "subscriptionwindow.h" 5 | #include "ui_subscriptionwindow.h" 6 | 7 | using namespace Qt::StringLiterals; 8 | 9 | SubscriptionWindow::SubscriptionWindow(QMqttSubscription *sub, QWidget *parent) : 10 | QWidget(parent), 11 | ui(new Ui::SubscriptionWindow), 12 | m_sub(sub) 13 | { 14 | ui->setupUi(this); 15 | 16 | ui->labelSub->setText(m_sub->topic().filter()); 17 | ui->labelQoS->setText(QString::number(m_sub->qos())); 18 | updateStatus(m_sub->state()); 19 | connect(m_sub, &QMqttSubscription::messageReceived, this, &SubscriptionWindow::updateMessage); 20 | connect(m_sub, &QMqttSubscription::stateChanged, this, &SubscriptionWindow::updateStatus); 21 | connect(m_sub, &QMqttSubscription::qosChanged, [this](quint8 qos) { 22 | ui->labelQoS->setText(QString::number(qos)); 23 | }); 24 | connect(ui->pushButton, &QAbstractButton::clicked, m_sub, &QMqttSubscription::unsubscribe); 25 | } 26 | 27 | SubscriptionWindow::~SubscriptionWindow() 28 | { 29 | m_sub->unsubscribe(); 30 | delete ui; 31 | } 32 | 33 | void SubscriptionWindow::updateMessage(const QMqttMessage &msg) 34 | { 35 | ui->listWidget->addItem(msg.payload()); 36 | } 37 | 38 | void SubscriptionWindow::updateStatus(QMqttSubscription::SubscriptionState state) 39 | { 40 | switch (state) { 41 | case QMqttSubscription::Unsubscribed: 42 | ui->labelStatus->setText(u"Unsubscribed"_s); 43 | break; 44 | case QMqttSubscription::SubscriptionPending: 45 | ui->labelStatus->setText(u"Pending"_s); 46 | break; 47 | case QMqttSubscription::Subscribed: 48 | ui->labelStatus->setText(u"Subscribed"_s); 49 | break; 50 | case QMqttSubscription::Error: 51 | ui->labelStatus->setText(u"Error"_s); 52 | break; 53 | case QMqttSubscription::UnsubscriptionPending: 54 | ui->labelStatus->setText(u"Pending Unsubscription"_s); 55 | break; 56 | default: 57 | ui->labelStatus->setText(u"--Unknown--"_s); 58 | break; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /examples/mqtt/doc/websocketsubscription.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | /*! 5 | \example websocketsubscription 6 | \examplecategory {Connectivity} 7 | \title WebSockets MQTT Subscription 8 | \ingroup qtmqtt-examples 9 | \brief Combining an MQTT client with a web socket connection. 10 | 11 | \e {WebSockets MQTT Subscription} shows how to design a custom 12 | QIODevice to combine a \l {Qt WebSockets}{web socket} connection with 13 | QMqttClient. 14 | 15 | \note Since Qt 6.10, WebSockets are supported natively by Qt MQTT. 16 | This example is retained to demonstrate how to implement a custom transport. 17 | 18 | \section1 Creating a Custom QIODevice 19 | 20 | The new custom device, \c WebSocketIODevice, has to be a subclass of 21 | \l QIODevice: 22 | 23 | \quotefromfile websocketsubscription/websocketiodevice.h 24 | \skipto WebSocketIODevice 25 | \printuntil } 26 | 27 | \section1 Designing a Class to Manage the Connection and Subscription 28 | 29 | \c WebSocketIODevice will be a private member of the \c ClientSubscription 30 | class alongside the QMqttClient and the QMqttSubscription: 31 | 32 | \quotefromfile websocketsubscription/clientsubscription.h 33 | \skipto private 34 | \printuntil m_version 35 | 36 | \section1 Subscribing to and Receiving Messages 37 | 38 | The main logic is implemented in the \c connectAndSubscribe() method of the 39 | \c ClientSubscription class. You need to verify that the web socket has 40 | successfully connected before you can initialize an MQTT connection over 41 | it. After the MQTT connection has been established, the QMqttClient can 42 | subscribe to the topic. If the subscription is successful, the 43 | QMqttSubscription can be used to receive messages from the subscribed topic 44 | that will be handled by the \c handleMessage() method of the 45 | \c ClientSubscription class. 46 | 47 | \quotefromfile websocketsubscription/clientsubscription.cpp 48 | \skipto connectAndSubscribe 49 | \printuntil Could 50 | \printuntil } 51 | */ 52 | -------------------------------------------------------------------------------- /examples/mqtt/websocketsubscription/websocketiodevice.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "websocketiodevice.h" 5 | 6 | #include 7 | 8 | #include 9 | 10 | WebSocketIODevice::WebSocketIODevice(QObject *parent) 11 | : QIODevice(parent) 12 | { 13 | connect(&m_socket, &QWebSocket::connected, this, &WebSocketIODevice::onSocketConnected); 14 | connect(&m_socket, &QWebSocket::binaryMessageReceived, this, &WebSocketIODevice::handleBinaryMessage); 15 | } 16 | 17 | bool WebSocketIODevice::isSequential() const 18 | { 19 | return true; 20 | } 21 | 22 | qint64 WebSocketIODevice::bytesAvailable() const 23 | { 24 | return static_cast(m_buffer.size()) + QIODevice::bytesAvailable(); 25 | } 26 | 27 | bool WebSocketIODevice::open(QIODevice::OpenMode mode) 28 | { 29 | QWebSocketHandshakeOptions options; 30 | options.setSubprotocols(QStringList{ QString::fromUtf8(m_protocol) }); 31 | 32 | m_socket.open(m_url, options); 33 | 34 | return QIODevice::open(mode); 35 | } 36 | 37 | void WebSocketIODevice::close() 38 | { 39 | m_socket.close(); 40 | QIODevice::close(); 41 | } 42 | 43 | qint64 WebSocketIODevice::readData(char *data, qint64 maxlen) 44 | { 45 | qint64 bytesToRead = qMin(maxlen, (qint64)m_buffer.size()); 46 | memcpy(data, m_buffer.constData(), static_cast(bytesToRead)); 47 | m_buffer = m_buffer.right(m_buffer.size() - bytesToRead); 48 | return bytesToRead; 49 | } 50 | 51 | qint64 WebSocketIODevice::writeData(const char *data, qint64 len) 52 | { 53 | QByteArray msg(data, len); 54 | const int length = m_socket.sendBinaryMessage(msg); 55 | return length; 56 | } 57 | 58 | void WebSocketIODevice::setUrl(const QUrl &url) 59 | { 60 | m_url = url; 61 | } 62 | 63 | void WebSocketIODevice::setProtocol(const QByteArray &data) 64 | { 65 | m_protocol = data; 66 | } 67 | 68 | void WebSocketIODevice::handleBinaryMessage(const QByteArray &msg) 69 | { 70 | m_buffer.append(msg); 71 | emit readyRead(); 72 | } 73 | 74 | void WebSocketIODevice::onSocketConnected() 75 | { 76 | emit socketConnected(); 77 | } 78 | -------------------------------------------------------------------------------- /examples/mqtt/doc/subscriptions.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | /*! 5 | \example subscriptions 6 | \examplecategory {Connectivity} 7 | \title MQTT Subscriptions 8 | \ingroup qtmqtt-examples 9 | \brief Creating a application that communicates with an MQTT broker. 10 | 11 | \image subscriptions.png 12 | 13 | \e {MQTT Subscriptions} shows how to create an application that communicates 14 | with an MQTT broker. A new dialog opens for each subscription, where you can 15 | see the messages on the subscribed topics. 16 | 17 | \section1 Creating a Client 18 | 19 | We use the QMqttClient class to create an MQTT client and to set the broker 20 | host name and port to use for the connection: 21 | 22 | \quotefromfile subscriptions/mainwindow.cpp 23 | \skipto m_client 24 | \printuntil setPort 25 | 26 | \section1 Subscribing to Topics 27 | 28 | When users subscribe to topics in the client, a new subscription object is 29 | created: 30 | 31 | \skipto on_buttonSubscribe_clicked 32 | \printuntil } 33 | \printuntil } 34 | 35 | We use the QMqttSubscription class to store the topic, state, and QoS level 36 | of a subscription: 37 | 38 | \quotefromfile subscriptions/subscriptionwindow.cpp 39 | \skipto QMqttSubscription 40 | \printuntil }); 41 | \printuntil } 42 | 43 | The QoS level can be set separately for a message and for a subscription. 44 | The QoS level set for a subscription determines the minimum QoS level. If 45 | a message is sent with a higher QoS level, the broker increases the QoS of 46 | that message to the higher level. For example, if client A subscribed to 47 | \e topic with QoS 1, and client B publishes a message on the topic, with 48 | QoS 0, the broker will automatically increase the QoS of the message to 1. 49 | If client B publishes a message on the topic with the QoS 2, the broker 50 | will send it with QoS 2. 51 | 52 | \section2 Receiving Messages 53 | 54 | When the client receives a message, the QMqttMessage class is used to store 55 | the actual message payload: 56 | 57 | \skipto updateMessage 58 | \printuntil } 59 | */ 60 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/subscriptionwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SubscriptionWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Subscription: 23 | 24 | 25 | 26 | 27 | 28 | 29 | TextLabel 30 | 31 | 32 | 33 | 34 | 35 | 36 | Status: 37 | 38 | 39 | 40 | 41 | 42 | 43 | TextLabel 44 | 45 | 46 | 47 | 48 | 49 | 50 | QoS: 51 | 52 | 53 | 54 | 55 | 56 | 57 | TextLabel 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | Unsubscribe 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/mqtt/quicksubscription/qmlmqttclient.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "qmlmqttclient.h" 5 | #include 6 | 7 | QmlMqttSubscription::QmlMqttSubscription(QMqttSubscription *s, QmlMqttClient *c) 8 | : sub(s) 9 | , client(c) 10 | { 11 | connect(sub, &QMqttSubscription::messageReceived, this, &QmlMqttSubscription::handleMessage); 12 | } 13 | 14 | QmlMqttSubscription::~QmlMqttSubscription() 15 | { 16 | } 17 | 18 | QmlMqttClient::QmlMqttClient(QObject *parent) 19 | : QObject(parent) 20 | { 21 | connect(&m_client, &QMqttClient::hostnameChanged, this, &QmlMqttClient::hostnameChanged); 22 | connect(&m_client, &QMqttClient::portChanged, this, &QmlMqttClient::portChanged); 23 | connect(&m_client, &QMqttClient::stateChanged, this, &QmlMqttClient::stateChanged); 24 | } 25 | 26 | void QmlMqttClient::connectToHost() 27 | { 28 | m_client.connectToHost(); 29 | } 30 | 31 | void QmlMqttClient::disconnectFromHost() 32 | { 33 | m_client.disconnectFromHost(); 34 | } 35 | 36 | QmlMqttSubscription* QmlMqttClient::subscribe(const QString &topic) 37 | { 38 | auto sub = m_client.subscribe(topic, 0); 39 | auto result = new QmlMqttSubscription(sub, this); 40 | return result; 41 | } 42 | 43 | void QmlMqttSubscription::handleMessage(const QMqttMessage &qmsg) 44 | { 45 | emit messageReceived(qmsg.payload()); 46 | } 47 | 48 | const QString QmlMqttClient::hostname() const 49 | { 50 | return m_client.hostname(); 51 | } 52 | 53 | void QmlMqttClient::setHostname(const QString &newHostname) 54 | { 55 | m_client.setHostname(newHostname); 56 | } 57 | 58 | int QmlMqttClient::port() const 59 | { 60 | return m_client.port(); 61 | } 62 | 63 | void QmlMqttClient::setPort(int newPort) 64 | { 65 | if (newPort < 0 || newPort > std::numeric_limits::max()) { 66 | qWarning() << "Trying to set invalid port number"; 67 | return; 68 | } 69 | m_client.setPort(static_cast(newPort)); 70 | } 71 | 72 | QMqttClient::ClientState QmlMqttClient::state() const 73 | { 74 | return m_client.state(); 75 | } 76 | 77 | void QmlMqttClient::setState(const QMqttClient::ClientState &newState) 78 | { 79 | m_client.setState(newState); 80 | } 81 | -------------------------------------------------------------------------------- /tests/manual/consolepubsub/main_pub.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | #include "configuration.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | QCoreApplication a(argc, argv); 14 | QCoreApplication::setApplicationName(QStringLiteral("qtmqtt_pub")); 15 | QCoreApplication::setApplicationVersion(QStringLiteral("1.0")); 16 | 17 | // Create the client 18 | Configuration description; 19 | auto *client = createClientWithConfiguration(&a, &description, true); 20 | 21 | if (!client) 22 | return -1; 23 | 24 | a.connect(client, &QMqttClient::errorChanged, [&client](const QMqttClient::ClientError e) { 25 | if (e == QMqttClient::NoError) 26 | return; 27 | 28 | qWarning() << "Error Occurred:" << e << " Client state:" << client->state(); 29 | client->disconnectFromHost(); 30 | }); 31 | 32 | a.connect(client, &QMqttClient::messageSent, [&client] (quint32 id) { 33 | qInfo() << "Message with ID:" << id << " sent"; 34 | client->disconnectFromHost(); 35 | }); 36 | 37 | a.connect(client, &QMqttClient::stateChanged, [&client] (QMqttClient::ClientState s) { 38 | if (s == QMqttClient::Disconnected) { 39 | client->deleteLater(); 40 | qApp->quit(); 41 | } 42 | }); 43 | 44 | a.connect(client, &QMqttClient::connected, [&client, description]() { 45 | qInfo() << "Message:"; 46 | qInfo() << " Topic:" << description.topic << " QoS:" << description.qos 47 | << " Retain:" << description.retain; 48 | qInfo() << " Content: " << description.content.left(50); 49 | client->publish(description.topic, 50 | description.content, 51 | description.qos, 52 | description.retain); 53 | if (description.qos == 0)// 0 has no acknowledgment 54 | QTimer::singleShot(500, client, &QMqttClient::disconnectFromHost); 55 | }); 56 | 57 | #ifndef QT_NO_SSL 58 | if (description.useEncryption) 59 | client->connectToHostEncrypted(description.sslConfiguration); 60 | else 61 | #endif 62 | client->connectToHost(); 63 | 64 | return a.exec(); 65 | } 66 | -------------------------------------------------------------------------------- /src/mqtt/qmqttconnectionproperties_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTCONNECTIONPROPERTIES_P_H 6 | #define QMQTTCONNECTIONPROPERTIES_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include "qmqttconnectionproperties.h" 20 | #include "private/qglobal_p.h" 21 | 22 | #include 23 | 24 | QT_BEGIN_NAMESPACE 25 | 26 | Q_DECLARE_LOGGING_CATEGORY(lcMqttConnection) 27 | 28 | class QMqttLastWillPropertiesData : public QSharedData 29 | { 30 | public: 31 | QString contentType; 32 | QString responseTopic; 33 | QByteArray correlationData; 34 | QMqttUserProperties userProperties; 35 | quint32 willDelayInterval{0}; 36 | quint32 messageExpiryInterval{0}; 37 | QMqtt::PayloadFormatIndicator formatIndicator{QMqtt::PayloadFormatIndicator::Unspecified}; 38 | }; 39 | 40 | class QMqttConnectionPropertiesData : public QSharedData 41 | { 42 | public: 43 | QMqttUserProperties userProperties; 44 | QString authenticationMethod; 45 | QByteArray authenticationData; 46 | quint32 sessionExpiryInterval{0}; 47 | quint32 maximumPacketSize{std::numeric_limits::max()}; 48 | quint16 maximumReceive{65535}; 49 | quint16 maximumTopicAlias{0}; 50 | bool requestResponseInformation{false}; 51 | bool requestProblemInformation{true}; 52 | }; 53 | 54 | class QMqttServerConnectionPropertiesData : public QSharedData 55 | { 56 | public: 57 | QMqttServerConnectionProperties::ServerPropertyDetails details{QMqttServerConnectionProperties::None}; 58 | QString reasonString; 59 | QString responseInformation; 60 | QString serverReference; 61 | quint16 serverKeepAlive{0}; 62 | quint8 maximumQoS{2}; 63 | QMqtt::ReasonCode reasonCode{QMqtt::ReasonCode::Success}; 64 | bool valid{false}; // Only set to true after CONNACK 65 | bool retainAvailable{true}; 66 | bool wildcardSupported{true}; 67 | bool subscriptionIdentifierSupported{true}; 68 | bool sharedSubscriptionSupported{true}; 69 | }; 70 | 71 | QT_END_NAMESPACE 72 | 73 | #endif // QMQTTCONNECTIONPROPERTIES_P_H 74 | -------------------------------------------------------------------------------- /tests/manual/consolepubsub/main_sub.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | #include "configuration.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | QCoreApplication a(argc, argv); 14 | QCoreApplication::setApplicationName(QStringLiteral("qtmqtt_sub")); 15 | QCoreApplication::setApplicationVersion(QStringLiteral("1.0")); 16 | 17 | // Create the client 18 | Configuration description; 19 | auto *client = createClientWithConfiguration(&a, &description, false); 20 | 21 | if (!client) 22 | return -1; 23 | 24 | a.connect(client, &QMqttClient::errorChanged, [&client](const QMqttClient::ClientError e) { 25 | if (e == QMqttClient::NoError) 26 | return; 27 | 28 | qWarning() << "Error Occurred:" << e << " Client state:" << client->state(); 29 | client->disconnectFromHost(); 30 | }); 31 | 32 | a.connect(client, &QMqttClient::stateChanged, [&client] (QMqttClient::ClientState s) { 33 | if (s == QMqttClient::Disconnected) { 34 | client->deleteLater(); 35 | qApp->quit(); 36 | } 37 | }); 38 | 39 | a.connect(client, &QMqttClient::connected, [&client, description]() { 40 | auto sub = client->subscribe(description.topic, description.qos); 41 | client->connect(sub, &QMqttSubscription::stateChanged, [&client](QMqttSubscription::SubscriptionState s) { 42 | qInfo() << "Subscription state:" << s; 43 | if (s == QMqttSubscription::Unsubscribed) 44 | client->disconnectFromHost(); 45 | }); 46 | 47 | client->connect(sub, &QMqttSubscription::messageReceived, [](const QMqttMessage &msg) { 48 | qInfo() << "ID:" << msg.id() 49 | << "Topic:" << msg.topic().name() 50 | << "QoS:" << msg.qos() 51 | << "Retain:" << msg.retain() 52 | << "Duplicate:" << msg.duplicate() 53 | << "Payload:" << msg.payload().left(50) << (msg.payload().size() > 50 ? "..." : ""); 54 | }); 55 | }); 56 | 57 | #ifndef QT_NO_SSL 58 | if (description.useEncryption) 59 | client->connectToHostEncrypted(description.sslConfiguration); 60 | else 61 | #endif 62 | client->connectToHost(); 63 | 64 | return a.exec(); 65 | } 66 | -------------------------------------------------------------------------------- /src/mqtt/qmqtttopicname.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 Lorenz Haas 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTTOPICNAME_H 6 | #define QMQTTTOPICNAME_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | QT_BEGIN_NAMESPACE 16 | 17 | class QMqttTopicNamePrivate; 18 | 19 | class QMqttTopicName; 20 | // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) 21 | Q_MQTT_EXPORT size_t qHash(const QMqttTopicName &name, size_t seed = 0) Q_DECL_NOTHROW; 22 | 23 | class Q_MQTT_EXPORT QMqttTopicName 24 | { 25 | public: 26 | QMqttTopicName(const QString &name = QString()); 27 | QMqttTopicName(const QLatin1String &name); 28 | QMqttTopicName(const QMqttTopicName &name); 29 | ~QMqttTopicName(); 30 | QMqttTopicName &operator=(const QMqttTopicName &name); 31 | 32 | #ifdef Q_COMPILER_RVALUE_REFS 33 | QMqttTopicName &operator=(QMqttTopicName &&other) noexcept { swap(other); return *this; } 34 | #endif 35 | 36 | void swap(QMqttTopicName &other) noexcept { d.swap(other.d); } 37 | 38 | QString name() const; 39 | void setName(const QString &name); 40 | 41 | Q_REQUIRED_RESULT bool isValid() const; 42 | Q_REQUIRED_RESULT int levelCount() const; 43 | Q_REQUIRED_RESULT QStringList levels() const; 44 | 45 | friend Q_MQTT_EXPORT bool operator==(const QMqttTopicName &lhs, const QMqttTopicName &rhs) Q_DECL_NOTHROW; 46 | friend inline bool operator!=(const QMqttTopicName &lhs, const QMqttTopicName &rhs) Q_DECL_NOTHROW { return !(lhs == rhs); } 47 | friend Q_MQTT_EXPORT bool operator<(const QMqttTopicName &lhs, const QMqttTopicName &rhs) Q_DECL_NOTHROW; 48 | friend Q_MQTT_EXPORT size_t qHash(const QMqttTopicName &name, size_t seed) Q_DECL_NOTHROW; 49 | 50 | private: 51 | QExplicitlySharedDataPointer d; 52 | }; 53 | 54 | Q_DECLARE_SHARED(QMqttTopicName) 55 | 56 | #ifndef QT_NO_DATASTREAM 57 | Q_MQTT_EXPORT QDataStream &operator<<(QDataStream &, const QMqttTopicName &); 58 | Q_MQTT_EXPORT QDataStream &operator>>(QDataStream &, QMqttTopicName &); 59 | #endif 60 | 61 | #ifndef QT_NO_DEBUG_STREAM 62 | Q_MQTT_EXPORT QDebug operator<<(QDebug, const QMqttTopicName &); 63 | #endif 64 | 65 | QT_END_NAMESPACE 66 | 67 | Q_DECLARE_METATYPE(QMqttTopicName) 68 | 69 | #endif // QMQTTTOPICNAME_H 70 | -------------------------------------------------------------------------------- /examples/mqtt/websocketsubscription/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "clientsubscription.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace Qt::StringLiterals; 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | QCoreApplication a(argc, argv); 15 | QCoreApplication::setApplicationVersion("1.0"); 16 | 17 | QCommandLineParser parser; 18 | parser.setApplicationDescription(u"Websocket MQTT subscription tool"_s); 19 | auto help = parser.addHelpOption(); 20 | 21 | // Use http://www.hivemq.com/demos/websocket-client/ in browser to publish 22 | QCommandLineOption urlOption(QStringList{ u"host"_s, u"url"_s, u"broker"_s }, 23 | u"Host to connect to, eg ws://broker.hivemq.com:8000/mqtt"_s, 24 | u"host"_s); 25 | parser.addOption(urlOption); 26 | 27 | QCommandLineOption subscriptionOption(QStringList{ u"t"_s, u"topic"_s }, 28 | u"Topic to subscribe to"_s, u"topic"_s); 29 | parser.addOption(subscriptionOption); 30 | 31 | QCommandLineOption debugOption(QStringList{ u"d"_s, u"debug"_s }, u"Enable Debug mode"_s); 32 | parser.addOption(debugOption); 33 | 34 | QCommandLineOption versionOption(QStringList{ u"v"_s, u"version"_s }, 35 | u"MQTT protocol version.\n3: MQTT 3.1\n4: MQTT 3.1.1"_s, 36 | u"version"_s, u"3"_s); 37 | parser.addOption(versionOption); 38 | 39 | parser.process(a.arguments()); 40 | 41 | const QString debugLog = QString::fromLatin1("qtdemo.websocket.mqtt*=%1").arg( 42 | parser.isSet(debugOption) ? "true" : "false"); 43 | QLoggingCategory::setFilterRules(debugLog); 44 | 45 | ClientSubscription clientsub; 46 | clientsub.setUrl(QUrl(parser.value(urlOption))); 47 | clientsub.setTopic(parser.value(subscriptionOption)); 48 | 49 | const QString versionString = parser.value(versionOption); 50 | 51 | if (versionString == "4") { 52 | clientsub.setVersion(4); 53 | } else if (versionString == "3") { 54 | clientsub.setVersion(3); 55 | } else { 56 | qInfo() << "Unknown MQTT version"; 57 | return -2; 58 | } 59 | 60 | clientsub.connectAndSubscribe(); 61 | return a.exec(); 62 | } 63 | -------------------------------------------------------------------------------- /src/mqtt/qmqttsubscription.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTSUBSCRIPTION_H 6 | #define QMQTTSUBSCRIPTION_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | QT_BEGIN_NAMESPACE 15 | 16 | class QMqttClient; 17 | class QMqttSubscriptionPrivate; 18 | 19 | class Q_MQTT_EXPORT QMqttSubscription : public QObject 20 | { 21 | Q_OBJECT 22 | Q_ENUMS(SubscriptionState) 23 | Q_PROPERTY(SubscriptionState state READ state NOTIFY stateChanged) 24 | Q_PROPERTY(quint8 qos READ qos NOTIFY qosChanged) 25 | Q_PROPERTY(QMqttTopicFilter topic READ topic) 26 | Q_PROPERTY(QString reason READ reason) 27 | Q_PROPERTY(QMqtt::ReasonCode reasonCode READ reasonCode) 28 | Q_PROPERTY(bool sharedSubscription READ isSharedSubscription) 29 | Q_PROPERTY(QString sharedSubscriptionName READ sharedSubscriptionName) 30 | public: 31 | ~QMqttSubscription() override; 32 | enum SubscriptionState { 33 | Unsubscribed = 0, 34 | SubscriptionPending, 35 | Subscribed, 36 | UnsubscriptionPending, 37 | Error 38 | }; 39 | 40 | SubscriptionState state() const; 41 | QMqttTopicFilter topic() const; 42 | quint8 qos() const; 43 | QString reason() const; 44 | QMqtt::ReasonCode reasonCode() const; 45 | QMqttUserProperties userProperties() const; 46 | 47 | bool isSharedSubscription() const; 48 | QString sharedSubscriptionName() const; 49 | 50 | Q_SIGNALS: 51 | void stateChanged(SubscriptionState state); 52 | void qosChanged(quint8); // only emitted when broker provides different QoS than requested 53 | void messageReceived(QMqttMessage msg); 54 | 55 | public Q_SLOTS: 56 | void unsubscribe(); 57 | 58 | private: 59 | Q_DECLARE_PRIVATE(QMqttSubscription) 60 | Q_DISABLE_COPY(QMqttSubscription) 61 | void setState(SubscriptionState state); 62 | void setTopic(const QMqttTopicFilter &topic); 63 | void setClient(QMqttClient *client); 64 | void setQos(quint8 qos); 65 | void setSharedSubscription(bool s); 66 | void setSharedSubscriptionName(const QString &name); 67 | friend class QMqttConnection; 68 | friend class QMqttClient; 69 | explicit QMqttSubscription(QObject *parent = nullptr); 70 | }; 71 | 72 | QT_END_NAMESPACE 73 | 74 | #endif // QMQTTSUBSCRIPTION_H 75 | -------------------------------------------------------------------------------- /examples/mqtt/websocketsubscription/clientsubscription.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "clientsubscription.h" 5 | 6 | #include 7 | #include 8 | 9 | Q_LOGGING_CATEGORY(lcWebSocketMqtt, "qtdemo.websocket.mqtt") 10 | 11 | ClientSubscription::ClientSubscription(QObject *parent) : QObject(parent) 12 | { 13 | connect(this, &ClientSubscription::errorOccured, qApp, &QCoreApplication::quit); 14 | } 15 | 16 | void ClientSubscription::setUrl(const QUrl &url) 17 | { 18 | m_url = url; 19 | } 20 | 21 | void ClientSubscription::setTopic(const QString &topic) 22 | { 23 | m_topic = topic; 24 | } 25 | 26 | void ClientSubscription::setVersion(int v) 27 | { 28 | m_version = v; 29 | } 30 | 31 | void ClientSubscription::connectAndSubscribe() 32 | { 33 | qCDebug(lcWebSocketMqtt) << "Connecting to broker at " << m_url; 34 | 35 | m_device.setUrl(m_url); 36 | m_device.setProtocol(m_version == 3 ? "mqttv3.1" : "mqtt"); 37 | 38 | connect(&m_device, &WebSocketIODevice::socketConnected, this, [this]() { 39 | qCDebug(lcWebSocketMqtt) << "WebSocket connected, initializing MQTT connection."; 40 | 41 | m_client.setProtocolVersion(m_version == 3 ? QMqttClient::MQTT_3_1 : QMqttClient::MQTT_3_1_1); 42 | m_client.setTransport(&m_device, QMqttClient::IODevice); 43 | 44 | connect(&m_client, &QMqttClient::connected, this, [this]() { 45 | qCDebug(lcWebSocketMqtt) << "MQTT connection established"; 46 | 47 | m_subscription = m_client.subscribe(m_topic); 48 | if (!m_subscription) { 49 | qDebug() << "Failed to subscribe to " << m_topic; 50 | emit errorOccured(); 51 | } 52 | 53 | connect(m_subscription, &QMqttSubscription::stateChanged, 54 | [](QMqttSubscription::SubscriptionState s) { 55 | qCDebug(lcWebSocketMqtt) << "Subscription state changed:" << s; 56 | }); 57 | 58 | connect(m_subscription, &QMqttSubscription::messageReceived, 59 | [this](QMqttMessage msg) { 60 | handleMessage(msg.payload()); 61 | }); 62 | }); 63 | 64 | m_client.connectToHost(); 65 | }); 66 | if (!m_device.open(QIODevice::ReadWrite)) 67 | qDebug() << "Could not open socket device"; 68 | } 69 | 70 | void ClientSubscription::handleMessage(const QByteArray &msgContent) 71 | { 72 | // Should happen when the internal device has ready read? 73 | qInfo() << "New message:" << msgContent; 74 | } 75 | -------------------------------------------------------------------------------- /src/mqtt/qmqtttopicfilter.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 Lorenz Haas 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QMQTTTOPICFILTER_H 6 | #define QMQTTTOPICFILTER_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | QT_BEGIN_NAMESPACE 16 | 17 | class QMqttTopicFilterPrivate; 18 | 19 | class QMqttTopicFilter; 20 | // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) 21 | Q_MQTT_EXPORT size_t qHash(const QMqttTopicFilter &name, size_t seed = 0) Q_DECL_NOTHROW; 22 | 23 | class Q_MQTT_EXPORT QMqttTopicFilter 24 | { 25 | public: 26 | enum MatchOption { 27 | NoMatchOption = 0x0000, 28 | WildcardsDontMatchDollarTopicMatchOption = 0x0001 29 | }; 30 | Q_DECLARE_FLAGS(MatchOptions, MatchOption) 31 | 32 | QMqttTopicFilter(const QString &filter = QString()); 33 | QMqttTopicFilter(const QLatin1String &filter); 34 | QMqttTopicFilter(const QMqttTopicFilter &filter); 35 | ~QMqttTopicFilter(); 36 | QMqttTopicFilter &operator=(const QMqttTopicFilter &filter); 37 | 38 | #ifdef Q_COMPILER_RVALUE_REFS 39 | QMqttTopicFilter &operator=(QMqttTopicFilter &&other) noexcept { swap(other); return *this; } 40 | #endif 41 | 42 | void swap(QMqttTopicFilter &other) noexcept { d.swap(other.d); } 43 | 44 | QString filter() const; 45 | void setFilter(const QString &filter); 46 | 47 | QString sharedSubscriptionName() const; 48 | 49 | Q_REQUIRED_RESULT bool isValid() const; 50 | Q_REQUIRED_RESULT bool match(const QMqttTopicName &name, MatchOptions matchOptions = NoMatchOption) const; 51 | 52 | friend Q_MQTT_EXPORT bool operator==(const QMqttTopicFilter &lhs, const QMqttTopicFilter &rhs) Q_DECL_NOTHROW; 53 | friend inline bool operator!=(const QMqttTopicFilter &lhs, const QMqttTopicFilter &rhs) Q_DECL_NOTHROW { return !(lhs == rhs); } 54 | friend Q_MQTT_EXPORT bool operator<(const QMqttTopicFilter &lhs, const QMqttTopicFilter &rhs) Q_DECL_NOTHROW; 55 | friend Q_MQTT_EXPORT size_t qHash(const QMqttTopicFilter &filter, size_t seed) Q_DECL_NOTHROW; 56 | 57 | private: 58 | QExplicitlySharedDataPointer d; 59 | }; 60 | 61 | Q_DECLARE_SHARED(QMqttTopicFilter) 62 | Q_DECLARE_OPERATORS_FOR_FLAGS(QMqttTopicFilter::MatchOptions) 63 | 64 | #ifndef QT_NO_DATASTREAM 65 | Q_MQTT_EXPORT QDataStream &operator<<(QDataStream &, const QMqttTopicFilter &); 66 | Q_MQTT_EXPORT QDataStream &operator>>(QDataStream &, QMqttTopicFilter &); 67 | #endif 68 | 69 | #ifndef QT_NO_DEBUG_STREAM 70 | Q_MQTT_EXPORT QDebug operator<<(QDebug, const QMqttTopicFilter &); 71 | #endif 72 | 73 | QT_END_NAMESPACE 74 | 75 | Q_DECLARE_METATYPE(QMqttTopicFilter) 76 | 77 | #endif // QMQTTTOPICFILTER_H 78 | -------------------------------------------------------------------------------- /src/mqtt/transportLayers/mqtt_websocket_io_base_p.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #ifndef QTMQTTCLIENT_WEBSOCKET_IODEVICE_BASE_H 6 | #define QTMQTTCLIENT_WEBSOCKET_IODEVICE_BASE_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Qt API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #ifdef QT_MQTT_WITH_WEBSOCKETS 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "qmqttclient.h" 26 | 27 | QT_BEGIN_NAMESPACE 28 | 29 | class QMqttWebSocketIOBase : public QIODevice 30 | { 31 | Q_OBJECT 32 | protected: 33 | QMqttWebSocketIOBase(QObject *parent = nullptr, QWebSocket *webSocket = nullptr); 34 | 35 | public: 36 | Q_DISABLE_COPY_MOVE(QMqttWebSocketIOBase) 37 | 38 | ~QMqttWebSocketIOBase() override; 39 | 40 | bool open(OpenMode mode) override; 41 | void close() override; 42 | 43 | qint64 readData(char *data, qint64 maxlen) override; 44 | qint64 writeData(const char *data, qint64 len) override; 45 | 46 | void setProtocol(QMqttClient::ProtocolVersion version); 47 | void setProtocol(const QByteArray &data); 48 | 49 | bool isSequential() const override 50 | { 51 | return true; 52 | } 53 | 54 | qint64 bytesAvailable() const override 55 | { 56 | return static_cast(m_buffer.size()) + QIODevice::bytesAvailable(); 57 | } 58 | 59 | bool waitForBytesWritten(int msecs) override 60 | { 61 | Q_UNUSED(msecs); 62 | m_socket->flush(); 63 | return true; 64 | } 65 | 66 | bool isConnected() const 67 | { 68 | return (m_socket->state() == QAbstractSocket::ConnectedState); 69 | } 70 | 71 | QAbstractSocket::SocketState state() const 72 | { 73 | return m_socket->state(); 74 | } 75 | 76 | bool isExternalSocket() const 77 | { 78 | return m_externalSocket; 79 | } 80 | Q_SIGNALS: 81 | void disconnected(); 82 | void errorOccurred(QAbstractSocket::SocketError error); 83 | 84 | public slots: 85 | void doSocketHandleBinaryMessage(const QByteArray &msg); 86 | void doSocketDisconnected(); 87 | void doSocketErrorOccured(QAbstractSocket::SocketError error); 88 | 89 | protected: 90 | std::shared_ptr m_socket; 91 | bool m_externalSocket = false; 92 | QByteArray m_protocol; 93 | QByteArray m_buffer; 94 | }; 95 | 96 | QT_END_NAMESPACE 97 | 98 | #endif /* QT_MQTT_WITH_WEBSOCKETS */ 99 | 100 | #endif /* QTMQTTCLIENT_WEBSOCKET_IODEVICE_BASE_H */ 101 | -------------------------------------------------------------------------------- /src/mqtt/doc/style/style.css: -------------------------------------------------------------------------------- 1 | a:link, a:visited { 2 | color: #00732F; 3 | text-decoration: none; 4 | font-weight: bold; 5 | } 6 | 7 | body { 8 | font: normal 400 14px/1.2 Arial; 9 | margin-top: 85px; 10 | } 11 | 12 | h1 { 13 | margin: 0; 14 | } 15 | 16 | h2 { 17 | font: 500 20px/1.2 Arial; 18 | } 19 | 20 | h3.fn, span.fn { 21 | -moz-border-radius: 7px 7px 7px 7px; 22 | -webkit-border-radius: 7px 7px 7px 7px; 23 | border-radius: 7px 7px 7px 7px; 24 | background-color: #F6F6F6; 25 | border-width: 1px; 26 | border-style: solid; 27 | border-color: #E6E6E6; 28 | word-spacing: 3px; 29 | padding: 3px 5px; 30 | } 31 | 32 | table, pre { 33 | -moz-border-radius: 7px 7px 7px 7px; 34 | -webkit-border-radius: 7px 7px 7px 7px; 35 | border-radius: 7px 7px 7px 7px; 36 | background-color: #F6F6F6; 37 | border: 1px solid #E6E6E6; 38 | border-collapse: separate; 39 | font-size: 12px; 40 | line-height: 1.2; 41 | margin-bottom: 25px; 42 | margin-left: 15px; 43 | } 44 | 45 | table td { 46 | padding: 3px 15px 3px 20px; 47 | } 48 | 49 | table tr.even { 50 | background-color: white; 51 | color: #66666E; 52 | } 53 | 54 | table tr.odd { 55 | background-color: #F6F6F6; 56 | color: #66666E; 57 | } 58 | 59 | li { 60 | margin-bottom: 10px; 61 | padding-left: 12px; 62 | } 63 | 64 | .cpp { 65 | display: block; 66 | margin: 10; 67 | overflow: hidden; 68 | overflow-x: hidden; 69 | overflow-y: hidden; 70 | padding: 20px 0 20px 0; 71 | } 72 | 73 | .footer { 74 | margin-top: 50px; 75 | } 76 | 77 | .memItemLeft { 78 | padding-right: 3px; 79 | } 80 | 81 | .memItemRight { 82 | padding: 3px 15px 3px 0; 83 | } 84 | 85 | .qml { 86 | display: block; 87 | margin: 10; 88 | overflow: hidden; 89 | overflow-x: hidden; 90 | overflow-y: hidden; 91 | padding: 20px 0 20px 0; 92 | } 93 | 94 | .qmldefault { 95 | padding-left: 5px; 96 | float: right; 97 | color: red; 98 | } 99 | 100 | .qmlreadonly { 101 | padding-left: 5px; 102 | float: right; 103 | color: #254117; 104 | } 105 | 106 | .rightAlign { 107 | padding: 3px 5px 3px 10px; 108 | text-align: right; 109 | } 110 | 111 | .title { 112 | background-color: white; 113 | color: #44A51C; 114 | font-family: Verdana; 115 | font-size: 35px; 116 | font-weight: normal; 117 | left: 0; 118 | padding-bottom: 5px; 119 | padding-left: 16px; 120 | padding-top: 20px; 121 | position: absolute; 122 | right: 0; 123 | top: 0; 124 | } 125 | 126 | .toc { 127 | float: right; 128 | -moz-border-radius: 7px 7px 7px 7px; 129 | -webkit-border-radius: 7px 7px 7px 7px; 130 | border-radius: 7px 7px 7px 7px; 131 | background-color: #F6F6F6; 132 | border: 1px solid #DDD; 133 | margin: 0 20px 10px 10px; 134 | padding: 20px 15px 20px 20px; 135 | height: auto; 136 | width: 200px; 137 | } 138 | -------------------------------------------------------------------------------- /src/mqtt/qmqttpublishproperties.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | #ifndef QMQTTPUBLISHPROPERTIES_H 5 | #define QMQTTPUBLISHPROPERTIES_H 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | QT_BEGIN_NAMESPACE 14 | 15 | class QMqttPublishPropertiesData; 16 | class QMqttMessageStatusPropertiesData; 17 | 18 | class Q_MQTT_EXPORT QMqttPublishProperties 19 | { 20 | public: 21 | enum PublishPropertyDetail : quint32 { 22 | None = 0x00000000, 23 | PayloadFormatIndicator = 0x00000001, 24 | MessageExpiryInterval = 0x00000002, 25 | TopicAlias = 0x00000004, 26 | ResponseTopic = 0x00000008, 27 | CorrelationData = 0x00000010, 28 | UserProperty = 0x00000020, 29 | SubscriptionIdentifier = 0x00000040, 30 | ContentType = 0x00000080 31 | }; 32 | Q_DECLARE_FLAGS(PublishPropertyDetails, PublishPropertyDetail) 33 | 34 | QMqttPublishProperties(); 35 | QMqttPublishProperties(const QMqttPublishProperties &); 36 | QMqttPublishProperties &operator=(const QMqttPublishProperties &); 37 | ~QMqttPublishProperties(); 38 | 39 | PublishPropertyDetails availableProperties() const; 40 | 41 | QMqtt::PayloadFormatIndicator payloadFormatIndicator() const; 42 | void setPayloadFormatIndicator(QMqtt::PayloadFormatIndicator indicator); 43 | 44 | quint32 messageExpiryInterval() const; 45 | void setMessageExpiryInterval(quint32 interval); 46 | 47 | quint16 topicAlias() const; 48 | void setTopicAlias(quint16 alias); 49 | 50 | QString responseTopic() const; 51 | void setResponseTopic(const QString &topic); 52 | 53 | QByteArray correlationData() const; 54 | void setCorrelationData(const QByteArray &correlation); 55 | 56 | QMqttUserProperties userProperties() const; 57 | void setUserProperties(const QMqttUserProperties &properties); 58 | 59 | QList subscriptionIdentifiers() const; 60 | void setSubscriptionIdentifiers(const QList &ids); 61 | 62 | QString contentType() const; 63 | void setContentType(const QString &type); 64 | private: 65 | QSharedDataPointer data; 66 | }; 67 | 68 | Q_DECLARE_OPERATORS_FOR_FLAGS(QMqttPublishProperties::PublishPropertyDetails) 69 | 70 | class Q_MQTT_EXPORT QMqttMessageStatusProperties 71 | { 72 | public: 73 | QMqttMessageStatusProperties(); 74 | QMqttMessageStatusProperties(const QMqttMessageStatusProperties &); 75 | QMqttMessageStatusProperties &operator=(const QMqttMessageStatusProperties &); 76 | ~QMqttMessageStatusProperties(); 77 | 78 | QMqtt::ReasonCode reasonCode() const; 79 | QString reason() const; 80 | QMqttUserProperties userProperties() const; 81 | 82 | private: 83 | friend class QMqttConnection; 84 | QSharedDataPointer data; 85 | }; 86 | 87 | QT_END_NAMESPACE 88 | 89 | #endif // QMQTTPUBLISHPROPERTIES_H 90 | -------------------------------------------------------------------------------- /tests/auto/qmqtttopicname/tst_qmqtttopicname.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 Lorenz Haas 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class Tst_QMqttTopicName : public QObject 11 | { 12 | Q_OBJECT 13 | 14 | private Q_SLOTS: 15 | void checkValidity(); 16 | void checkLevelCount(); 17 | void checkLevels_data(); 18 | void checkLevels(); 19 | void usableWithQList(); 20 | void usableWithQMap(); 21 | void usableWithQHash(); 22 | }; 23 | 24 | void Tst_QMqttTopicName::checkValidity() 25 | { 26 | QVERIFY(QMqttTopicName("a").isValid()); 27 | QVERIFY(QMqttTopicName("/").isValid()); 28 | QVERIFY(QMqttTopicName("a b").isValid()); 29 | 30 | QVERIFY(!QMqttTopicName("").isValid()); 31 | QVERIFY(!QMqttTopicName("/a/#").isValid()); 32 | QVERIFY(!QMqttTopicName("/+/a").isValid()); 33 | QVERIFY(!QMqttTopicName(QString(3, QChar(QChar::Null))).isValid()); 34 | } 35 | 36 | void Tst_QMqttTopicName::checkLevelCount() 37 | { 38 | QCOMPARE(QMqttTopicName("a").levelCount(), 1); 39 | QCOMPARE(QMqttTopicName("/").levelCount(), 2); 40 | QCOMPARE(QMqttTopicName("/a").levelCount(), 2); 41 | QCOMPARE(QMqttTopicName("a/").levelCount(), 2); 42 | QCOMPARE(QMqttTopicName("a/b").levelCount(), 2); 43 | QCOMPARE(QMqttTopicName("a/b/").levelCount(), 3); 44 | } 45 | 46 | void Tst_QMqttTopicName::checkLevels_data() 47 | { 48 | QTest::addColumn("name"); 49 | QTest::addColumn("levels"); 50 | 51 | QTest::newRow("1") << QMqttTopicName("a") << QStringList{"a"}; 52 | QTest::newRow("2") << QMqttTopicName("/") << QStringList{"", ""}; 53 | QTest::newRow("3") << QMqttTopicName("//") << QStringList{"", "", ""}; 54 | QTest::newRow("4") << QMqttTopicName("a/") << QStringList{"a", ""}; 55 | QTest::newRow("5") << QMqttTopicName("/a") << QStringList{"", "a"}; 56 | QTest::newRow("6") << QMqttTopicName("a/b") << QStringList{"a", "b"}; 57 | QTest::newRow("7") << QMqttTopicName("a/b/") << QStringList{"a", "b", ""}; 58 | QTest::newRow("8") << QMqttTopicName("/a/b") << QStringList{"", "a", "b"}; 59 | } 60 | 61 | void Tst_QMqttTopicName::checkLevels() 62 | { 63 | QFETCH(QMqttTopicName, name); 64 | QFETCH(QStringList, levels); 65 | 66 | QCOMPARE(name.levels(), levels); 67 | } 68 | 69 | void Tst_QMqttTopicName::usableWithQList() 70 | { 71 | const QMqttTopicName topic{"a/b"}; 72 | QList names; 73 | names.append(topic); 74 | QCOMPARE(topic, names.constFirst()); 75 | } 76 | 77 | void Tst_QMqttTopicName::usableWithQMap() 78 | { 79 | const QMqttTopicName topic{"a/b"}; 80 | QMap names; 81 | names.insert(topic, 42); 82 | QCOMPARE(names[topic], 42); 83 | } 84 | 85 | void Tst_QMqttTopicName::usableWithQHash() 86 | { 87 | const QMqttTopicName topic{"a/b"}; 88 | QHash names; 89 | names.insert(topic, 42); 90 | QCOMPARE(names[topic], 42); 91 | } 92 | 93 | QTEST_MAIN(Tst_QMqttTopicName) 94 | 95 | #include "tst_qmqtttopicname.moc" 96 | -------------------------------------------------------------------------------- /src/mqtt/qmqttcontrolpacket.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:critical reason:network-protocol 4 | 5 | #include "qmqttcontrolpacket_p.h" 6 | 7 | #include 8 | #include 9 | 10 | QT_BEGIN_NAMESPACE 11 | 12 | QMqttControlPacket::QMqttControlPacket() 13 | { 14 | 15 | } 16 | 17 | QMqttControlPacket::QMqttControlPacket(quint8 header) 18 | : m_header(header) 19 | { 20 | 21 | } 22 | 23 | QMqttControlPacket::QMqttControlPacket(quint8 header, const QByteArray &pay) 24 | : m_header(header) 25 | , m_payload(pay) 26 | { 27 | 28 | } 29 | 30 | void QMqttControlPacket::clear() 31 | { 32 | m_header = 0; 33 | m_payload.clear(); 34 | } 35 | 36 | void QMqttControlPacket::setHeader(quint8 h) 37 | { 38 | if (h < QMqttControlPacket::CONNECT || h > DISCONNECT || h & 0x0F) 39 | m_header = QMqttControlPacket::UNKNOWN; 40 | else 41 | m_header = h; 42 | } 43 | 44 | void QMqttControlPacket::append(char value) 45 | { 46 | m_payload.append(value); 47 | } 48 | 49 | void QMqttControlPacket::append(quint16 value) 50 | { 51 | const quint16 msb = qToBigEndian(value); 52 | const char * msb_c = reinterpret_cast(&msb); 53 | m_payload.append(msb_c, 2); 54 | } 55 | 56 | void QMqttControlPacket::append(quint32 value) 57 | { 58 | const quint32 msb = qToBigEndian(value); 59 | const char * msb_c = reinterpret_cast(&msb); 60 | m_payload.append(msb_c, 4); 61 | } 62 | 63 | void QMqttControlPacket::append(const QByteArray &data) 64 | { 65 | append(static_cast(data.size())); 66 | m_payload.append(data); 67 | } 68 | 69 | void QMqttControlPacket::appendRaw(const QByteArray &data) 70 | { 71 | m_payload.append(data); 72 | } 73 | 74 | void QMqttControlPacket::appendRawVariableInteger(quint32 value) 75 | { 76 | QByteArray data; 77 | // Add length 78 | if (value > 268435455) 79 | qCDebug(lcMqttClient) << "Attempting to write variable integer overflow."; 80 | do { 81 | quint8 b = value % 128; 82 | value /= 128; 83 | if (value > 0) 84 | b |= 0x80; 85 | data.append(char(b)); 86 | } while (value > 0); 87 | appendRaw(data); 88 | } 89 | 90 | QByteArray QMqttControlPacket::serialize() const 91 | { 92 | // Create ByteArray 93 | QByteArray data; 94 | // Add Header 95 | data.append(char(m_header)); 96 | data.append(serializePayload()); 97 | 98 | return data; 99 | } 100 | 101 | QByteArray QMqttControlPacket::serializePayload() const 102 | { 103 | QByteArray data; 104 | // Add length 105 | quint32 msgSize = quint32(m_payload.size()); 106 | if (msgSize > 268435455) 107 | qCDebug(lcMqttClient) << "Publishing a message bigger than maximum size."; 108 | do { 109 | quint8 b = msgSize % 128; 110 | msgSize /= 128; 111 | if (msgSize > 0) 112 | b |= 0x80; 113 | data.append(char(b)); 114 | } while (msgSize > 0); 115 | // Add payload 116 | data.append(m_payload); 117 | return data; 118 | } 119 | 120 | QT_END_NAMESPACE 121 | 122 | -------------------------------------------------------------------------------- /src/mqtt/qmqttauthenticationproperties.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #include "qmqttauthenticationproperties.h" 6 | 7 | QT_BEGIN_NAMESPACE 8 | 9 | /*! 10 | \class QMqttAuthenticationProperties 11 | 12 | \inmodule QtMqtt 13 | \since 5.12 14 | 15 | \brief The QMqttAuthenticationProperties class represents configuration 16 | options during the authentication process. 17 | 18 | \note Authentication properties are part of the MQTT 5.0 specification and 19 | cannot be used when connecting with a lower protocol level. See 20 | QMqttClient::ProtocolVersion for more information. 21 | */ 22 | 23 | class QMqttAuthenticationPropertiesData : public QSharedData 24 | { 25 | public: 26 | QString authenticationMethod; 27 | QByteArray authenticationData; 28 | QString reason; 29 | QMqttUserProperties userProperties; 30 | }; 31 | 32 | /*! 33 | \internal 34 | */ 35 | QMqttAuthenticationProperties::QMqttAuthenticationProperties() : data(new QMqttAuthenticationPropertiesData) 36 | { 37 | 38 | } 39 | 40 | /*! 41 | \internal 42 | */ 43 | QMqttAuthenticationProperties::QMqttAuthenticationProperties(const QMqttAuthenticationProperties &) = default; 44 | 45 | QMqttAuthenticationProperties &QMqttAuthenticationProperties::operator=(const QMqttAuthenticationProperties &rhs) 46 | { 47 | if (this != &rhs) 48 | data.operator=(rhs.data); 49 | return *this; 50 | } 51 | 52 | QMqttAuthenticationProperties::~QMqttAuthenticationProperties() = default; 53 | 54 | /*! 55 | Returns the authentication method. 56 | */ 57 | QString QMqttAuthenticationProperties::authenticationMethod() const 58 | { 59 | return data->authenticationMethod; 60 | } 61 | 62 | /*! 63 | Sets the authentication method to \a method. 64 | */ 65 | void QMqttAuthenticationProperties::setAuthenticationMethod(const QString &method) 66 | { 67 | data->authenticationMethod = method; 68 | } 69 | 70 | /*! 71 | Returns the authentication data 72 | */ 73 | QByteArray QMqttAuthenticationProperties::authenticationData() const 74 | { 75 | return data->authenticationData; 76 | } 77 | 78 | /*! 79 | Sets the authentication data to \a adata. 80 | 81 | Authentication data can only be used if an authentication method has 82 | been specified. 83 | 84 | \sa authenticationMethod() 85 | */ 86 | void QMqttAuthenticationProperties::setAuthenticationData(const QByteArray &adata) 87 | { 88 | data->authenticationData = adata; 89 | } 90 | 91 | /*! 92 | Returns the reason string. The reason string specifies the reason for 93 | a disconnect. 94 | */ 95 | QString QMqttAuthenticationProperties::reason() const 96 | { 97 | return data->reason; 98 | } 99 | 100 | /*! 101 | Sets the reason string to \a r. 102 | */ 103 | void QMqttAuthenticationProperties::setReason(const QString &r) 104 | { 105 | data->reason = r; 106 | } 107 | 108 | /*! 109 | Returns the user properties. 110 | */ 111 | QMqttUserProperties QMqttAuthenticationProperties::userProperties() const 112 | { 113 | return data->userProperties; 114 | } 115 | 116 | /*! 117 | Sets the user properties to \a user. 118 | */ 119 | void QMqttAuthenticationProperties::setUserProperties(const QMqttUserProperties &user) 120 | { 121 | data->userProperties = user; 122 | } 123 | 124 | QT_END_NAMESPACE 125 | -------------------------------------------------------------------------------- /src/mqtt/transportLayers/mqtt_websocket_io_base.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | #include "mqtt_websocket_io_base_p.h" 5 | 6 | #ifdef QT_MQTT_WITH_WEBSOCKETS 7 | 8 | QMqttWebSocketIOBase::~QMqttWebSocketIOBase() 9 | { 10 | disconnect(m_socket.get(), &QWebSocket::disconnected, this, &QMqttWebSocketIOBase::doSocketDisconnected); 11 | disconnect(m_socket.get(), &QWebSocket::errorOccurred, this, &QMqttWebSocketIOBase::doSocketErrorOccured); 12 | disconnect(m_socket.get(), &QWebSocket::binaryMessageReceived, this, &QMqttWebSocketIOBase::doSocketHandleBinaryMessage); 13 | } 14 | 15 | QMqttWebSocketIOBase::QMqttWebSocketIOBase(QObject *parent, QWebSocket *webSocket) 16 | : 17 | QIODevice(parent) 18 | { 19 | m_externalSocket = (webSocket != nullptr); 20 | 21 | if (webSocket) 22 | m_socket = std::shared_ptr(webSocket, [](QWebSocket *) { ; }); // skip deleter 23 | else 24 | m_socket = std::make_shared(); 25 | 26 | connect(m_socket.get(), &QWebSocket::disconnected, this, &QMqttWebSocketIOBase::doSocketDisconnected); 27 | connect(m_socket.get(), &QWebSocket::errorOccurred, this, &QMqttWebSocketIOBase::doSocketErrorOccured); 28 | connect(m_socket.get(), &QWebSocket::binaryMessageReceived, this, &QMqttWebSocketIOBase::doSocketHandleBinaryMessage); 29 | 30 | setProtocol(QMqttClient::ProtocolVersion::MQTT_3_1); 31 | } 32 | 33 | bool QMqttWebSocketIOBase::open(QIODevice::OpenMode mode) 34 | { 35 | if (!QIODevice::open(mode)) 36 | { 37 | close(); 38 | emit errorOccurred(QAbstractSocket::SocketResourceError); 39 | } 40 | // Will emit onConnectionEstablished or onConnectionError 41 | return false; 42 | } 43 | 44 | void QMqttWebSocketIOBase::close() 45 | { 46 | QIODevice::close(); 47 | } 48 | 49 | qint64 QMqttWebSocketIOBase::readData(char *data, qint64 maxlen) 50 | { 51 | qint64 bytesToRead = qMin(maxlen, (qint64)m_buffer.size()); 52 | memcpy(data, m_buffer.constData(), bytesToRead); 53 | m_buffer = m_buffer.right(m_buffer.size() - bytesToRead); 54 | return bytesToRead; 55 | } 56 | 57 | qint64 QMqttWebSocketIOBase::writeData(const char *data, qint64 len) 58 | { 59 | QByteArray msg(data, len); 60 | const int length = m_socket->sendBinaryMessage(msg); 61 | emit bytesWritten(length); 62 | return length; 63 | } 64 | 65 | void QMqttWebSocketIOBase::setProtocol(QMqttClient::ProtocolVersion version) 66 | { 67 | switch (version) { 68 | case QMqttClient::ProtocolVersion::MQTT_3_1: 69 | setProtocol("mqttv3.1"); 70 | break; 71 | case QMqttClient::ProtocolVersion::MQTT_3_1_1: 72 | setProtocol("mqtt"); 73 | break; 74 | case QMqttClient::ProtocolVersion::MQTT_5_0: 75 | setProtocol("mqtt"); 76 | break; 77 | } /* end-switch */ 78 | } 79 | 80 | void QMqttWebSocketIOBase::setProtocol(const QByteArray &data) 81 | { 82 | m_protocol = data; 83 | } 84 | 85 | void QMqttWebSocketIOBase::doSocketHandleBinaryMessage(const QByteArray &msg) 86 | { 87 | m_buffer.append(msg); 88 | emit readyRead(); 89 | } 90 | 91 | void QMqttWebSocketIOBase::doSocketDisconnected() 92 | { 93 | emit disconnected(); 94 | } 95 | 96 | void QMqttWebSocketIOBase::doSocketErrorOccured(QAbstractSocket::SocketError error) 97 | { 98 | emit errorOccurred(error); 99 | } 100 | 101 | #include "moc_mqtt_websocket_io_base_p.cpp" 102 | 103 | #endif /* QT_MQTT_WITH_WEBSOCKETS */ 104 | -------------------------------------------------------------------------------- /tests/auto/qmqttsubscriptionproperties/tst_qmqttsubscriptionproperties.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | #include "broker_connection.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class tst_QMqttSubscriptionProperties : public QObject 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | tst_QMqttSubscriptionProperties(); 19 | 20 | private Q_SLOTS: 21 | void initTestCase(); 22 | void cleanupTestCase(); 23 | void getSet(); 24 | void subscribe(); 25 | 26 | private: 27 | QProcess m_brokerProcess; 28 | QString m_testBroker; 29 | quint16 m_port{0}; 30 | }; 31 | 32 | tst_QMqttSubscriptionProperties::tst_QMqttSubscriptionProperties() 33 | { 34 | } 35 | 36 | void tst_QMqttSubscriptionProperties::initTestCase() 37 | { 38 | m_testBroker = invokeOrInitializeBroker(&m_brokerProcess); 39 | if (m_testBroker.isEmpty()) 40 | qFatal("No MQTT broker present to test against."); 41 | } 42 | 43 | void tst_QMqttSubscriptionProperties::cleanupTestCase() 44 | { 45 | } 46 | 47 | void tst_QMqttSubscriptionProperties::getSet() 48 | { 49 | QMqttSubscriptionProperties properties; 50 | 51 | const quint32 id = 123; 52 | properties.setSubscriptionIdentifier(id); 53 | QCOMPARE(properties.subscriptionIdentifier(), id); 54 | 55 | QCOMPARE(properties.noLocal(), false); 56 | properties.setNoLocal(true); 57 | QCOMPARE(properties.noLocal(), true); 58 | 59 | const QString userKey1 = QLatin1String("UserName1"); 60 | const QString userValue1 = QLatin1String("SomeValue"); 61 | const QString userKey2 = QLatin1String("UserName2"); 62 | const QString userValue2 = QLatin1String("OtherValue"); 63 | QMqttUserProperties userProperty; 64 | QCOMPARE(properties.userProperties(), userProperty); 65 | userProperty.append(QMqttStringPair(userKey1, userValue1)); 66 | userProperty.append(QMqttStringPair(userKey2, userValue2)); 67 | properties.setUserProperties(userProperty); 68 | QCOMPARE(properties.userProperties(), userProperty); 69 | } 70 | 71 | void tst_QMqttSubscriptionProperties::subscribe() 72 | { 73 | VersionClient(QMqttClient::MQTT_5_0, client); 74 | client.setHostname(m_testBroker); 75 | client.setPort(m_port); 76 | 77 | QMqttConnectionProperties conProperties; 78 | conProperties.setRequestResponseInformation(true); 79 | conProperties.setRequestProblemInformation(true); 80 | client.setConnectionProperties(conProperties); 81 | 82 | client.connectToHost(); 83 | QTRY_VERIFY2(client.state() == QMqttClient::Connected, "Could not connect to broker."); 84 | 85 | const QString topic = QLatin1String("sub/props"); 86 | 87 | QMqttSubscriptionProperties properties; 88 | properties.setSubscriptionIdentifier(10); 89 | const QString userKey1 = QLatin1String("UserName1"); 90 | const QString userValue1 = QLatin1String("SomeValue"); 91 | const QString userKey2 = QLatin1String("UserName2"); 92 | const QString userValue2 = QLatin1String("OtherValue"); 93 | QMqttUserProperties userProperty; 94 | userProperty.append(QMqttStringPair(userKey1, userValue1)); 95 | userProperty.append(QMqttStringPair(userKey2, userValue2)); 96 | 97 | auto sub = client.subscribe(topic, properties, 1); 98 | QTRY_COMPARE(sub->state(), QMqttSubscription::Subscribed); 99 | 100 | // ### TODO: Try to create a subscription which generates a reason code 101 | // and/or user properties. 102 | } 103 | 104 | QTEST_MAIN(tst_QMqttSubscriptionProperties) 105 | 106 | #include "tst_qmqttsubscriptionproperties.moc" 107 | -------------------------------------------------------------------------------- /examples/mqtt/doc/simpleclient.qdoc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only 3 | 4 | /*! 5 | \example simpleclient 6 | \examplecategory {Connectivity} 7 | \title Simple MQTT Client 8 | \ingroup qtmqtt-examples 9 | \brief Creating a minimalistic telemetry application. 10 | 11 | \image simpleclient.png 12 | 13 | \e {Simple MQTT Client} demonstrates how to create a minimalistic client 14 | application. 15 | 16 | To use the application, you first specify a Host, a Port, Secure on/off, 17 | WebSockets on/off, and Protocol. Then click on connect. Afterward you can 18 | subscribe to a topic and send a message, which you will also receive. 19 | You may also run the application twice. Publish in one and Subscribe in 20 | the other, and the messages shall be transmitted. 21 | 22 | \section1 simpleclient Options 23 | \list 24 | \li Host - you may use test.mosquitto.org or broker.hivemq.com 25 | \li Port - port to connect to, will depend on WebSockets selection and Secure selection 26 | \li WebSockets - you may specify: selected (enabled) or not selected (disabled) 27 | \li Secure - you may specify: selected (enabled) or not selected (disabled) 28 | \li Protocol - you may specify 29 | \list 30 | \li mqtt 3.1 31 | \li mqtt 3.1.1 32 | \li mqtt 5.0 33 | \endlist 34 | \li Topic - A topic to publish or subscribe to 35 | \li Message - A message to send on the topic if you are publishing 36 | \endlist 37 | 38 | \section1 Connection Settings 39 | These are the usual combinations, and will work with test.mosquitto.org. 40 | For broker.hivemq.com check the information in the links. Note that if 41 | Secure is enabled it might be necessary to install certificates on the 42 | computer. It might also be necessary to add the certificate to the mqtt 43 | client in code. 44 | 45 | \section1 46 | \list 47 | \li Port 1883, Secure=disabled, WebSockets=disabled - mqtt over tcp 48 | \li Port 8883, Secure=enabled, WebSockets=disabled - mqtt over ssl 49 | \li Port 8080, Secure=disabled, WebSockets=enabled - mqtt over websockets 50 | \li Port 8081, Secure=enabled, WebSockets=enabled - mqtt over secure websockets 51 | \endlist 52 | 53 | For more information about the brokers see: 54 | \list 55 | \li \l {https://test.mosquitto.org} 56 | \li \l {https://broker.hivemq.com} 57 | \li \l {https://www.hivemq.com/mqtt/public-mqtt-broker} 58 | \endlist 59 | 60 | \note Port numbers 1883 and 8080 are not encrypted, and therefore they are 61 | suitable only for development and testing purposes. In production, always 62 | use encrypted connections. 63 | 64 | \note WebAssembly only supports WebSockets enabled. 65 | 66 | \section1 Creating a Client 67 | 68 | First, we use the QMqttClient class to create an MQTT client. The class 69 | provides properties for setting a unique client ID as well as the broker 70 | host name and port to connect to: 71 | 72 | \quotefromfile simpleclient/mainwindow.cpp 73 | \skipto m_client 74 | \printuntil setPort 75 | 76 | We do not set the client ID, and therefore it will be automatically 77 | generated for us. 78 | 79 | Next, we connect to QMqttClient::messageReceived() to receive all messages 80 | sent to the broker: 81 | 82 | \skipto messageReceived 83 | \printuntil } 84 | 85 | When users subscribe to topics in the client, we call 86 | QMqttClient::subscribe() on the specified topic: 87 | 88 | \skipto on_buttonSubscribe_clicked 89 | \printuntil } 90 | 91 | In this example, we subscribe to all topics. For more information about 92 | how to receive messages on particular topics, see the 93 | \l {MQTT Subscriptions} example. 94 | 95 | For an example of how to use the QMqttClient class in a Qt Quick 96 | application, see \l {Qt Quick Subscription}. 97 | */ 98 | -------------------------------------------------------------------------------- /tests/auto/qmqttcontrolpacket/tst_qmqttcontrolpacket.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Tst_QMqttControlPacket : public QObject 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | Tst_QMqttControlPacket(); 14 | 15 | private Q_SLOTS: 16 | void initTestCase(); 17 | void cleanupTestCase(); 18 | void header(); 19 | void append(); 20 | void simple_data(); 21 | void simple(); 22 | }; 23 | 24 | Tst_QMqttControlPacket::Tst_QMqttControlPacket() 25 | { 26 | } 27 | 28 | void Tst_QMqttControlPacket::initTestCase() 29 | { 30 | } 31 | 32 | void Tst_QMqttControlPacket::cleanupTestCase() 33 | { 34 | } 35 | 36 | void Tst_QMqttControlPacket::header() 37 | { 38 | #ifdef QT_BUILD_INTERNAL 39 | { 40 | QMqttControlPacket packet; 41 | QVERIFY(packet.header() == QMqttControlPacket::UNKNOWN); 42 | } 43 | { 44 | QMqttControlPacket packet(QMqttControlPacket::CONNECT); 45 | QVERIFY(packet.header() == QMqttControlPacket::CONNECT); 46 | 47 | packet.setHeader(QMqttControlPacket::DISCONNECT); 48 | QVERIFY(packet.header() == QMqttControlPacket::DISCONNECT); 49 | 50 | packet.clear(); 51 | QVERIFY(packet.header() == QMqttControlPacket::UNKNOWN); 52 | 53 | packet.setHeader(42); 54 | QVERIFY(packet.header() == QMqttControlPacket::UNKNOWN); 55 | } 56 | #else 57 | QSKIP("This test requires a Qt -developer-build."); 58 | #endif 59 | } 60 | 61 | void Tst_QMqttControlPacket::append() 62 | { 63 | #ifdef QT_BUILD_INTERNAL 64 | QMqttControlPacket packet; 65 | QCOMPARE(packet.payload().size(), 0); 66 | 67 | packet.append('0'); 68 | QCOMPARE(packet.payload().size(), 1); 69 | QVERIFY(packet.payload() == QByteArray("0")); 70 | 71 | packet.clear(); 72 | QCOMPARE(packet.payload().size(), 0); 73 | 74 | const quint16 value = 100; 75 | packet.append(value); 76 | QByteArray payload = packet.payload(); 77 | QCOMPARE(payload.size(), 2); 78 | const quint16 valueBigEndian = qToBigEndian(value); 79 | const quint16 payloadUint16 = *reinterpret_cast(payload.constData()); 80 | QCOMPARE(payloadUint16, valueBigEndian); 81 | 82 | packet.clear(); 83 | QCOMPARE(packet.payload().size(), 0); 84 | 85 | const QByteArray data("some data in the packet"); 86 | packet.append(data); 87 | payload = packet.payload(); 88 | QCOMPARE(payload.size(), data.size() + 2); 89 | 90 | const QByteArray partSize = payload.left(2); 91 | const QByteArray partContent = payload.mid(2); 92 | const int partSizeInt = qFromBigEndian(*reinterpret_cast(partSize.constData())); 93 | QCOMPARE(partSizeInt, data.size()); 94 | QCOMPARE(partContent, data); 95 | 96 | packet.clear(); 97 | packet.appendRaw(data); 98 | payload = packet.payload(); 99 | QCOMPARE(payload.size(), data.size()); 100 | QCOMPARE(payload, data); 101 | 102 | const QByteArray containsZero("Some data\0 with zero", 21); 103 | packet.clear(); 104 | packet.appendRaw(containsZero); 105 | payload = packet.payload(); 106 | QCOMPARE(containsZero, payload); 107 | QCOMPARE(payload.size(), 21); 108 | 109 | packet.clear(); 110 | packet.append(containsZero); 111 | payload = packet.payload().mid(2); // mid because size got prepended 112 | QCOMPARE(containsZero, payload); 113 | QCOMPARE(payload.size(), 21); 114 | #else 115 | QSKIP("This test requires a Qt -developer-build."); 116 | #endif 117 | } 118 | 119 | void Tst_QMqttControlPacket::simple_data() 120 | { 121 | QTest::addColumn("data"); 122 | QTest::newRow("0") << QString(); 123 | } 124 | 125 | void Tst_QMqttControlPacket::simple() 126 | { 127 | QFETCH(QString, data); 128 | QVERIFY2(true, "Failure"); 129 | } 130 | 131 | QTEST_APPLESS_MAIN(Tst_QMqttControlPacket) 132 | 133 | #include "tst_qmqttcontrolpacket.moc" 134 | -------------------------------------------------------------------------------- /tests/libfuzzer/mqtt/data_receive/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | Q_DECLARE_METATYPE(QMqttSubscription::SubscriptionState) 10 | 11 | class FakeServer : public QIODevice 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit FakeServer(QObject *parent); 16 | 17 | qint64 readData(char *data, qint64 maxlen) override; 18 | qint64 writeData(const char *data, qint64 len) override; 19 | 20 | int m_messageState{0}; 21 | QByteArray m_readBuffer; 22 | }; 23 | 24 | FakeServer::FakeServer(QObject *parent) 25 | : QIODevice(parent) 26 | { 27 | m_messageState = 0; 28 | open(QIODevice::ReadWrite | QIODevice::Unbuffered); 29 | } 30 | 31 | qint64 FakeServer::readData(char *data, qint64 maxlen) 32 | { 33 | const qint64 dataToWrite = qMax(0, qMin(maxlen, m_readBuffer.size())); 34 | memcpy(data, m_readBuffer.constData(), static_cast(dataToWrite)); 35 | m_readBuffer = m_readBuffer.mid(static_cast(dataToWrite)); 36 | return dataToWrite; 37 | } 38 | 39 | void bufferAppend(QByteArray &buffer, quint16 value) 40 | { 41 | const quint16 msb = qToBigEndian(value); 42 | const char * msb_c = reinterpret_cast(&msb); 43 | buffer.append(msb_c, 2); 44 | } 45 | 46 | qint64 FakeServer::writeData(const char *data, qint64 len) 47 | { 48 | if (m_messageState == 0) { // Received CONNECT 49 | QByteArray response; 50 | response += 0x20; 51 | response += quint8(2); // Payload size 52 | response += char(0); // ackFlags 53 | response += char(0); // result 54 | 55 | m_readBuffer = response; 56 | emit readyRead(); 57 | m_messageState = 1; 58 | } else if (m_messageState == 1) { // Received SUBSCRIBE 59 | // Byte 0 == 0x82 (0x80 SUBSCRIBE 0x02 standard) 60 | quint8 msg = reinterpret_cast(data)[0]; 61 | if (msg != quint8(0x82)) 62 | qFatal("Expected subscribe message"); 63 | // Byte 1+2 == ID 64 | const quint16 id_big = *reinterpret_cast(&data[2]); 65 | const quint16 id = qFromBigEndian(id_big); 66 | 67 | QMqttControlPacket packet(QMqttControlPacket::SUBACK); 68 | packet.append(id); 69 | const quint8 qosLevel = 1; 70 | packet.append(static_cast(qosLevel)); 71 | m_readBuffer = packet.serialize(); 72 | // We need to be async to have QMqttConnection prepare its internals 73 | QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); 74 | 75 | m_messageState = 2; 76 | } 77 | // Ignore any follow up data 78 | 79 | return len; 80 | } 81 | 82 | extern "C" int LLVMFuzzerTestOneInput(const char *Data, size_t Size) 83 | { 84 | static int argc = 1; 85 | static char *argv_1[] = {qstrdup("fuzzprepare")}; 86 | static char **argv = argv_1; 87 | static QCoreApplication a(argc, argv); 88 | 89 | FakeServer serv(&a); 90 | QMqttClient client; 91 | client.setHostname(QLatin1String("localhost")); 92 | client.setPort(1883); 93 | 94 | client.setTransport(&serv, QMqttClient::IODevice); 95 | client.connectToHost(); 96 | 97 | QSignalSpy spy(&client, &QMqttClient::connected); 98 | spy.wait(5); 99 | 100 | if (client.state() != QMqttClient::Connected) { 101 | qFatal("Not able to run test propertly"); 102 | return -1; 103 | } 104 | 105 | auto sub = client.subscribe(QLatin1String("a"), 1); 106 | qRegisterMetaType("SubscriptionState"); 107 | QSignalSpy subSpy(sub, &QMqttSubscription::stateChanged); 108 | spy.wait(5); 109 | if (sub->state() != QMqttSubscription::Subscribed) 110 | spy.wait(10); 111 | if (sub->state() != QMqttSubscription::Subscribed) 112 | qFatal("Could not subscribe"); 113 | 114 | serv.m_readBuffer = QByteArray(Data, static_cast(Size)); 115 | QMetaObject::invokeMethod(&serv, "readyRead"); 116 | QCoreApplication::processEvents(); 117 | return 0; 118 | } 119 | 120 | #include "main.moc" 121 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 The Qt Company Ltd. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # This function adds the test 12 times if run on a computer where the 5 | # mosquitto broker has been provisioned by running the corresponding 6 | # script located qt6/coin/provisioning/*/*mosquitto* 7 | # 8 | # The script adds the file /etc/mosquitto/conf.d/mqtt.conf on unix-like 9 | # systems, and the file C:\\Program Files\\mosquitto\\conf.d\\mqtt.conf 10 | # on windows like systems. So this is what we test for. 11 | # 12 | # If we are on a provisioned system as detected by the two files above 13 | # we define these variables which the test use 14 | # MQTT_TEST_TYPE= selection from; 3, 4, 5 15 | # 3 -> Vers 3.1 16 | # 4 -> Vers 3.1.1 17 | # 5 -> Vers 5.0 18 | # MQTT_TEST_PROTOCOL= selection from; Tcp,Ssl,Ws,Wss 19 | # MQTT_TEST_BROKER="localhost" 20 | # 21 | # If neither of these files are present, we use the existing 22 | # design which is to run for tcp,3.1.1 by default. 23 | # In this case set the environment variable MQTT_TEST_BROKER 24 | # to localhost 25 | # 26 | # Finally, we allow the test to override for individual test 27 | # cases, if wanted. This is mostly used for MQTT_TEST_TYPE 28 | # 29 | 30 | function(qtmqtt_is_mosquitto_installed result) 31 | set(skip $ENV{COIN_NO_MOSQUITTO}) 32 | if(skip) 33 | set(${result} FALSE PARENT_SCOPE) 34 | elseif(EXISTS "/etc/mosquitto/conf.d/mqtt.conf" OR 35 | EXISTS "C:\\Program Files\\mosquitto\\conf.d\\mqtt.conf") 36 | set(${result} ON PARENT_SCOPE) 37 | else() 38 | set(${result} FALSE PARENT_SCOPE) 39 | endif() 40 | endfunction() 41 | 42 | function(qtmqtt_add_test) 43 | 44 | set(options) 45 | set(oneValueArgs TARGET) 46 | set(multiValueArgs SOURCES DEFINES INCLUDE_DIRECTORIES LIBRARIES) 47 | 48 | cmake_parse_arguments( 49 | arg_mqtt 50 | "${options}" 51 | "${oneValueArgs}" 52 | "${multiValueArgs}" 53 | ${ARGN} 54 | ) 55 | 56 | set(TYPES) 57 | set(PROTOCOLS) 58 | 59 | qtmqtt_is_mosquitto_installed(is_installed) 60 | 61 | if(${is_installed}) 62 | if(WASM) 63 | if(TARGET Qt::WebSockets) 64 | set(TYPES Ws Wss) 65 | set(PROTOCOLS 3 4 5) 66 | endif() 67 | elseif(QT_FEATURE_ssl) 68 | if(TARGET Qt::WebSockets) 69 | set(TYPES Tcp Ssl Ws Wss) 70 | else() 71 | set(TYPES Tcp Ssl) 72 | endif() 73 | set(PROTOCOLS 3 4 5) 74 | else() 75 | if(TARGET Qt::WebSockets) 76 | set(TYPES Tcp Ws) 77 | else() 78 | set(TYPES Tcp) 79 | endif() 80 | set(PROTOCOLS 3 4 5) 81 | endif() 82 | elseif(NOT WASM) 83 | set(TYPES Tcp) 84 | set(PROTOCOLS 4) 85 | endif() 86 | 87 | foreach(TYPE ${TYPES}) 88 | foreach(PROTOCOL ${PROTOCOLS}) 89 | set(EXTRA_DEFINES) 90 | set(EXTRA_LIBS) 91 | if(${is_installed}) 92 | set(EXTRA_DEFINES MQTT_TEST_TYPE="${TYPE}" MQTT_TEST_PROTOCOL=${PROTOCOL} MQTT_TEST_BROKER="localhost") 93 | endif() 94 | 95 | if(TARGET Qt::WebSockets) 96 | set(EXTRA_DEFINES ${EXTRA_DEFINES} QT_MQTT_WITH_WEBSOCKETS) 97 | set(EXTRA_LIBS Qt::WebSockets) 98 | endif() 99 | 100 | qt_internal_add_test( 101 | ${arg_mqtt_TARGET}_${TYPE}_${PROTOCOL} 102 | SOURCES 103 | ${arg_mqtt_SOURCES} 104 | DEFINES 105 | ${arg_mqtt_DEFINES} ${EXTRA_DEFINES} 106 | INCLUDE_DIRECTORIES 107 | ${arg_mqtt_INCLUDE_DIRECTORIES} 108 | LIBRARIES 109 | ${arg_mqtt_LIBRARIES} ${EXTRA_LIBS} 110 | TESTDATA 111 | "../../certificate/cert.crt" 112 | "../../certificate/cert.key" 113 | BUILTIN_TESTDATA 114 | ) 115 | 116 | endforeach() 117 | endforeach() 118 | endfunction() 119 | 120 | if(QT_BUILD_STANDALONE_TESTS) 121 | # Add qt_find_package calls for extra dependencies that need to be found when building 122 | # the standalone tests here. 123 | endif() 124 | qt_build_tests() 125 | -------------------------------------------------------------------------------- /tests/benchmarks/qmqttclient/tst_qmqttclient.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | 4 | #include "broker_connection.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class Tst_QMqttClient : public QObject 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | Tst_QMqttClient(); 17 | 18 | private Q_SLOTS: 19 | void initTestCase(); 20 | void cleanupTestCase(); 21 | void stressTest_data(); 22 | void stressTest(); 23 | void stressTest2_data(); 24 | void stressTest2(); 25 | private: 26 | QProcess m_brokerProcess; 27 | QString m_testBroker; 28 | quint16 m_port{0}; 29 | }; 30 | 31 | Tst_QMqttClient::Tst_QMqttClient() 32 | { 33 | } 34 | 35 | void Tst_QMqttClient::initTestCase() 36 | { 37 | m_testBroker = invokeOrInitializeBroker(&m_brokerProcess); 38 | if (m_testBroker.isEmpty()) 39 | qFatal("No MQTT broker present to test against."); 40 | } 41 | 42 | void Tst_QMqttClient::cleanupTestCase() 43 | { 44 | } 45 | 46 | void Tst_QMqttClient::stressTest_data() 47 | { 48 | QTest::addColumn("qos"); 49 | QTest::newRow("qos0") << 0; 50 | QTest::newRow("qos1") << 1; 51 | QTest::newRow("qos2") << 2; 52 | } 53 | 54 | void Tst_QMqttClient::stressTest() 55 | { 56 | QFETCH(int, qos); 57 | VersionClient(0, subscriber); 58 | VersionClient(0, publisher); 59 | 60 | subscriber.setHostname(m_testBroker); 61 | subscriber.setPort(m_port); 62 | publisher.setHostname(m_testBroker); 63 | publisher.setPort(m_port); 64 | 65 | quint64 messageCount = 0; 66 | QMqttSubscription *subscription; 67 | const QString testTopic = QLatin1String("Qt/benchmark/test/topic"); 68 | 69 | connect(&subscriber, &QMqttClient::connected, [&](){ 70 | subscription = subscriber.subscribe(testTopic); 71 | if (!subscription) 72 | qFatal("Failed to create subscription"); 73 | 74 | connect(subscription, &QMqttSubscription::messageReceived, [&](QMqttMessage) { 75 | messageCount++; 76 | publisher.publish(testTopic, QByteArray("some message"), qos); 77 | }); 78 | publisher.connectToHost(); 79 | }); 80 | subscriber.connectToHost(); 81 | 82 | connect(&publisher, &QMqttClient::connected, [&]() { 83 | publisher.publish(testTopic, QByteArray("initial message"), qos); 84 | }); 85 | 86 | QTest::qWait(30000); 87 | qDebug() << "Stress test result for QoS " << qos << ":" << messageCount; 88 | } 89 | 90 | void Tst_QMqttClient::stressTest2_data() 91 | { 92 | QTest::addColumn("qos"); 93 | QTest::addColumn("msgCount"); 94 | QTest::newRow("1/100") << 1 << 100; 95 | QTest::newRow("1/1000") << 1 << 1000; 96 | // Disable to avoid timeout 97 | //QTest::newRow("1/10000") << 1 << 10000; 98 | QTest::newRow("2/100") << 2 << 100; 99 | QTest::newRow("2/1000") << 2 << 1000; 100 | // Disabled as mosquitto is not able to handle this many message 101 | // QTest::newRow("2/10000") << 2 << 10000; 102 | } 103 | 104 | void Tst_QMqttClient::stressTest2() 105 | { 106 | QFETCH(int, qos); 107 | QFETCH(int, msgCount); 108 | 109 | QSet msgIds; 110 | msgIds.reserve(msgCount); 111 | 112 | VersionClient(0, publisher); 113 | publisher.setHostname(m_testBroker); 114 | publisher.setPort(m_port); 115 | 116 | connect(&publisher, &QMqttClient::messageSent, [&msgIds](qint32 id) { 117 | QVERIFY2(msgIds.contains(id), "Received messageSent for unknown id"); 118 | msgIds.remove(id); 119 | }); 120 | 121 | QSignalSpy spy(&publisher, SIGNAL(connected())); 122 | publisher.connectToHost(); 123 | QTRY_COMPARE(spy.count(), 1); 124 | 125 | const QString topic = QLatin1String("Qt/benchmark/SomeTopic/Sub"); 126 | const QByteArray message("messageContent"); 127 | 128 | for (qint32 i = 0; i < msgCount; ++i) { 129 | QSignalSpy writeSpy(publisher.transport(), SIGNAL(bytesWritten(qint64))); 130 | const qint32 id = publisher.publish(topic, message, qos); 131 | QTRY_VERIFY2(id != -1, "Could not publish message"); 132 | msgIds.insert(id); 133 | QTRY_VERIFY(writeSpy.count() >= 1); 134 | } 135 | 136 | // Give some extra time depending on connection 137 | if (msgCount > 1000) 138 | QTest::qWait(5000); 139 | QTRY_COMPARE(msgIds.count(), 0); 140 | 141 | publisher.disconnectFromHost(); 142 | } 143 | 144 | QTEST_MAIN(Tst_QMqttClient) 145 | 146 | #include "tst_qmqttclient.moc" 147 | -------------------------------------------------------------------------------- /examples/mqtt/subscriptions/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "mainwindow.h" 5 | #include "subscriptionwindow.h" 6 | #include "ui_mainwindow.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace Qt::StringLiterals; 13 | 14 | MainWindow::MainWindow(QWidget *parent) : 15 | QMainWindow(parent), 16 | ui(new Ui::MainWindow) 17 | { 18 | ui->setupUi(this); 19 | 20 | m_client = new QMqttClient(this); 21 | m_client->setHostname(ui->lineEditHost->text()); 22 | m_client->setPort(static_cast(ui->spinBoxPort->value())); 23 | 24 | connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateLogStateChange); 25 | connect(m_client, &QMqttClient::disconnected, this, &MainWindow::brokerDisconnected); 26 | 27 | connect(m_client, &QMqttClient::messageReceived, this, [this](const QByteArray &message, const QMqttTopicName &topic) { 28 | const QString content = QDateTime::currentDateTime().toString() 29 | + " Received Topic: "_L1 30 | + topic.name() 31 | + " Message: "_L1 32 | + message 33 | + u'\n'; 34 | ui->editLog->insertPlainText(content); 35 | }); 36 | 37 | connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() { 38 | const QString content = QDateTime::currentDateTime().toString() 39 | + " PingResponse\n"_L1; 40 | ui->editLog->insertPlainText(content); 41 | }); 42 | 43 | connect(ui->lineEditHost, &QLineEdit::textChanged, m_client, &QMqttClient::setHostname); 44 | connect(ui->spinBoxPort, QOverload::of(&QSpinBox::valueChanged), this, &MainWindow::setClientPort); 45 | connect(ui->lineEditUser, &QLineEdit::textChanged, m_client, &QMqttClient::setUsername); 46 | connect(ui->lineEditPassword, &QLineEdit::textChanged, m_client, &QMqttClient::setPassword); 47 | updateLogStateChange(); 48 | } 49 | 50 | MainWindow::~MainWindow() 51 | { 52 | delete ui; 53 | qApp->quit(); 54 | } 55 | 56 | void MainWindow::on_buttonConnect_clicked() 57 | { 58 | if (m_client->state() == QMqttClient::Disconnected) { 59 | ui->lineEditHost->setEnabled(false); 60 | ui->spinBoxPort->setEnabled(false); 61 | ui->lineEditUser->setEnabled(false); 62 | ui->lineEditPassword->setEnabled(false); 63 | ui->buttonConnect->setText(tr("Disconnect")); 64 | m_client->connectToHost(); 65 | } else { 66 | ui->lineEditHost->setEnabled(true); 67 | ui->spinBoxPort->setEnabled(true); 68 | ui->lineEditUser->setEnabled(true); 69 | ui->lineEditPassword->setEnabled(true); 70 | ui->buttonConnect->setText(tr("Connect")); 71 | m_client->disconnectFromHost(); 72 | } 73 | } 74 | 75 | void MainWindow::on_buttonQuit_clicked() 76 | { 77 | QApplication::quit(); 78 | } 79 | 80 | void MainWindow::updateLogStateChange() 81 | { 82 | const QString content = QDateTime::currentDateTime().toString() 83 | + ": State Change"_L1 84 | + QString::number(m_client->state()) 85 | + u'\n'; 86 | ui->editLog->insertPlainText(content); 87 | } 88 | 89 | void MainWindow::brokerDisconnected() 90 | { 91 | ui->lineEditHost->setEnabled(true); 92 | ui->spinBoxPort->setEnabled(true); 93 | ui->lineEditUser->setEnabled(true); 94 | ui->lineEditPassword->setEnabled(true); 95 | ui->buttonConnect->setText(tr("Connect")); 96 | } 97 | 98 | void MainWindow::setClientPort(int p) 99 | { 100 | m_client->setPort(static_cast(p)); 101 | } 102 | 103 | void MainWindow::on_buttonPublish_clicked() 104 | { 105 | if (m_client->publish(ui->lineEditTopic->text(), ui->lineEditMessage->text().toUtf8(), 106 | static_cast(ui->spinQoS_2->text().toUInt()), 107 | ui->checkBoxRetain->isChecked()) 108 | == -1) 109 | QMessageBox::critical(this, u"Error"_s, u"Could not publish message"_s); 110 | } 111 | 112 | void MainWindow::on_buttonSubscribe_clicked() 113 | { 114 | auto subscription = m_client->subscribe(ui->lineEditTopic->text(), 115 | static_cast(ui->spinQoS->text().toUInt())); 116 | if (!subscription) { 117 | QMessageBox::critical(this, u"Error"_s, 118 | u"Could not subscribe. Is there a valid connection?"_s); 119 | return; 120 | } 121 | auto subWindow = new SubscriptionWindow(subscription); 122 | subWindow->setWindowTitle(subscription->topic().filter()); 123 | subWindow->show(); 124 | } 125 | -------------------------------------------------------------------------------- /src/mqtt/qmqttsubscriptionproperties.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #include "qmqttsubscriptionproperties.h" 6 | 7 | QT_BEGIN_NAMESPACE 8 | 9 | /*! 10 | \class QMqttSubscriptionProperties 11 | 12 | \inmodule QtMqtt 13 | \since 5.12 14 | 15 | \brief The QMqttSubscriptionProperties class represents configuration 16 | options a QMqttClient can pass to the server when subscribing to a 17 | topic filter. 18 | 19 | \note Subscription properties are part of the MQTT 5.0 specification and 20 | cannot be used when connecting with a lower protocol level. See 21 | QMqttClient::ProtocolVersion for more information. 22 | */ 23 | 24 | /*! 25 | \class QMqttUnsubscriptionProperties 26 | 27 | \inmodule QtMqtt 28 | \since 5.12 29 | 30 | \brief The QMqttUnsubscriptionProperties class represents configuration 31 | options a QMqttClient can pass to the server when unsubscribing from a 32 | topic filter. 33 | 34 | \note Unsubscription properties are part of the MQTT 5.0 specification and 35 | cannot be used when connecting with a lower protocol level. See 36 | QMqttClient::ProtocolVersion for more information. 37 | */ 38 | 39 | class QMqttSubscriptionPropertiesData : public QSharedData 40 | { 41 | public: 42 | quint32 subscriptionIdentifier{0}; 43 | QMqttUserProperties userProperties; 44 | bool noLocal{false}; 45 | }; 46 | 47 | class QMqttUnsubscriptionPropertiesData : public QSharedData 48 | { 49 | public: 50 | QMqttUserProperties userProperties; 51 | }; 52 | 53 | /*! 54 | \internal 55 | */ 56 | QMqttSubscriptionProperties::QMqttSubscriptionProperties() : data(new QMqttSubscriptionPropertiesData) 57 | { 58 | 59 | } 60 | 61 | /*! 62 | \internal 63 | */ 64 | QMqttSubscriptionProperties::QMqttSubscriptionProperties(const QMqttSubscriptionProperties &) = default; 65 | 66 | QMqttSubscriptionProperties &QMqttSubscriptionProperties::operator=(const QMqttSubscriptionProperties &rhs) 67 | { 68 | if (this != &rhs) 69 | data.operator=(rhs.data); 70 | return *this; 71 | } 72 | 73 | QMqttSubscriptionProperties::~QMqttSubscriptionProperties() = default; 74 | 75 | /*! 76 | Returns the user specified properties. 77 | */ 78 | QMqttUserProperties QMqttSubscriptionProperties::userProperties() const 79 | { 80 | return data->userProperties; 81 | } 82 | 83 | /*! 84 | Sets the user properties to \a user. 85 | */ 86 | void QMqttSubscriptionProperties::setUserProperties(const QMqttUserProperties &user) 87 | { 88 | data->userProperties = user; 89 | } 90 | 91 | /*! 92 | Returns the subscription identifier used to describe this subscription. 93 | */ 94 | quint32 QMqttSubscriptionProperties::subscriptionIdentifier() const 95 | { 96 | return data->subscriptionIdentifier; 97 | } 98 | 99 | /*! 100 | Sets the subscription identifier to \a id. 101 | */ 102 | void QMqttSubscriptionProperties::setSubscriptionIdentifier(quint32 id) 103 | { 104 | data->subscriptionIdentifier = id; 105 | } 106 | 107 | /*! 108 | * \since 6.4 109 | * Returns true if the subscription shall not receive local messages on the same topic. 110 | */ 111 | bool QMqttSubscriptionProperties::noLocal() const 112 | { 113 | return data->noLocal; 114 | } 115 | 116 | /*! 117 | * \since 6.4 118 | * Sets the subscription option to not receive local message. 119 | * When a client publishes a message with the same topic as an existing local subscription 120 | * the server by default sends the message back to the client. If \a noloc is set to true 121 | * the broker will not send any message the same client has published. 122 | */ 123 | void QMqttSubscriptionProperties::setNoLocal(bool noloc) 124 | { 125 | data->noLocal = noloc; 126 | } 127 | 128 | /*! 129 | \internal 130 | */ 131 | QMqttUnsubscriptionProperties::QMqttUnsubscriptionProperties() : data(new QMqttUnsubscriptionPropertiesData) 132 | { 133 | } 134 | 135 | /*! 136 | \internal 137 | */ 138 | QMqttUnsubscriptionProperties &QMqttUnsubscriptionProperties::operator=(const QMqttUnsubscriptionProperties &rhs) 139 | { 140 | if (this != &rhs) 141 | data.operator=(rhs.data); 142 | return *this; 143 | } 144 | 145 | /*! 146 | Returns the user specified properties. 147 | */ 148 | QMqttUserProperties QMqttUnsubscriptionProperties::userProperties() const 149 | { 150 | return data->userProperties; 151 | } 152 | 153 | /*! 154 | Sets the user properties to \a user. 155 | */ 156 | void QMqttUnsubscriptionProperties::setUserProperties(const QMqttUserProperties &user) 157 | { 158 | data->userProperties = user; 159 | } 160 | 161 | QMqttUnsubscriptionProperties::~QMqttUnsubscriptionProperties() = default; 162 | 163 | QMqttUnsubscriptionProperties::QMqttUnsubscriptionProperties(const QMqttUnsubscriptionProperties &) = default; 164 | 165 | QT_END_NAMESPACE 166 | -------------------------------------------------------------------------------- /licenseRule.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "comment": ["file_pattern_ending: strings matched against the end of a file name.", 4 | "location keys: regular expression matched against the beginning of", 5 | "the file path (relative to the git submodule root).", 6 | "spdx: list of SPDX-License-Expression's allowed in the matching files.", 7 | "-------------------------------------------------------", 8 | "Files with the following endings are Build System licensed,", 9 | "unless they are examples", 10 | "Files with other endings can also be build system files" 11 | ], 12 | "file_pattern_ending": ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf", 13 | "configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in", 14 | ".cmake.conf", ".tag", "ci_config_linux.json", ".yaml"], 15 | "location": { 16 | "": { 17 | "comment": "Default", 18 | "file type": "build system", 19 | "spdx": ["BSD-3-Clause"] 20 | }, 21 | "(.*)(examples/|snippets/)": { 22 | "comment": "Example takes precedence", 23 | "file type": "examples and snippets", 24 | "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] 25 | } 26 | } 27 | }, 28 | { 29 | "comments": ["Files with the following endings are infrastructure licensed"], 30 | "file_pattern_ending": [".gitattributes", ".gitignore", ".gitmodules", ".gitreview", 31 | "_clang-format", "licenseRule.json", "REUSE.toml"], 32 | "location":{ 33 | "": { 34 | "comment": "Default", 35 | "file type": "infrastructure", 36 | "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] 37 | } 38 | } 39 | }, 40 | { 41 | "comments": ["Files with the following endings are Tool licensed,", 42 | "unless they are examples.", 43 | "Files with other endings can also be tool files."], 44 | "file_pattern_ending": [".sh", ".py", ".pl", ".bat", ".ps1"], 45 | "location":{ 46 | "": { 47 | "comment": "Default", 48 | "file type": "tools and utils", 49 | "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"] 50 | }, 51 | "(.*)(examples/|snippets/)": { 52 | "comment": "Example takes precedence", 53 | "file type": "examples and snippets", 54 | "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] 55 | } 56 | } 57 | }, 58 | { 59 | "comment": "Files with the following endings are Documentation licensed.", 60 | "file_pattern_ending": [".qdoc", ".qdocinc" , ".qdocconf", "README", "qt_attribution.json", 61 | ".css", "README.txt"], 62 | "location":{ 63 | "": { 64 | "comment": "", 65 | "file type": "documentation", 66 | "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] 67 | } 68 | } 69 | }, 70 | { 71 | "comment": ["All other files", 72 | "The licensing is defined only by the file location in the Qt module repository.", 73 | "NO key for this case!", 74 | "This needs to be the last entry of the file."], 75 | "location": { 76 | "": { 77 | "comment": "Default", 78 | "file type": "module and plugin", 79 | "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] 80 | }, 81 | "dist/": { 82 | "comment": "Default", 83 | "file type": "documentation", 84 | "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] 85 | }, 86 | "src/": { 87 | "comment": "Default", 88 | "file type": "module and plugin", 89 | "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] 90 | }, 91 | "tests/": { 92 | "comment": "Default", 93 | "file type": "test", 94 | "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] 95 | }, 96 | "(.*)(examples/|snippets/)": { 97 | "comment": "Default", 98 | "file type": "examples and snippets", 99 | "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] 100 | }, 101 | ".*/doc/images": { 102 | "comment": "Default", 103 | "file type": "examples and snippets", 104 | "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] 105 | } 106 | } 107 | } 108 | ] 109 | -------------------------------------------------------------------------------- /examples/mqtt/quicksubscription/Main.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | import QtQuick 5 | import QtQuick.Window 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | 9 | Window { 10 | visible: true 11 | width: 640 12 | height: 480 13 | title: qsTr("Qt Quick Subscription") 14 | id: root 15 | 16 | property var tempSubscription: 0 17 | 18 | MqttClient { 19 | id: client 20 | hostname: hostnameField.text 21 | port: portField.text 22 | } 23 | 24 | ListModel { 25 | id: messageModel 26 | } 27 | 28 | function addMessage(payload) 29 | { 30 | messageModel.insert(0, {"payload" : payload}) 31 | 32 | if (messageModel.count >= 100) 33 | messageModel.remove(99) 34 | } 35 | 36 | GridLayout { 37 | anchors.fill: parent 38 | anchors.margins: 10 39 | columns: 2 40 | 41 | Label { 42 | text: "Hostname:" 43 | enabled: client.state === MqttClient.Disconnected 44 | } 45 | 46 | TextField { 47 | id: hostnameField 48 | Layout.fillWidth: true 49 | text: "test.mosquitto.org" 50 | placeholderText: "" 51 | enabled: client.state === MqttClient.Disconnected 52 | } 53 | 54 | Label { 55 | text: "Port:" 56 | enabled: client.state === MqttClient.Disconnected 57 | } 58 | 59 | TextField { 60 | id: portField 61 | Layout.fillWidth: true 62 | text: "1883" 63 | placeholderText: "" 64 | inputMethodHints: Qt.ImhDigitsOnly 65 | enabled: client.state === MqttClient.Disconnected 66 | } 67 | 68 | Button { 69 | id: connectButton 70 | Layout.columnSpan: 2 71 | Layout.fillWidth: true 72 | text: client.state === MqttClient.Connected ? "Disconnect" : "Connect" 73 | onClicked: { 74 | if (client.state === MqttClient.Connected) { 75 | client.disconnectFromHost() 76 | messageModel.clear() 77 | root.tempSubscription.destroy() 78 | root.tempSubscription = 0 79 | } else 80 | client.connectToHost() 81 | } 82 | } 83 | 84 | RowLayout { 85 | enabled: client.state === MqttClient.Connected 86 | Layout.columnSpan: 2 87 | Layout.fillWidth: true 88 | 89 | Label { 90 | text: "Topic:" 91 | } 92 | 93 | TextField { 94 | id: subField 95 | placeholderText: "" 96 | Layout.fillWidth: true 97 | enabled: root.tempSubscription === 0 98 | } 99 | 100 | Button { 101 | id: subButton 102 | text: "Subscribe" 103 | visible: root.tempSubscription === 0 104 | onClicked: { 105 | if (subField.text.length === 0) { 106 | console.log("No topic specified to subscribe to.") 107 | return 108 | } 109 | tempSubscription = client.subscribe(subField.text) 110 | tempSubscription.messageReceived.connect(addMessage) 111 | } 112 | } 113 | } 114 | 115 | ListView { 116 | id: messageView 117 | model: messageModel 118 | implicitHeight: 300 119 | implicitWidth: 200 120 | Layout.columnSpan: 2 121 | Layout.fillHeight: true 122 | Layout.fillWidth: true 123 | clip: true 124 | delegate: Rectangle { 125 | id: delegatedRectangle 126 | required property int index 127 | required property string payload 128 | width: ListView.view.width 129 | height: 30 130 | color: index % 2 ? "#DDDDDD" : "#888888" 131 | radius: 5 132 | Text { 133 | text: delegatedRectangle.payload 134 | anchors.centerIn: parent 135 | } 136 | } 137 | } 138 | 139 | Label { 140 | function stateToString(value) { 141 | if (value === 0) 142 | return "Disconnected" 143 | else if (value === 1) 144 | return "Connecting" 145 | else if (value === 2) 146 | return "Connected" 147 | else 148 | return "Unknown" 149 | } 150 | 151 | Layout.columnSpan: 2 152 | Layout.fillWidth: true 153 | color: "#333333" 154 | text: "Status:" + stateToString(client.state) + "(" + client.state + ")" 155 | enabled: client.state === MqttClient.Connected 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/mqtt/qmqttmessage.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only 3 | // Qt-Security score:significant reason:default 4 | 5 | #include "qmqttmessage.h" 6 | #include "qmqttmessage_p.h" 7 | 8 | QT_BEGIN_NAMESPACE 9 | 10 | /*! 11 | \class QMqttMessage 12 | 13 | \inmodule QtMqtt 14 | \brief The QMqttMessage class provides information about a message received 15 | from a message broker based on a subscription. 16 | 17 | An MQTT message is created inside the module and returned via the 18 | \l QMqttSubscription::messageReceived() signal. 19 | */ 20 | 21 | /*! 22 | \property QMqttMessage::topic 23 | \brief This property holds the topic of a message. 24 | 25 | In case a wildcard has been used for a subscription, describes the topic 26 | matching this subscription. This property never contains wildcards. 27 | */ 28 | 29 | /*! 30 | \property QMqttMessage::payload 31 | \brief This property holds the payload of a message. 32 | */ 33 | 34 | /*! 35 | \property QMqttMessage::id 36 | \brief This property holds the ID of the message. 37 | 38 | IDs are used for messages with a QoS level above zero. 39 | */ 40 | 41 | /*! 42 | \property QMqttMessage::qos 43 | \brief This property holds the QoS level of a message. 44 | */ 45 | 46 | /*! 47 | \property QMqttMessage::duplicate 48 | \brief This property holds whether the message is a duplicate. 49 | 50 | Duplicate messages indicate that the message has been sent earlier, but it 51 | has not been confirmed yet. Hence, the broker assumes that it needs to 52 | resend to verify the transport of the message itself. Duplicate messages 53 | can only occur if the QoS level is one or two. 54 | */ 55 | 56 | /*! 57 | \property QMqttMessage::retain 58 | \brief This property holds whether the message has been retained. 59 | 60 | A retained message is kept on the broker for future clients to subscribe. 61 | Consequently, a retained message has been created previously and is not a 62 | live update. A broker can store only one retained message per topic. 63 | */ 64 | 65 | /*! 66 | Creates a new MQTT message. 67 | */ 68 | QMqttMessage::QMqttMessage() 69 | : d(new QMqttMessagePrivate()) 70 | { 71 | } 72 | 73 | /*! 74 | Constructs a new MQTT message that is a copy of \a other. 75 | */ 76 | QMqttMessage::QMqttMessage(const QMqttMessage &other) 77 | : d(other.d) 78 | { 79 | } 80 | 81 | QMqttMessage::~QMqttMessage() 82 | { 83 | } 84 | 85 | /*! 86 | Makes this object a copy of \a other and returns the new value of this object. 87 | */ 88 | QMqttMessage &QMqttMessage::operator=(const QMqttMessage &other) 89 | { 90 | d = other.d; 91 | return *this; 92 | } 93 | 94 | /*! 95 | Returns \c true if the message and \a other are equal, otherwise returns \c false. 96 | */ 97 | bool QMqttMessage::operator==(const QMqttMessage &other) const 98 | { 99 | return d == other.d; 100 | } 101 | 102 | /*! 103 | Returns \c true if the message and \a other are not equal, otherwise returns \c false. 104 | */ 105 | bool QMqttMessage::operator!=(const QMqttMessage &other) const 106 | { 107 | return !(*this == other); 108 | } 109 | 110 | const QByteArray &QMqttMessage::payload() const 111 | { 112 | return d->m_payload; 113 | } 114 | 115 | quint8 QMqttMessage::qos() const 116 | { 117 | return d->m_qos; 118 | } 119 | 120 | quint16 QMqttMessage::id() const 121 | { 122 | return d->m_id; 123 | } 124 | 125 | QMqttTopicName QMqttMessage::topic() const 126 | { 127 | return d->m_topic; 128 | } 129 | 130 | bool QMqttMessage::duplicate() const 131 | { 132 | return d->m_duplicate; 133 | } 134 | 135 | bool QMqttMessage::retain() const 136 | { 137 | return d->m_retain; 138 | } 139 | 140 | /*! 141 | \since 5.12 142 | 143 | Returns the publish properties received as part of the message. 144 | 145 | \note This function only specifies the properties when a 146 | publish message is received. Messages with a QoS value of 147 | 1 or 2 can contain additional properties when a message is released. 148 | Those can be obtained by the QMqttClient::messageStatusChanged signal. 149 | 150 | \note This function will only provide valid data when the client 151 | specifies QMqttClient::MQTT_5_0 as QMqttClient::ProtocolVersion. 152 | */ 153 | QMqttPublishProperties QMqttMessage::publishProperties() const 154 | { 155 | return d->m_publishProperties; 156 | } 157 | 158 | /*! 159 | \internal 160 | Constructs a new MQTT message with \a content on the topic \a topic. 161 | Furthermore the properties \a id, \a qos, \a dup, \a retain must be specified. 162 | 163 | This constructor is mostly used internally to construct a QMqttMessage at message 164 | receival. 165 | */ 166 | QMqttMessage::QMqttMessage(const QMqttTopicName &topic, const QByteArray &content, quint16 id, quint8 qos, bool dup, bool retain) 167 | : d(new QMqttMessagePrivate) 168 | { 169 | d->m_topic = topic; 170 | d->m_payload = content; 171 | d->m_id = id; 172 | d->m_qos = qos; 173 | d->m_duplicate = dup; 174 | d->m_retain = retain; 175 | } 176 | 177 | QT_END_NAMESPACE 178 | -------------------------------------------------------------------------------- /examples/mqtt/simpleclient/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 The Qt Company Ltd. 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause 3 | 4 | #include "mainwindow.h" 5 | #include "ui_mainwindow.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace Qt::StringLiterals; 12 | 13 | MainWindow::MainWindow(QWidget *parent) : 14 | QMainWindow(parent), 15 | ui(new Ui::MainWindow) 16 | { 17 | ui->setupUi(this); 18 | 19 | m_client = new QMqttClient(this); 20 | m_client->setHostname(ui->lineEditHost->text()); 21 | m_client->setPort(static_cast(ui->spinBoxPort->value())); 22 | 23 | connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateLogStateChange); 24 | connect(m_client, &QMqttClient::disconnected, this, &MainWindow::brokerDisconnected); 25 | 26 | connect(m_client, &QMqttClient::messageReceived, this, [this](const QByteArray &message, const QMqttTopicName &topic) { 27 | const QString content = QDateTime::currentDateTime().toString() 28 | + " Received Topic: "_L1 29 | + topic.name() 30 | + " Message: "_L1 31 | + message 32 | + u'\n'; 33 | ui->editLog->insertPlainText(content); 34 | }); 35 | 36 | connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() { 37 | const QString content = QDateTime::currentDateTime().toString() 38 | + "PingResponse\n"_L1; 39 | ui->editLog->insertPlainText(content); 40 | }); 41 | 42 | connect(ui->lineEditHost, &QLineEdit::textChanged, m_client, &QMqttClient::setHostname); 43 | connect(ui->spinBoxPort, QOverload::of(&QSpinBox::valueChanged), this, &MainWindow::setClientPort); 44 | connect(ui->checkBoxWebSockets, &QCheckBox::checkStateChanged, this, [this](int ws) { setWebSockets(ws != 0); }); 45 | connect(ui->checkBoxSecure, &QCheckBox::checkStateChanged, this, [this](int s) { setSecure(s != 0); } ); 46 | connect(ui->comboBoxProtocol, &QComboBox::currentIndexChanged, this, [this](int p) { setProtocol(static_cast(p + 3)); }); 47 | updateLogStateChange(); 48 | } 49 | 50 | MainWindow::~MainWindow() 51 | { 52 | delete ui; 53 | } 54 | 55 | void MainWindow::on_buttonConnect_clicked() 56 | { 57 | if (m_client->state() == QMqttClient::Disconnected) { 58 | ui->lineEditHost->setEnabled(false); 59 | ui->spinBoxPort->setEnabled(false); 60 | ui->buttonConnect->setText(tr("Disconnect")); 61 | 62 | m_client->setProtocolVersion(m_protocol); 63 | 64 | if (m_secure && m_webSockets) 65 | m_client->connectToHostWebSocketEncrypted(); 66 | #if !defined(QT_NO_SSL) && !defined(Q_OS_WASM) 67 | if (m_secure && !m_webSockets) 68 | m_client->connectToHostEncrypted({}); 69 | #endif 70 | if (!m_secure && m_webSockets) 71 | m_client->connectToHostWebSocket(); 72 | #if !defined(Q_OS_WASM) 73 | if (!m_secure && !m_webSockets) 74 | m_client->connectToHost(); 75 | #endif 76 | if (m_client->state() == QMqttClient::Disconnected) { 77 | ui->lineEditHost->setEnabled(true); 78 | ui->spinBoxPort->setEnabled(true); 79 | ui->buttonConnect->setText(tr("Connect")); 80 | m_client->disconnectFromHost(); 81 | } 82 | } else { 83 | ui->lineEditHost->setEnabled(true); 84 | ui->spinBoxPort->setEnabled(true); 85 | ui->buttonConnect->setText(tr("Connect")); 86 | m_client->disconnectFromHost(); 87 | } 88 | } 89 | 90 | void MainWindow::on_buttonQuit_clicked() 91 | { 92 | QApplication::quit(); 93 | } 94 | 95 | void MainWindow::updateLogStateChange() 96 | { 97 | const QString content = QDateTime::currentDateTime().toString() 98 | + ": State Change"_L1 99 | + QString::number(m_client->state()) 100 | + u'\n'; 101 | ui->editLog->insertPlainText(content); 102 | } 103 | 104 | void MainWindow::brokerDisconnected() 105 | { 106 | ui->lineEditHost->setEnabled(true); 107 | ui->spinBoxPort->setEnabled(true); 108 | ui->buttonConnect->setText(tr("Connect")); 109 | } 110 | 111 | void MainWindow::setClientPort(int p) 112 | { 113 | m_client->setPort(static_cast(p)); 114 | } 115 | 116 | void MainWindow::setSecure(bool s) 117 | { 118 | m_secure = s; 119 | } 120 | 121 | void MainWindow::setWebSockets(bool ws) 122 | { 123 | m_webSockets = ws; 124 | } 125 | 126 | void MainWindow::setProtocol(QMqttClient::ProtocolVersion p) 127 | { 128 | m_protocol = p; 129 | } 130 | 131 | void MainWindow::on_buttonPublish_clicked() 132 | { 133 | if (m_client->publish(ui->lineEditTopic->text(), ui->lineEditMessage->text().toUtf8()) == -1) 134 | QMessageBox::critical(this, u"Error"_s, u"Could not publish message"_s); 135 | } 136 | 137 | void MainWindow::on_buttonSubscribe_clicked() 138 | { 139 | auto subscription = m_client->subscribe(ui->lineEditTopic->text()); 140 | if (!subscription) { 141 | QMessageBox::critical(this, u"Error"_s, 142 | u"Could not subscribe. Is there a valid connection?"_s); 143 | return; 144 | } 145 | } 146 | --------------------------------------------------------------------------------