2 Коміти fb523328b2 ... 3969a187dc

Автор SHA1 Опис Дата
  舍得 3969a187dc 升级mqtt模块,并增加返回通路,未知原因未测试通过。 1 рік тому
  舍得 efe3d71eb6 更改逻辑:有报警时上报,报警取消上报取消;不连续上报 1 рік тому

+ 5 - 5
AlarmRecognition/Module.cpp

@@ -165,10 +165,8 @@ void Module::OnSubData(std::string table,std::string val)
         }
 
         // new alarm
-        if( nStatus == 1 && m_mpRangeConfig[szDataName].nStatus == 0)
+        if( nStatus != m_mpRangeConfig[szDataName].nStatus )
         {
-            m_mpRangeConfig[szDataName].nStatus = 1;
-
             std::vector<std::string>::iterator itr;
             for( itr = m_szOutputs.begin(); itr != m_szOutputs.end(); ++itr )
             {
@@ -176,8 +174,8 @@ void Module::OnSubData(std::string table,std::string val)
                 {
                     QString szJson;
                     szJson += "{";
-                    szJson += QString("\"occurTime\":\"%1\",").arg(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"));
-                    szJson += QString("\"status\":0,");
+                    szJson += QString("\"occurTime\":\"%1\",").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"));
+                    szJson += QString("\"status\":%1,").arg(nStatus != 0 ? 0 : 2);
                     szJson += QString("\"content\":\"%1 %2\",").arg(szDataName.c_str()).arg(m_mpRangeConfig[szDataName].szOperator.c_str());
                     szJson += QString("\"alarmRuleId\":\"%1\",").arg(m_mpRangeConfig[szDataName].alarmRuleId.c_str());
                     szJson += QString("\"alarmRuleVersion\":%1,").arg(m_mpRangeConfig[szDataName].alarmRuleVersion);
@@ -187,6 +185,8 @@ void Module::OnSubData(std::string table,std::string val)
                     m_pDataConsumer->OnData(*itr,QVariant(szJson));
                 }
             }
+
+            m_mpRangeConfig[szDataName].nStatus = nStatus;
         }
     }
     m_objDataLock.unlock();

+ 49 - 3
EngineAlarm/DataEngine.cpp

@@ -47,7 +47,7 @@ void DataEngine::OnData(std::string name,QVariant val)
     }
 }
 
-void DataEngine::sltSubData(const std::string topic, const std::string msg)
+void DataEngine::sltSubData_td(const std::string topic, const std::string msg)
 {
     if(m_mpDevControler.find(topic) == m_mpDevControler.end())
     {
@@ -65,6 +65,10 @@ void DataEngine::sltSubData(const std::string topic, const std::string msg)
     }
 }
 
+void DataEngine::sltSubData_mqtt(const std::string topic, const std::string msg)
+{
+}
+
 void loadConfig(std::string szFile,Config& config)
 {
     std::string cfg = loadContent(szFile);
@@ -99,7 +103,7 @@ void DataEngine::startup_DataAlarm(DeviceInfo di)
         ditem.ModuleInfo.vSettings.push_back(*itr);
         DeviceController* pControler = new DeviceController();
         pControler->regConsumer(this);
-        pControler->CreateDevice(/*m_pTDengine,*/ditem);
+        pControler->CreateDevice(ditem);
 
         lstTopics.push_back(table);
         m_mpDevControler[table].push_back(pControler);
@@ -142,6 +146,33 @@ void DataEngine::startup_CommAlarm(DeviceInfo di)
     }
 }
 
+void DataEngine::startup_AlarmMgr(DeviceInfo di)
+{
+    DeviceController* pControler = new DeviceController();
+    pControler->regConsumer(this);
+    pControler->CreateDevice(di);
+
+    std::list<std::string> lstTopics;
+    std::vector<Setting>::iterator itr;
+    for( itr = di.ModuleInfo.vSettings.begin(); itr != di.ModuleInfo.vSettings.end(); ++itr )
+    {
+        Setting oSet = *itr;
+        QJsonDocument jsonDoc(QJsonDocument::fromJson(oSet.qValue.toString().toLocal8Bit()));
+        QJsonArray json = jsonDoc.array();
+        for(auto i : json)
+        {
+            std::string topic = i.toString().toLocal8Bit().toStdString();
+
+            lstTopics.push_back(topic);
+            m_mpDevControler[topic].push_back(pControler);
+        }
+    }
+    if( lstTopics.begin() != lstTopics.end())
+    {
+        m_pMqtt->Subscribe(lstTopics);
+    }
+}
+
 void DataEngine::Startup()
 {
     // merge file name
@@ -183,10 +214,11 @@ void DataEngine::Startup()
     m_pTDengine = new TDAgent();
     m_pTDengine->Connect(mpConfig["tdengine"]);     // td
     qRegisterMetaType<std::string>("std::string");
-    connect(m_pTDengine,SIGNAL(sigEvent(const std::string, const std::string)),this,SLOT(sltSubData(const std::string, const std::string)));
+    connect(m_pTDengine,SIGNAL(sigEvent(const std::string, const std::string)),this,SLOT(sltSubData_td(const std::string, const std::string)));
 
     m_pMqtt = new MQTTAgent();
     m_pMqtt->Connect(mpConfig["mqtt"]);             // mqtt
+    connect(m_pMqtt,SIGNAL(sigEvent(const std::string, const std::string)),this,SLOT(sltSubData_mqtt(const std::string, const std::string)));
 
     // server.id
     DeviceManagerProxy dm(m_pRedis);
@@ -195,5 +227,19 @@ void DataEngine::Startup()
 
     DeviceInfo ca = dm.loadCommAlarm("alarmruledevicestatus", "plugins/CommRecognition.dll");
     startup_CommAlarm(ca);
+
+    /* 这里是想向mqtt订阅,在另外的模块里,实现对数据库操作
+    std::list<std::string> lstTopics;
+    DeviceInfo am = dm.loadAlarmMgr("alarmrule", "plugins/AlarmMgr.dll");
+    std::list<DataItem>::iterator itr;
+    for( itr = da.ModuleInfo.Properties.begin(); itr != da.ModuleInfo.Properties.end(); ++itr )
+    {
+        lstTopics.push_back(da.ModuleInfo.Code + "_" + itr->Code);
+    }
+    if( lstTopics.begin() != lstTopics.end())
+    {
+        m_pMqtt->Subscribe(lstTopics);
+    }
+    */
 }
 

+ 3 - 1
EngineAlarm/DataEngine.h

@@ -23,11 +23,13 @@ private:
              std::list<DeviceController*>>  m_mpDevControler;   // 订阅列表
 
 public slots:
-    void sltSubData(const std::string, const std::string);
+    void sltSubData_td(const std::string, const std::string);
+    void sltSubData_mqtt(const std::string, const std::string);
 
 private:
     void startup_DataAlarm(DeviceInfo di);
     void startup_CommAlarm(DeviceInfo di);
+    void startup_AlarmMgr(DeviceInfo di);
 
 public:
     virtual void OnData(std::string name,QVariant val);

+ 2 - 1
EngineAlarm/EngineAlarm.pro

@@ -1,4 +1,4 @@
-QT = core
+QT = core network
 QT -= gui
 
 CONFIG += c++17 cmdline
@@ -15,6 +15,7 @@ else{
 
 INCLUDEPATH += .
 INCLUDEPATH += ../include
+INCLUDEPATH += ../include/qmqtt
 
 LIBS += -L$$PWD/../bin/ -lRedisAgent
 LIBS += -L$$PWD/../bin/ -lTDAgent

+ 56 - 38
MQTTAgent/MQTTAgent.cpp

@@ -1,73 +1,91 @@
 #include "MQTTAgent.h"
-#include <QMqtt.h>
+#include <qmqtt.h>
 #include <QtCore/QUuid>
 
-MQTTAgent* g_pThis;
+/*
+class ForReason_MustDoThis : public QObject
+{
+    Q_OBJECT
+public:
+    ForReason_MustDoThis()
+        :QObject(){
+        };
+
+public slots:
+};
+ForReason_MustDoThis    g_objMust;
+*/
 
-QMQTT::Client*  m_pMqtt;
+QMQTT::Client*          g_pMqtt;
 MQTTAgent::MQTTAgent()
 	: QObject()
 {
-    m_pMqtt = nullptr;
-    g_pThis = this;
+    g_pMqtt = nullptr;
+    //g_pThis = this;
+    //shareCbFunc = std::bind(&MQTTAgent::SubCB,this,std::placeholders::_1,std::placeholders::_2);
+
+    g_pMqtt = new QMQTT::Client();
+    connect(g_pMqtt, &QMQTT::Client::connected, []{
+        qDebug()<< __FILE__ << __LINE__ << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "connected";
+    });
+    connect(g_pMqtt, &QMQTT::Client::disconnected, []{
+        qDebug()<< __FILE__ << __LINE__ << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "disconnect";
+    });
+
+    bool b = connect(g_pMqtt, &QMQTT::Client::received, this, &MQTTAgent::onReceived);
+    //bool b = connect(g_pMqtt, SIGNAL(QMQTT::Client::received), this, SLOT(onReceived));
+    qDebug() << b;
 }
 
 MQTTAgent::~MQTTAgent()
 {
-    if( m_pMqtt != nullptr )
+    if( g_pMqtt != nullptr )
     {
-        delete m_pMqtt;
+        g_pMqtt->disconnected();
+        g_pMqtt->deleteLater();
     }
 }
 
-void onReceived(const QMQTT::Message& message)
+void MQTTAgent::onReceived(const QMQTT::Message& message)
 {
-    emit g_pThis->sigEvent((char*)message.topic().toLocal8Bit().toStdString().c_str(), (char*)message.payload().toStdString().c_str());
-    //qDebug() << "recv" << message.topic() << message.payload();
+    qDebug() << ":onReceived";
+    int x = 0;
+ //   emit sigEvent((char*)message.topic().toLocal8Bit().toStdString().c_str(), (char*)message.payload().toStdString().c_str());
 }
 
 bool MQTTAgent::Connect(tagSetup ts)
 {
-    m_pMqtt = new QMQTT::Client();
-
-    connect(m_pMqtt, &QMQTT::Client::connected, []{
-        qDebug()<< __FILE__ << __LINE__ << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "connected";
-    });
-    connect(m_pMqtt, &QMQTT::Client::disconnected, []{
-        qDebug()<< __FILE__ << __LINE__ << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "disconnect";
-    });
-    connect(m_pMqtt, &QMQTT::Client::received, this, &onReceived);
+    g_pMqtt->setHostName(ts.addr.c_str());
+    //g_pMqtt->setHostName("mq.tongxinmao.com"); //18830
+    //g_pMqtt->setHostName("www.kjxry.cn");
+    g_pMqtt->setPort(ts.port);
+    g_pMqtt->setKeepAlive(60);
+    g_pMqtt->setClientId("C002");//QUuid::createUuid().toString()); //唯一id, 相同id不能同时连接
+    g_pMqtt->setUsername(ts.user.c_str());
 
-    m_pMqtt->setHostName(ts.addr.c_str());
-    //m_pMqtt->setHostName("mq.tongxinmao.com"); //18830
-    //m_pMqtt->setHostName("www.kjxry.cn");
-    m_pMqtt->setPort(ts.port);
-    m_pMqtt->setKeepAlive(60);
-    m_pMqtt->setClientId(QUuid::createUuid().toString()); //唯一id, 相同id不能同时连接
-    m_pMqtt->setUsername(ts.user.c_str());
-    m_pMqtt->setPassword(ts.password.c_str());
+    QString pwd = ts.password.c_str();
+    g_pMqtt->setPassword(pwd.toUtf8());
 
-    m_pMqtt->setAutoReconnect(true); //开启自动重连
-    m_pMqtt->setCleanSession(true); //非持久化连接,上线时,将不再关心之前所有的订阅关系以及离线消息
+    g_pMqtt->setAutoReconnect(true); //开启自动重连
+    g_pMqtt->setCleanSession(true); //非持久化连接,上线时,将不再关心之前所有的订阅关系以及离线消息
 
-    m_pMqtt->setVersion(QMQTT::V3_1_1);
-    //qDebug()<< __FILE__ << __LINE__<< "ver" << m_pMqtt->version();
-
-    m_pMqtt->connectToHost();
+    g_pMqtt->setVersion(QMQTT::V3_1_1);
+    //qDebug()<< __FILE__ << __LINE__<< "ver" << g_pMqtt->version();
 
+    g_pMqtt->connectToHost();
     return true;
 }
 
 bool MQTTAgent::Subscribe(std::list<std::string> topics)
 {
-    bool ret = true;
     std::list<std::string>::iterator itr;
     for (itr = topics.begin(); itr != topics.end(); ++itr)
     {
-        m_pMqtt->subscribe(itr->c_str(), 1);
+        QString topic = itr->c_str();
+        g_pMqtt->subscribe(topic, 1);
     }
 
-	return ret;
+    return true;
 }
 
 void MQTTAgent::Publish(std::string szKey,QVariant v)
@@ -102,9 +120,9 @@ void MQTTAgent::Publish(std::string szKey,QVariant v)
     message.setTopic(szKey.c_str());
     message.setPayload(v.toByteArray());
     message.setRetain(true); //保留最后一条数据
-    if( m_pMqtt != nullptr )
+    if( g_pMqtt != nullptr )
     {
-        m_pMqtt->publish(message);
+        g_pMqtt->publish(message);
         //qDebug() << __FILE__ << __LINE__ << szKey.c_str() << " " << v.toString();
     }
 }

+ 5 - 14
MQTTAgent/MQTTAgent.h

@@ -1,32 +1,23 @@
 #pragma once
 
-//#include "BaseModule.h"
-//#include "libaray_symbols.h"
 #include "MWareInterface.h"
-#include <QtNetwork/QUdpSocket>
+#include <qmqtt.h>
 #include <QtCore/QVariant>
 #include <QtCore/QObject>
 
-class MQTTAgent : public QObject,public EventSubInterface//,public BaseModule
+//using MQTTCbFunc = std::function<void(const std::string, const std::string)>;
+class MQTTAgent : public QObject
 {
 	Q_OBJECT
 public:
     MQTTAgent();
     ~MQTTAgent();
 
-private:
-//    virtual void Setup(ModuleInfo mi) {};
-//    virtual void regConsumer(DataConsumer* pDC) {};
-//    virtual bool isInheritedFrom(std::string tp) {return false;};
-//    virtual void OnSubData(std::string name,std::string val) {};
-
-private:
-
 signals:
     void sigEvent(const std::string topic, const std::string msg);
 
-private:
-    void SubCB(const std::string topic, const std::string msg){};
+public slots:
+    void onReceived(const QMQTT::Message& message);
 
 public:
     bool Connect(tagSetup ts);

+ 1 - 0
MQTTAgent/MQTTAgent.pro

@@ -14,6 +14,7 @@ else{
 DESTDIR = $$PWD/../bin
 }
 
+INCLUDEPATH += ../include/qmqtt
 INCLUDEPATH += ../include
 LIBS += $$PWD/../bin/Qt5Qmqtt.dll
 #LIBS += -L$$PWD/lib/ -lQt5Qmqtt

+ 38 - 0
include/qmqtt/qmqtt.h

@@ -0,0 +1,38 @@
+/*
+ * qmqtt.h - qmqtt library heaer
+ *
+ * Copyright (c) 2013  Ery Lee <ery.lee at gmail dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of mqttc nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef QMQTT_H
+#define QMQTT_H
+
+#include <qmqtt_message.h>
+#include <qmqtt_client.h>
+
+#endif // QMQTT_H

+ 286 - 0
include/qmqtt/qmqtt_client.h

@@ -0,0 +1,286 @@
+/*
+ * qmqtt_client.h - qmqtt client header
+ *
+ * Copyright (c) 2013  Ery Lee <ery.lee at gmail dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of mqttc nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef QMQTT_CLIENT_H
+#define QMQTT_CLIENT_H
+
+#include <qmqtt_global.h>
+
+#include <QObject>
+#include <QString>
+#include <QHostAddress>
+#include <QByteArray>
+#include <QAbstractSocket>
+#include <QScopedPointer>
+#include <QList>
+
+#ifdef QT_WEBSOCKETS_LIB
+#include <QWebSocket>
+#endif // QT_WEBSOCKETS_LIB
+
+#ifndef QT_NO_SSL
+#include <QSslConfiguration>
+QT_FORWARD_DECLARE_CLASS(QSslError)
+#endif // QT_NO_SSL
+
+#ifndef Q_ENUM_NS
+#define Q_ENUM_NS(x)
+#endif // Q_ENUM_NS
+
+namespace QMQTT {
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
+Q_MQTT_EXPORT Q_NAMESPACE
+#endif
+
+static const quint8 LIBRARY_VERSION_MAJOR = 0;
+static const quint8 LIBRARY_VERSION_MINOR = 3;
+static const quint8 LIBRARY_VERSION_REVISION = 1;
+//static const char* LIBRARY_VERSION = "0.3.1";
+
+enum MQTTVersion
+{
+    V3_1_0 = 3,
+    V3_1_1 = 4
+};
+Q_ENUM_NS(MQTTVersion)
+
+enum ConnectionState
+{
+    STATE_INIT = 0,
+    STATE_CONNECTING,
+    STATE_CONNECTED,
+    STATE_DISCONNECTED
+};
+Q_ENUM_NS(ConnectionState)
+
+enum ClientError
+{
+    UnknownError = 0,
+    SocketConnectionRefusedError,
+    SocketRemoteHostClosedError,
+    SocketHostNotFoundError,
+    SocketAccessError,
+    SocketResourceError,
+    SocketTimeoutError,
+    SocketDatagramTooLargeError,
+    SocketNetworkError,
+    SocketAddressInUseError,
+    SocketAddressNotAvailableError,
+    SocketUnsupportedSocketOperationError,
+    SocketUnfinishedSocketOperationError,
+    SocketProxyAuthenticationRequiredError,
+    SocketSslHandshakeFailedError,
+    SocketProxyConnectionRefusedError,
+    SocketProxyConnectionClosedError,
+    SocketProxyConnectionTimeoutError,
+    SocketProxyNotFoundError,
+    SocketProxyProtocolError,
+    SocketOperationError,
+    SocketSslInternalError,
+    SocketSslInvalidUserDataError,
+    SocketTemporaryError,
+    MqttUnacceptableProtocolVersionError=1<<16,
+    MqttIdentifierRejectedError,
+    MqttServerUnavailableError,
+    MqttBadUserNameOrPasswordError,
+    MqttNotAuthorizedError,
+    MqttNoPingResponse
+};
+Q_ENUM_NS(ClientError)
+
+class ClientPrivate;
+class Message;
+class Frame;
+class NetworkInterface;
+
+class Q_MQTT_EXPORT Client : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(quint16 _port READ port WRITE setPort)
+    Q_PROPERTY(QHostAddress _host READ host WRITE setHost)
+    Q_PROPERTY(QString _hostName READ hostName WRITE setHostName)
+    Q_PROPERTY(QString _clientId READ clientId WRITE setClientId)
+    Q_PROPERTY(QString _username READ username WRITE setUsername)
+    Q_PROPERTY(QByteArray _password READ password WRITE setPassword)
+    Q_PROPERTY(quint16 _keepAlive READ keepAlive WRITE setKeepAlive)
+    Q_PROPERTY(MQTTVersion _version READ version WRITE setVersion)
+    Q_PROPERTY(bool _autoReconnect READ autoReconnect WRITE setAutoReconnect)
+    Q_PROPERTY(int _autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval)
+    Q_PROPERTY(bool _cleanSession READ cleanSession WRITE setCleanSession)
+    Q_PROPERTY(QString _willTopic READ willTopic WRITE setWillTopic)
+    Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos)
+    Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain)
+    Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage)
+    Q_PROPERTY(ConnectionState _connectionState READ connectionState)
+#ifndef QT_NO_SSL
+    Q_PROPERTY(QSslConfiguration _sslConfiguration READ sslConfiguration WRITE setSslConfiguration)
+#endif // QT_NO_SSL
+
+public:
+    Client(const QHostAddress& host = QHostAddress::LocalHost,
+           const quint16 port = 1883,
+           QObject* parent = nullptr);
+
+#ifndef QT_NO_SSL
+    Client(const QString& hostName,
+           const quint16 port,
+           const QSslConfiguration& config,
+           const bool ignoreSelfSigned=false,
+           QObject* parent = nullptr);
+#endif // QT_NO_SSL
+
+    // This function is provided for backward compatibility with older versions of QMQTT.
+    // If the ssl parameter is true, this function will load a private key ('cert.key') and a local
+    // certificate ('cert.crt') from the current working directory. It will also set PeerVerifyMode
+    // to None. This may not be the safest way to set up an SSL connection.
+    Client(const QString& hostName,
+           const quint16 port,
+           const bool ssl,
+           const bool ignoreSelfSigned,
+           QObject* parent = nullptr);
+
+#ifdef QT_WEBSOCKETS_LIB
+    // Create a connection over websockets
+    Client(const QString& url,
+           const QString& origin,
+           QWebSocketProtocol::Version version,
+           bool ignoreSelfSigned = false,
+           QObject* parent = nullptr);
+
+#ifndef QT_NO_SSL
+    Client(const QString& url,
+           const QString& origin,
+           QWebSocketProtocol::Version version,
+           const QSslConfiguration& config,
+           const bool ignoreSelfSigned = false,
+           QObject* parent = nullptr);
+#endif // QT_NO_SSL
+#endif // QT_WEBSOCKETS_LIB
+
+    // for testing purposes only
+    Client(NetworkInterface* network,
+           const QHostAddress& host = QHostAddress::LocalHost,
+           const quint16 port = 1883,
+           QObject* parent = nullptr);
+
+    virtual ~Client();
+
+    QHostAddress host() const;
+    QString hostName() const;
+    quint16 port() const;
+    QString clientId() const;
+    QString username() const;
+    QByteArray password() const;
+    QMQTT::MQTTVersion version() const;
+    quint16 keepAlive() const;
+    bool cleanSession() const;
+    bool autoReconnect() const;
+    int autoReconnectInterval() const;
+    ConnectionState connectionState() const;
+    QString willTopic() const;
+    quint8 willQos() const;
+    bool willRetain() const;
+    QByteArray willMessage() const;
+
+    bool isConnectedToHost() const;
+#ifndef QT_NO_SSL
+    QSslConfiguration sslConfiguration() const;
+    void setSslConfiguration(const QSslConfiguration& config);
+#endif // QT_NO_SSL
+
+public Q_SLOTS:
+    void setHost(const QHostAddress& host);
+    void setHostName(const QString& hostName);
+    void setPort(const quint16 port);
+    void setClientId(const QString& clientId);
+    void setUsername(const QString& username);
+    void setPassword(const QByteArray& password);
+    void setVersion(const MQTTVersion version);
+    void setKeepAlive(const quint16 keepAlive);
+    void setCleanSession(const bool cleanSession);
+    void setAutoReconnect(const bool value);
+    void setAutoReconnectInterval(const int autoReconnectInterval);
+    void setWillTopic(const QString& willTopic);
+    void setWillQos(const quint8 willQos);
+    void setWillRetain(const bool willRetain);
+    void setWillMessage(const QByteArray& willMessage);
+
+    void connectToHost();
+    void disconnectFromHost();
+
+    void subscribe(const QString& topic, const quint8 qos = 0);
+    void unsubscribe(const QString& topic);
+
+    quint16 publish(const QMQTT::Message& message);
+
+#ifndef QT_NO_SSL
+    void ignoreSslErrors();
+    void ignoreSslErrors(const QList<QSslError>& errors);
+#endif // QT_NO_SSL
+
+Q_SIGNALS:
+    void connected();
+    void disconnected();
+    void error(const QMQTT::ClientError error);
+
+    void subscribed(const QString& topic, const quint8 qos = 0);
+    void unsubscribed(const QString& topic);
+    void published(const QMQTT::Message& message, quint16 msgid = 0);
+    void received(const QMQTT::Message& message);
+    void pingresp();
+#ifndef QT_NO_SSL
+    void sslErrors(const QList<QSslError>& errors);
+#endif // QT_NO_SSL
+
+protected Q_SLOTS:
+    void onNetworkConnected();
+    void onNetworkDisconnected();
+    void onNetworkReceived(const QMQTT::Frame& frame);
+    void onTimerPingReq();
+    void onPingTimeout();
+    void onNetworkError(QAbstractSocket::SocketError error);
+#ifndef QT_NO_SSL
+    void onSslErrors(const QList<QSslError>& errors);
+#endif // QT_NO_SSL
+
+protected:
+    QScopedPointer<ClientPrivate> d_ptr;
+
+private:
+    Q_DISABLE_COPY(Client)
+    Q_DECLARE_PRIVATE(Client)
+};
+
+} // namespace QMQTT
+
+Q_DECLARE_METATYPE(QMQTT::ClientError)
+
+#endif // QMQTT_CLIENT_H

+ 48 - 0
include/qmqtt/qmqtt_global.h

@@ -0,0 +1,48 @@
+/*
+ * qmqtt_global.h - qmqtt libray global
+ *
+ * Copyright (c) 2013  Ery Lee <ery.lee at gmail dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of mqttc nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef QMQTT_GLOBAL_H
+#define QMQTT_GLOBAL_H
+
+#include <QtGlobal>
+
+#if !defined(QT_STATIC) && !defined(MQTT_PROJECT_INCLUDE_SRC)
+#  if defined(QT_BUILD_QMQTT_LIB)
+#    define Q_MQTT_EXPORT Q_DECL_EXPORT
+#  else
+#    define Q_MQTT_EXPORT Q_DECL_IMPORT
+#  endif
+#else
+#  define Q_MQTT_EXPORT
+#endif
+
+#endif // QMQTT_GLOBAL_H
+

+ 96 - 0
include/qmqtt/qmqtt_message.h

@@ -0,0 +1,96 @@
+/*
+ * qmqtt_message.h - qmqtt message header
+ *
+ * Copyright (c) 2013  Ery Lee <ery.lee at gmail dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of mqttc nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef QMQTT_MESSAGE_H
+#define QMQTT_MESSAGE_H
+
+#include <qmqtt_global.h>
+
+#include <QMetaType>
+#include <QString>
+#include <QByteArray>
+#include <QSharedDataPointer>
+
+namespace QMQTT {
+
+class MessagePrivate;
+
+class Q_MQTT_EXPORT Message
+{
+public:
+    Message();
+    explicit Message(const quint16 id, const QString &topic, const QByteArray &payload,
+                     const quint8 qos = 0, const bool retain = false, const bool dup = false);
+    Message(const Message &other);
+    ~Message();
+
+    Message &operator=(const Message &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+    inline Message &operator=(Message &&other) Q_DECL_NOTHROW
+    { swap(other); return *this; }
+#endif
+
+    bool operator==(const Message &other) const;
+    inline bool operator!=(const Message &other) const
+    { return !operator==(other); }
+
+    inline void swap(Message &other) Q_DECL_NOTHROW
+    { qSwap(d, other.d); }
+
+    quint16 id() const;
+    void setId(const quint16 id);
+
+    quint8 qos() const;
+    void setQos(const quint8 qos);
+
+    bool retain() const;
+    void setRetain(const bool retain);
+
+    bool dup() const;
+    void setDup(const bool dup);
+
+    QString topic() const;
+    void setTopic(const QString &topic);
+
+    QByteArray payload() const;
+    void setPayload(const QByteArray &payload);
+
+private:
+    QSharedDataPointer<MessagePrivate> d;
+};
+
+} // namespace QMQTT
+
+Q_DECLARE_SHARED(QMQTT::Message)
+
+Q_DECLARE_METATYPE(QMQTT::Message)
+
+#endif // QMQTT_MESSAGE_H