diff options
Diffstat (limited to 'src/cloudmessagingembeddedkaltiot')
10 files changed, 1757 insertions, 0 deletions
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 ¶meters) +{ + // 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 ¶meters = 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 ¶meters) +{ + 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 ¶meters) +{ + 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 ¶meters) +{ + 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 ¶meters = QVariantMap()) override; + + virtual void deregisterProvider() override; + + virtual QString connectClient(const QString &clientId, + const QVariantMap ¶meters = QVariantMap()) override; + + virtual void disconnectClient(const QString &clientId, + const QVariantMap ¶meters = 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 |