/****************************************************************************
**
** 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.

    \image quickmulticastclient.png

    The \e {Quick CoAP Multicast Discovery Example} demonstrates how to register
    QCoapClient as a QML type and use it in a Qt Quick application for CoAP multicast
    resource discovery.

    \note Qt CoAP does not provide a QML API in its current version. However, you can
    make the C++ classes of the module available to QML as shown in this example.

    \section1 Running the Example

    To run the example application, you first need to set up and start at least one CoAP
    server supporting multicast resource discovery. You have the following options:

    \list
        \li Manually build and run CoAP servers using
        \l {https://github.com/obgm/libcoap} {libcoap},
        \l {https://github.com/eclipse/californium/} {Californium}, or any
        other CoAP server implementation, which supports multicast and resource
        discovery features.
        \li Use the ready Docker image available at Docker Hub, which builds and starts
        CoAP server based on Californium's
        \l {https://github.com/eclipse/californium/tree/2.0.x/demo-apps/cf-helloworld-server}
        {multicast server example}.
    \endlist

    \section2 Using the Docker-based Test Server

    The following command pulls the docker container for the CoAP server from the
    Docker Hub and starts it:

    \badcode
    docker run --name coap-multicast-server -d --rm --net=host sokurazy/coap-multicast-test-server:californium.2.0.x
    \endcode

    \note You can run more than one multicast CoAP servers (on the same host or other
    hosts in the network) by passing a different \c{--name} to the command above.

    \section1 Creating a Client and Using It with QML

    We create the \c QmlCoapMulticastClient class with the QCoapClient class as a
    base class:

    \quotefromfile quickmulticastclient/qmlcoapmulticastclient.h
    \skipto QmlCoapMulticastClient
    \printuntil };

    In the main.cpp file, we register the \c QmlCoapMulticastClient class as a QML
    type:

    \quotefromfile quickmulticastclient/main.cpp
    \skipto qmlRegisterType
    \printline qmlRegisterType

    We also register the QtCoap namespace, to be able to use it in QML code:

    \skipto qmlRegisterUncreatableMetaObject
    \printto const QUrl

    Now in the QML code, we can import and use these types:

    \quotefromfile quickmulticastclient/main.qml
    \dots
    \skipto CoapMulticastClient
    \printuntil qtcoap.example.namespace
    \dots
    \skipto CoapMulticastClient
    \printto GridLayout
    \dots

    The \c {QCoapClient::error()} signal triggers the \c onError signal handler of
    \c CoapMulticastClient, and the \c {QmlCoapMulticastClient::finished()} signal
    triggers the \c onFinished signal handler, to show the request's status in the UI.
    Note that we are not using the \c {QCoapClient::finished()} signal directly,
    because it takes a \c {QCoapReply} as a parameter (which is not a QML type), and
    we are interested only in the error code.

    In the \c QmlCoapMulticastClient's constructor, we arrange for the
    \c {QCoapClient::finished()} signal to be forwarded to the
    \c {QmlCoapMulticastClient::finished()} signal:

    \quotefromfile quickmulticastclient/qmlcoapmulticastclient.cpp
    \skipto QmlCoapMulticastClient::QmlCoapMulticastClient
    \printto QmlCoapMulticastClient::discover

    When the \uicontrol Discover button is pressed, we invoke one of the overloaded
    \c {discover()} methods, based on the selected multicast group:

    \quotefromfile quickmulticastclient/main.qml
    \skipto Button {
    \dots
    \printto ListModel {
    \dots

    This overload is called when a custom multicast group or a host address is selected:

    \quotefromfile quickmulticastclient/qmlcoapmulticastclient.cpp
    \skipto QmlCoapMulticastClient::discover
    \printto QmlCoapMulticastClient::discover(QtCoap::MulticastGroup

    And this overload is called when one of the suggested multicast groups is selected
    in the UI:

    \printto void QmlCoapMulticastClient::onDiscovered

    The \c {QCoapClient::discovered()} signal delivers a list of \c {QCoapResources},
    which is not a QML type. To make the resources available in QML, we forward each
    resource in the list to the \c {QmlCoapMulticastClient::discovered()} signal, which
    takes a \c QmlCoapResource instead:

    \printuntil

    \c QmlCoapResource is a wrapper around QCoapResource, to make some of its
    properties available in QML:

    \quotefromfile quickmulticastclient/qmlcoapmulticastclient.h
    \skipto class QmlCoapResource
    \printuntil };

    The discovered resources are added to the \c resourceModel of the list view in the UI:

    \quotefromfile quickmulticastclient/main.qml
    \skipto addResource
    \dots
    \printto CoapMulticastClient {
    \dots
*/
