aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAri Salmi <snowgrains@snowgrains.com>2017-07-15 00:37:31 +0300
committerSamuli Piippo <samuli.piippo@qt.io>2017-11-30 09:58:46 +0000
commitd683d8b556f924a67aaa0012c417f9346b46ec1a (patch)
tree02936aa4c1d890299d7787de683b584c16f4d259
parent8737866cee70b782ce862a450d0f8db1917be0df (diff)
Initial import
Change-Id: I6a868ab4b9f418114e52f57c5b9db2b54f350a4f Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
-rw-r--r--.gitignore10
-rw-r--r--.qmake.conf4
-rw-r--r--README.md242
-rw-r--r--dist/changes-1.0.023
-rw-r--r--examples/README.md8
-rw-r--r--qtcloudmessaging.pro1
-rw-r--r--src/cloudmessaging/cloudmessaging.pro24
-rw-r--r--src/cloudmessaging/doc/README.md11
-rw-r--r--src/cloudmessaging/doc/qtcloudmessaging.qdocconf51
-rw-r--r--src/cloudmessaging/qcloudmessaging.cpp501
-rw-r--r--src/cloudmessaging/qcloudmessaging.h122
-rw-r--r--src/cloudmessaging/qcloudmessaging_p.h79
-rw-r--r--src/cloudmessaging/qcloudmessagingclient.cpp333
-rw-r--r--src/cloudmessaging/qcloudmessagingclient.h115
-rw-r--r--src/cloudmessaging/qcloudmessagingclient_p.h69
-rw-r--r--src/cloudmessaging/qcloudmessagingprovider.cpp543
-rw-r--r--src/cloudmessaging/qcloudmessagingprovider.h142
-rw-r--r--src/cloudmessaging/qcloudmessagingprovider_p.h71
-rw-r--r--src/cloudmessaging/qcloudmessagingrestapi.cpp658
-rw-r--r--src/cloudmessaging/qcloudmessagingrestapi.h144
-rw-r--r--src/cloudmessaging/qcloudmessagingrestapi_p.h87
-rw-r--r--src/cloudmessaging/qtcloudmessagingglobal.h47
-rw-r--r--src/cloudmessagingembeddedkaltiot/android/ks_gw_client_android.h258
-rw-r--r--src/cloudmessagingembeddedkaltiot/cloudmessagingembeddedkaltiot.pro48
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.cpp342
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.h95
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient_p.h84
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.cpp486
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.h95
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider_p.h77
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.cpp145
-rw-r--r--src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.h127
-rw-r--r--src/cloudmessagingfirebase/cloudmessagingfirebase.pro51
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.cpp336
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.h94
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaseclient_p.h75
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.cpp271
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.h95
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider_p.h67
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaserest.cpp119
-rw-r--r--src/cloudmessagingfirebase/qcloudmessagingfirebaserest.h72
-rw-r--r--src/src.pro8
-rw-r--r--sync.profile7
-rw-r--r--tests/tests.pro15
-rw-r--r--tests/tst_qcloudmessaging.cpp63
45 files changed, 6315 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..574d08e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+.DS_Store
+build*
+*.pro.*
+.qmake.stash
+*.autosave
+Makefile.*
+/mkspecs*
+.moc/
+.pch/
+.obj/
diff --git a/.qmake.conf b/.qmake.conf
new file mode 100644
index 0000000..42ad5e7
--- /dev/null
+++ b/.qmake.conf
@@ -0,0 +1,4 @@
+load(qt_build_config)
+
+MODULE_VERSION = 5.11.0
+CMAKE_MODULE_TESTS = -
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..97fa634
--- /dev/null
+++ b/README.md
@@ -0,0 +1,242 @@
+QT CLOUD MESSAGING API INSTALLATION:
+
+1. To install with available backend add following to qmake script:
+ qmake "CONFIG += embedded-kaltiot"
+ or
+ qmake "CONFIG += firebase"
+
+ e.g.:
+ qmake "CONFIG += embedded-kaltiot firebase"
+ make qmake_all
+ make
+ make install
+
+Google Firebase requirements:
+2. Download and unzip google firebase c++ SDK:
+ https://firebase.google.com/docs/cpp/setup
+
+3. To use firebase as backend, define the following ENVIRONMENT variable
+ GOOGLE_FIREBASE_SDK =
+ and make it to point to your firebase sdk root
+
+Embedded-Kaltiot requirements:
+4. To use in embedded Kaltiot backend:
+ 3.1. Register your app in
+ https://console.torqhub.io/signin
+
+ 3.2. Download platform SDK from the console download page
+
+ 3.3. Add environment variable to pointing to downloaded and unzipped SDK root:
+ KALTIOT_SDK = ../../../<yourappname>_RasperryPi_SDK_1.0.17
+
+
+5. Install first the QtCloudMessaging from command line with:
+
+ qmake "CONFIG += embedded-kaltiot firebase"
+ make
+ make install
+
+6. Now you can use the QtCloudMessaging in your app with
+
+ Just API wrapper (e.g. creating new service providers)
+ QT += cloudmessaging
+
+ With Firebase backend:
+ QT += cloudmessagingfirebase
+
+ With Embedded devices & Kaltiot
+ QT += cloudmessagingembeddedkaltiot
+
+ See more from the example apps.
+ NOTE: Examples are in Github:
+ https://github.com/snowgrains/qtcloudmessaging-examples
+
+7. Usage basics:
+
+ main.cpp:
+
+ // Using QCloudMessaging:
+ #include <QtCloudMessaging>
+ #include <kaltiotdemo.h>
+
+ // Depending on your backend provider, add:
+
+ // For Embedded systems
+ #include <QtCloudMessagingEmbeddedKaltiot>
+
+ // for Google firebase
+ #include <QCloudMessagingFirebaseProvider>
+
+ #include <QGuiApplication>
+ #include <QQmlApplicationEngine>
+ #include <QQmlContext>
+
+ int main(int argc, char *argv[])
+ {
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+
+ //*** QTCLOUDMSG DEFINITIONS
+ QCloudMessaging *pushServices = new QCloudMessaging();
+
+ //***** For Kaltiot Embedded systems
+ QCloudMessagingEmbeddedKaltiotProvider *kaltiotPushService = new QCloudMessagingEmbeddedKaltiotProvider()
+
+ // Provider based init parameters are given with QVariantMap
+ QVariantMap provider_params;
+ provider_params["API_KEY"] = "Your API key from the Kaltiot console for server communication";
+
+ // Creating name for provider which can be used cross your app.
+ pushServices->registerProvider("KaltiotService", kaltiotPushService, provider_params);
+
+ QVariantMap client_params;
+ client_params["address"] = "IOTSensor1";
+ client_params["version"] = "1.0";
+ client_params["customer_id"] = "Kaltiot";
+
+ QVariantList channels;
+ channels.append("Temperatures");
+ client_params["channels"] = channels;
+
+ /*! Connected client for the device.
+ \param Service name "KaltiotService"
+ \param Client identifier name to be used inside the application
+ \param Parameters for the client specific for the provider API
+ */
+ pushServices->connectClient("KaltiotService", "IOTSensor1", client_params);
+
+ //***** OR For Firebase mobile systems:
+ QCloudMessagingFirebaseProvider *m_firebaseService = new QCloudMessagingFirebaseProvider();
+
+ QVariantMap provider_params;
+
+ // Server API key is not recommended to store inside to the application code due security reasons.
+ // But if you do, make sure it is inside compiled C file or if you are doing a server side implementation with C++ & Qt.
+ // SERVER_API_KEY Is needed to be able to send topic messages from the client without Firebase application server.
+
+ provider_params["SERVER_API_KEY"] = "Get your SERVER API KEY from the google firebase console";
+
+ // Registering the Google firebase service component.
+ pushServices->registerProvider("GoogleFireBase", m_firebaseService, provider_params);
+
+ /*! Connected client is needed for mobile device.
+ \param Service name "GoogleFireBase"
+ \param Client identifier name to be used inside the demo application
+ \param Parameters for the client. No params for firebase client.
+ */
+ pushServices->connectClient("GoogleFireBase", "MobileClient", QVariantMap());
+
+ //! Automatically subscribe to listen one example topic
+ pushServices->subscribeToChannel("ChatRoom", "GoogleFireBase", "MobileClient");
+
+ //*** END OF QTCLOUD MSG DEFINITIONS
+
+ // these are needed for keeping the received RID in memory after restart (in Android)
+ QCoreApplication::setOrganizationName("MyOrganisation");
+ QCoreApplication::setOrganizationDomain("MyOrganisation.com");
+ QCoreApplication::setApplicationName("QtCloudMessagingDemo");
+
+
+ // To Give QML the push service context:
+ engine.rootContext()->setContextProperty("pushServices", pushServices);
+
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+ }
+
+ main.qml:
+
+ import QtQuick 2.6
+ import QtQuick.Window 2.2
+
+
+ Window {
+ visible: true
+ width: 640
+ height: 480
+ title: qsTr("Qt Cloud Messaging Demo")
+
+
+ // NOTIFICATIONS FROM THE ALL PROVIDERS:
+ Connections {
+ target:pushServices
+ onMessageReceived:{
+ console.log("Message to " + providerId + " service to " + clientId + " client.")
+ console.log("Message: " + message)
+
+ var msg_in_json = JSON.parse(decodeURI(message));
+
+ // Example to respond to embedded system request:
+ if (msg_in_json.command === "REQUESTING_TEMPERATURE")
+ embeddedPublishTemperatureToServer(msg_in_json.serverID, mydevicecommand.getTemperature());
+
+ // Or firebase the message itself is a container of the info.
+ updateGameNotification(message);
+ }
+
+ // Own Uuid to be used or broadcasted to server.
+ onClientTokenReceived: {
+
+ console.log("MY Uuid:"+rid)
+
+ // Id this is server code:
+ serverUuid = rid;
+
+ // Id this is client code:
+ clientUuid = rid;
+
+ }
+ }
+ Component.onCompleted {
+ // In case android app and firebase sdk gets started fast and token is needed, it can be requested with:
+ clientUuid = pushServices.clientToken("GoogleFireBase", "MobileClient");
+ }
+
+ //***** EMBEDDED DEVICES
+
+ // Function to send msg as server with Kaltiot provider to all clients as broadcast
+ property string serverUuid: ""
+
+ function sendKaltiotEmbeddedServerMessage(command_msg, msg) {
+
+ var payload = {command: command_msg, server_id : serverUuid}; // e.g. "REQUESTING_TEMPERATURE"
+ var payload_array = [{"payload_type": "STRING","payload": encodeURI(JSON.stringify(payload))}]
+ var p = "payload=" + JSON.stringify( payload_array );
+
+ pushServices.sendMessage(p, "KaltiotService", "", "", "Temperatures");
+ }
+
+ // Function to send temperature status message from the embedded client to Kaltiot server:
+ property string clientUuid :""
+
+ function embeddedPublishTemperatureToServer(serverUuid, temperature) {
+ var payload = {command: "TEMPERATURE_INFO", clientId: clientUuid}
+ var payload_array = [{"payload_type": "STRING","payload": encodeURI(JSON.stringify(payload))}]
+ var p = "payload=" + JSON.stringify( payload_array );
+
+ pushServices.sendMessage(p, "KaltiotService", "IOTSensor1", serverUuid,"");
+ }
+ //***** FIREBASE
+ // Function to post msg as a server and broadcast it to all clients in the same room
+ function sendFirebaseServerMessage(msg){
+ var data = {"data": {"message": {"text": msg } },
+ "notification": {"body": msg, "title": "Qt Cloud Messaging Chat"}}
+
+ /*!
+ * \brief SendMessage
+ * \param msg Message as text which needs to be modified to the provider specific JSON.
+ * \param providerId Provider name specified at config
+ * \param localclientId clientId spefied at startup
+ * \param send_to_device Device Uuid (rid) to send for one known device
+ * \param send_to_channel Channel name to broadcast message to channel
+ * \return
+ */
+
+ pushServices.sendMessage(JSON.stringify(data), "GoogleFireBase", "MobileClient", "", "ChatRoom");
+ }
+ }
+
+
+
diff --git a/dist/changes-1.0.0 b/dist/changes-1.0.0
new file mode 100644
index 0000000..75bd156
--- /dev/null
+++ b/dist/changes-1.0.0
@@ -0,0 +1,23 @@
+Qt Cloud Messaging 1.0
+
+Qt Cloud Messaging 1.0 is supported from Qt 5.x onwards.
+
+For more details on the features and fixes, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+ http://doc.qt.io/QtCloudMessaging
+
+General Improvements
+--------------------
+Introducing new component for Qt
+
+API changes (source break)
+--------------------------
+
+
+New features
+------------
+- Introducing new component for Qt
+
+Fixed issues
+------------
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..9e3825b
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,8 @@
+QT CLOUD MESSAGING API EXAMPLES ARE IN GITHUB:
+
+Cloud messaging API examples are in the following address in github:
+https://github.com/snowgrains/qtcloudmessaging-examples
+
+See more instructions from the README.md
+
+
diff --git a/qtcloudmessaging.pro b/qtcloudmessaging.pro
new file mode 100644
index 0000000..58c33f2
--- /dev/null
+++ b/qtcloudmessaging.pro
@@ -0,0 +1 @@
+load(qt_parts)
diff --git a/src/cloudmessaging/cloudmessaging.pro b/src/cloudmessaging/cloudmessaging.pro
new file mode 100644
index 0000000..7065843
--- /dev/null
+++ b/src/cloudmessaging/cloudmessaging.pro
@@ -0,0 +1,24 @@
+TARGET = QtCloudMessaging
+
+QT = core network
+
+QMAKE_DOCS = $$PWD/doc/qtcloudmessaging.qdocconf
+
+HEADERS += \
+ $$PWD/qcloudmessaging.h \
+ $$PWD/qcloudmessagingclient.h \
+ $$PWD/qcloudmessagingprovider.h \
+ $$PWD/qtcloudmessagingglobal.h \
+ $$PWD/qcloudmessaging_p.h \
+ $$PWD/qcloudmessagingclient_p.h \
+ $$PWD/qcloudmessagingprovider_p.h \
+ $$PWD/qcloudmessagingrestapi_p.h \
+ $$PWD/qcloudmessagingrestapi.h
+
+SOURCES += \
+ $$PWD/qcloudmessaging.cpp \
+ $$PWD/qcloudmessagingclient.cpp \
+ $$PWD/qcloudmessagingprovider.cpp \
+ $$PWD/qcloudmessagingrestapi.cpp
+
+load(qt_module)
diff --git a/src/cloudmessaging/doc/README.md b/src/cloudmessaging/doc/README.md
new file mode 100644
index 0000000..50b4824
--- /dev/null
+++ b/src/cloudmessaging/doc/README.md
@@ -0,0 +1,11 @@
+QT CLOUD MESSAGING DOC GENERATION:
+
+define following exports in command prompt / terminal:
+BUILDDIR="."
+QT_VER="5.11"
+QT_VERSION="5.11"
+QT_VERSION_TAG="5.11"
+QT_INSTALL_DOCS="<pathToQt>/Qt/Docs/Qt-5.9.2"
+
+Then run command:
+<pathToQt>/Qt/5.9.2/<arch>/bin/qdoc qtcloudmessaging.qdocconf
diff --git a/src/cloudmessaging/doc/qtcloudmessaging.qdocconf b/src/cloudmessaging/doc/qtcloudmessaging.qdocconf
new file mode 100644
index 0000000..32dd078
--- /dev/null
+++ b/src/cloudmessaging/doc/qtcloudmessaging.qdocconf
@@ -0,0 +1,51 @@
+include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+
+
+project = QtCloudMessaging
+description = Qt Cloud Messaging Documentation
+version = $QT_VERSION
+
+qhp.projects = QtCloudMessaging
+
+qhp.QtCloudMessaging.file = QtCloudMessaging.qhp
+qhp.QtCloudMessaging.namespace = org.qt-project.qtcloudmessaging.$QT_VERSION_TAG
+qhp.QtCloudMessaging.virtualFolder = qtcloudmessaging
+qhp.QtCloudMessaging.indexTitle = Qt CloudMessaging
+qhp.QtCloudMessaging.indexRoot =
+
+qhp.QtCloudMessaging.filterAttributes = qcloudmessaging $QT_VERSION qtrefdoc
+qhp.QtCloudMessaging.customFilters.Qt.name = QtCloudMessaging $QT_VERSION
+qhp.QtCloudMessaging.customFilters.Qt.filterAttributes = qcloudmessaging $QT_VERSION
+
+qhp.QtCloudMessaging.subprojects = classes
+qhp.QtCloudMessaging.subprojects.classes.title = C++ Classes
+qhp.QtCloudMessaging.subprojects.classes.indexTitle = Qt CloudMessaging C++ Classes
+qhp.QtCloudMessaging.subprojects.classes.selectors = class fake:headerfile
+qhp.QtCloudMessaging.subprojects.classes.sortPages = true
+
+# The outputdir variable specifies the directory
+# where QDoc will put the generated documentation.
+
+outputdir = html
+
+# The headerdirs variable specifies the directories
+# containing the header files associated
+# with the .cpp source files used in the documentation.
+
+headerdirs += ..
+
+# The sourcedirs variable specifies the
+# directories containing the .cpp or .qdoc
+# files used in the documentation.
+
+sourcedirs += ..
+
+# The exampledirs variable specifies the directories containing
+# the source code of the example files.
+
+#exampledirs += .
+
+# The imagedirs variable specifies the
+# directories containing the images used in the documentation.
+
+#imagedirs += ./images
diff --git a/src/cloudmessaging/qcloudmessaging.cpp b/src/cloudmessaging/qcloudmessaging.cpp
new file mode 100644
index 0000000..3ecce6c
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessaging.cpp
@@ -0,0 +1,501 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessaging.h"
+#include "qcloudmessaging_p.h"
+#include <QString>
+
+
+/*!
+ \class QCloudMessaging
+ \inmodule QtCloudMessaging
+ \since 5.11
+
+ \brief The QtCloudMessaging module implements Qt wrapper API for multiple
+ cloud messaging and cloud service providers. The QtCloudMessaging module
+ can be easily extended to support private clouds or existing cloud
+ providers.
+
+ The QtCloudMessaging module currently has Google
+ Firebase Cloud Messaging and Kaltiot IoT push messaging backends to
+ get started with IoT or mobile cloud development.
+
+ QCloudMessaging class enables registering of cloud messaging
+ provider backends and backend clients.
+
+ Cloud messaging providers and clients implement virtual functions which
+ subscribe or unsubscribe to cloud messaging channels and receive or send
+ messages to servers and to other clients.
+
+ \list
+ \li To create new cloud messaging service provider and client:
+ \list
+ \li Inherit the QCloudMessagingProvider class and implement the virtual
+ functions.
+ \li Inherit the QCloudMessagingClient class and implement the virtual
+ functions.
+ \endlist
+ \endlist
+
+*/
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \brief QCloudMessaging::QCloudMessaging
+ * QCloudMessaging constructor
+ *
+ * \param parent
+ * Parent is QObject
+ */
+QCloudMessaging::QCloudMessaging(QObject *parent) :
+ QObject(parent), d(new QCloudMessagingPrivate)
+{
+}
+/*!
+ * \brief QCloudMessaging::~QCloudMessaging
+ */
+QCloudMessaging::~QCloudMessaging()
+{
+}
+
+/*!
+ * \brief registerProvider
+ * Registers the service provider that handles service clients and can be used
+ * for server side development.
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API.
+ *
+ * \param provider
+ * Use case specific provider object that can handle the communication as a
+ * server and can have multiple internal and external clients.
+ *
+ * \param parameters
+ * Provider specific parameters in a variant map.
+ *
+ * \return
+ * true if register succeeds, false if fails.
+ */
+bool QCloudMessaging::registerProvider(const QString &providerId,
+ QCloudMessagingProvider *provider,
+ const QVariantMap &parameters)
+{
+ bool return_value = false;
+ // If this is duplicate service name
+ if (!d->m_cloudProviders.contains(providerId)) {
+ d->m_cloudProviders.insert(providerId, provider);
+
+ connect(provider, &QCloudMessagingProvider::messageReceived,
+ this, &QCloudMessaging::messageReceived);
+
+ connect(provider, &QCloudMessagingProvider::serviceStateUpdated,
+ this, &QCloudMessaging::serviceStateUpdated);
+
+ connect(provider, &QCloudMessagingProvider::remoteClientsReceived,
+ this, &QCloudMessaging::remoteClientsReceived);
+
+ connect(provider, &QCloudMessagingProvider::clientTokenReceived,
+ this, &QCloudMessaging::clientTokenReceived);
+
+ return_value = d->m_cloudProviders[providerId]->
+ registerProvider(providerId,parameters);
+ } else {
+ return_value = d->m_cloudProviders[providerId]->getServiceState();
+ }
+
+ return return_value;
+}
+
+/*!
+ * \brief connectClient
+ * Attaches the client into the provider
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for the
+ * provider
+ *
+ * \param parameters
+ * Client specific parameters in a variant map.
+ *
+ * \return
+ * return given ClientId when succeeds, empty string if not.
+ *
+ */
+QString QCloudMessaging::connectClient(const QString &providerId,
+ const QString &clientId,
+ const QVariantMap &parameters)
+{
+ if (d->m_cloudProviders.contains(providerId))
+ return d->m_cloudProviders[providerId]->connectClient(clientId,
+ parameters);
+
+ return QString();
+}
+
+/*!
+ * \brief sendMessage
+ * Sends a message to one single client or or to a subscribed channel
+ *
+ * \param msg
+ * Service specific message. Usually JSON string.
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using
+ * the API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for
+ * the provider
+ *
+ * \param clientToken
+ * By providing client token, message is targeted straight to client
+ *
+ * \param channel
+ * Channel name if broadcasting the message to channel
+ *
+ * \return
+ * return true when succeeds, false otherwise.
+ */
+bool QCloudMessaging::sendMessage(const QByteArray &msg,
+ const QString &providerId,
+ const QString &clientId,
+ const QString &clientToken,
+ const QString &channel)
+{
+
+ if (d->m_cloudProviders.contains(providerId))
+ return d->m_cloudProviders[providerId]->sendMessage(msg,
+ clientId,
+ clientToken,
+ channel);
+
+ return false;
+}
+
+
+/*!
+ * \brief disconnectClient
+ * Disconnects the client from the provider
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for the
+ * provider
+ *
+ * \param parameters
+ * Client specific parameters in a variant map.
+ */
+void QCloudMessaging::disconnectClient(const QString &providerId,
+ const QString &clientId,
+ const QVariantMap &parameters)
+{
+ if (d->m_cloudProviders.contains(providerId))
+ d->m_cloudProviders[providerId]->disconnectClient(clientId,
+ parameters);
+}
+
+/*!
+ * \brief removeClient
+ * Removes client from the provider
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for the
+ * provider
+ */
+void QCloudMessaging::removeClient(const QString &providerId,
+ const QString &clientId)
+{
+ if (d->m_cloudProviders.contains(providerId))
+ d->m_cloudProviders[providerId]->removeClient(clientId);
+
+}
+
+/*!
+ * \brief deRegisterProvider
+ * Closes down the provider and disconnects clients.
+ *
+ * \param providerId
+ * Povider identification string that is defined by the user when using the
+ * API
+ */
+void QCloudMessaging::deregisterProvider(const QString &providerId)
+{
+ if (d->m_cloudProviders.contains(providerId)) {
+ disconnect(d->m_cloudProviders[providerId]);
+
+ d->m_cloudProviders[providerId]->deregisterProvider();
+ d->m_cloudProviders.remove(providerId);
+
+ }
+}
+
+/*!
+ * \brief localClients
+ * If system has multiple clients connected at the same app process, one can
+ * request the
+ * list of available clientIds from the provider class.
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \return
+ * List of ClientIds as QStringList.
+ */
+const QStringList QCloudMessaging::localClients(const QString &providerId)
+{
+ if (d->m_cloudProviders.contains(providerId))
+ return d->m_cloudProviders[providerId]->clients()->keys();
+
+ return QStringList();
+}
+
+/*!
+ * \brief requestRemoteClients
+ * Uses provider rest api interface to request all the remote clients
+ * connected to provider service.
+ * This can be used e.g. in server implementation or if creating
+ * client dashboard etc.
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when
+ * using the API
+ *
+ * \return
+ * true if sending request via rest api succeeds, fail if not.
+ */
+bool QCloudMessaging::requestRemoteClients(const QString &providerId)
+{
+ if (d->m_cloudProviders.contains(providerId)) {
+ return d->m_cloudProviders[providerId]->remoteClients();
+ }
+
+ return false;
+}
+
+/*!
+ * \brief clientToken
+ * Gets client token (uuid / rid received from the provider services)
+ *
+ * \param providerI
+ * Provider identification string that is defined by the user when using
+ * the API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for
+ * the provider
+ *
+ * \return
+ * If found returns client token as QString. Returns empty QString otherwise.
+ */
+QString QCloudMessaging::clientToken(const QString &providerId,
+ const QString &clientId)
+{
+ if (d->m_cloudProviders.contains(providerId))
+ return d->m_cloudProviders[providerId]->clientToken(clientId);
+
+ return QString();
+}
+
+/*!
+ * \brief setClientToken
+ * Sets the client token for the client.
+ * This can be used in case of client
+ * token is received otherwise or defined by
+ * API user separately.
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for the
+ * provider
+ *
+ * \param token
+ * Token value as string
+ */
+void QCloudMessaging::setClientToken(const QString &providerId,
+ const QString &clientId,
+ const QString &token)
+{
+ if (d->m_cloudProviders.contains(providerId))
+ return d->m_cloudProviders[providerId]->
+ client(clientId)->setClientToken(token);
+}
+
+/*!
+ * \brief QCloudMessaging::subscribeToChannel
+ * Subscribing the client to the channel
+ *
+ * \param channel
+ * Channel name as string, cannot be empty
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for
+ * the provider
+ *
+ * \return
+ * true if succeeds, false if not.
+ */
+bool QCloudMessaging::subscribeToChannel(const QString &channel,
+ const QString &providerId,
+ const QString &clientId)
+{
+ if (!d->m_cloudProviders.contains(providerId))
+ return false;
+
+ if (!clientId.isEmpty())
+ {
+ return d->m_cloudProviders[providerId]->client(clientId)->
+ subscribeToChannel(channel);
+ } else
+ {
+ return d->m_cloudProviders[providerId]->subscribeToChannel(channel,
+ clientId);
+ }
+}
+
+/*!
+ * \brief unsubscribeFromChannel
+ * Unsubscribing the client from the channel
+ *
+ * \param channel
+ * Channel name as string, cannot be empty
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for the
+ * provider
+ *
+ * \return
+ * true if succeeds, false if not.
+ */
+bool QCloudMessaging::unsubscribeFromChannel(const QString &channel,
+ const QString &providerId,
+ const QString &clientId)
+{
+ if (!d->m_cloudProviders.contains(providerId))
+ return false;
+
+ if (!clientId.isEmpty())
+ {
+ return d->m_cloudProviders[providerId]->client(clientId)->
+ unsubscribeFromChannel(channel);
+ } else
+ {
+ return d->m_cloudProviders[providerId]->unsubscribeFromChannel(channel,
+ clientId);
+ }
+}
+
+/*!
+ * \brief flushMessageQueue
+ * When receiving push messages they can be stored by clients internally.
+ * This function gives developers possibility to do flush commnand for them .
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \return
+ * true if succeeds, false if not
+ */
+void QCloudMessaging::flushMessageQueue(const QString &providerId)
+{
+ if (d->m_cloudProviders.contains(providerId))
+ d->m_cloudProviders[providerId]->flushMessageQueue();
+}
+
+// Signals documentation
+/*!
+ \fn QCloudMessaging::clientTokenReceived(const QString &token)
+ This signal is triggered when connected gets the client
+ token from the service provider.
+
+ \param token
+ Received token as a QString.
+ Token is unique identification value used for straight communication
+ and identification with the client.
+*/
+
+/*!
+ \fn QCloudMessaging::messageReceived(const QString &providerId,
+ const QString &clientId,
+ const QByteArray &message)
+ This signal is triggered when a message is received from the network to client.
+
+ \param providerId
+ Receiving Provider identification string
+
+ \param clientId
+ Receiving clientId string
+
+ \param message
+ Received message as QByteArray. Message is service specific.
+*/
+
+/*!
+ \fn QCloudMessaging::remoteClientsReceived(const QString &clients)
+ This signal is triggered when the return value for requestRemoteClients
+ function is is received.
+ \param response
+ Response data is based on the service and can be e.g. a list
+ of client tokens in QString format.
+*/
+
+/*!
+ \fn QCloudMessaging::serviceStateUpdated(int state)
+ This signal is triggered when the service provider registered
+ state has changed.
+
+ \param state
+ State can be one of the enums from the QCloudMessagingProvider
+
+*/
+
+QT_END_NAMESPACE
diff --git a/src/cloudmessaging/qcloudmessaging.h b/src/cloudmessaging/qcloudmessaging.h
new file mode 100644
index 0000000..cbd5b95
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessaging.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCLOUDMESSAGING_H
+#define QTCLOUDMESSAGING_H
+
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QtCloudMessaging/qcloudmessagingprovider.h>
+#include <QObject>
+#include <QVariantMap>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \class QCloudMessaging
+ * \brief The QCloudMessaging class
+ *
+ * This is the Qt Cloud Messaging Class.
+ */
+class QCloudMessagingPrivate;
+
+
+class Q_CLOUDMESSAGING_EXPORT QCloudMessaging : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ explicit QCloudMessaging(QObject *parent = nullptr);
+ ~QCloudMessaging();
+
+ Q_INVOKABLE bool registerProvider(const QString &providerId,
+ QCloudMessagingProvider *provider,
+ const QVariantMap &parameters = QVariantMap());
+
+ Q_INVOKABLE void deregisterProvider(const QString &providerId);
+
+ Q_INVOKABLE QString connectClient(const QString &providerId,
+ const QString &clientId,
+ const QVariantMap &parameters =
+ QVariantMap());
+
+ Q_INVOKABLE void disconnectClient(const QString &providerId,
+ const QString &clientId,
+ const QVariantMap &parameters =
+ QVariantMap());
+
+ Q_INVOKABLE const QStringList localClients(const QString &providerId);
+
+ Q_INVOKABLE bool requestRemoteClients(const QString &providerId);
+
+ Q_INVOKABLE void removeClient(const QString &providerId,
+ const QString &clientId);
+
+ Q_INVOKABLE QString clientToken(const QString &providerId,
+ const QString &clientId);
+
+ Q_INVOKABLE void setClientToken(const QString &providerId,
+ const QString &clientId,
+ const QString &token);
+
+ Q_INVOKABLE bool sendMessage(const QByteArray &msg,
+ const QString &providerId = QString(),
+ const QString &clientId = QString(),
+ const QString &clientToken = QString(),
+ const QString &channel = QString()) ;
+
+ Q_INVOKABLE bool subscribeToChannel(const QString &channel,
+ const QString &providerId = QString(),
+ const QString &clientId = QString());
+
+ Q_INVOKABLE bool unsubscribeFromChannel(const QString &channel,
+ const QString &providerId = QString(),
+ const QString &clientId = QString());
+
+ Q_INVOKABLE void flushMessageQueue(const QString &providerId);
+
+Q_SIGNALS:
+ void clientTokenReceived(const QString &token);
+
+ void messageReceived(const QString &providerId,
+ const QString &clientId,
+ const QByteArray &message);
+
+ void remoteClientsReceived(const QString &clients);
+
+ void serviceStateUpdated(int state);
+
+private:
+ QScopedPointer<QCloudMessagingPrivate> d;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTCLOUDMESSAGING_H
diff --git a/src/cloudmessaging/qcloudmessaging_p.h b/src/cloudmessaging/qcloudmessaging_p.h
new file mode 100644
index 0000000..e7b26c0
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessaging_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLOUDMESSAGING_P_H
+#define QCLOUDMESSAGING_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QMap>
+#include <QMapIterator>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingProvider;
+
+class QCloudMessagingPrivate
+{
+
+public:
+ QCloudMessagingPrivate()
+ : m_serviceState(0)
+ {
+ }
+
+ ~QCloudMessagingPrivate()
+ {
+ m_serviceState = 0;
+
+ // To verify that all providers and clients are removed
+ // without memory leaks
+ QMapIterator<QString, QCloudMessagingProvider *> i(m_cloudProviders);
+ while (i.hasNext()) {
+ i.next();
+ m_cloudProviders[i.key()]->deregisterProvider();
+ m_cloudProviders.remove(i.key());
+ }
+ }
+
+ int m_serviceState;
+ QMap<QString, QCloudMessagingProvider *> m_cloudProviders;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGING_P_H
diff --git a/src/cloudmessaging/qcloudmessagingclient.cpp b/src/cloudmessaging/qcloudmessagingclient.cpp
new file mode 100644
index 0000000..e2c6685
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingclient.cpp
@@ -0,0 +1,333 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessagingclient.h"
+#include "qcloudmessagingclient_p.h"
+
+/*!
+ \class QCloudMessagingClient
+ \inmodule QtCloudMessaging
+ \since 5.11
+
+ \brief The QCloudMessagingClient class is a single IoT/embedded or mobile device
+ providing way to received and send messages either by broadcasting or
+ by direct connect to other client with known token.
+
+ Implementing specific cloud messaging service client needs inherit this
+ QCloudMessagingClient class and implement the virtual functions defined in the
+ header.
+
+*/
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \brief QCloudMessagingClient::QCloudMessagingClient
+ * QCloudMessagingClient constructor
+ *
+ * \param parent
+ * Parent is QObject
+ */
+QCloudMessagingClient::QCloudMessagingClient(QObject *parent) :
+ QObject(parent),
+ d(new QCloudMessagingClientPrivate)
+{
+}
+
+/*!
+ * \brief QCloudMessagingClient::~QCloudMessagingClient
+ * Desctructor
+ */
+QCloudMessagingClient::~QCloudMessagingClient()
+{
+ disconnectClient();
+}
+
+/*!
+ * \brief QCloudMessagingClient::connectClient
+ * Attaches the client into the provider. This is virtual function
+ * and should be re-implemented in the inheritance for connecting
+ * the client to real service.
+ *
+ * \param clientId
+ * Mobile or IoT client identification string (defined by user) added for the
+ * provider
+ *
+ * \param parameters
+ * Client specific parameters in a variant map.
+ *
+ * \return
+ * return given ClientId when successful, empty string if not.
+ *
+ */
+QString QCloudMessagingClient::connectClient(const QString &clientId,
+ const QVariantMap &parameters)
+{
+ d->m_clientId = clientId;
+ d->m_clientState = QtCloudMessagingClientConnecting;
+ d->m_client_parameters = parameters;
+
+ return QString();
+}
+
+/*!
+ * \brief QCloudMessagingClient::disconnectClient
+ * Virtual function to disconnect the client from the service.
+ *
+ * \return
+ * returns the client specific state as integer
+ */
+void QCloudMessagingClient::disconnectClient()
+{
+ d->m_clientState = QtCloudMessagingClientDisconnecting;
+}
+
+/*!
+ * \brief QCloudMessagingClient::setClientState
+ * Sets the client state. This is virtual function and can be
+ * re-implemented in the inheritance
+ *
+ * \param state
+ * Setting client specific state as integer.
+ */
+void QCloudMessagingClient::setClientState(int state)
+{
+ d->m_clientState = state;
+}
+
+/*!
+ * \brief QCloudMessagingClient::clientState
+ * Gets the client specific state
+ *
+ * \return
+ * Returns clients specific state value as integer.
+ */
+int QCloudMessagingClient::clientState()
+{
+ return (CloudMessagingClientState) d->m_clientState;
+}
+
+/*!
+ * \brief QCloudMessagingClient::clientId
+ * Gets the client id.
+ *
+ * \return
+ * Returns client id as QString
+ */
+QString QCloudMessagingClient::clientId()
+{
+ return d->m_clientId;
+}
+
+/*!
+ * \brief QCloudMessagingClient::providerId
+ * Gets the client's service provider id.
+ *
+ * \return
+ * Returns the provider id as QString.
+ */
+QString QCloudMessagingClient::providerId()
+{
+ return d->m_providerId;
+}
+
+/*!
+ * \brief QCloudMessagingClient::setClientId
+ * Sets the client id
+ *
+ * \param clientid
+ * Client id as QString
+ *
+ * \return
+ * Returns new client id as QString
+ */
+void QCloudMessagingClient::setClientId(const QString &clientid)
+{
+ d->m_clientId = clientid;
+}
+
+/*!
+ * \brief QCloudMessagingClient::setProviderId
+ * Gets the client's service provider id.
+ *
+ * \return
+ * Returns new provider id as QString.
+ */
+void QCloudMessagingClient::setProviderId(const QString &providerId)
+{
+ d->m_providerId = providerId;
+}
+
+/*!
+ * \brief QCloudMessagingClient::clientParameters
+ * Gets the client parameters
+ *
+ * \return
+ * Returns client parameters as QVariantMap
+ */
+QVariantMap QCloudMessagingClient::clientParameters()
+{
+ return d->m_client_parameters;
+}
+
+// Pure Virtual functions documentation
+
+/*!
+ \fn QCloudMessagingClient::flushMessageQueue()
+ When receiving push messages they can be stored by clients internally.
+ This function gives developers possibility to do flush commnand for them.
+
+ This is pure virtual function and needs to be implemented in the
+ inheritance.
+
+ \return
+ return true when successful, false otherwise.
+*/
+/*!
+ \fn QCloudMessagingClient::sendMessage(
+ const QByteArray &msg,
+ const QString &clientToken = QString(),
+ const QString &channel = QString())
+ Sends a message to one single client or to subscribed channel.
+ This is pure virtual function and needs to be implemented in the inheritance.
+
+ \param msg
+ Message as string which is interpreted to the service specific message
+ type e.g. json
+
+ \param clientToken
+ By providing client token, message is targeted straight to client
+
+ \param channel
+ Channel name if broadcasting the message to channel
+
+ \return
+ return true when successful, false otherwise.
+*/
+
+/*!
+ \fn QCloudMessagingClient::setClientToken(const QString &token)
+ Sets the client token for the client.
+ This can be used in case of client
+ token is received otherwise or defined by
+ API user separately.
+
+
+ \param token
+ Token value as string
+*/
+
+/*!
+ \fn QCloudMessagingClient::clientToken()
+ Gets client token (uuid / rid received from the provider services)
+
+ \return
+ If found returns client token as QString. Returns empty QString otherwise.
+*/
+
+/*!
+ \fn QCloudMessagingClient::subscribeToChannel(
+ const QString &channel)
+ Subscribes client to broadcast channel of the provider service.
+ This is pure virtual function and needs to be implemented in the
+ inheritance.
+
+ \param channnel
+ Channel name as QString
+
+ \return
+ return true when successful, false otherwise.
+*/
+
+/*!
+ \fn QCloudMessagingClient::unsubscribeFromChannel(
+ const QString &channel)
+ Unsubscribes client from the broadcast channel of the provider service.
+ This is pure virtual function and needs to be implemented in the
+ inheritance.
+
+ \param channnel
+ Channel name as QString
+
+ \return
+ return true when successful, false otherwise.
+*/
+
+// Signals documentation
+/*!
+ \fn QCloudMessagingClient::clientStateChanged(
+ const QString &clientId,
+ int state)
+ This signal is triggered when the client state has changed
+
+ \param clientId
+ Client idenfitication string
+
+ \param state
+ Client State can be either enum from QCloudMessagingClient::CloudMessagingClientState
+ or it can be client backend specific state.
+
+*/
+
+/*!
+ \fn QCloudMessagingClient::messageReceived(const QString &clientId,
+ const QByteArray &message)
+ This signal is triggered when a message is received from the network to client.
+
+ \param clientId
+ Receiving clientId string
+
+ \param message
+ Received message as QByteArray. Message content is service specific.
+*/
+
+/*!
+ \fn QCloudMessagingClient::clientTokenReceived(const QString &token)
+ This signal is triggered when connected gets the client
+ token from the service provider.
+
+ \param token
+ Received token as a QString.
+ Token is unique identification value used for straight communication
+ and identification with the client.
+*/
+
+// Enums
+/*!
+ \enum QCloudMessagingClient::CloudMessagingClientState
+
+ This enum type describes types of QCloudMessagingClient connection states.
+
+ \value QtCloudMessgingClientDisconnected Client is disconnected.
+ \value QtCloudMessagingClientConnecting Client connection started.
+ \value QtCloudMessagingClientDisconnecting Client disconnection started.
+ \value QtCloudMessagingClientOffline Client is connected but offline.
+ \value QtCloudMessagingClientOnline Client is connected and online.
+
+*/
+QT_END_NAMESPACE
diff --git a/src/cloudmessaging/qcloudmessagingclient.h b/src/cloudmessaging/qcloudmessagingclient.h
new file mode 100644
index 0000000..35a6f39
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingclient.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCLOUDMESSAGINGCLIENT_H
+#define QTCLOUDMESSAGINGCLIENT_H
+
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+
+#include <QObject>
+#include <QVariantMap>
+#include <QString>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingClientPrivate;
+
+class Q_CLOUDMESSAGING_EXPORT QCloudMessagingClient : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum CloudMessagingClientState {
+ QtCloudMessgingClientDisconnected = 0,
+ QtCloudMessagingClientConnecting,
+ QtCloudMessagingClientDisconnecting,
+ QtCloudMessagingClientOffline,
+ QtCloudMessagingClientOnline
+ };
+ Q_ENUM(CloudMessagingClientState)
+
+ explicit QCloudMessagingClient(QObject *parent = nullptr);
+
+ virtual ~QCloudMessagingClient();
+
+ virtual QString connectClient(
+ const QString &clientId,
+ const QVariantMap &parameters = QVariantMap());
+
+ virtual void disconnectClient();
+
+ virtual void cloudMessageReceived(const QString &client,
+ const QByteArray &message) = 0;
+
+ virtual QString clientToken() = 0;
+
+ virtual void setClientToken(const QString &token) = 0;
+
+ virtual bool sendMessage(
+ const QByteArray &msg,
+ const QString &clientToken = QString(),
+ const QString &channel = QString()) = 0;
+
+ virtual bool flushMessageQueue() = 0;
+
+ virtual bool subscribeToChannel(const QString &channel) = 0;
+
+ virtual bool unsubscribeFromChannel(const QString &channel) = 0;
+
+ void setClientState(int state);
+
+ int clientState();
+
+ QString clientId();
+
+ QString providerId();
+
+ void setClientId(const QString &clientid);
+
+ void setProviderId(const QString &providerId);
+
+ QVariantMap clientParameters();
+
+Q_SIGNALS:
+ void clientStateChanged(const QString &clientId, int state);
+
+ void messageReceived(const QString &clientId, const QByteArray &msg);
+
+ void clientTokenReceived(const QString &token);
+
+private:
+
+ QScopedPointer<QCloudMessagingClientPrivate> d;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTCLOUDMESSAGINGCLIENT_H
diff --git a/src/cloudmessaging/qcloudmessagingclient_p.h b/src/cloudmessaging/qcloudmessagingclient_p.h
new file mode 100644
index 0000000..a1d0b0b
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingclient_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLOUDMESSAGINGCLIENT_P_H
+#define QCLOUDMESSAGINGCLIENT_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QVariantMap>
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QCloudMessagingClient;
+
+class QCloudMessagingClientPrivate
+{
+public:
+ QCloudMessagingClientPrivate()
+ : m_clientState(0)
+ {
+ }
+
+ ~QCloudMessagingClientPrivate() = default;
+
+ QString m_clientId;
+ QString m_providerId;
+ int m_clientState;
+ QVariantMap m_client_parameters;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGCLIENT_P_H
diff --git a/src/cloudmessaging/qcloudmessagingprovider.cpp b/src/cloudmessaging/qcloudmessagingprovider.cpp
new file mode 100644
index 0000000..0c276d4
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingprovider.cpp
@@ -0,0 +1,543 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessagingprovider.h"
+#include "qcloudmessagingprovider_p.h"
+#include <QMapIterator>
+
+/*!
+ \class QCloudMessagingProvider
+ \inmodule QtCloudMessaging
+ \since 5.11
+
+ \brief The QCloudMessagingProvider class provides the functions to register
+ multiple cloud messaging providers and clients. CloudMessagingProvider class
+ manages locally registered cloud messaging clients and provides the
+ status of the services.
+
+ To implement specific cloud messaging provider functionality, the inherit of this
+ QCloudMessagingProvider class is needed. Inherited class also needs to implement the
+ QCloudMessagingProvider virtual functions.
+
+*/
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \brief QCloudMessagingProvider::QCloudMessagingProvider
+ * Class constructor
+ *
+ * \param parent
+ * QObject parent
+ */
+QCloudMessagingProvider::QCloudMessagingProvider(QObject *parent) :
+ QObject(parent),
+ d(new QCloudMessagingProviderPrivate)
+{
+}
+
+/*!
+ * \brief QCloudMessagingProvider::~QCloudMessagingProvider
+ * Class descructor
+ */
+QCloudMessagingProvider::~QCloudMessagingProvider()
+{
+}
+
+/*!
+ * \brief QCloudMessagingProvider::registerProvider
+ * Registers the service provider that handles service clients and can be used
+ * for server side development.
+ * This is pure virtual function which needs to be implemented by the provider
+ * class inheritance.
+ *
+ * \param providerId
+ * Provider identification string that is defined by the user when using the
+ * API
+ *
+ * \param parameters
+ * Provider specific parameters in the variant map.
+ *
+ * \return
+ */
+bool QCloudMessagingProvider::registerProvider(const QString &providerId,
+ const QVariantMap &parameters)
+{
+ Q_UNUSED(parameters);
+
+ d->m_providerId = providerId;
+
+ d->m_serviceState = CloudMessagingProviderState::QtCloudMessagingProviderRegistering;
+ emit serviceStateUpdated(d->m_serviceState);
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingProvider::connectClientToProvider
+ * Function to create necessary signal connections between the new service client
+ * and calls serviceClients connectClient virtual function.
+ * This function should be called from the inherited class connectClient function.
+ *
+ * Example code:
+ * \code
+ * QCloudMessagingEmbeddedKaltiotClient *serviceClient = new QCloudMessagingEmbeddedKaltiotClient();
+ * QString retval = connectClientToProvider(clientId, parameters, serviceClient);
+ * \endcode
+ *
+ * \param clientId
+ * Client id as QString
+ *
+ * \param parameters
+ * Client specific parameters in a variant map.
+ *
+ * \param serviceClient
+ * Service client instance of inheritance of QCloudMessagingClient class
+ *
+ * \return
+ * Returns clientId as QString if succesfull, empty QString otherwise.
+ */
+QString QCloudMessagingProvider::connectClientToProvider(const QString &clientId,
+ const QVariantMap &parameters,
+ QCloudMessagingClient *serviceClient)
+{
+ if (!d->m_providerId.isEmpty()) {
+ d->m_provider_parameters = parameters;
+ if (!clientId.isEmpty()) {
+
+ connect(serviceClient, &QCloudMessagingClient::messageReceived,
+ this, &QCloudMessagingProvider::messageReceivedSlot);
+
+ connect(serviceClient, &QCloudMessagingClient::clientTokenReceived,
+ this, &QCloudMessagingProvider::clientTokenReceived);
+
+ connect(serviceClient, &QCloudMessagingClient::clientStateChanged,
+ this, &QCloudMessagingProvider::clientStateChanged);
+
+ serviceClient->connectClient(clientId, parameters);
+
+ d->m_QtCloudMessagingClients.insert(clientId, serviceClient);
+
+ return clientId;
+ }
+ }
+
+ return QString();
+}
+
+/*!
+ * \brief QCloudMessagingProvider::messageReceivedSlot
+ * This slot is executed when new message is received from the service provider.
+ *
+ * \param clientId
+ * Client id receiving the message
+ *
+ * \param message
+ * Message content as QByteArray
+ *
+ */
+void QCloudMessagingProvider::messageReceivedSlot(const QString &clientId, const QByteArray &message)
+{
+ emit messageReceived(providerId(), clientId, message);
+}
+
+/*!
+ * \brief QCloudMessagingProvider::disconnectClient
+ * \param clientId
+ * \param parameters
+ * \return
+ */
+void QCloudMessagingProvider::disconnectClient(const QString &clientId,
+ const QVariantMap &parameters)
+{
+ Q_UNUSED(parameters);
+
+ if (!d->m_providerId.isEmpty() && d->m_QtCloudMessagingClients[clientId]) {
+ QCloudMessagingClient *client = d->m_QtCloudMessagingClients[clientId];
+
+ // Disconnect connections for the client
+ disconnect(client);
+
+ d->m_QtCloudMessagingClients[clientId]->disconnectClient();
+ }
+
+}
+
+/*!
+ * \brief QCloudMessagingProvider::removeClient
+ * \param clientId
+ * \return
+ */
+bool QCloudMessagingProvider::removeClient(const QString &clientId)
+{
+ if (!d->m_providerId.isEmpty() && d->m_QtCloudMessagingClients[clientId]) {
+
+ disconnectClient(clientId);
+ d->m_QtCloudMessagingClients.remove(clientId);
+
+ return true;
+ }
+
+ return false;
+}
+
+/*!
+ * \brief QCloudMessagingProvider::deregisterProvider
+ * Function to deregistering the service provider. This
+ * function automatically removes clients registered to the provider.
+ * This is virtual function and can be implemented by the provider
+ * class inheritance.
+ *
+ * \return
+ */
+void QCloudMessagingProvider::deregisterProvider()
+{
+ if (d->m_QtCloudMessagingClients.count()) {
+
+ QMapIterator<QString, QCloudMessagingClient *> i(d->m_QtCloudMessagingClients);
+
+ while (i.hasNext()) {
+ i.next();
+ removeClient(i.key());
+ }
+
+ d->m_serviceState = CloudMessagingProviderState::QtCloudMessagingProviderNotRegistered;
+ emit serviceStateUpdated(d->m_serviceState);
+ }
+}
+
+/*!
+ * \brief QCloudMessagingProvider::flushMessageQueue
+ * This function calls the service provider to clear clients message buffers.
+ * Client flushMessageQueue is virtualized for client specific usages.
+ *
+ * \return
+ * false if no clients found, true if also clients removed.
+ */
+bool QCloudMessagingProvider::flushMessageQueue()
+{
+ if (d->m_QtCloudMessagingClients.count()) {
+ QMapIterator<QString, QCloudMessagingClient *> i(d->m_QtCloudMessagingClients);
+ while (i.hasNext()) {
+ i.next();
+ d->m_QtCloudMessagingClients[i.key()]->flushMessageQueue();
+ }
+ return true;
+ }
+ return false;
+}
+
+/*!
+ * \brief QCloudMessagingProvider::clientToken
+ * Get the clientToken from the client
+ *
+ * \param clientId
+ * ClientId as string.
+ *
+ * \return
+ * Return clientId token as string if found. Empty string if client not found.
+ */
+QString QCloudMessagingProvider::clientToken(const QString &clientId)
+{
+ if (!d->m_providerId.isEmpty() && d->m_QtCloudMessagingClients[clientId]) {
+ return d->m_QtCloudMessagingClients[clientId]->clientToken();
+
+ }
+ return QString();
+}
+
+/*!
+ * \brief QCloudMessagingProvider::clients
+ * Get client instances as key value pairs, where clientId is the key.
+ *
+ * \return
+ * Client instances as key value pairs
+ */
+QMap <QString, QCloudMessagingClient *> *QCloudMessagingProvider::clients()
+{
+ return &d->m_QtCloudMessagingClients;
+}
+
+/*!
+ * \brief QCloudMessagingProvider::client
+ * Finds the client instance based on the clientId
+ *
+ * \param clientId
+ * ClientId as QString
+ *
+ * \return
+ * Client instance if found, nullptr if not found.
+ */
+QCloudMessagingClient *QCloudMessagingProvider::client(const QString &clientId)
+{
+ if (d->m_QtCloudMessagingClients.find(clientId) == d->m_QtCloudMessagingClients.end())
+ return nullptr;
+
+ return d->m_QtCloudMessagingClients[clientId];
+}
+
+/*!
+ * \brief QCloudMessagingProvider::setServiceState
+ * Sets the provider service state
+ *
+ * \param state
+ * State value from the enum CloudMessagingProviderState.
+ *
+ * \return
+ * Returns the given state back.
+ */
+QCloudMessagingProvider::CloudMessagingProviderState QCloudMessagingProvider::
+ setServiceState(QCloudMessagingProvider::CloudMessagingProviderState state)
+{
+ d->m_serviceState = state;
+ return (QCloudMessagingProvider::CloudMessagingProviderState)d->m_serviceState;
+}
+
+/*!
+ * \brief QCloudMessagingProvider::getServiceState
+ * Gets the service provider state
+ *
+ * \return
+ * Return the current state value as CloudMessagingProviderState.
+ */
+QCloudMessagingProvider::CloudMessagingProviderState QCloudMessagingProvider::getServiceState()
+{
+ return (QCloudMessagingProvider::CloudMessagingProviderState) d->m_serviceState;
+}
+
+/*!
+ * \brief QCloudMessagingProvider::providerId
+ * Gets the service provider Id
+ *
+ * \return
+ * return service provider id as a QString
+ */
+QString QCloudMessagingProvider::providerId()
+{
+ return d->m_providerId;
+}
+
+/*!
+ * \brief QCloudMessagingProvider::setProviderId
+ * Sets the service provider Id
+ *
+ * \param providerId
+ * Service provider id as QString
+ */
+void QCloudMessagingProvider::setProviderId(const QString &providerId)
+{
+ d->m_providerId = providerId;
+}
+
+// Pure Virtual functions documentation
+/*!
+ \fn QCloudMessagingProvider::connectClient(
+ const QString &clientId,
+ const QVariantMap &parameters = QVariantMap())
+ Connects the client to provider. This is pure virtual function
+ and needs to be implemented in the inheritance.
+
+ \param clientId
+ Mobile or IoT client identification string (defined by user) added for the
+ provider
+
+ \param parameter
+ Client specific parameters in a variant map.
+
+ \return
+ return given ClientID when successful, empty string otherwise.
+*/
+/*!
+ \fn QCloudMessagingProvider::disconnectClient(
+ const QString &clientId,
+ const QVariantMap &parameters = QVariantMap())
+ Disconnects the client from the provider. This is pure virtual function
+ and needs to be implemented in the inheritance.
+
+ \param clientId
+ Mobile or IoT client identification string (defined by user) added for the
+ provider
+
+ \param parameter
+ Client specific parameters in a variant map.
+
+ \return
+ return true when successful, false otherwise.
+*/
+
+/*!
+ \fn QCloudMessagingProvider::sendMessage(
+ const QByteArray &msg,
+ const QString &clientId = QString(),
+ const QString &clientToken = QString(),
+ const QString &channel = QString())
+ Sends a message to one single client or to subscribed channel.
+ This is pure virtual function and needs to be implemented in the inheritance.
+
+ \param msg
+ Message as string which is interpreted to the service specific message
+ type e.g. json
+
+ \param clientId
+ Mobile or IoT client identification string (defined by user) added for the
+ provider
+
+ \param clientToken
+ By providing client token, message is targeted straight to client
+
+ \param channel
+ Channel name if broadcasting the message to channel
+
+ \return
+ return true when successful, false otherwise.
+*/
+
+/*!
+ \fn QCloudMessagingProvider::subscribeToChannel(
+ const QString &channel,
+ const QString &clientId = QString())
+ Subscribes client to broadcast channel of the provider service.
+ This is pure virtual function and needs to be implemented in the
+ inheritance.
+
+ \param channnel
+ Channel name as QString
+
+ \param clientId
+ Client id as QString
+
+ \return
+ return true when successful, false otherwise.
+*/
+
+/*!
+ \fn QCloudMessagingProvider::unsubscribeFromChannel(
+ const QString &channel,
+ const QString &clientId = QString())
+ Unsubscribes client from the broadcast channel of the provider service.
+ This is pure virtual function and needs to be implemented in the
+ inheritance.
+
+ \param channnel
+ Channel name as QString
+
+ \param clientId
+ Client id as QString
+
+ \return
+ return true when successful, false otherwise.
+*/
+
+/*!
+ \fn QCloudMessagingProvider::remoteClients()
+ Requests remote clients from the provider services.
+ This is pure virtual function and needs to be implemented in the
+ inheritance.
+
+ \return
+ return true if request successed, false otherwise
+*/
+
+
+// Signals documentation
+/*!
+ \fn QCloudMessagingProvider::clientTokenReceived(const QString &token)
+ This signal is triggered when connected gets the client
+ token from the service provider.
+
+ \param token
+ Received token as a QString.
+ Token is unique identification value used for straight communication
+ and identification with the client.
+*/
+
+/*!
+ \fn QCloudMessagingProvider::messageReceived(const QString &providerId,
+ const QString &clientId,
+ const QByteArray &message)
+ This signal is triggered when a message is received from the network to client.
+
+ \param providerId
+ Receiving Provider identification string
+
+ \param clientId
+ Receiving clientId string
+
+ \param message
+ Received message as QByteArray. Message is service specific.
+*/
+
+/*!
+ \fn QCloudMessagingProvider::remoteClientsReceived(const QString &clients)
+ This signal is triggered when the return value for requestRemoteClients
+ function is is received.
+
+ \param response
+ Response data is based on the service and can be e.g. a list
+ of client tokens in QString format.
+*/
+
+/*!
+ \fn QCloudMessagingProvider::serviceStateUpdated(int state)
+ This signal is triggered when the service provider register
+ state has changed.
+
+ \param state
+ State can be one of the enums from the QCloudMessagingProvider
+
+*/
+
+/*!
+ \fn QCloudMessagingProvider::clientStateChanged(
+ const QString &clientId,
+ int state)
+ This signal is triggered when the client state has changed
+
+ \param clientId
+ Client idenfitication string
+
+ \param state
+ Client State can be either enum from QCloudMessagingClient::CloudMessagingClientState
+ or it can be client backend specific state.
+
+*/
+
+// Public slots documentation
+
+
+// Enums
+/*!
+ \enum QCloudMessagingProvider::CloudMessagingProviderState
+
+ This enum type describes types of QCloudMessagingProvider connection states.
+
+ \value QtCloudMessagingProviderNotRegistered Messaging Provider is not registered.
+ \value QtCloudMessagingProviderRegistering Messaging Provider register started.
+ \value QtCloudMessagingProviderRegistered Messaging Provider registered.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/cloudmessaging/qcloudmessagingprovider.h b/src/cloudmessaging/qcloudmessagingprovider.h
new file mode 100644
index 0000000..36130a7
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingprovider.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCLOUDMESSAGINGPROVIDER_H
+#define QTCLOUDMESSAGINGPROVIDER_H
+
+#include <QObject>
+#include <QVariantMap>
+#include <QMap>
+#include <QString>
+#include <QScopedPointer>
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QtCloudMessaging/qcloudmessagingclient.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \brief The QtCloudMessagingProvider class
+ */
+class QCloudMessagingProviderPrivate;
+
+class Q_CLOUDMESSAGING_EXPORT QCloudMessagingProvider : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum CloudMessagingProviderState {
+ QtCloudMessagingProviderNotRegistered,
+ QtCloudMessagingProviderRegistering,
+ QtCloudMessagingProviderRegistered
+ };
+ Q_ENUM(CloudMessagingProviderState)
+
+ explicit QCloudMessagingProvider(QObject *parent = nullptr);
+ ~QCloudMessagingProvider();
+
+ virtual bool registerProvider(
+ const QString &providerId,
+ const QVariantMap &parameters = QVariantMap());
+
+ virtual void deregisterProvider();
+
+ virtual QString connectClient(
+ const QString &clientId,
+ const QVariantMap &parameters = QVariantMap()) = 0;
+
+ virtual void disconnectClient(
+ const QString &clientId,
+ const QVariantMap &parameters = QVariantMap());
+
+ virtual bool sendMessage(
+ const QByteArray &msg,
+ const QString &clientId = QString(),
+ const QString &clientToken = QString(),
+ const QString &channel = QString()) = 0;
+
+ virtual CloudMessagingProviderState setServiceState(QCloudMessagingProvider::CloudMessagingProviderState state);
+
+ virtual QMap <QString, QCloudMessagingClient *> *clients();
+
+ QString clientToken(const QString &clientId);
+
+ virtual bool remoteClients() = 0;
+
+ QCloudMessagingClient *client(const QString &clientId);
+
+ QString providerId();
+
+ void setProviderId(const QString &providerId);
+
+ QCloudMessagingProvider::CloudMessagingProviderState getServiceState();
+
+ bool removeClient(const QString &clientId);
+
+ virtual bool subscribeToChannel(
+ const QString &channel,
+ const QString &clientId = QString()) = 0;
+
+ virtual bool unsubscribeFromChannel(
+ const QString &channel,
+ const QString &clientId = QString()) = 0;
+
+
+ bool flushMessageQueue();
+
+ QString connectClientToProvider(
+ const QString &clientId,
+ const QVariantMap &parameters = QVariantMap(),
+ QCloudMessagingClient *serviceClient = nullptr);
+
+private Q_SLOTS:
+ void messageReceivedSlot(const QString &clientId,
+ const QByteArray &message);
+
+Q_SIGNALS:
+ void clientTokenReceived(const QString &token);
+
+ void messageReceived(const QString &providerId,
+ const QString &clientId,
+ const QByteArray &message);
+
+ void remoteClientsReceived(const QString &clients);
+
+ void serviceStateUpdated(int state);
+
+ void clientStateChanged(const QString &clientId,
+ int status);
+
+
+private:
+ QScopedPointer<QCloudMessagingProviderPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTCLOUDMESSAGINGPROVIDER_H
diff --git a/src/cloudmessaging/qcloudmessagingprovider_p.h b/src/cloudmessaging/qcloudmessagingprovider_p.h
new file mode 100644
index 0000000..5371363
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingprovider_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLOUDMESSAGINGCLIENT_P_H
+#define QCLOUDMESSAGINGCLIENT_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QMap>
+#include <QVariantMap>
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingClient;
+class QCloudMessagingProvider;
+
+class QCloudMessagingProviderPrivate
+{
+public:
+ QCloudMessagingProviderPrivate()
+ : m_serviceState(0)
+ {
+ }
+
+ ~QCloudMessagingProviderPrivate() = default;
+
+ QString m_providerId;
+ int m_serviceState;
+
+ QVariantMap m_provider_parameters;
+ QMap <QString, QCloudMessagingClient *> m_QtCloudMessagingClients;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGCLIENT_P_H
diff --git a/src/cloudmessaging/qcloudmessagingrestapi.cpp b/src/cloudmessaging/qcloudmessagingrestapi.cpp
new file mode 100644
index 0000000..c59e538
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingrestapi.cpp
@@ -0,0 +1,658 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessagingrestapi.h"
+#include "qcloudmessagingrestapi_p.h"
+#include <QUuid>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QAuthenticator>
+#include <QTimer>
+
+/*!
+ \class QCloudMessagingRestApi
+ \inmodule QtCloudMessaging
+ \since 5.11
+
+ \brief Cloud messaging services usually needs two way communication
+ from the server or the client. The QCloudMessagingRestApi class
+ provides the functions to send XML HTTP(s) requests to server or
+ other clients.
+
+ The QCloudMessagingRestApi implements typical get, post, put and delete
+ functionalites.
+
+ To use the class in own implementation, first inherit the
+ QCloudMessagingRestApi
+ class and then implement the virtual function to receive responses.
+
+*/
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \brief QCloudMessagingRestApi::QCloudMessagingRestApi
+ * QCloudMessagingRestApi constructor
+ *
+ * \param parent
+ * Parent as QObject
+ */
+QCloudMessagingRestApi::QCloudMessagingRestApi(QObject *parent) :
+ QObject(parent),
+ d(new QCloudMessagingRestApiPrivate)
+{
+
+ d->m_online_state = d->m_network_info.isOnline();
+ d->m_wait_for_last_request_response = false;
+ d->m_waiting_counter = 0;
+
+ connect(&(d->m_network_info), &QNetworkConfigurationManager::onlineStateChanged,
+ this, &QCloudMessagingRestApi::onlineStateChanged);
+
+ connect(&(d->m_manager), &QNetworkAccessManager::authenticationRequired,
+ this, &QCloudMessagingRestApi::provideAuthentication);
+
+ connect(&(d->m_msgTimer), &QTimer::timeout,
+ this, &QCloudMessagingRestApi::networkMsgTimerTriggered);
+
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::~QCloudMessagingRestApi
+ * Destructor
+ */
+QCloudMessagingRestApi::~QCloudMessagingRestApi()
+{
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::setServerTimers
+ * Sets rest server message retry and timeouts.
+ *
+ * \param messageTimer
+ * Timeout to wait before sending the next message.
+ * Same timeout is used for waiting response from the server.
+ * Useful when sending lot of message in fast sequency.
+ * Default is 800 milliseconds.
+ *
+ * \param waitForResponseCounter
+ * How long we wait for response to last send message
+ * Time is waitForResponseCounter x messageTimer milliseconds.
+ * Useful to tune for slower network conditions.
+ * Default is 3 times = 3 x 800 ms = 2400 ms
+ *
+ * \param messageRetryCount
+ * Describes how many times the message sending is retried if
+ * no response from the server.
+ */
+void QCloudMessagingRestApi::setServerTimers(int messageTimer,
+ int waitForResponseCounter,
+ int messageRetryCount)
+{
+ d->setServerTimers(messageTimer, waitForResponseCounter, messageRetryCount);
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::provideAuthentication
+ * Virtual function to provide authentication for the network connection.
+ * By default this function is omitted and service is connected without
+ * separate authentication.
+ *
+ * \param reply
+ * Sent QNetworkReply data
+ * \param authenticator
+ * Authenticator instance where to set username and password.
+ */
+void QCloudMessagingRestApi::provideAuthentication(
+ QNetworkReply *reply,
+ QAuthenticator *authenticator)
+{
+ Q_UNUSED(reply);
+ Q_UNUSED(authenticator);
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::xmlHttpPostRequest
+ * Private function to send Post specific message to server.
+ * Connects to virtualized xmlHttpRequestReply function.
+ *
+ * \param request
+ * QNetworkRequest instance
+ *
+ * \param data
+ * Data to be sent as QByteArray
+
+ * \param req_id
+ * Requirement id to identify the received message.
+ *
+ * \param uuid
+ * Unique uuid for internal message array manipulation.
+ *
+ * \param info
+ * Additional info to provide via QNetworkReply instance
+ *
+ * \return
+ * Returns updated QNetworkReply instance after sending the post message.
+ */
+QNetworkReply *
+QCloudMessagingRestApi::xmlHttpPostRequest(
+ QNetworkRequest request,
+ QByteArray data,
+ int req_id,
+ const QString &uuid,
+ const QString &info)
+{
+
+ connect(&d->m_manager, &QNetworkAccessManager::finished,
+ this, &QCloudMessagingRestApi::xmlHttpRequestReply);
+
+ QNetworkReply *reply = d->m_manager.post(request, data);
+
+ reply->setProperty("req_id", req_id);
+ reply->setProperty("uuid", uuid);
+ reply->setProperty("info", info);
+
+ return reply;
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::xmlHttpPutRequest
+ * Private function to send Put specific message to server.
+ * Connects to virtualized xmlHttpRequestReply function.
+ *
+ * \param request
+ * QNetworkRequest instance
+ *
+ * \param data
+ * Data to be sent as QByteArray
+
+ * \param req_id
+ * Requirement id to identify the received message.
+ *
+ * \param uuid
+ * Unique uuid for internal message array manipulation.
+ *
+ * \param info
+ * Additional info to provide via QNetworkReply instance
+ *
+ * \return
+ * Returns updated QNetworkReply instance after sending the post message.
+ */
+QNetworkReply *
+QCloudMessagingRestApi::xmlHttpPutRequest(
+ QNetworkRequest request,
+ QByteArray data,
+ int req_id,
+ const QString &uuid,
+ const QString &info)
+{
+
+ connect(&d->m_manager, &QNetworkAccessManager::finished,
+ this, &QCloudMessagingRestApi::xmlHttpRequestReply);
+
+
+ QNetworkReply *reply = d->m_manager.put(request, data);
+
+ reply->setProperty("req_id", req_id);
+ reply->setProperty("uuid", uuid);
+ reply->setProperty("info", info);
+
+ return reply;
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::xmlHttpDeleteRequest
+ * Private function to send Delete specific message to server.
+ * Connects to virtualized xmlHttpRequestReply function.
+ *
+ * \param request
+ * QNetworkRequest instance
+ *
+ * \param data
+ * Data to be sent as QByteArray
+
+ * \param req_id
+ * Requirement id to identify the received message.
+ *
+ * \param uuid
+ * Unique uuid for internal message array manipulation.
+ *
+ * \param info
+ * Additional info to provide via QNetworkReply instance
+ *
+ * \return
+ * Returns updated QNetworkReply instance after sending the post message.
+ */
+QNetworkReply *
+QCloudMessagingRestApi::xmlHttpDeleteRequest(
+ QNetworkRequest request,
+ int req_id,
+ const QString &uuid,
+ const QString &info)
+{
+
+ connect(&d->m_manager, &QNetworkAccessManager::finished,
+ this, &QCloudMessagingRestApi::xmlHttpRequestReply);
+
+
+ QNetworkReply *reply = d->m_manager.deleteResource(request);
+
+ reply->setProperty("req_id", req_id);
+ reply->setProperty("uuid", uuid);
+ reply->setProperty("info", info);
+
+ return reply;
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::xmlHttpGetRequest
+ * Private function to send Get specific message to server.
+ * Connects to virtualized xmlHttpRequestReply function.
+ *
+ * \param request
+ * QNetworkRequest instance
+ *
+ * \param data
+ * Data to be sent as QByteArray
+
+ * \param req_id
+ * Requirement id to identify the received message.
+ *
+ * \param uuid
+ * Unique uuid for internal message array manipulation.
+ *
+ * \param info
+ * Additional info to provide via QNetworkReply instance
+ *
+ * \return
+ * Returns updated QNetworkReply instance after sending the post message.
+ */
+QNetworkReply *QCloudMessagingRestApi::xmlHttpGetRequest(
+ QNetworkRequest request,
+ int req_id,
+ const QString &uuid,
+ const QString &info)
+{
+
+ connect(&d->m_manager, &QNetworkAccessManager::finished,
+ this, &QCloudMessagingRestApi::xmlHttpRequestReply);
+
+
+ QNetworkReply *reply = d->m_manager.get(request);
+
+ reply->setProperty("req_id", req_id);
+ reply->setProperty("uuid", uuid);
+ reply->setProperty("info", info);
+
+ return reply;
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::sendNetworkMessage
+ * Sends message with info from the QCloudMessagingNetworkMessage class parameter.
+ *
+ * \param msg
+ * QCloudMessagingNetworkMessage class as parameter
+ *
+ * \param immediate
+ * If true, defines that message is sent immediately and no message timers are involved
+ * if false, message is set to message queue and message will be sent after message timer
+ * timeouts.
+ */
+void QCloudMessagingRestApi::sendNetworkMessage(
+ const QCloudMessagingNetworkMessage &msg,
+ int immediate)
+{
+ sendMessage((QCloudMessagingRestApi::MessageType)msg.type,
+ msg.req_id,
+ msg.request,
+ msg.data,
+ immediate,
+ QString());
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::sendMessage
+ * Sends type specific network message to server
+ *
+ * \param type
+ * Type as QCloudMessagingRestApi::MessageType
+ *
+ * \param req_id
+ * Requirement id to identify the received message.
+ *
+ * \param request
+ * QNetworkRequest instance
+ *
+ * \param data
+ * Data to be sent as QByteArray
+ *
+ * \param immediate
+ * If true, defines that message is sent immediately and no message timers are involved
+ * if false, message is set to message queue and message will be sent after message timer
+ * timeouts.
+ *
+ * \param info
+ * Additional info to provide via QNetworkReply instance
+ *
+ * \return
+ * Return true if message was sent immediately. False if it went to the queue.
+ */
+bool QCloudMessagingRestApi::sendMessage(QCloudMessagingRestApi::MessageType type,
+ int req_id,
+ QNetworkRequest request,
+ QByteArray data,
+ int immediate,
+ const QString &info)
+{
+ QCloudMessagingNetworkMessage msg;
+ bool sent = false;
+
+ // Remember the message if not online
+ if (!immediate || !d->m_online_state) {
+ QUuid quid = QUuid::createUuid();;
+
+ QString pure_quid = quid.toString();
+ pure_quid = pure_quid.mid(1, pure_quid.length() - 2);
+
+ msg.req_id = req_id;
+ msg.type = type;
+ msg.uuid = pure_quid;
+ msg.request = request;
+ msg.data = data;
+ msg.retry_count = 0;
+ msg.info = info;
+
+ d->m_network_requests.append(msg);
+
+ if (!d->m_msgTimer.isActive()) d->m_msgTimer.start(d->m_server_message_timer);
+ } else {
+ if (type == POST_MSG) {
+ xmlHttpPostRequest(request, data, req_id, msg.uuid, info);
+ }
+
+ if (type == GET_MSG) {
+ xmlHttpGetRequest(request, req_id, msg.uuid, info);
+ }
+ if (type == PUT_MSG) {
+ xmlHttpPutRequest(request, data, req_id, msg.uuid, info);
+ }
+ if (type == DELETE_MSG) {
+ xmlHttpDeleteRequest(request, req_id, msg.uuid, info);
+ }
+ sent = true;
+ }
+ return sent;
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::clearMessage
+ * Clears the specific messages from the message queue
+ * Should be used in the implementatio of xmlHttpRequestReply
+ *
+ * \param msg_uuid
+ * Unique uuid of the message
+ */
+void QCloudMessagingRestApi::clearMessage(const QString &msg_uuid)
+{
+ for (int i = 0; i < d->m_network_requests.length(); i++) {
+ if (d->m_network_requests[i].uuid == msg_uuid) {
+ d->m_network_requests.removeAt(i);
+ return;
+ }
+ }
+}
+
+
+/*!
+ * \brief QCloudMessagingRestApi::clearMessageBuffer
+ * Clears the message queue.
+ */
+void QCloudMessagingRestApi::clearMessageBuffer()
+{
+ d->m_network_requests.clear();
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::networkMsgTimerTriggered
+ * Private slot for handling message timeouts and resending of the
+ * messages.
+ */
+void QCloudMessagingRestApi::networkMsgTimerTriggered()
+{
+ // Do not send messages if we are not online or we are waiting
+ // for message to arrive
+ if (!d->m_online_state) {
+ d->m_msgTimer.start(d->m_server_message_timer);
+ return;
+ }
+
+ if (d->m_wait_for_last_request_response) {
+ d->m_waiting_counter++;
+
+ if (d->m_waiting_counter > d->m_server_wait_for_response_counter) {
+ d->m_wait_for_last_request_response = false;
+ d->m_waiting_counter = 0;
+ }
+ d->m_msgTimer.start(d->m_server_message_timer);
+ return;
+ }
+
+ d->m_waiting_counter = 0;
+
+ // Send latest message.
+ if (d->m_network_requests.length() > 0) {
+
+ if (d->m_network_requests[0].type == POST_MSG) {
+
+ xmlHttpPostRequest(d->m_network_requests[0].request,
+ d->m_network_requests[0].data,
+ d->m_network_requests[0].req_id,
+ d->m_network_requests[0].uuid,
+ d->m_network_requests[0].info);
+
+ d->m_network_requests[0].retry_count++;
+ }
+
+ if (d->m_network_requests[0].type == GET_MSG &&
+ d->m_network_requests[0].retry_count < d->m_server_message_retry_count) {
+
+ xmlHttpGetRequest(d->m_network_requests[0].request,
+ d->m_network_requests[0].req_id,
+ d->m_network_requests[0].uuid,
+ d->m_network_requests[0].info);
+
+ d->m_network_requests[0].retry_count++;
+ }
+
+ if (d->m_network_requests[0].type == PUT_MSG &&
+ d->m_network_requests[0].retry_count < d->m_server_message_retry_count) {
+
+ xmlHttpPutRequest(d->m_network_requests[0].request,
+ d->m_network_requests[0].data,
+ d->m_network_requests[0].req_id,
+ d->m_network_requests[0].uuid,
+ d->m_network_requests[0].info);
+
+ d->m_network_requests[0].retry_count++;
+ }
+
+ if (d->m_network_requests[0].type == DELETE_MSG &&
+ d->m_network_requests[0].retry_count < d->m_server_message_retry_count) {
+
+ xmlHttpDeleteRequest(d->m_network_requests[0].request,
+ d->m_network_requests[0].req_id,
+ d->m_network_requests[0].uuid,
+ d->m_network_requests[0].info);
+
+ d->m_network_requests[0].retry_count++;
+ }
+
+ if (d->m_network_requests[0].retry_count < d->m_server_message_retry_count) {
+ d->m_network_requests.move(0, d->m_network_requests.length() - 1);
+ } else {
+ d->m_network_requests.removeAt(0);
+ }
+
+ if (d->m_network_requests.length() > 0)
+ d->m_msgTimer.start(d->m_server_message_timer);
+ }
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::onlineStateChanged
+ * Private slot for saving the online state based on the network class
+ * info
+ *
+ * \param online
+ * True if online, false if offline
+ */
+void QCloudMessagingRestApi::onlineStateChanged(bool online)
+{
+ d->m_online_state = online;
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::getNetworkRequestCount
+ * Returns the count of network messages in the queue waiting
+ * to be sent.
+ *
+ * \return
+ * Returns amount of network messages in queue.
+ */
+int QCloudMessagingRestApi::getNetworkRequestCount()
+{
+ return d->m_network_requests.count();
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::getOnlineState
+ * Get the current online state info from the class.
+ *
+ * \return
+ * Returns true if online. False if offline.
+ */
+bool QCloudMessagingRestApi::getOnlineState()
+{
+ return d->m_online_state;
+}
+
+/*!
+ * \brief QCloudMessagingRestApi::getNetworkManager
+ * Gets the QNetworkAccessManager for the current connection.
+ * Used in xmlHttpRequestReply implementation.
+ *
+ * \return
+ * Return the used QNetworkAccessManager instance.
+ */
+QNetworkAccessManager *QCloudMessagingRestApi::getNetworkManager()
+{
+ return &(d->m_manager);
+}
+
+// Signals documentation
+/*!
+ \fn QCloudMessagingRestApi::xmlHttpRequestError(const QString &errorString)
+ This signal is emitted when there is an error in the network transport.
+
+ \param errorString
+ Error message as QString
+*/
+
+// Public slots documentation
+/*!
+ \fn virtual void QCloudMessagingRestApi:: xmlHttpRequestReply(QNetworkReply *reply)
+
+ This slot is executed when \c QNetworkReply is received for the client request.
+ This is virtual function which needs to be implemented the by inheriting class.
+
+ Example implementation:
+ \code
+ void QCloudMessagingEmbeddedKaltiotRest::xmlHttpRequestReply(QNetworkReply *reply)
+ {
+ getNetworkManager()->disconnect(SIGNAL(finished(QNetworkReply *)));
+
+ QString m_msg_uuid = reply->property("uuid").toString();
+ int req_id = reply->property("req_id").toInt();
+
+ if (reply->error()) {
+ Q_EMIT xmlHttpRequestError(reply->errorString());
+ }
+
+ // Ok message, lets proceed and read all
+ QByteArray data(reply->readAll());
+
+ // Make decisions about req_id
+ switch (req_id) {
+ case REQ_GET_ALL_DEVICES: {
+ emit remoteClientsReceived(QString::fromUtf8(data));
+ }
+ }
+
+ reply->deleteLater();
+
+ clearMessage(m_msg_uuid);
+
+ }
+ \endcode
+ \param reply
+ provides QNetworkReply for reading data from the network response.
+
+
+*/
+
+/*!
+ \fn QCloudMessagingRestApi::provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator)
+ This slot is executed when network request requires authentication.
+ This is virtual function which needs to be implemented by inheriting class if
+ created service is know to request specific authentications. Otherwise
+ provideAuthentication request is omitted.
+
+ \param reply
+ provides QNetworkReply for reading data from the network response.
+
+ \param authentication
+ QAuthenticator pointer to provide username and password back.
+*/
+
+// Enums
+/*!
+ \enum QCloudMessagingRestApi::MessageType
+
+ This enum type describes types of QCloudMessagingRestApi xmlHttpRequest
+ messaging types.
+
+ \value NO_TYPE No type.
+ \value POST_MSG Post message type for uploading data to server.
+ \value GET_MSG Get message type for requesting data from the server.
+ \value PUT_MSG Put message type for updating data in the server.
+ \value DELETE_MSG Delete message type for deleting data from the server.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/cloudmessaging/qcloudmessagingrestapi.h b/src/cloudmessaging/qcloudmessagingrestapi.h
new file mode 100644
index 0000000..c609289
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingrestapi.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCLOUDMESSAGINGRESTAPI_H
+#define QTCLOUDMESSAGINGRESTAPI_H
+
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QtCloudMessaging/qcloudmessagingprovider.h>
+
+#include <QObject>
+#include <QNetworkRequest>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkAccessManager;
+class QAuthenticator;
+class QNetworkReply;
+
+
+class QCloudMessagingNetworkMessage
+{
+public:
+ int type;
+ int req_id;
+ QString uuid;
+ QNetworkRequest request;
+ QByteArray data;
+ QString related_uuid;
+ QString info;
+ int retry_count;
+
+};
+
+class QCloudMessagingRestApiPrivate;
+
+class Q_CLOUDMESSAGING_EXPORT QCloudMessagingRestApi : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum MessageType{
+ NO_TYPE = 0,
+ POST_MSG,
+ GET_MSG,
+ PUT_MSG,
+ DELETE_MSG
+ };
+ Q_ENUM(MessageType)
+
+ explicit QCloudMessagingRestApi(QObject *parent = nullptr);
+
+ ~QCloudMessagingRestApi();
+
+
+ bool sendMessage(MessageType type, int req_id, QNetworkRequest request,
+ QByteArray data, int immediate,
+ const QString &related_uuid);
+
+ void sendNetworkMessage(const QCloudMessagingNetworkMessage &msg,
+ int immediate);
+
+ void clearMessageBuffer();
+
+ int getNetworkRequestCount();
+
+ bool getOnlineState();
+
+ QNetworkAccessManager *getNetworkManager();
+
+ void setServerTimers(int messageTimer,
+ int messageRetryCount,
+ int messageNoResponseTimer);
+
+ void clearMessage(const QString &msg_uuid);
+
+ QNetworkReply *xmlHttpPostRequest(QNetworkRequest request,
+ QByteArray data,
+ int req_id,
+ const QString &uuid,
+ const QString &info);
+
+ QNetworkReply *xmlHttpGetRequest(QNetworkRequest request,
+ int req_id,
+ const QString &uuid,
+ const QString &info);
+
+ QNetworkReply *xmlHttpPutRequest(QNetworkRequest request,
+ QByteArray data,
+ int req_id,
+ const QString &uuid,
+ const QString &info);
+
+ QNetworkReply *xmlHttpDeleteRequest(QNetworkRequest request,
+ int req_id,
+ const QString &uuid,
+ const QString &info);
+Q_SIGNALS:
+ void xmlHttpRequestError(const QString &errorString);
+
+public Q_SLOTS:
+ virtual void xmlHttpRequestReply(QNetworkReply *reply) = 0;
+ virtual void provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator);
+
+private Q_SLOTS:
+ void networkMsgTimerTriggered();
+ void onlineStateChanged(bool online);
+
+private:
+ void append_network_request(int req_id, const QString &param, QVariant data);
+
+ QScopedPointer<QCloudMessagingRestApiPrivate> d;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTCLOUDMESSAGINGRESTAPI_H
diff --git a/src/cloudmessaging/qcloudmessagingrestapi_p.h b/src/cloudmessaging/qcloudmessagingrestapi_p.h
new file mode 100644
index 0000000..71e0547
--- /dev/null
+++ b/src/cloudmessaging/qcloudmessagingrestapi_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCLOUDMESSAGINGRESTAPI_P_H
+#define QTCLOUDMESSAGINGRESTAPI_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QList>
+#include <QNetworkReply>
+#include <QTimer>
+#include <QNetworkAccessManager>
+#include <QNetworkConfigurationManager>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingNetworkMessage;
+
+class QCloudMessagingRestApiPrivate
+{
+public:
+ QCloudMessagingRestApiPrivate()
+ {
+ m_online_state = false;
+ m_server_message_timer = 800;
+ m_server_wait_for_response_counter = 10;
+ m_server_message_retry_count = 1;
+ }
+
+ ~QCloudMessagingRestApiPrivate() = default;
+
+ void setServerTimers(int messageTimer, int waitForResponseCounter, int messageRetryCount)
+ {
+ m_server_message_timer = messageTimer;
+ m_server_wait_for_response_counter = waitForResponseCounter;
+ m_server_message_retry_count = messageRetryCount;
+ }
+
+ QNetworkAccessManager m_manager;
+ bool m_wait_for_last_request_response;
+ QTimer m_msgTimer;
+ bool m_online_state;
+ QList <QCloudMessagingNetworkMessage> m_network_requests;
+ QNetworkConfigurationManager m_network_info;
+ int m_waiting_counter;
+ int m_server_message_timer;
+ int m_server_wait_for_response_counter;
+ int m_server_message_retry_count;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTCLOUDMESSAGINGRESTAPI_P_H
diff --git a/src/cloudmessaging/qtcloudmessagingglobal.h b/src/cloudmessaging/qtcloudmessagingglobal.h
new file mode 100644
index 0000000..2cc131e
--- /dev/null
+++ b/src/cloudmessaging/qtcloudmessagingglobal.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCLOUDMESSAGINGGLOBAL_H
+#define QTCLOUDMESSAGINGGLOBAL_H
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_STATIC
+# if defined(QT_BUILD_CLOUDMESSAGING_LIB)
+# define Q_CLOUDMESSAGING_EXPORT Q_DECL_EXPORT
+# else
+# define Q_CLOUDMESSAGING_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define Q_CLOUDMESSAGING_EXPORT
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QTCLOUDMESSAGINGGLOBAL_H
diff --git a/src/cloudmessagingembeddedkaltiot/android/ks_gw_client_android.h b/src/cloudmessagingembeddedkaltiot/android/ks_gw_client_android.h
new file mode 100644
index 0000000..b6184b8
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/android/ks_gw_client_android.h
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (c) by Kaltiot Oy 2017
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __STATIC_LIBRARY_KS_GW_CLIENT_H__
+#define __STATIC_LIBRARY_KS_GW_CLIENT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef enum {
+ KS_STATE_OFFLINE,
+ KS_STATE_DISCONNECTING,
+ KS_STATE_CONNECTING,
+ KS_STATE_ONLINE
+} KaltiotSmartState;
+
+typedef enum {
+ KS_ERROR_NO_ERROR = 0,
+ KS_ERROR_CONNECT_ERROR,
+ KS_ERROR_GATEWAY_DISCONNECT,
+ KS_ERROR_UNKNOWN,
+ KS_ERROR_CLIENT_DISCONNECT
+} KaltiotSmartError;
+
+typedef enum {
+ KS_GW_CLIENT_PAYLOAD_BINARY = 1,
+ KS_GW_CLIENT_PAYLOAD_INT,
+ KS_GW_CLIENT_PAYLOAD_STRING,
+ KS_GW_CLIENT_PAYLOAD_PING,
+ KS_GW_CLIENT_PAYLOAD_PONG
+} payload_type_t;
+
+typedef enum {
+ NETWORK_STATE_DISABLED,
+ NETWORK_STATE_MOBILE_2G,
+ NETWORK_STATE_MOBILE_3G,
+ NETWORK_STATE_MOBILE_4G,
+ NETWORK_STATE_MOBILE_5G,
+ NETWORK_STATE_WIFI,
+ NETWORK_STATE_COUNT
+} network_state_e;
+
+typedef struct {
+ void* userdata;
+ bool connected;
+ int32_t socket_fd;
+ void* old_info;
+} ks_gw_client_instance_t;
+
+
+/**
+ * Callback function that is called when a notification is received. You
+ * should implement this.
+ *
+ * If payload_type is KS_CLIENT_PAYLOAD_STRING, KS_CLIENT_PAYLOAD_PING or
+ * KS_CLIENT_PAYLOAD_PONG, payload and length will include the null
+ * terminator of the string.
+ *
+ * @param address Null-terminated string.
+ * @param payload Byte data.
+ * @param payload_length Length of the payload.
+ * @param payload_type Type of the payload.
+ * @param msg_id Message id
+ * @param msg_id_length Message id length
+
+ */
+void ks_gw_client_notification_cb(const char *address, const char *payload,
+ const uint16_t payload_length,
+ const payload_type_t payload_type,
+ const char *msg_id,
+ const uint16_t msg_id_length);
+
+/**
+ * Callback function that is called when a rid is received. You should
+ * implement this.
+ *
+ * @param address Null-terminated string.
+ * @param rid Null-terminated string.
+ Unique resource identifier for every iot application
+ registered to the service. Using this identifier you are
+ able to send notifications to the application.
+ * @param secret Null-terminated string.
+ */
+void ks_gw_client_rid_cb(const char *address, const char *rid,
+ const char *secret);
+
+/**
+ * Callback function that is called when the state of the daemon changes. You
+ * should implement this.
+ *
+ * @param state Status code that tells the new state.
+ * @param error Possible error code associated with the state.
+ */
+void ks_gw_client_state_changed_cb(KaltiotSmartState state, KaltiotSmartError error);
+
+
+/**
+ * Initialize the client instance. Must be the first function to call for new client.
+ */
+void ks_gw_client_init(ks_gw_client_instance_t *inst);
+
+/**
+ * Connects to the daemon. Call this before registering. Returns true if the
+ * connection has been successfully established.
+ *
+ * @param path The path or address to connect to. It is treated as a unix
+ * domain socket path unless it has a colon in it, in which case
+ * the IPC will use local TCP on ip:port. You can also leave it
+ * NULL, then the default path (/tmp/ks_gw_socket) will be
+ * used.
+ */
+extern bool ks_gw_client_connect(ks_gw_client_instance_t *inst, const char *path);
+
+/**
+ * Disconnects from the daemon.
+ */
+extern void ks_gw_client_disconnect(ks_gw_client_instance_t *inst);
+
+/**
+ * Registers with the daemon. App will start receiving notifications and other
+ * events.
+ *
+ * NOTE: If you need to update the channels, you have to first unregister
+ * and then register again, with the different channels.
+ *
+ * @param address Alphanumeric, null-terminated string.
+ * @param version Alphanumeric, null-terminated string.
+ * @param customer_id Alphanumeric, null-terminated string.
+ Identifier given by customer to the IoT application
+ registering to Kaltiot Smart Iot. Use this field to identify your
+ iot application on gateway. It has to be unique for a
+ given gateway. For example "sensor1".
+ * @param channels Array of alphanumeric, null-terminated strings that
+ * represent the channels such as "temperature" or
+ * "motion".
+ * @param num_channels The number of channels in the array.
+ */
+extern void ks_gw_client_register_iot(ks_gw_client_instance_t *inst,
+ const char *address,
+ const char *version,
+ const char *customer_id,
+ const char **channels,
+ uint16_t num_channels);
+
+/**
+ * Unregisters from the daemon.
+ *
+ * @param address Alphanumeric, null-terminated string.
+ * @param version Alphanumeric, null-terminated string.
+ * @param customer_id Alphanumeric, null-terminated string.
+ */
+extern void ks_gw_client_unregister_iot(ks_gw_client_instance_t *inst,
+ const char *address,
+ const char *version,
+ const char *customer_id);
+
+/**
+ * Publishes a message to the server.
+ *
+ * If payload_type is KS_CLIENT_PAYLOAD_STRING, KS_CLIENT_PAYLOAD_PING or
+ * KS_CLIENT_PAYLOAD_PONG, payload and length should include the null
+ * terminator of the string.
+ *
+ * @param payload Byte data.
+ * @param payload_len Length of the payload.
+ * @param payload_type Type of the payload.
+ * @param tag Tag of the payload. maximum size could be MAX_TAG_LENGTH
+ * @return bool true if the parameters are valid else false
+ */
+extern bool ks_gw_client_publish_message(ks_gw_client_instance_t *inst,
+ const uint8_t *payload,
+ const uint16_t payload_len,
+ const payload_type_t payload_type,
+ const char* tag);
+
+/**
+ * Should be called periodically. It checks whether there is any data waiting
+ * to be read in the buffer, and based on said data calls the above callbacks.
+ */
+extern void ks_gw_client_task(ks_gw_client_instance_t *inst);
+
+/**
+ * Forces state_changed_cb to be called with the current state.
+ */
+extern void ks_gw_client_request_state(ks_gw_client_instance_t *inst);
+
+/**
+ * Forces rid_cb to be called with the current rid info.
+ */
+extern void ks_gw_client_request_rid(ks_gw_client_instance_t *inst);
+
+typedef void (*ks_app_id_callback) (const char *app_id, void *arg);
+
+/**
+ * Requests the application id from the daemon. The callback is called with
+ * the application id and an optional argument that the user can specify.
+ *
+ * @param callback Callback function.
+ * @param arg Optional argument passed to the callback.
+ */
+extern void ks_gw_client_request_app_id(ks_gw_client_instance_t *inst,
+ ks_app_id_callback callback,
+ void *arg);
+
+/**
+ * Enables or disables the entire engine. Equivalent to closing the daemon.
+ *
+ * @param enabled
+ */
+extern void ks_gw_client_set_engine_enabled(ks_gw_client_instance_t *inst, bool enabled);
+
+/**
+ * Sets the network status. MCC and MNC can be included with a mobile network
+ * state.
+ *
+ * @param state
+ * @param mcc Can be an empty null-terminated string, not NULL.
+ * @param mnc Can be an empty null-terminated string, not NULL.
+ */
+extern void ks_gw_client_set_network_available(ks_gw_client_instance_t *inst,
+ network_state_e state,
+ const char *mcc, const char *mnc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/cloudmessagingembeddedkaltiot/cloudmessagingembeddedkaltiot.pro b/src/cloudmessagingembeddedkaltiot/cloudmessagingembeddedkaltiot.pro
new file mode 100644
index 0000000..1190234
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/cloudmessagingembeddedkaltiot.pro
@@ -0,0 +1,48 @@
+TARGET = QtCloudMessagingEmbeddedKaltiot
+QT = core cloudmessaging
+
+# Check for KALTIOT_SDK environment
+ENV_KALTIOT_SDK = $$(KALTIOT_SDK)
+
+# Or define KALTIOT_SDK path here
+KALTIOT_SDK =
+
+isEmpty(ENV_KALTIOT_SDK) {
+ isEmpty(KALTIOT_SDK) {
+ message("KALTIOT_SDK" environment variable or define in radardemo.pro file not detected!)
+ }
+}
+
+INCLUDEPATH += $$(KALTIOT_SDK)
+INCLUDEPATH += $$(KALTIOT_SDK)/src
+
+HEADERS += \
+ qcloudmessagingembeddedkaltiotclient.h \
+ qcloudmessagingembeddedkaltiotprovider.h \
+ qcloudmessagingembeddedkaltiotclient_p.h \
+ qcloudmessagingembeddedkaltiotprovider_p.h \
+ qcloudmessagingembeddedkaltiotrest.h
+
+SOURCES += \
+ qcloudmessagingembeddedkaltiotclient.cpp \
+ qcloudmessagingembeddedkaltiotprovider.cpp \
+ qcloudmessagingembeddedkaltiotrest.cpp
+
+android {
+ DEFINES += ANDROID_OS
+ QT += androidextras
+ HEADERS += \
+ $$PWD/android/ks_gw_client_android.h
+} else {
+
+ DEFINES += EMBEDDED_AND_DESKTOP_OS
+ HEADERS += \
+ $$(KALTIOT_SDK)/src/ks_gw_client.h
+
+ LIBS += $$(KALTIOT_SDK)/libks_gw_client.a
+}
+
+load(qt_module)
+
+DISTFILES += \
+ README.md
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.cpp b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.cpp
new file mode 100644
index 0000000..c1325dd
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.cpp
@@ -0,0 +1,342 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessagingembeddedkaltiotclient.h"
+#include <qcloudmessagingembeddedkaltiotclient_p.h>
+
+#include <QStringList>
+
+#ifdef ANDROID_OS
+#include <QtAndroid>
+#include "jni.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::QCloudMessagingEmbeddedKaltiotClient
+ * Kaltiot client constructor
+ */
+QCloudMessagingEmbeddedKaltiotClient::QCloudMessagingEmbeddedKaltiotClient(QObject *parent) :
+ QCloudMessagingClient(parent),
+ d(new QCloudMessagingEmbeddedKaltiotClientPrivate)
+{
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::~QCloudMessagingEmbeddedKaltiotClient
+ * Desctructor
+ */
+QCloudMessagingEmbeddedKaltiotClient::~QCloudMessagingEmbeddedKaltiotClient()
+{
+ // if thread is running, ask for exit it first and then terminate thread
+ if (d->m_running && d->m_clientThread.isRunning()) {
+ d->m_running = false;
+ d->m_clientThread.quit();
+ d->m_clientThread.terminate();
+ }
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::connectClient
+ * \param clientId
+ * \param parameters
+ * \return
+ */
+QString QCloudMessagingEmbeddedKaltiotClient::connectClient(const QString &clientId,
+ const QVariantMap &parameters)
+{
+ // Call parent function to setup service ids and states.
+ QCloudMessagingClient::connectClient(clientId, parameters);
+
+ QStringList channels;
+ QVariantMap params = parameters;
+ d->m_address = params.value(QStringLiteral("address")).toString();
+ d->m_version = params.value(QStringLiteral("version")).toString();
+ d->m_customer_id = params.value(QStringLiteral("customer_id")).toString();
+
+ channels = params.value(QStringLiteral("channels")).toStringList();
+
+ for (int i = 0; i < channels.count(); i++) {
+ bool new_channel = true;
+ for (int j = 0; i < d->m_channels.count(); j++) {
+ if (channels[i] == d->m_channels[j])
+ new_channel = false;
+ }
+ if (new_channel) {
+ d->m_channels.append(channels[i]);
+ }
+ }
+
+ setClientToken(clientId);
+ make_kaltiot_client_registration();
+ runBackgroundThread();
+ return d->m_address;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::runBackgroundThread
+ */
+void QCloudMessagingEmbeddedKaltiotClient::runBackgroundThread()
+{
+ this->moveToThread(&d->m_clientThread);
+ d->m_clientThread.start();
+
+ // Run service task in the thread.
+ connect(&(d->m_threadTimer), &QTimer::timeout, [ = ] {
+
+ if (!d->m_running) d->m_running = true;
+#ifdef EMBEDDED_AND_DESKTOP_OS
+ ks_gw_client_task(&d->m_kaltiot_client_instance);
+#endif
+ d->m_threadTimer.start();
+ });
+
+ d->m_threadTimer.setInterval(1);
+ d->m_threadTimer.start();
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::make_kaltiot_client_registration
+ */
+void QCloudMessagingEmbeddedKaltiotClient::make_kaltiot_client_registration()
+{
+#ifdef EMBEDDED_AND_DESKTOP_OS
+
+ char const *channels[d->m_channels.count()];
+ QList<QByteArray> constChannels;
+
+ for (int i = 0; i < d->m_channels.count(); i++) {
+ constChannels.append(d->m_channels[i].toLatin1());
+ channels[i] = constChannels[constChannels.count()-1].constData();
+ }
+
+ uint16_t num_channels = d->m_channels.count();
+
+ ks_gw_client_init(&d->m_kaltiot_client_instance);
+
+ if (!ks_gw_client_connect(&d->m_kaltiot_client_instance, NULL)) {
+ // Failed to connect!;
+ return;
+ }
+
+ if (d->m_rid.isEmpty()) {
+ d->m_rid = d->m_client_settings.value("clients/" + d->m_address + "/rid").toString();
+ }
+
+ if (!d->m_rid.isEmpty())
+ setClientToken(d->m_rid);
+
+ ks_gw_client_set_engine_enabled(&d->m_kaltiot_client_instance, true);
+
+ ks_gw_client_set_network_available(&d->m_kaltiot_client_instance,
+ NETWORK_STATE_MOBILE_2G, "123","45");
+
+ ks_gw_client_register_iot(&d->m_kaltiot_client_instance,
+ d->m_address.toLatin1().constData(),
+ d->m_version.toLatin1().constData(),
+ d->m_customer_id.toLatin1().constData(),
+ channels, num_channels);
+
+ ks_gw_client_request_rid(&d->m_kaltiot_client_instance);
+
+ constChannels.clear();
+
+#endif
+
+#ifdef ANDROID_OS
+
+ QAndroidJniObject j_rid = QtAndroid::androidActivity().callObjectMethod<jstring>("get_rid");
+
+ d->m_rid = j_rid.toString();
+ if (d->m_rid.isEmpty()) {
+ d->m_rid = d->m_client_settings.value("clients/" + d->m_address + "/rid").toString();
+
+ }
+ if (!d->m_rid.isEmpty())
+ setClientToken(d->m_rid);
+
+#endif
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::sendMessage
+ * \param msg
+ * \param send_to_device
+ * \param send_to_channel
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotClient::sendMessage(const QByteArray &msg,
+ const QString &clientToken,
+ const QString &channel)
+{
+ // In Kaltiot client send message goes via client daemon and channel or
+ // clientToken attributes are not used.
+ Q_UNUSED(channel);
+ Q_UNUSED(clientToken);
+
+
+#ifdef EMBEDDED_AND_DESKTOP_OS
+ // TAG NOT USED ATM.
+ ks_gw_client_publish_message(&d->m_kaltiot_client_instance,
+ (const uint8_t *)msg.constData(),
+ msg.size(),
+ KS_GW_CLIENT_PAYLOAD_STRING,
+ nullptr);
+#endif
+
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::disconnectClient
+ * \return
+ */
+void QCloudMessagingEmbeddedKaltiotClient::disconnectClient()
+{
+ QCloudMessagingClient::disconnectClient();
+
+ d->m_running = false;
+#ifdef EMBEDDED_AND_DESKTOP_OS
+ ks_gw_client_unregister_iot(&d->m_kaltiot_client_instance, d->m_address.toLatin1(),
+ d->m_version.toLatin1(), clientToken().toLatin1());
+ ks_gw_client_disconnect(&d->m_kaltiot_client_instance);
+ ks_gw_client_set_engine_enabled(&d->m_kaltiot_client_instance, false);
+#endif
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::cloudMessageReceived
+ * \param client
+ * \param message
+ */
+void QCloudMessagingEmbeddedKaltiotClient::cloudMessageReceived(const QString &client,
+ const QByteArray &message)
+{
+ emit messageReceived(client, message);
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::setClientToken
+ * \param token
+ */
+void QCloudMessagingEmbeddedKaltiotClient::setClientToken(const QString &token)
+{
+ d->m_rid = token;
+ if (!d->m_rid.isEmpty())
+ d->m_client_settings.setValue("clients/" + d->m_address + "/rid", d->m_rid);
+
+ emit clientTokenReceived(d->m_rid);
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::clientToken
+ * \return
+ */
+QString QCloudMessagingEmbeddedKaltiotClient::clientToken()
+{
+ return d->m_rid;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::getKaltiotEngineInstance
+ * \return
+ */
+ks_gw_client_instance_t *QCloudMessagingEmbeddedKaltiotClient::getKaltiotEngineInstance()
+{
+ return &d->m_kaltiot_client_instance;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::subscribeToChannel
+ * * Unsubscribes client from the channel
+ *
+ * \param channel
+ * * Channel name QString
+ *
+ * \return
+ * false if channel not found, true if found and updated
+ */
+bool QCloudMessagingEmbeddedKaltiotClient::subscribeToChannel(const QString &channel)
+{
+
+ for (int i = 0; i < d->m_channels.count(); i++) {
+ if (channel == d->m_channels[i])
+ return false; // Already subscribed
+ }
+
+ // Not found, lets add new channel and restart client.
+ d->m_channels.append(channel);
+
+ disconnectClient();
+ connectClient(clientToken(), clientParameters());
+
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::unsubscribeFromChannel
+ * Unsubscribes client from the channel
+ *
+ * \param channel
+ * Channel name QString
+ *
+ * \return
+ * false if channel not found, true if found and updated
+ */
+bool QCloudMessagingEmbeddedKaltiotClient::unsubscribeFromChannel(const QString &channel)
+{
+
+ for (int i = 0; i < d->m_channels.count(); i++) {
+ if (channel == d->m_channels[i]) {
+ d->m_channels.removeAt(i);
+
+ disconnectClient();
+ connectClient(clientToken(), clientParameters());
+
+ return true;
+ }
+ }
+ return false; // Not found
+
+
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotClient::flushMessageQueue
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotClient::flushMessageQueue()
+{
+ return true;
+}
+
+// Provide link to main - which will be in the app using this service.
+extern int main(int argc, char *argv[]);
+
+QT_END_NAMESPACE
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.h b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.h
new file mode 100644
index 0000000..e592efa
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCloudMessagingEmbeddedKaltiotClient_H
+#define QCloudMessagingEmbeddedKaltiotClient_H
+
+#include <QtCloudMessaging/QtCloudMessaging>
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+
+#include <QObject>
+#include <QVariantMap>
+#include <QString>
+#include <QScopedPointer>
+
+#ifndef ANDROID_OS
+#include "ks_gw_client.h"
+#else
+#include "ks_gw_client_android.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingEmbeddedKaltiotClientPrivate;
+
+class Q_CLOUDMESSAGING_EXPORT QCloudMessagingEmbeddedKaltiotClient : public QCloudMessagingClient
+{
+ Q_OBJECT
+public:
+
+ explicit QCloudMessagingEmbeddedKaltiotClient(QObject *parent = nullptr);
+ ~QCloudMessagingEmbeddedKaltiotClient();
+
+ // Qt Cloud messaging client virtual functions
+ virtual QString connectClient(const QString &clientId,
+ const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual void disconnectClient() override;
+
+ virtual void cloudMessageReceived(const QString &client, const QByteArray &message) override;
+
+ virtual QString clientToken() override;
+
+ virtual void setClientToken(const QString &token) override;
+
+ virtual bool sendMessage(const QByteArray &msg,
+ const QString &clientToken = QString(),
+ const QString &channel = QString()) override;
+
+
+ virtual bool flushMessageQueue() override;
+
+ virtual bool subscribeToChannel(const QString &channel) override;
+
+ virtual bool unsubscribeFromChannel(const QString &channel) override;
+
+ void kaltiotMessageReceived(const QString &client, const QString &message);
+
+ ks_gw_client_instance_t *getKaltiotEngineInstance();
+
+private:
+ void make_kaltiot_client_registration();
+ void runBackgroundThread();
+
+ QScopedPointer<QCloudMessagingEmbeddedKaltiotClientPrivate> d;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QCloudMessagingEmbeddedKaltiotClient_H
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient_p.h b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient_p.h
new file mode 100644
index 0000000..f92b52a
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotclient_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLOUDMESSAGINGCLIENT_P_H
+#define QCLOUDMESSAGINGCLIENT_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QStringList>
+#include <QSettings>
+#include <QThread>
+#include <QTimer>
+
+#ifndef ANDROID_OS
+#include "ks_gw_client.h"
+#else
+#include "ks_gw_client_android.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessaging;
+class QCloudMessagingEmbeddedKaltiotClient;
+
+class QCloudMessagingEmbeddedKaltiotClientPrivate
+{
+public:
+ QCloudMessagingEmbeddedKaltiotClientPrivate()
+ {
+ m_running = false;
+ }
+
+ ~QCloudMessagingEmbeddedKaltiotClientPrivate() = default;
+
+ bool m_running;
+ QString m_uuid;
+ QString m_address;
+ QString m_version;
+ QString m_customer_id;
+ QStringList m_channels;
+ QString m_rid;
+ QSettings m_client_settings;
+ QThread m_clientThread;
+ QTimer m_threadTimer;
+ ks_gw_client_instance_t m_kaltiot_client_instance;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGCLIENT_P_H
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.cpp b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.cpp
new file mode 100644
index 0000000..dcb4129
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.cpp
@@ -0,0 +1,486 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessagingembeddedkaltiotprovider.h"
+#include "qcloudmessagingembeddedkaltiotprovider_p.h"
+
+#ifdef ANDROID_OS
+#include <QtAndroid>
+#include "jni.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @brief QCloudMessagingProvider
+ * @abstract Make the smart iot class accessible outside of the class for callback msgs.
+ */
+
+static QCloudMessagingEmbeddedKaltiotProvider *m_KaltiotServiceProvider;
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::QCloudMessagingEmbeddedKaltiotProvider
+ */
+QCloudMessagingEmbeddedKaltiotProvider::QCloudMessagingEmbeddedKaltiotProvider(QObject *parent) :
+ QCloudMessagingProvider(parent),
+ d(new QCloudMessagingEmbeddedKaltiotProviderPrivate)
+{
+ m_KaltiotServiceProvider = this;
+ connect(&d->m_restInterface, &QCloudMessagingEmbeddedKaltiotRest::remoteClientsReceived,
+ this, &QCloudMessagingEmbeddedKaltiotProvider::remoteClientsReceived);
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::~QCloudMessagingEmbeddedKaltiotProvider
+ */
+QCloudMessagingEmbeddedKaltiotProvider::~QCloudMessagingEmbeddedKaltiotProvider()
+{
+ deregisterProvider();
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::registerProvider
+ * \param serviceID
+ * \param parameters
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotProvider::registerProvider(const QString &serviceID,
+ const QVariantMap &parameters)
+{
+ d->m_serviceID = serviceID;
+
+ QCloudMessagingProvider::registerProvider(serviceID, parameters);
+
+ setServiceState(QtCloudMessagingProviderRegistered);
+
+ // Get the API key for HTTP communication
+ d->m_key = parameters.value(QStringLiteral("API_KEY")).toString();
+ d->m_restInterface.setAuthKey(d->m_key);
+
+ return QtCloudMessagingProviderRegistered;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::deregisterProvider
+ * \return
+ */
+void QCloudMessagingEmbeddedKaltiotProvider::deregisterProvider()
+{
+ QCloudMessagingProvider::deregisterProvider();
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::setServiceState
+ * \param service_mode
+ * \return
+ */
+QCloudMessagingProvider::CloudMessagingProviderState QCloudMessagingEmbeddedKaltiotProvider::setServiceState(QCloudMessagingProvider::CloudMessagingProviderState service_mode)
+{
+ if (getServiceState() != QtCloudMessagingProviderNotRegistered) {
+ return QCloudMessagingProvider::setServiceState(service_mode);
+ }
+ return QtCloudMessagingProviderNotRegistered;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::connectClient
+ * \param clientId
+ * \param parameters
+ * \return
+ */
+QString QCloudMessagingEmbeddedKaltiotProvider::connectClient(const QString &clientId,
+ const QVariantMap &parameters)
+{
+ if (!providerId().isEmpty()) {
+ QCloudMessagingEmbeddedKaltiotClient *serviceClient = new QCloudMessagingEmbeddedKaltiotClient();
+
+ QString retval = connectClientToProvider(clientId, parameters, serviceClient);
+
+#ifdef ANDROID_OS
+ QtAndroid::androidActivity().callMethod<void>("init_kaltiot_wrapper", "()V");
+#endif
+ return retval;
+ }
+ return QString();
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::sendMessage
+ * \param msg
+ * \param clientId
+ * \param clientToken
+ * \param channel
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotProvider::sendMessage(const QByteArray &msg,
+ const QString &clientId,
+ const QString &clientToken,
+ const QString &channel)
+{
+ // Is this local client?
+ if (!clientId.isEmpty()) {
+
+ if (getKaltiotClient(clientId) && clientToken.isEmpty()) {
+ getKaltiotClient(clientId)->messageReceived(clientId, msg);
+ return true;
+ }
+
+ // No, not local. Its somewhere out there
+ } else {
+
+ if (!clientToken.isEmpty() && channel.isEmpty()) {
+
+ // Publish message to server via kaltiot SDK
+ QCloudMessagingEmbeddedKaltiotClient *tempClient =
+ (QCloudMessagingEmbeddedKaltiotClient *) clients()->first();
+
+ if (tempClient)
+ return tempClient->sendMessage(msg, clientToken, QString());
+ }
+
+ // Send to known device by using rest api - by giving not empty string to channel
+ if (!clientToken.isEmpty() && !channel.isEmpty())
+ return d->m_restInterface.sendDataToDevice(clientToken, msg);
+
+ // Broadcast to subscribed channel!
+ if (clientToken.isEmpty() && !channel.isEmpty())
+ return d->m_restInterface.sendBroadcast(channel, msg);
+ }
+
+ return false;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::disconnectClient
+ * \param clientId
+ * \param parameters
+ * \return
+ */
+void QCloudMessagingEmbeddedKaltiotProvider::disconnectClient(
+ const QString &clientId,
+ const QVariantMap &parameters)
+{
+ QCloudMessagingProvider::disconnectClient(clientId, parameters);
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::clients
+ * \return
+ */
+QMap <QString, QCloudMessagingClient*> *QCloudMessagingEmbeddedKaltiotProvider::clients()
+{
+ return QCloudMessagingProvider::clients();
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::remoteClients
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotProvider::remoteClients()
+{
+ // Requesting remote clients via REST APi interface.
+ return d->m_restInterface.getAllDevices();
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::setClientToken
+ * \param client
+ * \param uuid
+ */
+void QCloudMessagingEmbeddedKaltiotProvider::setClientToken(const QString &client,
+ const QString &uuid)
+{
+ getKaltiotClient(client)->setClientToken(uuid);
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::cloudMessageReceived
+ * \param client
+ * \param message
+ */
+void QCloudMessagingEmbeddedKaltiotProvider::cloudMessageReceived(const QString &client,
+ const QByteArray &message)
+{
+ getKaltiotClient(client)->cloudMessageReceived(client, message);
+
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::subscribeToChannel
+ * \param channel
+ * \param clientId
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotProvider::subscribeToChannel(const QString &channel,
+ const QString &clientId)
+{
+ if (getKaltiotClient(clientId)) {
+ return getKaltiotClient(clientId)->subscribeToChannel(channel);
+ }
+ return false;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::unsubscribeFromChannel
+ * \param channel
+ * \param clientId
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotProvider::unsubscribeFromChannel(
+ const QString &channel,
+ const QString &clientId)
+{
+ if (getKaltiotClient(clientId)) {
+ return getKaltiotClient(clientId)->unsubscribeFromChannel(channel);
+ }
+ return false;
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotProvider::getKaltiotClient
+ * \param clientId
+ * \return
+ */
+QCloudMessagingEmbeddedKaltiotClient *QCloudMessagingEmbeddedKaltiotProvider::
+ getKaltiotClient(const QString &clientId)
+{
+ return (QCloudMessagingEmbeddedKaltiotClient *)client(clientId);
+}
+
+/*** CALLBACK IMPLEMENTATIONS AGAINST KALTIOT SMART IOT LIBRARY */
+/*!
+ * \brief ks_gw_client_notification_cb
+ * Handles the callback function from the backend daemon.
+ * Informs the incoming notification / message from the server.
+ * \param address
+ * \param payload
+ * \param payload_length
+ * \param payload_type
+ * \param msg_id
+ * \param msg_id_length
+ */
+void ks_gw_client_notification_cb(const char *address, const char *payload,
+ const uint16_t payload_length,
+ const payload_type_t payload_type,
+ const char *msg_id,
+ const uint16_t msg_id_length)
+{
+ Q_UNUSED(payload_type);
+ Q_UNUSED(msg_id);
+ Q_UNUSED(msg_id_length);
+
+ QString client = address != nullptr ? QString::fromLatin1(address) : QString();
+ QByteArray b_payload = payload != nullptr ? QByteArray(payload,
+ payload_length) : QString().toLatin1();
+ //QString msg = QString::fromLatin1(b_payload);
+
+ if (!client.isEmpty())
+ m_KaltiotServiceProvider->cloudMessageReceived(client, b_payload);
+}
+
+/*!
+ * \brief ks_gw_client_state_changed_cb
+ * Handles the callback function from the backend daemon.
+ * Gets the state and forwards it to right client.
+ * \param state
+ * \param error
+ */
+void ks_gw_client_state_changed_cb(KaltiotSmartState state, KaltiotSmartError error)
+{
+ Q_UNUSED(error);
+
+ // State related to client - assuming first client
+ QCloudMessagingEmbeddedKaltiotClient *firstClient = (QCloudMessagingEmbeddedKaltiotClient *)m_KaltiotServiceProvider->clients()->first();
+ emit firstClient->clientStateChanged(firstClient->clientId(), state);
+
+}
+
+/*!
+ * \brief ks_gw_client_rid_cb
+ * Handles the callback function from the backend daemon.
+ * Gets the token and forwards it to right client.
+ * \param address
+ * \param rid
+ * \param secret
+ */
+void ks_gw_client_rid_cb(const char *address, const char *rid,
+ const char *secret)
+{
+ if (!address) address = "nullptr";
+ if (!rid) rid = "nullptr";
+ if (!secret) secret = "nullptr";
+
+ m_KaltiotServiceProvider->setClientToken(QString::fromLatin1(address), QString::fromLatin1(rid));
+
+}
+
+#ifdef ANDROID_OS
+
+/*!
+ * \brief fromJavaOnStateChanged
+ * Handles the Android Kaltiot daemon message through JNI interface.
+ * Informs the client state change.
+ * \param env
+ * \param thiz
+ * \param address
+ * \param state
+ */
+static void fromJavaOnStateChanged(JNIEnv *env, jobject thiz, jstring address, jstring state)
+{
+ Q_UNUSED(env)
+ Q_UNUSED(thiz)
+
+ QAndroidJniObject _address = address;
+ QAndroidJniObject _state = state;
+
+ ks_gw_client_state_changed_cb((KaltiotSmartState)_state.toString().toInt(),
+ (KaltiotSmartError) 0);
+}
+
+/*!
+ * \brief fromJavaOnRidChanged
+ * Handles the Android Kaltiot daemon message through JNI interface.
+ * Informs the client token change.
+ * \param env
+ * \param thiz
+ * \param address
+ * \param rid
+ */
+static void fromJavaOnRidChanged(JNIEnv *env, jobject thiz, jstring address, jstring rid)
+{
+ Q_UNUSED(env)
+ Q_UNUSED(thiz)
+
+
+ QAndroidJniObject _address = address;
+ QAndroidJniObject _rid = rid;
+
+ ks_gw_client_rid_cb(_address.toString().toLatin1(), _rid.toString().toLatin1(), nullptr);
+
+}
+
+/*!
+ * \brief fromJavaOnAppIdChanged
+ * Handles the Android Kaltiot daemon message through JNI interface.
+ * Informs the application id string change.
+ * \param env
+ * \param thiz
+ * \param address
+ * \param appid
+ */
+static void fromJavaOnAppIdChanged(JNIEnv *env, jobject thiz, jstring address, jstring appid)
+{
+ Q_UNUSED(env)
+ Q_UNUSED(thiz)
+
+ QAndroidJniObject _address = address;
+ QAndroidJniObject _appid = appid;
+
+}
+
+/*!
+ * \brief fromJavaOnNotification
+ * Handles the Android Kaltiot daemon message through JNI interface.
+ * Informs the incoming notification / message from the server.
+ * \param env
+ * \param thiz
+ * \param address
+ * \param payload
+ * \param msg
+ * \param payload_length
+ * \param payload_type
+ */
+static void fromJavaOnNotification(JNIEnv *env, jobject thiz, jstring address, jstring payload,
+ jstring msg, jint payload_length, jint payload_type)
+{
+ Q_UNUSED(env)
+ Q_UNUSED(thiz)
+
+ const char *_payload = env->GetStringUTFChars(payload, JNI_FALSE);
+
+ const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
+ const char *_msg = env->GetStringUTFChars(msg, JNI_FALSE);
+ ks_gw_client_notification_cb(_address,
+ _payload,
+ payload_length,
+ (payload_type_t)payload_type,
+ _msg,
+ sizeof(_msg));
+
+}
+
+static JNINativeMethod methods[] {
+ //{"native_notification_callback", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II;)V", reinterpret_cast<void *>(fromJavaOnNotification)},
+ {"native_state_callback", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void *>(fromJavaOnStateChanged)},
+ {"native_rid_callback", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void *>(fromJavaOnRidChanged)},
+ {"native_appid_callback", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void *>(fromJavaOnAppIdChanged)},
+
+};
+
+extern "C"
+{
+
+ JNIEXPORT void JNICALL
+ Java_com_snowgrains_radarsensor_QtApp_native_1notification_1callback__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2II(
+ JNIEnv *env, jobject thiz, jstring address, jstring payload, jstring msg, jint payload_length,
+ jint payload_type)
+ {
+ env = env;
+ const char *_payload = payload != nullptr ? env->GetStringUTFChars(payload, JNI_FALSE) : nullptr;
+ const char *_address = address != nullptr ? env->GetStringUTFChars(address, JNI_FALSE) : nullptr;
+ const char *_msg = msg != nullptr ? env->GetStringUTFChars(msg, JNI_FALSE) : nullptr;
+ ks_gw_client_notification_cb(_address,
+ _payload,
+ payload_length,
+ (payload_type_t)payload_type,
+ _msg,
+ sizeof(_msg));
+ }
+
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *)
+ {
+
+ JNIEnv *env;
+ if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4) != JNI_OK) {
+ return JNI_FALSE;
+ }
+ jclass clazz = env->FindClass("com/snowgrains/radarsensor/QtApp");
+ if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ return JNI_FALSE;
+ }
+ return JNI_VERSION_1_4;
+ }
+}
+#endif
+
+/** CALLBACK IMPLEMENTATIONS ENDED ***/
+
+// Provide link to main - which will be in the app using this service.
+extern int main(int argc, char *argv[]);
+
+QT_END_NAMESPACE
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.h b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.h
new file mode 100644
index 0000000..705c08a
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef KALTIOTPUSHSERVICE_H
+#define KALTIOTPUSHSERVICE_H
+
+#include <QtCloudMessaging/QtCloudMessaging>
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QtCloudMessaging/qcloudmessagingrestapi.h>
+#include <QtCloudMessagingEmbeddedKaltiot/qcloudmessagingembeddedkaltiotclient.h>
+
+#include <QObject>
+#include <QVariantMap>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingEmbeddedKaltiotProviderPrivate;
+class Q_CLOUDMESSAGING_EXPORT QCloudMessagingEmbeddedKaltiotProvider : public
+ QCloudMessagingProvider
+{
+ Q_OBJECT
+public:
+
+ explicit QCloudMessagingEmbeddedKaltiotProvider(QObject *parent = nullptr);
+ ~QCloudMessagingEmbeddedKaltiotProvider();
+
+ //! Qt Cloud messaging client virtual functions
+ virtual bool registerProvider(const QString &providerId,
+ const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual void deregisterProvider() override;
+
+ virtual QString connectClient(const QString &clientId,
+ const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual void disconnectClient(const QString &clientId,
+ const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual bool sendMessage(const QByteArray &msg, const QString &clientId = QString(),
+ const QString &clientToken = QString(),
+ const QString &channel = QString()) override;
+
+ virtual QCloudMessagingProvider::CloudMessagingProviderState setServiceState(
+ QCloudMessagingProvider::CloudMessagingProviderState state) override;
+
+ virtual QMap <QString, QCloudMessagingClient *> *clients() override;
+
+ virtual bool subscribeToChannel(const QString &channel,
+ const QString &clientId = QString()) override;
+
+ virtual bool unsubscribeFromChannel(const QString &channel,
+ const QString &clientId = QString()) override;
+
+ virtual bool remoteClients() override;
+
+ /* KALTIOT SPECIFIC FUNCTIONS */
+ void cloudMessageReceived(const QString &client, const QByteArray &message);
+ QCloudMessagingEmbeddedKaltiotClient *getKaltiotClient(const QString &clientId);
+
+ void setClientToken(const QString &client, const QString &uuid);
+
+private:
+ QScopedPointer<QCloudMessagingEmbeddedKaltiotProviderPrivate> d;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // KALTIOTPUSHSERVICE_H
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider_p.h b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider_p.h
new file mode 100644
index 0000000..d475ba8
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotprovider_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLOUDMESSAGINGEMBEDDEDKALTIOTPROVIDER_P_H
+#define QCLOUDMESSAGINGEMBEDDEDKALTIOTPROVIDER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QtCloudMessagingEmbeddedKaltiot/QCloudMessagingEmbeddedKaltiotRest>
+
+#include <QStringList>
+
+#ifndef ANDROID_OS
+#include "ks_gw_client.h"
+#else
+#include "ks_gw_client_android.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessaging;
+
+class QCloudMessagingEmbeddedKaltiotProviderPrivate
+{
+public:
+ QCloudMessagingEmbeddedKaltiotProviderPrivate()
+ {
+ }
+
+ ~QCloudMessagingEmbeddedKaltiotProviderPrivate() = default;
+
+ QStringList m_channels;
+ QString m_serviceID;
+ QString m_key;
+
+ QCloudMessagingEmbeddedKaltiotRest m_restInterface;
+ ks_gw_client_instance_t *m_kaltiot_engine_instance;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGEMBEDDEDKALTIOTPROVIDER_P_H
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.cpp b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.cpp
new file mode 100644
index 0000000..141e54e
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCloudMessaging/QtCloudMessaging>
+#include "qtcloudmessagingglobal.h"
+#include "qcloudmessagingembeddedkaltiotrest.h"
+
+#include <QObject>
+#include <QByteArray>
+
+QT_BEGIN_NAMESPACE
+
+/* REST API INTERFACE */
+const QString SERVER_ADDRESS = QStringLiteral("https://restapi.torqhub.io");
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotRest::getAllDevices
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotRest::getAllDevices()
+{
+ QString url = SERVER_ADDRESS + "/rids/identities" + "?ApiKey=" + m_auth_key;
+ QUrl uri(url);
+ QNetworkRequest request(uri);
+
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain; charset=ISO-8859-1");
+
+ return sendMessage(GET_MSG, REQ_GET_ALL_DEVICES, request, "", true, "");
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotRest::sendDataToDevice
+ * \param rid
+ * \param data
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotRest::sendDataToDevice(const QString &rid, const QByteArray &data)
+{
+
+ QString url = SERVER_ADDRESS + "/rids/" + rid + "?ApiKey=" + m_auth_key;
+ QUrl uri(url);
+ QNetworkRequest request(uri);
+
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain; charset=ISO-8859-1");
+
+ return sendMessage(POST_MSG, REQ_SEND_DATA_TO_DEVICE, request, data, true, "");
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotRest::sendBroadcast
+ * \param channel
+ * \param data
+ * \return
+ */
+bool QCloudMessagingEmbeddedKaltiotRest::sendBroadcast(const QString &channel, const QByteArray &data)
+{
+
+ QString url = SERVER_ADDRESS + "/rids/channel/" + channel + "?ApiKey=" + m_auth_key;
+ QUrl uri(url);
+ QNetworkRequest request(uri);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain; charset=ISO-8859-1");
+
+ return sendMessage(POST_MSG, REQ_SEND_BROADCAST_DATA_TO_CHANNEL, request, data, true, "");
+
+}
+
+/*!
+ * \brief QCloudMessagingEmbeddedKaltiotRest::xmlHttpRequestReply
+ * \param reply
+ */
+void QCloudMessagingEmbeddedKaltiotRest::xmlHttpRequestReply(QNetworkReply *reply)
+{
+
+ getNetworkManager()->disconnect(SIGNAL(finished(QNetworkReply *)));
+ QString m_msg_uuid = reply->property("uuid").toString();
+ int req_id = reply->property("req_id").toInt();
+
+ if (reply->error()) {
+ emit xmlHttpRequestError(reply->errorString());
+
+ }
+
+ // Ok message, lets proceed.
+
+ QByteArray data(reply->readAll());
+
+ switch (req_id) {
+ case REQ_GET_DEVICES_BY_CUSTOMER_ID:
+
+ break;
+ case REQ_GET_ALL_DEVICES: {
+ Q_EMIT remoteClientsReceived(QString::fromUtf8(data));
+ }
+ break;
+ case REQ_SEND_DATA_TO_DEVICE:
+
+ break;
+ case REQ_SEND_BROADCAST_DATA_TO_CHANNEL:
+
+ break;
+ case REQ_GET_DEVICE_INFO:
+
+ break;
+ }
+
+ reply->deleteLater();
+ clearMessage(m_msg_uuid);
+
+}
+
+// Signals documentation
+/*!
+ \fn QCloudMessagingEmbeddedKaltiotRest::remoteClientsReceived(const QString &clients)
+ This signal is triggered when the return value for requestRemoteClients
+ function is is received
+.
+ \param response
+ Response data is based on the service and can be e.g. a list
+ of client tokens in QString format.
+*/
+QT_END_NAMESPACE
diff --git a/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.h b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.h
new file mode 100644
index 0000000..3da3059
--- /dev/null
+++ b/src/cloudmessagingembeddedkaltiot/qcloudmessagingembeddedkaltiotrest.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QCLOUDMESSAGINGEMBEDDEDKALTIOTREST_H
+#define QCLOUDMESSAGINGEMBEDDEDKALTIOTREST_H
+
+#include <QtCloudMessaging/QtCloudMessaging>
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QtCloudMessaging/qcloudmessagingrestapi.h>
+#include <QtCloudMessagingEmbeddedKaltiot/qcloudmessagingembeddedkaltiotclient.h>
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingEmbeddedKaltiotRest : public QCloudMessagingRestApi
+{
+ Q_OBJECT
+public:
+ enum KaltiotRESTRequests {
+ REQ_NO_REQ,
+ REQ_GET_DEVICES_BY_CUSTOMER_ID,
+ REQ_GET_ALL_DEVICES,
+ REQ_SEND_DATA_TO_DEVICE,
+ REQ_SEND_BROADCAST_DATA_TO_CHANNEL,
+ REQ_GET_DEVICE_INFO
+ };
+ Q_ENUM(KaltiotRESTRequests)
+
+ void setAuthKey(QString key)
+ {
+ m_auth_key = key;
+ }
+
+ /* KALTIOT REST API
+ *
+ * Get Identities
+ * GET /rids/identities/customerId/:cust_id - Your device identities by customer id
+ * GET /rids/identities/paginStart/:paginStart/paginCount/:paginCount - Your devices identities with pagination
+ * GET /rids/identities/timeFrom/:timeFrom/timeTo/:timeTo - Your device identities by creation timestamps
+ * GET /rids/identities - All your devices identities
+ *
+ * Create persistence sessions
+ * POST /cn/:cn/data_stream - Create persistent web socket session to all your devices
+ * POST /rids/:rid/data_stream - Create persistent web socket session to single device
+ *
+ * Get data from devices
+ * GET /cn/:cn/data_stream/sessionId/:sessionId - Use persistent web socket to all your devices
+ * GET /cn/:cn/data_stream - Use non persistent web socket to all your devices
+ * GET /rids/:rid/data_stream/sessionId/:sessionId - Use Persistent web socket to single device
+ * GET /rids/:rid/data_stream - Use non persistent web socket to single device
+ *
+ * Send data to devices
+ * POST /rids/:rid - Send data to single device
+ * POST /rids/channel/:channel - Send data to group of devices
+ *
+ * Get Device Information
+ * GET /rids/:rid/presence - Get your device presence information
+ *
+ */
+
+
+ /* getAllDevices implements
+ * GET /rids/identities - All your devices identities
+ */
+ bool getAllDevices();
+
+ /* Implements
+ * POST /rids/:rid - Send data to single device
+ */
+ bool sendDataToDevice(const QString &rid, const QByteArray &data);
+
+ /* Implements
+ * POST /rids/channel/:channel - Send data to group of devices
+ */
+ bool sendBroadcast(const QString &channel, const QByteArray &data);
+
+ /* Error codes for requests */
+ /**
+ * {"result": "<Error Message>"}
+ * 1 - InvalidJSON Json used in request was not valid
+ * 2 - RidNotFound RID used in request was not connected
+ * 3 - HandshakeFailure WebSocket handshake was unsuccessful
+ * 4 - MessageLost Message received by RestApi was lost, delivery to client cannot be guaranteed
+ * 5 - NoRoute Message received by RestApi was not able to deliver to client
+ * 6 - MalformedRequest Request received by RestApi was not properly formatted
+ * 7 - UriNotFound Request to URI which was made is not existing
+ * 8 - MethodNotAllowed Http method which was used to access URI is not allowed
+ * 9 - DeliveryFailure Message received by RestApi was not able to deliver to client
+ * 10 - UnAuthorized Apikey which was used was not accepted
+ */
+
+ void xmlHttpRequestReply(QNetworkReply *reply);
+
+Q_SIGNALS:
+ void remoteClientsReceived(const QString &clients);
+
+private:
+ QString m_auth_key;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGEMBEDDEDKALTIOTREST_H
diff --git a/src/cloudmessagingfirebase/cloudmessagingfirebase.pro b/src/cloudmessagingfirebase/cloudmessagingfirebase.pro
new file mode 100644
index 0000000..e9ad425
--- /dev/null
+++ b/src/cloudmessagingfirebase/cloudmessagingfirebase.pro
@@ -0,0 +1,51 @@
+TARGET = QtCloudMessagingFirebase
+QT = core cloudmessaging
+CONFIG += static
+HEADERS += \
+ qcloudmessagingfirebaseclient.h \
+ qcloudmessagingfirebaseprovider.h \
+ qcloudmessagingfirebaseclient_p.h \
+ qcloudmessagingfirebaseprovider_p.h \
+ qcloudmessagingfirebaserest.h
+
+SOURCES += \
+ $$PWD/qcloudmessagingfirebaseclient.cpp \
+ $$PWD/qcloudmessagingfirebaseprovider.cpp \
+ qcloudmessagingfirebaserest.cpp
+
+# Check for GOOGLE_FIREBASE_SDK environment variable
+ENV_GOOGLE_FIREBASE_SDK = $$(GOOGLE_FIREBASE_SDK)
+
+# Or define GOOGLE_FIREBASE_SDK path here
+GOOGLE_FIREBASE_SDK =
+
+isEmpty(ENV_GOOGLE_FIREBASE_SDK) {
+ isEmpty(GOOGLE_FIREBASE_SDK) {
+ message("GOOGLE_FIREBASE_SDK" environment variable not detected!)
+ }
+}
+
+INCLUDEPATH += $$(GOOGLE_FIREBASE_SDK)
+INCLUDEPATH += $$(GOOGLE_FIREBASE_SDK)/include
+
+android {
+ QT += androidextras
+
+ LIBS += $$(GOOGLE_FIREBASE_SDK)/libs/android/armeabi-v7a/gnustl/libmessaging.a
+ LIBS += $$(GOOGLE_FIREBASE_SDK)/libs/android/armeabi-v7a/gnustl/libapp.a
+
+} else: macos {
+ LIBS += -F$$(GOOGLE_FIREBASE_SDK)/frameworks/darwin \
+ -framework firebase \
+ -framework firebase_messaging
+} else: ios {
+ LIBS += -F$$(GOOGLE_FIREBASE_SDK)/frameworks/ios/universal \
+ -framework firebase_messaging \
+ -framework firebase \
+ -framework Foundation \
+ -framework UserNotifications \
+ -framework UIKit \
+ -framework CoreGraphics
+}
+
+load(qt_module)
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.cpp b/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.cpp
new file mode 100644
index 0000000..2ef4921
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.cpp
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessagingfirebaseclient.h"
+#include "qcloudmessagingfirebaseclient_p.h"
+
+#if defined(Q_OS_ANDROID)
+#include <QtAndroid>
+#include <QtAndroidExtras>
+#include <QAndroidJniObject>
+#elif defined(Q_OS_DARWIN)
+extern "C" {
+#include <objc/objc.h>
+} // extern "C"
+#endif // __ANDROID__
+
+QT_BEGIN_NAMESPACE
+
+extern void LogMessage(const char *format, ...);
+static QCloudMessagingFirebaseClient *m_client_pointer;
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::QCloudMessagingFirebaseClient
+ */
+QCloudMessagingFirebaseClient::QCloudMessagingFirebaseClient(QObject *parent) :
+ QCloudMessagingClient(parent),
+ d(new QCloudMessagingFirebaseClientPrivate)
+{
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::~QCloudMessagingFirebaseClient
+ */
+QCloudMessagingFirebaseClient::~QCloudMessagingFirebaseClient()
+{
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::connectClient
+ * \param clientId
+ * \param parameters
+ * \return
+ */
+QString QCloudMessagingFirebaseClient::connectClient(const QString &clientId,
+ const QVariantMap &parameters)
+{
+ QCloudMessagingClient::connectClient(clientId, parameters);
+ // Call parent function to setup service ids and states.
+
+ // Setup Firebase app for the client.
+#if defined(__ANDROID__)
+ d->m_firebaseApp = ::firebase::App::Create(::firebase::AppOptions(), QAndroidJniEnvironment(),
+ QtAndroid::androidActivity().object());
+
+#endif
+#if defined(__APPLE__)
+ d->m_firebaseApp = ::firebase::App::Create(::firebase::AppOptions());
+
+#endif // defined(__ANDROID__)
+ m_client_pointer = this;
+
+ d->m_firebase_initializer.Initialize(d->m_firebaseApp,
+ nullptr, [](::firebase::App * fapp, void *) {
+ LogMessage("Try to initialize Firebase Messaging");
+ return ::firebase::messaging::Initialize(
+ *fapp,
+ (::firebase::messaging::Listener *)m_client_pointer);
+ });
+
+ while (d->m_firebase_initializer.InitializeLastResult().status() !=
+ firebase::kFutureStatusComplete) {
+
+ LogMessage("Firebase: InitializeLastResult wait...");
+ }
+
+ setClientId(clientId);
+ return clientId;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::sendMessage
+ * \param msg
+ * \param send_to_device
+ * \param send_to_channel
+ * \return
+ */
+bool QCloudMessagingFirebaseClient::sendMessage(const QByteArray &msg, const QString &clientToken,
+ const QString &channel)
+{
+ Q_UNUSED(channel)
+
+ ::firebase::messaging::Message message;
+
+ QString message_to = clientToken + "@gcm.googleapis.com";
+
+ message.to = message_to.toStdString();
+
+ //TODO: USE Uuid Qt generator
+ message.message_id = QString("uniqueId" + QString::number(rand() * 10000)).toStdString();
+
+ //TODO: QString to std map conversion from the input message
+ Q_UNUSED(msg);
+ // message.data
+
+ // TODO: Use specific client parameters for time to live
+ message.time_to_live = 1000000 ;//TIME_TO_LIVE;
+ ::firebase::messaging::Send(message);
+
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::disconnectClient
+ * \return
+ */
+void QCloudMessagingFirebaseClient::disconnectClient()
+{
+ QCloudMessagingClient::disconnectClient();
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::cloudMessageReceived
+ * \param client
+ * \param message
+ */
+void QCloudMessagingFirebaseClient::cloudMessageReceived(const QString &client,
+ const QByteArray &message)
+{
+ emit messageReceived(client, message);
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::OnTokenReceived
+ * \param token
+ */
+void QCloudMessagingFirebaseClient::OnTokenReceived(const char *token)
+{
+ d->m_token = QString::fromLatin1(token);
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::OnMessage
+ * \param message
+ */
+void QCloudMessagingFirebaseClient::OnMessage(const::firebase::messaging::Message &message)
+{
+ d->m_last_firebase_message = message;
+ emit messageReceived(clientId(), parseMessage(d->m_last_firebase_message).toUtf8());
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::setClientToken
+ * \param uuid
+ */
+void QCloudMessagingFirebaseClient::setClientToken(const QString &uuid)
+{
+ d->m_token = uuid;
+ emit clientTokenReceived(d->m_token);
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::parseMessage
+ * \param msg_map
+ * \return
+ */
+QString QCloudMessagingFirebaseClient::parseMessage(::firebase::messaging::Message msg_map)
+{
+ QString msg;
+ msg = QString::fromLatin1("{");
+ bool dotSign = false;
+
+ if (!msg_map.from.empty()) {
+ if (dotSign) msg += QString::fromLatin1(",");
+ msg += QString::fromLatin1("\"from\":\"") + QString::fromLatin1(msg_map.from.c_str()) + "\"";
+ dotSign = true;
+ }
+ if (!msg_map.error.empty()) {
+ if (dotSign) msg += QString::fromLatin1(",");
+ msg += QString::fromLatin1("\"error\":\"") + QString::fromLatin1(msg_map.error.c_str()) + "\"";
+ dotSign = true;
+ }
+ if (!msg_map.message_id.empty()) {
+ if (dotSign) msg += QString::fromLatin1(",");
+ msg += QString::fromLatin1("\"message_id\":\"") + QString::fromLatin1(
+ msg_map.message_id.c_str()) + "\"";
+ dotSign = true;
+ }
+
+ if (msg_map.notification) {
+
+ if (dotSign) msg += QString::fromLatin1(",");
+
+ msg += QString::fromLatin1("\"notification\":{");
+
+ if (msg_map.notification_opened)
+ msg += QString::fromLatin1("\"notification_opened\":true");
+ else
+ msg += QString::fromLatin1("\"notification_opened\":false");
+
+ if (!msg_map.notification->title.empty())
+ msg += QString::fromLatin1(",\"title\":\"") + QString::fromLatin1(
+ msg_map.notification->title.c_str()) + QString::fromLatin1("\"");
+
+ if (!msg_map.notification->body.empty())
+ msg += QString::fromLatin1(",\"body\":\"") + QString::fromLatin1(msg_map.notification->body.c_str())
+ + QString::fromLatin1("\"");
+
+ if (!msg_map.notification->icon.empty())
+ msg += QString::fromLatin1(",\"icon\":\"") + QString::fromLatin1(msg_map.notification->icon.c_str())
+ + QString::fromLatin1("\"");
+
+ if (!msg_map.notification->tag.empty())
+ msg += QString::fromLatin1(",\"tag\":\"") + QString::fromLatin1(msg_map.notification->tag.c_str()) +
+ QString::fromLatin1("\"");
+
+ if (!msg_map.notification->color.empty())
+ msg += QString::fromLatin1(",\"color\":\"") + QString::fromLatin1(
+ msg_map.notification->color.c_str()) + QString::fromLatin1("\"");
+
+ if (!msg_map.notification->sound.empty())
+ msg += QString::fromLatin1(",\"sound\":\"") + QString::fromLatin1(
+ msg_map.notification->sound.c_str()) + QString::fromLatin1("\"");
+
+ if (!msg_map.notification->click_action.empty())
+ msg += QString::fromLatin1(",\"click_action\":\"") + QString::fromLatin1(
+ msg_map.notification->click_action.c_str()) + QString::fromLatin1("\"");
+
+ msg += QString::fromLatin1("}");
+
+ dotSign = true;
+ }
+ if (msg_map.data.size() > 0) {
+ if (dotSign) msg += QString::fromLatin1(",");
+
+ dotSign = false;
+
+ msg += QString::fromLatin1("\"data\":{");
+
+ for (const auto &field : msg_map.data) {
+
+ if (!field.first.empty() && !field.second.empty()) {
+ if (dotSign) msg += QString::fromLatin1(",");
+
+ msg += QString::fromLatin1("\"") + QString::fromStdString(field.first) + QString::fromLatin1("\":")
+ + QString::fromStdString(field.second);
+
+ dotSign = true;
+ }
+ }
+ msg += QString::fromLatin1("}");
+ }
+ msg += QString::fromLatin1("}");
+ return msg;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::flushMessageQueue
+ * \return
+ */
+bool QCloudMessagingFirebaseClient::flushMessageQueue()
+{
+ if (!d->m_last_firebase_message.message_id.empty()) {
+ emit messageReceived(clientId(), parseMessage(d->m_last_firebase_message).toUtf8());
+ }
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::subscribeToChannel
+ * \param channel
+ * \return
+ */
+bool QCloudMessagingFirebaseClient::subscribeToChannel(const QString &channel)
+{
+ ::firebase::messaging::Subscribe(channel.toLatin1());
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::unsubscribeFromChannel
+ * \param channel
+ * \return
+ */
+bool QCloudMessagingFirebaseClient::unsubscribeFromChannel(const QString &channel)
+{
+ ::firebase::messaging::Unsubscribe(channel.toLatin1());
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::clientToken
+ * \return
+ */
+QString QCloudMessagingFirebaseClient::clientToken()
+{
+ return d->m_token;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseClient::clientUuid
+ * \return
+ */
+QString QCloudMessagingFirebaseClient::clientUuid()
+{
+ return d->m_token;
+}
+
+// Provide link to main - which will be in the app using this service.
+extern int main(int argc, char *argv[]);
+
+QT_END_NAMESPACE
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.h b/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.h
new file mode 100644
index 0000000..4679c0a
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCloudMessagingFirebaseClient_H
+#define QCloudMessagingFirebaseClient_H
+
+#include <QtCloudMessaging/QtCloudMessaging>
+#include "firebase/app.h"
+#include "firebase/messaging.h"
+#include "firebase/util.h"
+#include <QObject>
+#include <QVariantMap>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingFirebaseClientPrivate;
+
+class QCloudMessagingFirebaseClient: public QCloudMessagingClient, firebase::messaging::Listener
+{
+
+public:
+
+ explicit QCloudMessagingFirebaseClient(QObject *parent = nullptr);
+
+ ~QCloudMessagingFirebaseClient();
+
+ //! Firebase virtual functions
+
+ virtual void OnMessage(const ::firebase::messaging::Message &message) override;
+
+ virtual void OnTokenReceived(const char *token) override;
+
+
+ //! Qt Cloud messaging client virtual functions
+
+ virtual bool flushMessageQueue() override;
+
+ virtual QString connectClient(const QString &clientId,
+ const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual void disconnectClient() override;
+
+ virtual bool subscribeToChannel(const QString &channel) override;
+
+ virtual bool unsubscribeFromChannel(const QString &channel) override;
+
+ QString clientToken() override;
+
+ QString clientUuid();
+
+ bool sendMessage(const QByteArray &msg,
+ const QString &clientToken = QString(),
+ const QString &channel = QString()) override;
+
+ void cloudMessageReceived(const QString &client,
+ const QByteArray &message) override;
+
+ void setClientToken(const QString &uuid) override;
+
+private:
+ QString parseMessage(firebase::messaging::Message msg_map);
+
+ QScopedPointer<QCloudMessagingFirebaseClientPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCloudMessagingFirebaseClient_H
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient_p.h b/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient_p.h
new file mode 100644
index 0000000..70f0d8d
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaseclient_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLOUDMESSAGINGFIREBASECLIENT_P_H
+#define QCLOUDMESSAGINGFIREBASECLIENT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qtcloudmessagingglobal.h>
+#include "qcloudmessagingfirebaseclient.h"
+#include "qcloudmessagingfirebaserest.h"
+#include "firebase/app.h"
+#include "firebase/messaging.h"
+#include "firebase/util.h"
+
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessaging;
+
+class QCloudMessagingFirebaseClientPrivate
+{
+public:
+ QCloudMessagingFirebaseClientPrivate()
+ {
+ }
+
+ ~QCloudMessagingFirebaseClientPrivate() = default;
+
+ QString m_uuid;
+ QString m_token;
+
+ ::firebase::App *m_firebaseApp;
+ ::firebase::ModuleInitializer m_firebase_initializer;
+ ::firebase::messaging::Message m_last_firebase_message;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGFIREBASECLIENT_P_H
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.cpp b/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.cpp
new file mode 100644
index 0000000..065a00a
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcloudmessagingfirebaseprovider.h"
+#include "qcloudmessagingfirebaseprovider_p.h"
+
+#include "firebase/app.h"
+#include "firebase/messaging.h"
+#include "firebase/util.h"
+
+QT_BEGIN_NAMESPACE
+
+static QCloudMessagingFirebaseProvider *m_FirebaseServiceProvider;
+
+/*!
+ * \brief LogMessage
+ * \param format
+ */
+void LogMessage(const char *format, ...)
+{
+ static const int kLineBufferSize = 100;
+ char buffer[kLineBufferSize + 2];
+
+ va_list list;
+ va_start(list, format);
+ int string_len = vsnprintf(buffer, kLineBufferSize, format, list);
+ string_len = string_len < kLineBufferSize ? string_len : kLineBufferSize;
+ // append a linebreak to the buffer:
+ buffer[string_len] = '\n';
+ buffer[string_len + 1] = '\0';
+ va_end(list);
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::QCloudMessagingFirebaseProvider
+ */
+QCloudMessagingFirebaseProvider::QCloudMessagingFirebaseProvider(QObject *parent) :
+ QCloudMessagingProvider(parent),
+ d(new QCloudMessagingFirebaseProviderPrivate)
+{
+ m_FirebaseServiceProvider = this;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::~QCloudMessagingFirebaseProvider
+ */
+QCloudMessagingFirebaseProvider::~QCloudMessagingFirebaseProvider()
+{
+ deregisterProvider();
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::registerProvider
+ * \param providerId
+ * \param parameters
+ * \return
+ */
+bool QCloudMessagingFirebaseProvider::registerProvider(const QString &providerId,
+ const QVariantMap &parameters)
+{
+
+ QCloudMessagingProvider::registerProvider(providerId, parameters);
+
+ setServiceState(QtCloudMessagingProviderRegistered);
+
+ // Get the API key for HTTP communication
+ d->m_key = parameters.value(QStringLiteral("SERVER_API_KEY")).toString();
+ d->m_restInterface.setAuthKey(d->m_key);
+
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::deregisterProvider
+ * \return
+ */
+void QCloudMessagingFirebaseProvider::deregisterProvider()
+{
+ ::firebase::messaging::Terminate();
+ QCloudMessagingProvider::deregisterProvider();
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::setServiceState
+ * \param service_mode
+ * \return
+ */
+QCloudMessagingProvider::CloudMessagingProviderState QCloudMessagingFirebaseProvider::setServiceState(QCloudMessagingProvider::CloudMessagingProviderState service_mode)
+{
+ if (getServiceState() != QtCloudMessagingProviderNotRegistered) {
+ return QCloudMessagingProvider::setServiceState(service_mode);
+ }
+
+ return QCloudMessagingProvider::QtCloudMessagingProviderNotRegistered;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::connectClient
+ * \param clientId
+ * \param parameters
+ * \return
+ */
+QString QCloudMessagingFirebaseProvider::connectClient(const QString &clientId,
+ const QVariantMap &parameters)
+{
+ if (!providerId().isEmpty()) {
+ QCloudMessagingFirebaseClient *serviceClient = new QCloudMessagingFirebaseClient();
+ QString retval = connectClientToProvider(clientId, parameters, serviceClient);
+ return retval;
+ }
+ return QString();
+}
+
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::sendMessage
+ * \param msg
+ * \param clientId
+ * \param send_to_device
+ * \param send_to_channel
+ * \return
+ */
+bool QCloudMessagingFirebaseProvider::sendMessage(const QByteArray &msg, const QString &clientId,
+ const QString &clientToken, const QString &channel)
+{
+ //! Sending to internal client
+ if (!clientId.isEmpty() && clientToken.isEmpty() && channel.isEmpty()) {
+
+ if (client(clientId)) {
+ client(clientId)->messageReceived(clientId, msg);
+ return true;
+ }
+ } else
+ //! Sending to device or channel out there, by using the client (e.g. in mobile)
+ if (!clientId.isEmpty() && (!clientToken.isEmpty() && !channel.isEmpty())) {
+
+ if (client(clientId)) {
+ return client(clientId)->sendMessage(msg, clientToken, channel);
+ }
+
+ } else {
+ //! Sending via rest api interface (SERVER side)
+ if (!channel.isEmpty())
+ return d->m_restInterface.sendBroadcast(channel, msg);
+
+ if (!clientToken.isEmpty())
+ return d->m_restInterface.sendToDevice(clientToken, msg);
+ }
+ return false;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::disconnectClient
+ * \param clientId
+ * \param parameters
+ * \return
+ */
+void QCloudMessagingFirebaseProvider::disconnectClient(const QString &clientId,
+ const QVariantMap &parameters)
+{
+ return QCloudMessagingProvider::disconnectClient(clientId, parameters);
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::clients
+ * \return
+ */
+QMap <QString, QCloudMessagingClient *> *QCloudMessagingFirebaseProvider::clients()
+{
+ return QCloudMessagingProvider::clients();
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::setClientToken
+ * \param client
+ * \param uuid
+ */
+void QCloudMessagingFirebaseProvider::setClientToken(const QString &clientId, const QString &uuid)
+{
+ client(clientId)->setClientToken(uuid);
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::cloudMessageReceived
+ * \param client
+ * \param message
+ */
+void QCloudMessagingFirebaseProvider::cloudMessageReceived(const QString &clientId,
+ const QByteArray &message)
+{
+ client(clientId)->messageReceived(clientId, message);
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::subscribeToChannel
+ * \param channel
+ * \param clientId
+ * \return
+ */
+bool QCloudMessagingFirebaseProvider::subscribeToChannel(const QString &channel,
+ const QString &clientId)
+{
+ if (!clientId.isEmpty())
+ return client(clientId)->subscribeToChannel(channel);
+
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::unsubscribeFromChannel
+ * \param channel
+ * \param clientId
+ * \return
+ */
+bool QCloudMessagingFirebaseProvider::unsubscribeFromChannel(const QString &channel,
+ const QString &clientId)
+{
+ if (!clientId.isEmpty())
+ return client(clientId)->unsubscribeFromChannel(channel);
+
+ return true;
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::clientToken
+ * \param clientId
+ * \return
+ */
+QString QCloudMessagingFirebaseProvider::clientToken(const QString &clientId)
+{
+ return client(clientId)->clientToken();
+}
+
+/*!
+ * \brief QCloudMessagingFirebaseProvider::remoteClients
+ * \return
+ */
+bool QCloudMessagingFirebaseProvider::remoteClients()
+{
+ return false;
+}
+
+QT_END_NAMESPACE
+
+
+
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.h b/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.h
new file mode 100644
index 0000000..30b3ce0
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FIREBASESERVICE_H
+#define FIREBASESERVICE_H
+
+#include <QtCloudMessaging/QtCloudMessaging>
+#include <QtCloudMessaging/qcloudmessagingrestapi.h>
+#include <QtCloudMessagingFirebase/qcloudmessagingfirebaseclient.h>
+#include "firebase/app.h"
+#include "firebase/messaging.h"
+#include "firebase/util.h"
+#include <QObject>
+#include <QVariantMap>
+#include <QByteArray>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessagingFirebaseProviderPrivate;
+
+class QCloudMessagingFirebaseProvider : public QCloudMessagingProvider
+{
+ Q_OBJECT
+public:
+
+ explicit QCloudMessagingFirebaseProvider(QObject *parent = nullptr);
+
+ ~QCloudMessagingFirebaseProvider();
+
+ virtual bool registerProvider(const QString &providerId, const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual void deregisterProvider() override;
+
+ virtual QCloudMessagingProvider::CloudMessagingProviderState setServiceState(
+ QCloudMessagingProvider::CloudMessagingProviderState state) override;
+
+ virtual QString connectClient(const QString &clientId, const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual void disconnectClient(const QString &clientId, const QVariantMap &parameters = QVariantMap()) override;
+
+ virtual bool sendMessage(const QByteArray &msg, const QString &clientId = QString(),
+ const QString &clientToken = QString(),
+ const QString &channel = QString()) override;
+
+
+ virtual bool subscribeToChannel(const QString &channel, const QString &clientId = QString()) override;
+
+ virtual bool unsubscribeFromChannel(const QString &channel, const QString &clientId = QString()) override;
+
+ QMap <QString, QCloudMessagingClient *> *clients() override;
+
+ // Firefox server API tbd.
+ bool remoteClients() override;
+
+ QString clientToken(const QString &clientId);
+
+ void setClientToken(const QString &clientId, const QString &uuid);
+
+
+private Q_SLOTS:
+ void cloudMessageReceived(const QString &clientId, const QByteArray &message);
+
+private:
+ QScopedPointer<QCloudMessagingFirebaseProviderPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // FIREBASESERVICE_H
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider_p.h b/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider_p.h
new file mode 100644
index 0000000..e64f452
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaseprovider_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLOUDMESSAGINGFIREBASEPROVIDER_P_H
+#define QCLOUDMESSAGINGFIREBASEPROVIDER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include "qcloudmessagingfirebaseprovider.h"
+#include "qcloudmessagingfirebaserest.h"
+
+QT_BEGIN_NAMESPACE
+
+class QCloudMessaging;
+
+class QCloudMessagingFirebaseProviderPrivate
+{
+public:
+ QCloudMessagingFirebaseProviderPrivate()
+ {
+ }
+
+ ~QCloudMessagingFirebaseProviderPrivate() = default;
+
+ QStringList m_channels;
+ QString m_key;
+ FirebaseRestServer m_restInterface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGFIREBASEPROVIDER_P_H
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaserest.cpp b/src/cloudmessagingfirebase/qcloudmessagingfirebaserest.cpp
new file mode 100644
index 0000000..df27b6a
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaserest.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCloudMessaging/QtCloudMessaging>
+#include "qtcloudmessagingglobal.h"
+#include "qcloudmessagingfirebaserest.h"
+
+#include <QByteArray>
+
+/* REST API INTERFACE */
+const QString SERVER_ADDRESS = QStringLiteral("https://fcm.googleapis.com/fcm/send");
+
+/*!
+ * \brief FirebaseRestServer::sendToDevice
+ * \param token
+ * \param data
+ * \return
+ */
+bool FirebaseRestServer::sendToDevice(const QString &token, const QByteArray &data)
+{
+ QString data_to_send = "{\"to\":\"" + token + "\",\"data\":" + QString::fromUtf8(data) + "}";
+ QString url = SERVER_ADDRESS;
+ QUrl uri(url);
+ m_auth_key = "key=" + m_auth_key;
+ QNetworkRequest request(uri);
+ QString authHeader = QString::fromLatin1("Authorization");
+ request.setHeader(QNetworkRequest::ContentTypeHeader, QString::fromLatin1("application/json"));
+ request.setRawHeader(authHeader.toLocal8Bit(), m_auth_key.toLocal8Bit());
+
+ return sendMessage(POST_MSG,
+ REQ_SEND_BROADCAST_DATA_TO_CHANNEL,
+ request,
+ data_to_send.toUtf8(),
+ true,
+ QString());
+}
+
+/*!
+ * \brief FirebaseRestServer::sendBroadcast
+ * \param channel
+ * \param data
+ * \return
+ */
+bool FirebaseRestServer::sendBroadcast(const QString &channel, const QByteArray &data)
+{
+ QString mod_data = QString::fromUtf8(data);
+ if (mod_data[0] == '{')
+ mod_data.remove(0, 1);
+ if (mod_data[mod_data.length() - 1] == '}')
+ mod_data.remove(mod_data.length() - 1, 1);
+
+ QString data_to_send = "{\"to\":\"/topics/" + channel + "\"," + mod_data + "}";
+
+ QString url = SERVER_ADDRESS;
+ QUrl uri(url);
+ QString auth = "key=" + m_auth_key;
+ QNetworkRequest request(uri);
+ QString authHeader = QString::fromLatin1("Authorization");
+ request.setHeader(QNetworkRequest::ContentTypeHeader, QString::fromLatin1("application/json"));
+ request.setRawHeader(authHeader.toLocal8Bit(), auth.toLocal8Bit());
+
+ return sendMessage(POST_MSG,
+ REQ_SEND_BROADCAST_DATA_TO_CHANNEL,
+ request,
+ data_to_send.toUtf8(),
+ true,
+ QString());
+
+}
+
+/*!
+ * \brief FirebaseRestServer::xmlHttpRequestReply
+ * \param reply
+ */
+void FirebaseRestServer::xmlHttpRequestReply(QNetworkReply *reply)
+{
+ getNetworkManager()->disconnect(SIGNAL(finished(QNetworkReply *)));
+ QString m_msg_uuid = reply->property("uuid").toString();
+ int req_id = reply->property("req_id").toInt();
+
+ if (reply->error()) {
+ emit xmlHttpRequestError(reply->errorString());
+
+ }
+
+ // Ok message, lets proceed.
+
+ QByteArray data(reply->readAll());
+
+ emit xmlHttpRequestReplyData(data);
+
+ reply->deleteLater();
+ clearMessage(m_msg_uuid);
+}
diff --git a/src/cloudmessagingfirebase/qcloudmessagingfirebaserest.h b/src/cloudmessagingfirebase/qcloudmessagingfirebaserest.h
new file mode 100644
index 0000000..152bd9e
--- /dev/null
+++ b/src/cloudmessagingfirebase/qcloudmessagingfirebaserest.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QCLOUDMESSAGINGFIREBASEREST_H
+#define QCLOUDMESSAGINGFIREBASEREST_H
+
+#include <QtCloudMessaging/QtCloudMessaging>
+#include <QtCloudMessaging/qtcloudmessagingglobal.h>
+#include <QtCloudMessaging/qcloudmessagingrestapi.h>
+#include <QtCloudMessagingFirebase/qcloudmessagingfirebaseclient.h>
+
+QT_BEGIN_NAMESPACE
+
+class FirebaseRestServer : public QCloudMessagingRestApi
+{
+ Q_OBJECT
+public:
+ enum FirebaseRESTRequests {
+ REQ_NO_REQ,
+ REQ_GET_DEVICES_BY_CUSTOMER_ID,
+ REQ_GET_ALL_DEVICES,
+ REQ_SEND_DATA_TO_DEVICE,
+ REQ_SEND_BROADCAST_DATA_TO_CHANNEL,
+ REQ_GET_DEVICE_INFO
+ };
+ Q_ENUM(FirebaseRESTRequests)
+
+ void setAuthKey(const QString &key)
+ {
+ m_auth_key = key;
+ }
+
+ // Response function
+ void xmlHttpRequestReply(QNetworkReply *reply);
+
+ bool sendToDevice(const QString &token, const QByteArray &data);
+ bool sendBroadcast(const QString &channel, const QByteArray &data);
+
+Q_SIGNALS:
+ void xmlHttpRequestReplyData(const QByteArray &data);
+
+private:
+ QString m_auth_key;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCLOUDMESSAGINGFIREBASEREST_H
diff --git a/src/src.pro b/src/src.pro
new file mode 100644
index 0000000..8f68f6c
--- /dev/null
+++ b/src/src.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+SUBDIRS = cloudmessaging
+
+embedded-kaltiot { SUBDIRS += cloudmessagingembeddedkaltiot }
+firebase { SUBDIRS += cloudmessagingfirebase }
+
+DISTFILES += \
+ ../README.md
diff --git a/sync.profile b/sync.profile
new file mode 100644
index 0000000..2e9008b
--- /dev/null
+++ b/sync.profile
@@ -0,0 +1,7 @@
+%modules = ( # path to module name map
+ "QtCloudMessaging" => "$basedir/src/cloudmessaging",
+ "QtCloudMessagingEmbeddedKaltiot" => "$basedir/src/cloudmessagingembeddedkaltiot",
+ "QtCloudMessagingFirebase" => "$basedir/src/cloudmessagingfirebase"
+);
+%moduleheaders = ( # restrict the module headers to those found in relative path
+);
diff --git a/tests/tests.pro b/tests/tests.pro
new file mode 100644
index 0000000..4e68796
--- /dev/null
+++ b/tests/tests.pro
@@ -0,0 +1,15 @@
+QT += testlib cloudmessaging
+QT -= gui
+
+TARGET = tst_qcloudmessaging
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+DEFINES += QT_DEPRECATED_WARNINGS
+
+SOURCES += \
+ tst_qcloudmessaging.cpp
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/tst_qcloudmessaging.cpp b/tests/tst_qcloudmessaging.cpp
new file mode 100644
index 0000000..6dd4f1f
--- /dev/null
+++ b/tests/tst_qcloudmessaging.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCloudMessaging module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-COMM$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+#include <QtTest>
+
+class QCloudmessaging : public QObject
+{
+ Q_OBJECT
+
+public:
+ QCloudmessaging();
+
+private Q_SLOTS:
+ void initTestCase();
+ void cleanupTestCase();
+ void testCase1();
+};
+
+QCloudmessaging::QCloudmessaging()
+{
+}
+
+void QCloudmessaging::initTestCase()
+{
+}
+
+void QCloudmessaging::cleanupTestCase()
+{
+}
+
+void QCloudmessaging::testCase1()
+{
+}
+
+QTEST_APPLESS_MAIN(QCloudmessaging)
+
+#include "tst_qcloudmessaging.moc"