diff options
Diffstat (limited to 'examples/coap')
-rw-r--r-- | examples/coap/coap.pro | 5 | ||||
-rw-r--r-- | examples/coap/consolecoapclient/coaphandler.cpp | 132 | ||||
-rw-r--r-- | examples/coap/consolecoapclient/coaphandler.h | 73 | ||||
-rw-r--r-- | examples/coap/consolecoapclient/consolecoapclient.pro | 14 | ||||
-rw-r--r-- | examples/coap/consolecoapclient/main.cpp | 75 | ||||
-rw-r--r-- | examples/coap/doc/consolecoapclient.qdoc | 33 | ||||
-rw-r--r-- | examples/coap/doc/examples.qdoc | 35 | ||||
-rw-r--r-- | examples/coap/doc/quickmulticastclient.qdoc | 34 | ||||
-rw-r--r-- | examples/coap/doc/quicksecureclient.qdoc | 33 | ||||
-rw-r--r-- | examples/coap/doc/simplecoapclient.qdoc | 33 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/main.cpp | 62 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/mainwindow.cpp | 259 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/mainwindow.h | 99 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/mainwindow.ui | 360 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/optiondialog.cpp | 121 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/optiondialog.h | 84 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/optiondialog.ui | 154 | ||||
-rw-r--r-- | examples/coap/simplecoapclient/simplecoapclient.pro | 33 |
18 files changed, 1639 insertions, 0 deletions
diff --git a/examples/coap/coap.pro b/examples/coap/coap.pro new file mode 100644 index 0000000..0a8f1c3 --- /dev/null +++ b/examples/coap/coap.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + simplecoapclient \ + consolecoapclient diff --git a/examples/coap/consolecoapclient/coaphandler.cpp b/examples/coap/consolecoapclient/coaphandler.cpp new file mode 100644 index 0000000..04ef6f3 --- /dev/null +++ b/examples/coap/consolecoapclient/coaphandler.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Witekio. +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCoap module. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "coaphandler.h" + +#include <QDebug> +#include <QLoggingCategory> +#include <QCoapClient> +#include <QCoapReply> +#include <QCoapDiscoveryReply> + +Q_LOGGING_CATEGORY(lcCoapClient, "qt.coap.client") + +CoapHandler::CoapHandler(QObject *parent) : QObject(parent) +{ + connect(&m_coapClient, &QCoapClient::finished, this, &CoapHandler::onFinished); + connect(&m_coapClient, &QCoapClient::error, this, &CoapHandler::onError); + connect(&m_coapClient, &QCoapClient::responseToMulticastReceived, + this, &CoapHandler::onResponseToMulticast); +} + +bool CoapHandler::runGet(const QUrl &url) +{ + return m_coapClient.get(url); +} + +bool CoapHandler::runPost(const QUrl &url) +{ + return m_coapClient.post(url); +} + +bool CoapHandler::runPut(const QUrl &url) +{ + return m_coapClient.put(url); +} + +bool CoapHandler::runDelete(const QUrl &url) +{ + return m_coapClient.deleteResource(url); +} + +bool CoapHandler::runObserve(const QUrl &url) +{ + QCoapReply *observeReply = m_coapClient.observe(url); + if (!observeReply) + return false; + + connect(observeReply, &QCoapReply::notified, this, &CoapHandler::onNotified); + return true; +} + +bool CoapHandler::runDiscover(const QUrl &url) +{ + QCoapDiscoveryReply *discoverReply = m_coapClient.discover(url); + if (!discoverReply) + return false; + + connect(discoverReply, &QCoapDiscoveryReply::discovered, this, &CoapHandler::onDiscovered); + return true; +} + +void CoapHandler::onFinished(QCoapReply *reply) +{ + if (reply->errorReceived() == QtCoap::NoError) + qCInfo(lcCoapClient) << "Request finished with payload:" << reply->readAll(); + else + qCWarning(lcCoapClient, "Request failed"); + + // Don't forget to remove the reply + reply->deleteLater(); +} + +void CoapHandler::onNotified(QCoapReply *reply, QCoapMessage message) +{ + Q_UNUSED(message) + + // You can alternatively use `message.payload();` + qCInfo(lcCoapClient) << "Received Observe notification with payload:" << reply->readAll(); +} + +void CoapHandler::onDiscovered(QCoapDiscoveryReply *reply, QVector<QCoapResource> resources) +{ + Q_UNUSED(reply) + + for (const QCoapResource &res : qAsConst(resources)) + qCInfo(lcCoapClient) << "Discovered resource:" << res.path() << res.title(); +} + +void CoapHandler::onResponseToMulticast(QCoapReply *reply, const QCoapMessage& message, + const QHostAddress &sender) +{ + if (reply->errorReceived() == QtCoap::NoError) + qCInfo(lcCoapClient) << "Got a response for multicast request from:" << sender.toString() + << "with payload:" << message.payload(); + else + qCWarning(lcCoapClient, "Multicast request failed"); +} + +void CoapHandler::onError(QCoapReply *reply, QtCoap::Error error) +{ + if (reply) + qCInfo(lcCoapClient) << "CoAP reply error:" << reply->errorString(); + else + qCWarning(lcCoapClient) << "CoAP error:" << error; +} diff --git a/examples/coap/consolecoapclient/coaphandler.h b/examples/coap/consolecoapclient/coaphandler.h new file mode 100644 index 0000000..1034ad1 --- /dev/null +++ b/examples/coap/consolecoapclient/coaphandler.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Witekio. +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCoap module. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COAPHANDLER_H +#define COAPHANDLER_H + +#include <QObject> +#include <QCoapClient> +#include <QCoapMessage> +#include <QCoapResource> +#include <qcoapnamespace.h> + +QT_BEGIN_NAMESPACE + +class QCoapReply; +class QCoapDiscoveryReply; +class QCoapResource; + +QT_END_NAMESPACE + +class CoapHandler : public QObject +{ + Q_OBJECT +public: + explicit CoapHandler(QObject *parent = nullptr); + + bool runGet(const QUrl &url); + bool runPost(const QUrl &url); + bool runPut(const QUrl &url); + bool runDelete(const QUrl &url); + bool runObserve(const QUrl &url); + bool runDiscover(const QUrl &url); + +public Q_SLOTS: + void onFinished(QCoapReply *reply); + void onNotified(QCoapReply *reply, QCoapMessage message); + void onDiscovered(QCoapDiscoveryReply *reply, QVector<QCoapResource> resources); + void onResponseToMulticast(QCoapReply *reply, const QCoapMessage& message, + const QHostAddress &sender); + void onError(QCoapReply *reply, QtCoap::Error error); + +private: + QCoapClient m_coapClient; +}; + +#endif // COAPHANDLER_H diff --git a/examples/coap/consolecoapclient/consolecoapclient.pro b/examples/coap/consolecoapclient/consolecoapclient.pro new file mode 100644 index 0000000..9d271ed --- /dev/null +++ b/examples/coap/consolecoapclient/consolecoapclient.pro @@ -0,0 +1,14 @@ +QT -= gui +QT += network coap + +TARGET = testapp + +HEADERS += \ + coaphandler.h + +SOURCES += main.cpp \ + coaphandler.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/coap/consolecoapclient +INSTALLS += target diff --git a/examples/coap/consolecoapclient/main.cpp b/examples/coap/consolecoapclient/main.cpp new file mode 100644 index 0000000..096277c --- /dev/null +++ b/examples/coap/consolecoapclient/main.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Witekio. +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCoap module. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "coaphandler.h" + +#include <QCoreApplication> +#include <QCommandLineParser> +#include <QUrl> + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + QCommandLineParser parser; + parser.setApplicationDescription("Qt CoAP test application"); + parser.addHelpOption(); + parser.addPositionalArgument("url", + "The targeted coap resource URL, e.g. 'coap://10.10.10.10/myresource'"); + parser.addOption({"get", "Use GET method for the request. This is the default method"}); + parser.addOption({"post", "Use POST method for the request"}); + parser.addOption({"put", "Use PUT method for the request"}); + parser.addOption({"delete", "Use DELETE method for the request"}); + parser.addOption({"observe", "Observe a resource"}); + parser.addOption({"discover", "Discover available resources"}); + + parser.process(a); + + if (parser.positionalArguments().isEmpty()) { + qWarning("Please provide an url for the request"); + parser.showHelp(1); + } + + QUrl url = parser.positionalArguments().first(); + if (!url.isValid()) { + qWarning("The url provided is not valid."); + parser.showHelp(1); + } + + CoapHandler handler; + if (parser.isSet("get")) handler.runGet(url); + if (parser.isSet("post")) handler.runPost(url); + if (parser.isSet("put")) handler.runPut(url); + if (parser.isSet("delete")) handler.runDelete(url); + if (parser.isSet("observe")) handler.runObserve(url); + if (parser.isSet("discover")) handler.runDiscover(url); + + return a.exec(); +} diff --git a/examples/coap/doc/consolecoapclient.qdoc b/examples/coap/doc/consolecoapclient.qdoc new file mode 100644 index 0000000..c382ab2 --- /dev/null +++ b/examples/coap/doc/consolecoapclient.qdoc @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example consolecoapclient + \title Console CoAP Client Example + \ingroup qtcoap-examples + \brief Creating a simple console application that communicates with a CoAP server. +*/ diff --git a/examples/coap/doc/examples.qdoc b/examples/coap/doc/examples.qdoc new file mode 100644 index 0000000..96930e1 --- /dev/null +++ b/examples/coap/doc/examples.qdoc @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group qtcoap-examples + \title Qt CoAP Examples + \brief List of Qt CoAP examples. + + The Qt CoAP examples demonstrate the functionality provided by the + \l{Qt CoAP} module. +*/ diff --git a/examples/coap/doc/quickmulticastclient.qdoc b/examples/coap/doc/quickmulticastclient.qdoc new file mode 100644 index 0000000..c3295c5 --- /dev/null +++ b/examples/coap/doc/quickmulticastclient.qdoc @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example quickmulticastclient + \title Quick CoAP Multicast Discovery Example + \ingroup qtcoap-examples + \brief Using the CoAP client for a multicast resource discovery with a Qt Quick + user interface. +*/ diff --git a/examples/coap/doc/quicksecureclient.qdoc b/examples/coap/doc/quicksecureclient.qdoc new file mode 100644 index 0000000..1c72633 --- /dev/null +++ b/examples/coap/doc/quicksecureclient.qdoc @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example quicksecureclient + \title Quick Secure CoAP Client Example + \ingroup qtcoap-examples + \brief Securing the CoAP client and using it with a Qt Quick user interface. +*/ diff --git a/examples/coap/doc/simplecoapclient.qdoc b/examples/coap/doc/simplecoapclient.qdoc new file mode 100644 index 0000000..6ca6459 --- /dev/null +++ b/examples/coap/doc/simplecoapclient.qdoc @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example simplecoapclient + \title Simple CoAP Client Example + \ingroup qtcoap-examples + \brief Creating an application that communicates with a CoAP server. +*/ diff --git a/examples/coap/simplecoapclient/main.cpp b/examples/coap/simplecoapclient/main.cpp new file mode 100644 index 0000000..2968a11 --- /dev/null +++ b/examples/coap/simplecoapclient/main.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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 "mainwindow.h" + +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/examples/coap/simplecoapclient/mainwindow.cpp b/examples/coap/simplecoapclient/mainwindow.cpp new file mode 100644 index 0000000..c14f3ce --- /dev/null +++ b/examples/coap/simplecoapclient/mainwindow.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** 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 "mainwindow.h" +#include "optiondialog.h" +#include "ui_mainwindow.h" + +#include <QCoapDiscoveryReply> +#include <QCoapReply> +#include <QDateTime> +#include <QFileDialog> +#include <QHostInfo> +#include <QMessageBox> +#include <QMetaEnum> +#include <QNetworkInterface> + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow), + m_client(new QCoapClient(QtCoap::NoSec, this)) +{ + ui->setupUi(this); + + ui->methodComboBox->addItem("Get", QtCoap::Method::Get); + ui->methodComboBox->addItem("Put", QtCoap::Method::Put); + ui->methodComboBox->addItem("Post", QtCoap::Method::Post); + ui->methodComboBox->addItem("Delete", QtCoap::Method::Delete); + + fillHostSelector(); + ui->hostComboBox->setFocus(); + + connect(m_client, &QCoapClient::finished, this, &MainWindow::onFinished); + connect(m_client, &QCoapClient::error, this, &MainWindow::onError); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::fillHostSelector() +{ + const auto networkInterfaces = QNetworkInterface::allInterfaces(); + for (const auto &interface : networkInterfaces) + for (const auto &address : interface.addressEntries()) + ui->hostComboBox->addItem(address.ip().toString()); +} + +void MainWindow::addMessage(const QString &message, bool isError) +{ + const QString content = "--------------- " + + QDateTime::currentDateTime().toString() + + " ---------------\n" + + message + "\n\n"; + ui->textEdit->setTextColor(isError ? Qt::red : Qt::black); + ui->textEdit->insertPlainText(content); + ui->textEdit->ensureCursorVisible(); +} + +void MainWindow::onFinished(QCoapReply *reply) +{ + if (reply->errorReceived() == QtCoap::NoError) + addMessage(reply->message().payload()); +} + +static QString errorMessage(QtCoap::Error errorCode) +{ + const auto error = QMetaEnum::fromType<QtCoap::Error>().valueToKey(errorCode); + return QString("Request failed with error: %1\n").arg(error); +} + +void MainWindow::onError(QCoapReply *reply, QtCoap::Error error) +{ + const auto errorCode = reply ? reply->errorReceived() : error; + addMessage(errorMessage(errorCode), true); +} + +void MainWindow::onDiscovered(QCoapDiscoveryReply *reply, QVector<QCoapResource> resources) +{ + if (reply->errorReceived() != QtCoap::NoError) + return; + + QString message; + for (const auto &resource : resources) { + ui->resourceComboBox->addItem(resource.path()); + message += "Discovered resource: \"" + resource.title() + "\" on path " + + resource.path() + "\n"; + } + addMessage(message); +} + +void MainWindow::onNotified(QCoapReply *reply, const QCoapMessage &message) +{ + if (reply->errorReceived() == QtCoap::NoError) + addMessage("Received observe notification with payload: " + message.payload()); +} + + +static QString tryToResolveHostName(const QString hostName) +{ + const auto hostInfo = QHostInfo::fromName(hostName); + if (!hostInfo.addresses().empty()) + return hostInfo.addresses().first().toString(); + + return hostName; +} + +void MainWindow::on_runButton_clicked() +{ + const auto msgType = ui->msgTypeCheckBox->isChecked() ? QCoapMessage::Confirmable + : QCoapMessage::NonConfirmable; + QUrl url; + url.setHost(tryToResolveHostName(ui->hostComboBox->currentText())); + url.setPort(ui->portSpinBox->value()); + url.setPath(ui->resourceComboBox->currentText()); + + QCoapRequest request(url, msgType); + for (const auto &option : m_options) + request.addOption(option); + m_options.clear(); + + const auto method = ui->methodComboBox->currentData(Qt::UserRole).value<QtCoap::Method>(); + switch (method) { + case QtCoap::Get: + m_client->get(request); + break; + case QtCoap::Put: + m_client->put(request, m_currentData); + break; + case QtCoap::Post: + m_client->post(request, m_currentData); + break; + case QtCoap::Delete: + m_client->deleteResource(request); + break; + default: + break; + } + m_currentData.clear(); +} + +void MainWindow::on_discoverButton_clicked() +{ + QUrl url; + url.setHost(tryToResolveHostName(ui->hostComboBox->currentText())); + url.setPort(ui->portSpinBox->value()); + + QCoapDiscoveryReply *discoverReply = m_client->discover(url, ui->discoveryPathEdit->text()); + if (discoverReply) + connect(discoverReply, &QCoapDiscoveryReply::discovered, this, &MainWindow::onDiscovered); + else + QMessageBox::critical(this, "Error", "Something went wrong, discovery request failed."); +} + +void MainWindow::on_observeButton_clicked() +{ + QUrl url; + url.setHost(tryToResolveHostName(ui->hostComboBox->currentText())); + url.setPort(ui->portSpinBox->value()); + url.setPath(ui->resourceComboBox->currentText()); + + QCoapReply *observeReply = m_client->observe(url); + if (!observeReply) { + QMessageBox::critical(this, "Error", "Something went wrong, observe request failed."); + return; + } + + connect(observeReply, &QCoapReply::notified, this, &MainWindow::onNotified); + + ui->cancelObserveButton->setEnabled(true); + connect(ui->cancelObserveButton, &QPushButton::clicked, this, [=]() { + m_client->cancelObserve(url); + ui->cancelObserveButton->setEnabled(false); + }); +} + +void MainWindow::on_addOptionsButton_clicked() +{ + OptionDialog dialog; + if (dialog.exec() == QDialog::Accepted) + m_options = dialog.options(); +} + +void MainWindow::on_contentButton_clicked() +{ + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::AnyFile); + if (!dialog.exec()) + return; + + const auto fileName = dialog.selectedFiles().back(); + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, "Error", QString("Failed to read from file %1").arg(fileName)); + return; + } + + m_currentData = file.readAll(); +} + +void MainWindow::on_resourceComboBox_editTextChanged(const QString &text) +{ + ui->observeButton->setEnabled(!text.isEmpty()); +} + +void MainWindow::on_methodComboBox_currentIndexChanged(int index) +{ + Q_UNUSED(index); + + const auto method = ui->methodComboBox->currentData(Qt::UserRole).value<QtCoap::Method>(); + ui->contentButton->setEnabled(method == QtCoap::Put || method == QtCoap::Post); +} diff --git a/examples/coap/simplecoapclient/mainwindow.h b/examples/coap/simplecoapclient/mainwindow.h new file mode 100644 index 0000000..a561c0e --- /dev/null +++ b/examples/coap/simplecoapclient/mainwindow.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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 MAINWINDOW_H +#define MAINWINDOW_H + +#include <QCoapClient> +#include <QCoapOption> +#include <QCoapResource> +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +class QCoapMessage; +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private: + void fillHostSelector(); + void addMessage(const QString &message, bool isError = false); + +private slots: + void onFinished(QCoapReply *reply); + void onError(QCoapReply *reply, QtCoap::Error error); + void onDiscovered(QCoapDiscoveryReply *reply, QVector<QCoapResource> resources); + void onNotified(QCoapReply *reply, const QCoapMessage &message); + + void on_runButton_clicked(); + void on_discoverButton_clicked(); + void on_observeButton_clicked(); + void on_addOptionsButton_clicked(); + void on_contentButton_clicked(); + void on_resourceComboBox_editTextChanged(const QString &text); + void on_methodComboBox_currentIndexChanged(int index); + +private: + Ui::MainWindow *ui; + QCoapClient *m_client; + QVector<QCoapOption> m_options; + QByteArray m_currentData; +}; + +#endif // MAINWINDOW_H diff --git a/examples/coap/simplecoapclient/mainwindow.ui b/examples/coap/simplecoapclient/mainwindow.ui new file mode 100644 index 0000000..f6cff95 --- /dev/null +++ b/examples/coap/simplecoapclient/mainwindow.ui @@ -0,0 +1,360 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>731</width> + <height>530</height> + </rect> + </property> + <property name="windowTitle"> + <string>CoAP Client</string> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Host</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Request Method</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="3" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QComboBox" name="resourceComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="observeButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Observe</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QComboBox" name="hostComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>250</width> + <height>0</height> + </size> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="4" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QComboBox" name="methodComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>150</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="msgTypeCheckBox"> + <property name="text"> + <string>Confirmable</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="addOptionsButton"> + <property name="text"> + <string>Add Options</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="contentButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Add Content</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Disscovery Path:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="6" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Output</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QTextEdit" name="textEdit"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Port</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="5" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_12"> + <item> + <widget class="QPushButton" name="runButton"> + <property name="text"> + <string>Run</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelObserveButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Cancel Observe</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Resource</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_13"> + <item> + <widget class="QLineEdit" name="discoveryPathEdit"> + <property name="text"> + <string>/.well-known/core</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="discoverButton"> + <property name="text"> + <string>Discover</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_7"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QSpinBox" name="portSpinBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="maximum"> + <number>65535</number> + </property> + <property name="value"> + <number>5683</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>731</width> + <height>22</height> + </rect> + </property> + </widget> + <widget class="QToolBar" name="mainToolBar"> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + </widget> + <widget class="QStatusBar" name="statusBar"/> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/examples/coap/simplecoapclient/optiondialog.cpp b/examples/coap/simplecoapclient/optiondialog.cpp new file mode 100644 index 0000000..5125541 --- /dev/null +++ b/examples/coap/simplecoapclient/optiondialog.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** 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 "optiondialog.h" +#include "ui_optiondialog.h" + +OptionDialog::OptionDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::OptionDialog) +{ + ui->setupUi(this); + + fillOptions(); + + auto header = ui->tableWidget->horizontalHeader(); + header->setSectionResizeMode(QHeaderView::Stretch); +} + +OptionDialog::~OptionDialog() +{ + delete ui; +} + +QVector<QCoapOption> OptionDialog::options() const +{ + return m_options; +} + +void OptionDialog::on_addButton_clicked() +{ + const auto option = + ui->optionComboBox->currentData(Qt::UserRole).value<QCoapOption::OptionName>(); + m_options.push_back(QCoapOption(option, ui->optionValueEdit->text())); + + const auto rowCount = ui->tableWidget->rowCount(); + ui->tableWidget->insertRow(rowCount); + + QTableWidgetItem *optionItem = new QTableWidgetItem(ui->optionComboBox->currentText()); + optionItem->setFlags(optionItem->flags() ^ Qt::ItemIsEditable); + ui->tableWidget->setItem(rowCount, 0, optionItem); + + QTableWidgetItem *valueItem = new QTableWidgetItem(ui->optionValueEdit->text()); + valueItem->setFlags(valueItem->flags() ^ Qt::ItemIsEditable); + ui->tableWidget->setItem(rowCount, 1, valueItem); +} + +void OptionDialog::on_clearButton_clicked() +{ + m_options.clear(); + ui->tableWidget->setRowCount(0); +} + +void OptionDialog::fillOptions() +{ + ui->tableWidget->setHorizontalHeaderLabels({"Name", "Value"}); + ui->optionComboBox->addItem("None", QCoapOption::Invalid); + ui->optionComboBox->addItem("Block1", QCoapOption::Block1); + ui->optionComboBox->addItem("Block2", QCoapOption::Block2); + ui->optionComboBox->addItem("Content-Format", QCoapOption::ContentFormat); + ui->optionComboBox->addItem("If-Match", QCoapOption::IfMatch); + ui->optionComboBox->addItem("If-None-Match", QCoapOption::IfNoneMatch); + ui->optionComboBox->addItem("Location-Path", QCoapOption::LocationPath); + ui->optionComboBox->addItem("Location-Query", QCoapOption::LocationQuery); + ui->optionComboBox->addItem("Max-Age", QCoapOption::MaxAge); + ui->optionComboBox->addItem("Observe", QCoapOption::Observe); + ui->optionComboBox->addItem("Proxy-Scheme", QCoapOption::ProxyScheme); + ui->optionComboBox->addItem("Proxy-Uri", QCoapOption::ProxyUri); + ui->optionComboBox->addItem("Size1", QCoapOption::Size1); + ui->optionComboBox->addItem("Size2", QCoapOption::Size2); + ui->optionComboBox->addItem("Uri-Host", QCoapOption::UriHost); + ui->optionComboBox->addItem("Uri-Path", QCoapOption::UriPath); + ui->optionComboBox->addItem("Uri-Port", QCoapOption::UriPort); + ui->optionComboBox->addItem("Uri-Query", QCoapOption::UriQuery); +} diff --git a/examples/coap/simplecoapclient/optiondialog.h b/examples/coap/simplecoapclient/optiondialog.h new file mode 100644 index 0000000..ecd0b34 --- /dev/null +++ b/examples/coap/simplecoapclient/optiondialog.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** 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 OPTIONDIALOG_H +#define OPTIONDIALOG_H + +#include <QCoapOption> +#include <QDialog> + +QT_BEGIN_NAMESPACE +namespace Ui { +class OptionDialog; +} +QT_END_NAMESPACE + +class OptionDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OptionDialog(QWidget *parent = nullptr); + ~OptionDialog(); + + QVector<QCoapOption> options() const; + +private slots: + void on_addButton_clicked(); + void on_clearButton_clicked(); + +private: + void fillOptions(); + + Ui::OptionDialog *ui; + QVector<QCoapOption> m_options; +}; + +#endif // OPTIONDIALOG_H diff --git a/examples/coap/simplecoapclient/optiondialog.ui b/examples/coap/simplecoapclient/optiondialog.ui new file mode 100644 index 0000000..7313b32 --- /dev/null +++ b/examples/coap/simplecoapclient/optiondialog.ui @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>OptionDialog</class> + <widget class="QDialog" name="OptionDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>414</width> + <height>313</height> + </rect> + </property> + <property name="windowTitle"> + <string>Add Options</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Option</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="optionComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>120</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="optionValueEdit"/> + </item> + </layout> + </item> + <item> + <widget class="QTableWidget" name="tableWidget"> + <property name="columnCount"> + <number>2</number> + </property> + <column/> + <column/> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="addButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="clearButton"> + <property name="text"> + <string>Clear</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>OptionDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>152</x> + <y>289</y> + </hint> + <hint type="destinationlabel"> + <x>206</x> + <y>156</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>OptionDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>152</x> + <y>289</y> + </hint> + <hint type="destinationlabel"> + <x>206</x> + <y>156</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/examples/coap/simplecoapclient/simplecoapclient.pro b/examples/coap/simplecoapclient/simplecoapclient.pro new file mode 100644 index 0000000..d83d7b3 --- /dev/null +++ b/examples/coap/simplecoapclient/simplecoapclient.pro @@ -0,0 +1,33 @@ +QT += core gui network coap widgets + +TARGET = simplecoapclient +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +CONFIG += c++11 + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + optiondialog.cpp + +HEADERS += \ + mainwindow.h \ + optiondialog.h + +FORMS += \ + mainwindow.ui \ + optiondialog.ui + +target.path = $$[QT_INSTALL_EXAMPLES]/coap/simplecoapclient +INSTALLS += target |