aboutsummaryrefslogtreecommitdiffstats
path: root/examples/coap
diff options
context:
space:
mode:
Diffstat (limited to 'examples/coap')
-rw-r--r--examples/coap/coap.pro5
-rw-r--r--examples/coap/consolecoapclient/coaphandler.cpp132
-rw-r--r--examples/coap/consolecoapclient/coaphandler.h73
-rw-r--r--examples/coap/consolecoapclient/consolecoapclient.pro14
-rw-r--r--examples/coap/consolecoapclient/main.cpp75
-rw-r--r--examples/coap/doc/consolecoapclient.qdoc33
-rw-r--r--examples/coap/doc/examples.qdoc35
-rw-r--r--examples/coap/doc/quickmulticastclient.qdoc34
-rw-r--r--examples/coap/doc/quicksecureclient.qdoc33
-rw-r--r--examples/coap/doc/simplecoapclient.qdoc33
-rw-r--r--examples/coap/simplecoapclient/main.cpp62
-rw-r--r--examples/coap/simplecoapclient/mainwindow.cpp259
-rw-r--r--examples/coap/simplecoapclient/mainwindow.h99
-rw-r--r--examples/coap/simplecoapclient/mainwindow.ui360
-rw-r--r--examples/coap/simplecoapclient/optiondialog.cpp121
-rw-r--r--examples/coap/simplecoapclient/optiondialog.h84
-rw-r--r--examples/coap/simplecoapclient/optiondialog.ui154
-rw-r--r--examples/coap/simplecoapclient/simplecoapclient.pro33
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