From 637b228a380d9f5a4a2a2f85fb487b32127076cb Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Thu, 28 Mar 2019 11:23:41 +0100 Subject: Add secure CoAP client example This example demonstrates sending secure CoAP GET requests in PreSharedKey and Certificate modes. Change-Id: I90ea8c77232bfca1ca86bdd7a73223b6ba8b0c9b Reviewed-by: Alex Blasche --- examples/coap/coap.pro | 1 + examples/coap/quicksecureclient/FilePicker.qml | 88 +++++++++ examples/coap/quicksecureclient/main.cpp | 97 +++++++++ examples/coap/quicksecureclient/main.qml | 220 +++++++++++++++++++++ examples/coap/quicksecureclient/qml.qrc | 6 + .../coap/quicksecureclient/qmlcoapsecureclient.cpp | 161 +++++++++++++++ .../coap/quicksecureclient/qmlcoapsecureclient.h | 81 ++++++++ .../coap/quicksecureclient/quicksecureclient.pro | 21 ++ 8 files changed, 675 insertions(+) create mode 100644 examples/coap/quicksecureclient/FilePicker.qml create mode 100644 examples/coap/quicksecureclient/main.cpp create mode 100644 examples/coap/quicksecureclient/main.qml create mode 100644 examples/coap/quicksecureclient/qml.qrc create mode 100644 examples/coap/quicksecureclient/qmlcoapsecureclient.cpp create mode 100644 examples/coap/quicksecureclient/qmlcoapsecureclient.h create mode 100644 examples/coap/quicksecureclient/quicksecureclient.pro diff --git a/examples/coap/coap.pro b/examples/coap/coap.pro index dcac089..ba1d57a 100644 --- a/examples/coap/coap.pro +++ b/examples/coap/coap.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS += \ + quicksecureclient \ quickmulticastclient \ simplecoapclient \ consolecoapclient diff --git a/examples/coap/quicksecureclient/FilePicker.qml b/examples/coap/quicksecureclient/FilePicker.qml new file mode 100644 index 0000000..a7cd641 --- /dev/null +++ b/examples/coap/quicksecureclient/FilePicker.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtCoap module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * 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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.13 +import QtQuick.Controls 2.13 +import QtQuick.Layouts 1.13 +import Qt.labs.platform 1.0 + +Item { + id: filePicker + + property string dialogText + property alias selectedFile: filePathField.text + + height: addFileButton.height + + FileDialog { + id: fileDialog + title: qsTr("Please Choose %1").arg(dialogText) + folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + fileMode: FileDialog.OpenFile + onAccepted: filePathField.text = fileDialog.file + } + + RowLayout { + anchors.fill: parent + TextField { + id: filePathField + placeholderText: qsTr("<%1>").arg(dialogText) + inputMethodHints: Qt.ImhUrlCharactersOnly + selectByMouse: true + Layout.fillWidth: true + } + + Button { + id: addFileButton + text: qsTr("Add %1").arg(dialogText) + onClicked: fileDialog.open() + } + } +} diff --git a/examples/coap/quicksecureclient/main.cpp b/examples/coap/quicksecureclient/main.cpp new file mode 100644 index 0000000..2bfeff5 --- /dev/null +++ b/examples/coap/quicksecureclient/main.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtCoap module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * 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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmlcoapsecureclient.h" + +#include +#include +#include +#include + +static QStringList availableHosts() +{ + QStringList hosts; + + const auto networkInterfaces = QNetworkInterface::allInterfaces(); + for (const auto &interface : networkInterfaces) + for (const auto &address : interface.addressEntries()) + hosts.push_back(address.ip().toString()); + + return hosts; +} + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setOrganizationName("Qt CoAP Example"); + + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine; + + qmlRegisterType("CoapSecureClient", 1, 0, "CoapSecureClient"); + + // Register the QtCoap namespace + qmlRegisterUncreatableMetaObject(QtCoap::staticMetaObject, "qtcoap.example.namespace", 1, 0, + "QtCoap", "Access to enums is read-only"); + + const QUrl url(QStringLiteral("qrc:/main.qml")); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + // Exit with error, if the object for main.qml could not be loaded. + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + + engine.rootContext()->setContextProperty("hostsModel", availableHosts()); + + engine.load(url); + + return app.exec(); +} diff --git a/examples/coap/quicksecureclient/main.qml b/examples/coap/quicksecureclient/main.qml new file mode 100644 index 0000000..8b637db --- /dev/null +++ b/examples/coap/quicksecureclient/main.qml @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtCoap module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * 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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.13 +import QtQuick.Layouts 1.13 +import QtQuick.Controls 2.13 +import QtQuick.Window 2.13 +import CoapSecureClient 1.0 +import qtcoap.example.namespace 1.0 + +Window { + visible: true + width: 480 + height: 640 + title: qsTr("Qt Quick Secure CoAP Client") + + CoapSecureClient { + id: client + onFinished: { + outputView.text = result + statusLabel.text = "" + } + } + + GridLayout { + anchors.fill: parent + anchors.margins: 10 + columns: 2 + + Label { + text: qsTr("Host:") + } + ComboBox { + id: hostComboBox + editable: true + model: hostsModel + Layout.fillWidth: true + } + + Label { + text: qsTr("Port:") + } + TextField { + id: portField + text: "5684" + placeholderText: qsTr("") + inputMethodHints: Qt.ImhDigitsOnly + Layout.preferredWidth: 80 + } + + Label { + text: qsTr("Resource:") + } + TextField { + id: resourceField + placeholderText: qsTr("") + inputMethodHints: Qt.ImhUrlCharactersOnly + selectByMouse: true + Layout.fillWidth: true + } + + Label { + text: qsTr("Security Mode:") + } + ButtonGroup { + id: securityModeGroup + onClicked: { + if (securityModeGroup.checkedButton === preSharedMode) + client.setSecurityMode(QtCoap.PreSharedKey); + else + client.setSecurityMode(QtCoap.Certificate); + } + } + RowLayout { + RadioButton { + id: preSharedMode + text: qsTr("Pre-shared Key") + ButtonGroup.group: securityModeGroup + } + RadioButton { + id: certificateMode + text: qsTr("X.509 Certificate") + ButtonGroup.group: securityModeGroup + } + } + + RowLayout { + enabled: securityModeGroup.checkedButton === preSharedMode + Layout.columnSpan: 2 + + Label { + text: qsTr("Key") + } + TextField { + id: pskField + placeholderText: qsTr("") + Layout.fillWidth: true + } + + Label { + text: qsTr("Identity") + } + TextField { + id: identityField + placeholderText: qsTr("") + Layout.fillWidth: true + } + } + + FilePicker { + id: localCertificatePicker + dialogText: "Local Certificate" + enabled: securityModeGroup.checkedButton === certificateMode + Layout.columnSpan: 2 + Layout.fillWidth: true + } + + FilePicker { + id: caCertificatePicker + dialogText: "CA Certificate" + enabled: securityModeGroup.checkedButton === certificateMode + Layout.columnSpan: 2 + Layout.fillWidth: true + } + + FilePicker { + id: privateKeyPicker + dialogText: "Private Key" + enabled: securityModeGroup.checkedButton === certificateMode + Layout.columnSpan: 2 + Layout.fillWidth: true + } + + Button { + id: requestButton + text: qsTr("Send Request") + enabled: securityModeGroup.checkState !== Qt.Unchecked + Layout.columnSpan: 2 + + onClicked: { + outputView.text = ""; + if (securityModeGroup.checkedButton === preSharedMode) + client.setSecurityConfiguration(pskField.text, identityField.text); + else + client.setSecurityConfiguration(localCertificatePicker.selectedFile, + caCertificatePicker.selectedFile, + privateKeyPicker.selectedFile); + + client.sendGetRequest(hostComboBox.editText, resourceField.text, + parseInt(portField.text)); + + statusLabel.text = qsTr("Sending request to %1%2...").arg(hostComboBox.editText) + .arg(resourceField.text); + } + } + + TextArea { + id: outputView + placeholderText: qsTr("") + background: Rectangle { + border.color: "gray" + } + Layout.columnSpan: 2 + Layout.fillHeight: true + Layout.fillWidth: true + } + Label { + id: statusLabel + Layout.columnSpan: 2 + Layout.fillWidth: true + } + } +} diff --git a/examples/coap/quicksecureclient/qml.qrc b/examples/coap/quicksecureclient/qml.qrc new file mode 100644 index 0000000..7f8ea45 --- /dev/null +++ b/examples/coap/quicksecureclient/qml.qrc @@ -0,0 +1,6 @@ + + + main.qml + FilePicker.qml + + diff --git a/examples/coap/quicksecureclient/qmlcoapsecureclient.cpp b/examples/coap/quicksecureclient/qmlcoapsecureclient.cpp new file mode 100644 index 0000000..f73af8e --- /dev/null +++ b/examples/coap/quicksecureclient/qmlcoapsecureclient.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtCoap module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * 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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmlcoapsecureclient.h" + +#include +#include +#include +#include +#include + +Q_LOGGING_CATEGORY(lcCoapClient, "qt.coap.client") + +QmlCoapSecureClient::QmlCoapSecureClient(QObject *parent) + : QObject(parent) + , m_coapClient(nullptr) + , m_securityMode(QtCoap::NoSec) +{ +} + +QmlCoapSecureClient::~QmlCoapSecureClient() +{ + if (m_coapClient) { + delete m_coapClient; + m_coapClient = nullptr; + } +} + +static QString errorMessage(QtCoap::Error errorCode) +{ + const auto error = QMetaEnum::fromType().valueToKey(errorCode); + return QString("Request failed with error: %1\n").arg(error); +} + +void QmlCoapSecureClient::setSecurityMode(QtCoap::SecurityMode mode) +{ + // Create a new client, if the security mode has changed + if (m_coapClient && mode != m_securityMode) { + delete m_coapClient; + m_coapClient = nullptr; + } + + if (!m_coapClient) { + m_coapClient = new QCoapClient(mode); + m_securityMode = mode; + + connect(m_coapClient, &QCoapClient::finished, this, + [this](QCoapReply *reply) { + if (!reply) + emit finished("Something went wrong, received a null reply"); + else if (reply->errorReceived() != QtCoap::NoError) + emit finished(errorMessage(reply->errorReceived())); + else + emit finished(reply->message().payload()); + }); + + connect(m_coapClient, &QCoapClient::error, this, + [this](QCoapReply *, QtCoap::Error errorCode) { + emit finished(errorMessage(errorCode)); + }); + } +} + +void QmlCoapSecureClient::sendGetRequest(const QString &host, const QString &path, int port) +{ + if (!m_coapClient) + return; + + m_coapClient->setSecurityConfiguration(m_configuration); + + QUrl url; + url.setHost(host); + url.setPath(path); + url.setPort(port); + m_coapClient->get(url); +} + +void +QmlCoapSecureClient::setSecurityConfiguration(const QString &preSharedKey, const QString &identity) +{ + QCoapSecurityConfiguration configuration; + configuration.setPreSharedKey(preSharedKey.toUtf8()); + configuration.setIdentity(identity.toUtf8()); + m_configuration = configuration; +} + +void QmlCoapSecureClient::setSecurityConfiguration(const QString &localCertificatePath, + const QString &caCertificatePath, + const QString &privateKeyPath) +{ + QCoapSecurityConfiguration configuration; + + const auto localCerts = QSslCertificate::fromPath(QUrl(localCertificatePath).toLocalFile()); + if (localCerts.isEmpty()) + qCWarning(lcCoapClient, "The specified local certificate file is not valid."); + else + configuration.setLocalCertificateChain(localCerts.toVector()); + + const auto caCerts = QSslCertificate::fromPath(QUrl(caCertificatePath).toLocalFile()); + if (caCerts.isEmpty()) + qCWarning(lcCoapClient, "The specified CA certificate file is not valid."); + else + configuration.setCaCertificates(caCerts.toVector()); + + QFile privateKey(QUrl(privateKeyPath).toLocalFile()); + if (privateKey.open(QIODevice::ReadOnly)) { + QCoapPrivateKey key(privateKey.readAll(), QSsl::Ec); + configuration.setPrivateKey(key); + } else { + qCWarning(lcCoapClient) << "Unable to read the specified private key file" + << privateKeyPath; + } + m_configuration = configuration; +} diff --git a/examples/coap/quicksecureclient/qmlcoapsecureclient.h b/examples/coap/quicksecureclient/qmlcoapsecureclient.h new file mode 100644 index 0000000..1451d32 --- /dev/null +++ b/examples/coap/quicksecureclient/qmlcoapsecureclient.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtCoap module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * 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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLCOAPSECURECLIENT_H +#define QMLCOAPSECURECLIENT_H + +#include +#include + +class QmlCoapSecureClient : public QObject +{ + Q_OBJECT + +public: + QmlCoapSecureClient(QObject *parent = nullptr); + ~QmlCoapSecureClient() override; + + Q_INVOKABLE void setSecurityMode(QtCoap::SecurityMode mode); + Q_INVOKABLE void sendGetRequest(const QString &host, const QString &path, int port); + Q_INVOKABLE void setSecurityConfiguration(const QString &preSharedKey, const QString &identity); + Q_INVOKABLE void setSecurityConfiguration(const QString &localCertificatePath, + const QString &caCertificatePath, + const QString &privateKeyPath); + +Q_SIGNALS: + void finished(const QString &result); + +private: + QCoapClient *m_coapClient; + QCoapSecurityConfiguration m_configuration; + QtCoap::SecurityMode m_securityMode; +}; + +#endif // QMLCOAPSECURECLIENT_H diff --git a/examples/coap/quicksecureclient/quicksecureclient.pro b/examples/coap/quicksecureclient/quicksecureclient.pro new file mode 100644 index 0000000..52fcea9 --- /dev/null +++ b/examples/coap/quicksecureclient/quicksecureclient.pro @@ -0,0 +1,21 @@ +TEMPLATE = app + +QT += qml quick coap +CONFIG += c++11 + +DEFINES += QT_DEPRECATED_WARNINGS + +HEADERS += \ + qmlcoapsecureclient.h + +SOURCES += \ + main.cpp \ + qmlcoapsecureclient.cpp + +DISTFILES += \ + FilePicker.qml + +RESOURCES += qml.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/coap/quicksecureclient +INSTALLS += target -- cgit v1.2.3