Browse Source

开发边缘网关程序

james 2 years ago
parent
commit
455cb11509
100 changed files with 9155 additions and 0 deletions
  1. 20 0
      AGBoxDog/AGBoxDog.pro
  2. 25 0
      AGBoxDog/agboxshm.h
  3. 8 0
      AGBoxDog/boxshm.h
  4. 223 0
      AGBoxDog/dogcore.cpp
  5. 35 0
      AGBoxDog/dogcore.h
  6. 70 0
      AGBoxDog/logthread.cpp
  7. 30 0
      AGBoxDog/logthread.h
  8. 41 0
      AGBoxDog/main.cpp
  9. 57 0
      HttpUtil.h
  10. 31 0
      QReplyTimeout.h
  11. 25 0
      agElevatorProcess/agElevatorProcess.pro
  12. 88 0
      agElevatorProcess/databasethread.cpp
  13. 37 0
      agElevatorProcess/databasethread.h
  14. 118 0
      agElevatorProcess/elevatorcore.cpp
  15. 48 0
      agElevatorProcess/elevatorcore.h
  16. 225 0
      agElevatorProcess/httpthread.cpp
  17. 50 0
      agElevatorProcess/httpthread.h
  18. 52 0
      agElevatorProcess/logthread.cpp
  19. 28 0
      agElevatorProcess/logthread.h
  20. 12 0
      agElevatorProcess/main.cpp
  21. 27 0
      agEnvironmentProcess/agEnvironmentProcess.pro
  22. 135 0
      agEnvironmentProcess/environmentcore.cpp
  23. 45 0
      agEnvironmentProcess/environmentcore.h
  24. 52 0
      agEnvironmentProcess/logthread.cpp
  25. 28 0
      agEnvironmentProcess/logthread.h
  26. 12 0
      agEnvironmentProcess/main.cpp
  27. 121 0
      agEnvironmentProcess/mqttpub.cpp
  28. 45 0
      agEnvironmentProcess/mqttpub.h
  29. 69 0
      agEnvironmentProcess/mqttsub.cpp
  30. 34 0
      agEnvironmentProcess/mqttsub.h
  31. 26 0
      agGeneratorProcess/agGeneratorProcess.pro
  32. 88 0
      agGeneratorProcess/databasethread.cpp
  33. 37 0
      agGeneratorProcess/databasethread.h
  34. 118 0
      agGeneratorProcess/generatorcore.cpp
  35. 41 0
      agGeneratorProcess/generatorcore.h
  36. 330 0
      agGeneratorProcess/httpthread.cpp
  37. 53 0
      agGeneratorProcess/httpthread.h
  38. 52 0
      agGeneratorProcess/logthread.cpp
  39. 28 0
      agGeneratorProcess/logthread.h
  40. 12 0
      agGeneratorProcess/main.cpp
  41. 28 0
      agGuardProcess/agGuardProcess.pro
  42. 88 0
      agGuardProcess/databasethread.cpp
  43. 37 0
      agGuardProcess/databasethread.h
  44. 118 0
      agGuardProcess/guardcore.cpp
  45. 41 0
      agGuardProcess/guardcore.h
  46. 226 0
      agGuardProcess/httpthread.cpp
  47. 51 0
      agGuardProcess/httpthread.h
  48. 52 0
      agGuardProcess/logthread.cpp
  49. 28 0
      agGuardProcess/logthread.h
  50. 12 0
      agGuardProcess/main.cpp
  51. 30 0
      agLightingProcess/agLightingProcess.pro
  52. 52 0
      agLightingProcess/logthread.cpp
  53. 28 0
      agLightingProcess/logthread.h
  54. 8 0
      agLightingProcess/main.cpp
  55. 29 0
      agVideoProcess/agVideoProcess.pro
  56. 37 0
      agVideoProcess/agboxdeviceshm.h
  57. 8 0
      agVideoProcess/boxdeviceshm.h
  58. 121 0
      agVideoProcess/httpthread.cpp
  59. 46 0
      agVideoProcess/httpthread.h
  60. 52 0
      agVideoProcess/logthread.cpp
  61. 28 0
      agVideoProcess/logthread.h
  62. 13 0
      agVideoProcess/main.cpp
  63. 144 0
      agVideoProcess/videocore.cpp
  64. 38 0
      agVideoProcess/videocore.h
  65. 10 0
      data-agbox.pro
  66. 680 0
      data-agbox.pro.user
  67. 4 0
      qmqtt-master/.qmake.conf
  68. 1 0
      qmqtt-master/.tag
  69. 24 0
      qmqtt-master/.travis.yml
  70. 298 0
      qmqtt-master/CMakeLists.txt
  71. 2 0
      qmqtt-master/LICENSE
  72. 139 0
      qmqtt-master/README.md
  73. 30 0
      qmqtt-master/edl-v10
  74. 220 0
      qmqtt-master/epl-v10
  75. 3 0
      qmqtt-master/examples/examples.pro
  76. 9 0
      qmqtt-master/examples/examples.qbs
  77. 9 0
      qmqtt-master/examples/qmqtt/client/client.pro
  78. 28 0
      qmqtt-master/examples/qmqtt/client/client.qbs
  79. 132 0
      qmqtt-master/examples/qmqtt/client/example.cpp
  80. 3 0
      qmqtt-master/examples/qmqtt/qmqtt.pro
  81. 9 0
      qmqtt-master/examples/qmqtt/qmqtt.qbs
  82. 62 0
      qmqtt-master/qmqtt.pri
  83. 1 0
      qmqtt-master/qmqtt.pro
  84. 656 0
      qmqtt-master/qmqtt.pro.user
  85. 11 0
      qmqtt-master/qmqtt.qbs
  86. 38 0
      qmqtt-master/src/mqtt/qmqtt.h
  87. 48 0
      qmqtt-master/src/mqtt/qmqtt.pri
  88. 17 0
      qmqtt-master/src/mqtt/qmqtt.pro
  89. 134 0
      qmqtt-master/src/mqtt/qmqtt.qbs
  90. 412 0
      qmqtt-master/src/mqtt/qmqtt_client.cpp
  91. 286 0
      qmqtt-master/src/mqtt/qmqtt_client.h
  92. 811 0
      qmqtt-master/src/mqtt/qmqtt_client_p.cpp
  93. 183 0
      qmqtt-master/src/mqtt/qmqtt_client_p.h
  94. 209 0
      qmqtt-master/src/mqtt/qmqtt_frame.cpp
  95. 137 0
      qmqtt-master/src/mqtt/qmqtt_frame.h
  96. 48 0
      qmqtt-master/src/mqtt/qmqtt_global.h
  97. 136 0
      qmqtt-master/src/mqtt/qmqtt_message.cpp
  98. 96 0
      qmqtt-master/src/mqtt/qmqtt_message.h
  99. 83 0
      qmqtt-master/src/mqtt/qmqtt_message_p.h
  100. 295 0
      qmqtt-master/src/mqtt/qmqtt_network.cpp

+ 20 - 0
AGBoxDog/AGBoxDog.pro

@@ -0,0 +1,20 @@
+QT += core sql
+
+QT -= gui
+
+TARGET = agBoxDog
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+SOURCES += \
+        main.cpp \
+    dogcore.cpp \
+    logthread.cpp
+
+HEADERS += \
+    agboxshm.h \
+    boxshm.h \
+    dogcore.h \
+    logthread.h

+ 25 - 0
AGBoxDog/agboxshm.h

@@ -0,0 +1,25 @@
+#ifndef AGBOXSHM_H
+#define AGBOXSHM_H
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#define SHM_PORT 8522
+#define SHM_PATH "/"
+
+
+typedef struct {
+    uint t_time;
+}ProcessStatus;
+
+typedef struct {
+    unsigned char Enabled;
+    ProcessStatus processStatus[16];
+}AGBoxShm;
+
+
+#endif // AGBOXSHM_H

+ 8 - 0
AGBoxDog/boxshm.h

@@ -0,0 +1,8 @@
+#ifndef BOXSHM_H
+#define BOXSHM_H
+
+#include "agboxshm.h"
+
+extern AGBoxShm *agBoxShm;
+
+#endif // BOXSHM_H

+ 223 - 0
AGBoxDog/dogcore.cpp

@@ -0,0 +1,223 @@
+#include "dogcore.h"
+#include "boxshm.h"
+
+DogCore::DogCore(QObject *parent) : QObject(parent)
+{
+    logThread = new LogThread(this);
+    logThread->start();
+    isWorking = false;
+
+    timer = new QTimer(this);
+    connect(timer,SIGNAL(timeout()),this,SLOT(time_out()));
+    for(int i=0;i<16;i++)
+        chkTime[i] = QDateTime::currentDateTime().toTime_t();
+}
+
+unsigned int DogCore::chkrootprocmem(QString proname)
+{
+    FILE *f1=NULL,*f2=NULL;
+    int pid, vmrss;
+    char buff[512],name[64];
+    QString cmd = QString("pgrep %1 -u root").arg(proname);
+    f1 = popen(cmd.toUtf8().data(),"r");
+    if(f1==NULL)
+        return 0;
+    if(NULL == fgets(buff,512,f1)){
+        pclose(f1);
+        return 0;
+    }
+    pid = atoi(buff);
+    pclose(f1);
+    QString filename = QString("/proc/%1/status").arg(pid);
+    f2 = fopen(filename.toUtf8().data(),"r");
+    if(NULL == f2)
+        return 0;
+    for(int i=0;i<16;i++)
+        fgets(buff,512,f2);
+    fgets(buff,512,f2);
+    sscanf(buff,"%s %d",name,&vmrss);
+    fclose(f2);
+    return (vmrss>>10);
+}
+
+void DogCore::time_out()
+{
+    if(!isWorking){
+        isWorking = true;
+        uint chkTime1 = QDateTime::currentDateTime().toTime_t();
+        if((chkTime1-chkTime[1])>=300){
+            chkTime[1]=chkTime1;
+            if(chkrootprocmem("agDP0001")>200){
+                logThread->appendData(QString("[%1 agBoxDog %2] %3 chkrootprocmem(agDP0001): %4")
+                                      .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                      .arg(chkTime1)
+                                      .arg(chkTime[1])
+                                      .arg(chkrootprocmem("agDP0001")));
+                system("killall agDP0001");
+                sleep(1);
+                system("/root/bin/agDP0001 &");
+            }
+
+        }
+        if((agBoxShm->processStatus[1].t_time>0)
+                &&(static_cast<int>(chkTime1-agBoxShm->processStatus[1].t_time)>60)){
+            if(system("killall agDP0001")!=-1){
+                if(system("/root/bin/agDP0001 &")!=-1){
+                    logThread->appendData(QString("[ %1 agBoxDog %2 ] agDP0001 time out: %3")
+                                          .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                          .arg(chkTime1)
+                                          .arg(static_cast<int>(chkTime1-agBoxShm->processStatus[1].t_time)));
+                }
+            }
+        }
+
+        if((chkTime1-chkTime[2])>300){
+            chkTime[2]=chkTime1;
+            if(chkrootprocmem("agDP0002")>200){
+                logThread->appendData(QString("[%1 agBoxDog %2] %3 chkrootprocmem(agDP0002): %4")
+                                      .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                      .arg(chkTime1)
+                                      .arg(chkTime[2])
+                                      .arg(chkrootprocmem("agDP0002")));
+                system("killall agDP0002");
+                sleep(1);
+                system("/root/bin/agDP0002 &");
+            }
+
+        }
+        if((agBoxShm->processStatus[2].t_time>0)
+                &&(static_cast<int>(chkTime1-agBoxShm->processStatus[2].t_time)>60)){
+            if(system("killall agDP0002")!=-1){
+                if(system("/root/bin/agDP0002 &")!=-1){
+                    logThread->appendData(QString("[%1 agBoxDog %2] agDP0002 time out: %3")
+                                          .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                          .arg(chkTime1)
+                                          .arg(static_cast<int>(chkTime1-agBoxShm->processStatus[2].t_time)));
+                }
+
+            }
+
+        }
+
+        if((chkTime1-chkTime[3])>300){
+            chkTime[3]=chkTime1;
+            if(chkrootprocmem("agDP0003")>200){
+                logThread->appendData(QString("[%1 agBoxDog %2] %3 chkrootprocmem(agDP0003): %4")
+                                      .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                      .arg(chkTime1)
+                                      .arg(chkTime[3])
+                                      .arg(chkrootprocmem("agDP0003")));
+                system("killall agDP0003");
+                sleep(1);
+                system("/root/bin/agDP0003 &");
+            }
+        }
+        if((agBoxShm->processStatus[3].t_time>0)
+                &&(static_cast<int>(chkTime1-agBoxShm->processStatus[3].t_time)>60)){
+            if(system("killall agDP0003")!=-1){
+                if(system("/root/bin/agDP0003 &")!=-1){
+                    logThread->appendData(QString("[%1 agBoxDog %2] agDP0003 time out: %3")
+                                          .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                          .arg(chkTime1)
+                                          .arg(static_cast<int>(chkTime1-agBoxShm->processStatus[3].t_time)));
+                }
+            }
+        }
+
+        if((chkTime1-chkTime[4])>300){
+            chkTime[4]=chkTime1;
+            if(chkrootprocmem("agDP0004")>200){
+                logThread->appendData(QString("[%1 agBoxDog %2] %3 chkrootprocmem(agDP0004): %4")
+                                      .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                      .arg(chkTime1)
+                                      .arg(chkTime[4])
+                                      .arg(chkrootprocmem("agDP0004")));
+                system("killall agDP0004");
+                sleep(1);
+                system("/root/bin/agDP0004 &");
+            }
+        }
+        if((agBoxShm->processStatus[4].t_time>0)
+                &&(static_cast<int>(chkTime1-agBoxShm->processStatus[4].t_time)>60)){
+            if(system("killall agDP0004")!=-1){
+                if(system("/root/bin/agDP0004 &")!=-1){
+                    logThread->appendData(QString("[%1 agBoxDog %2] agDP0004 time out: %3")
+                                          .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                          .arg(chkTime1)
+                                          .arg(static_cast<int>(chkTime1-agBoxShm->processStatus[4].t_time)));
+                }
+            }
+        }
+
+        if((chkTime1-chkTime[5])>300){
+            chkTime[5]=chkTime1;
+            if(chkrootprocmem("agDP0005")>200){
+                logThread->appendData(QString("[%1 agBoxDog %2] %3 chkrootprocmem(agDP0005): %4")
+                                      .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                      .arg(chkTime1)
+                                      .arg(chkTime[5])
+                                      .arg(chkrootprocmem("agDP0005")));
+                system("killall agDP0005");
+                sleep(1);
+                system("/root/bin/agDP0005 &");
+            }
+        }
+        if((agBoxShm->processStatus[5].t_time>0)
+                &&(static_cast<int>(chkTime1-agBoxShm->processStatus[5].t_time)>60)){
+            if(system("killall agDP0005")!=-1){
+                if(system("/root/bin/agDP0005 &")!=-1){
+                    logThread->appendData(QString("[%1 agBoxDog %2] agDP0005 time out: %3")
+                                          .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                          .arg(chkTime1)
+                                          .arg(static_cast<int>(chkTime1-agBoxShm->processStatus[5].t_time)));
+                }
+            }
+        }
+
+        if((chkTime1-chkTime[6])>300){
+            chkTime[6]=chkTime1;
+            if(chkrootprocmem("agDP0006")>200){
+                logThread->appendData(QString("[%1 agBoxDog %2] %3 chkrootprocmem(agDP0006): %4")
+                                      .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                      .arg(chkTime1)
+                                      .arg(chkTime[6])
+                                      .arg(chkrootprocmem("agDP0006")));
+                system("killall agDP0006");
+                sleep(1);
+                system("/root/bin/agDP0006 &");
+            }
+        }
+        if((agBoxShm->processStatus[6].t_time>0)
+                &&(static_cast<int>(chkTime1-agBoxShm->processStatus[6].t_time)>60)){
+            if(system("killall agDP0006")!=-1){
+                if(system("/root/bin/agDP0006 &")!=-1){
+                    logThread->appendData(QString("[%1 agBoxDog %2] agDP0006 time out: %3")
+                                          .arg(QDateTime::fromTime_t(chkTime1).toString("yyyy-MM-dd HH:mm:ss"))
+                                          .arg(chkTime1)
+                                          .arg(static_cast<int>(chkTime1-agBoxShm->processStatus[6].t_time)));
+                }
+            }
+        }
+
+
+        isWorking = false;
+    }
+
+}
+
+
+void DogCore::start(){
+    time_out();
+    timer->start(5000);
+}
+
+
+
+
+
+
+
+
+
+
+

+ 35 - 0
AGBoxDog/dogcore.h

@@ -0,0 +1,35 @@
+#ifndef DOGCORE_H
+#define DOGCORE_H
+
+#include <QObject>
+#include <QTimer>
+#include <QDateTime>
+#include <QVariant>
+#include <QFile>
+#include <QTextStream>
+#include <QProcess>
+#include <QStringList>
+#include <unistd.h>
+#include "logthread.h"
+
+class DogCore : public QObject
+{
+    Q_OBJECT
+public:
+    explicit DogCore(QObject *parent = nullptr);
+    void start();
+    unsigned int chkrootprocmem(QString proname);
+
+signals:
+
+public slots:
+    void time_out();
+
+private:
+    QTimer *timer;
+    bool isWorking;
+    uint chkTime[16];
+    LogThread *logThread;
+};
+
+#endif // DOGCORE_H

+ 70 - 0
AGBoxDog/logthread.cpp

@@ -0,0 +1,70 @@
+#include "logthread.h"
+
+LogThread::LogThread(QObject *parent) :
+    QThread(parent)
+{
+    keep = false;
+    dataList.clear();
+    wrongList.clear();
+    QDir path("/usky/data-agbox/agboxdog/log");
+    if(!path.exists()){
+        system("mkdir -p /usky/data-agbox/agboxdog/log/");
+    }
+    file = new QFile("/usky/data-agbox/agboxdog/log/agboxdog-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+    wfile = new QFile("/opt/agBoxProcess/log/agboxdog.log");
+    day = QDate::currentDate().day();
+}
+
+void LogThread::appendData(QString data)
+{
+    dataList.append(data);
+}
+
+void LogThread::appendWrongData(QString data)
+{
+    wrongList.append(data);
+}
+
+void LogThread::stop()
+{
+    keep = false;
+}
+
+void LogThread::run()
+{
+    printf("log thread start\n");
+    if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+        file->write(QString("agBoxDog start at %1.\r\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).toUtf8());
+        file->close();
+    }
+    keep = true;
+    while(keep){
+        if(dataList.length()>0){
+            if(day!=QDate::currentDate().day()){
+                day = QDate::currentDate().day();
+                file = new QFile("/usky/data-agbox/agboxdog/log/dataProcessDog-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+            }
+            if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(dataList.length()>0){
+                    file->write(dataList.first().toUtf8());
+                    file->write("\r\n");
+                    dataList.removeFirst();
+                    usleep(1000);
+                }
+                file->close();
+            }
+        }
+        if(wrongList.length()>0){
+            if(wfile->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(wrongList.length()>0){
+                    wfile->write(wrongList.first().toUtf8());
+                    wfile->write("\r\n");
+                    wrongList.removeFirst();
+                    usleep(1000);
+                }
+                wfile->close();
+            }
+        }
+        usleep(50000);
+    }
+}

+ 30 - 0
AGBoxDog/logthread.h

@@ -0,0 +1,30 @@
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QStringList>
+#include <QDate>
+#include <QDir>
+#include <QFile>
+
+class LogThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit LogThread(QObject *parent = nullptr);
+    void appendData(QString data);
+    void appendWrongData(QString data);
+    void run();
+    void stop();
+signals:
+
+public slots:
+private:
+    QFile *file,*wfile;
+    QStringList dataList;
+    QStringList wrongList;
+    int day;
+    bool keep;
+};
+
+#endif // LOGTHREAD_H

+ 41 - 0
AGBoxDog/main.cpp

@@ -0,0 +1,41 @@
+#include <QCoreApplication>
+#include "boxshm.h"
+#include "dogcore.h"
+#include <QFile>
+#include <QDir>
+
+AGBoxShm *agBoxShm;
+
+bool shm_load(){
+    int shmid;
+    key_t key;
+    if((key=ftok(SHM_PATH,static_cast<int>(SHM_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof (AGBoxShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    agBoxShm = static_cast<AGBoxShm *>(shmat(shmid,nullptr,0));
+
+    return true;
+}
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+    QDir path("/opt/agBoxProcess");
+    if(!path.exists()){
+        system("mkdir -p /opt/agBoxProcess");
+        system("mkdir -p /opt/agBoxProcess/log");
+    }
+    if(shm_load()){
+        DogCore *dogcore = new DogCore(nullptr);
+        dogcore->start();
+    }else{
+        fprintf(stderr,"shm load failed!\n");
+        exit(1);
+    }
+
+
+    return a.exec();
+}

+ 57 - 0
HttpUtil.h

@@ -0,0 +1,57 @@
+#ifndef HIK_HTTPUTIL_H
+#define HIK_HTTPUTIL_H
+
+#if (defined(WIN32) || defined(WIN64))
+	#ifdef HTTPUTIL_EXPORTS
+		#define HTTPUTIL_API extern "C" _declspec(dllexport)
+	#else
+		#define HTTPUTIL_API extern "C" _declspec(dllimport)
+	#endif
+#else  // LINUX
+	#define HTTPUTIL_API extern "C"
+#endif
+
+namespace httpUtil
+{
+	// 状态码定义: 
+	// 0 表示成功
+	// 10000~20000 表示具体的错误码. 
+	// 小于10000大于0 表示HTTP状态码(如404),HTTP状态码请自行查阅HTTP状态码定义
+	const int  HTTPUTIL_ERR_SUCCESS = 0;                                   // 成功
+	const int  HTTPUTIL_ERR_BASE = 10000;                                  // 错误码基准
+	const int  HTTPUTIL_ERR_PARAM = (HTTPUTIL_ERR_BASE + 1);               // 参数错误,如传入空指针、超时时间不对
+	const int  HTTPUTIL_ERR_ALLOC_SESSION = (HTTPUTIL_ERR_BASE + 2);       // HTTP请求分配session失败
+	const int  HTTPUTIL_ERR_SET_HEADER_FIELD = (HTTPUTIL_ERR_BASE + 3);    // 头域设置失败
+	const int  HTTPUTIL_ERR_SEND_REQUEST = (HTTPUTIL_ERR_BASE + 4);        // HTTP请求失败
+	const int  HTTPUTIL_ERR_ALLOC_MEM = (HTTPUTIL_ERR_BASE + 5);           // 分配内存错误
+	const int  HTTPUTIL_ERR_GET_REDIRECT_URL = (HTTPUTIL_ERR_BASE + 6);    // 获取重定向Url失败
+	const int  HTTPUTIL_ERR_OTHER = (HTTPUTIL_ERR_BASE + 10000);           // 其它错误
+
+	// HTTP POST
+	// url: url
+	// body: body
+	// appkey: API网关提供的APPKey
+	// secret: API网关提供的APPSecret
+	// timeout: 秒级超时时间(内部分别使用此超时时间设置建立连接、请求发送、等待回复超时时间)
+	// dataLen: 响应数据长度,如果确定返回的内容是字符串,可以指定NULL
+	// return: HTTP请求响应,如果是二进制,请结合dataLen获取数据。失败返回NULL,可使用HTTPUTIL_GetLastStatus获取状态码。成功需使用HTTPUTIL_Free释放内存
+	HTTPUTIL_API char* HTTPUTIL_Post(const char* url, const char* body, const char* appkey, const char* secret, int timeout, int* dataLen);
+
+	// HTTP GET
+	// url: url
+	// appkey: API网关提供的APPKey
+	// secret: API网关提供的APPSecret
+	// timeout: 秒级超时时间(内部分别使用此超时时间设置建立连接、请求发送、等待回复超时时间)
+	// dataLen: 响应数据长度,如果确定返回的内容是字符串,可以指定NULL
+	// return: HTTP请求响应,如果是二进制,请结合dataLen获取数据。失败返回NULL,可使用HTTPUTIL_GetLastStatus获取状态码。成功需使用HTTPUTIL_Free释放内存
+	HTTPUTIL_API char* HTTPUTIL_Get(const char* url, const char* appkey, const char* secret, int timeout, int* dataLen);
+
+	// 释放内存
+	// buffer: pHTTPUTIL_Get和HTTPUTIL_Post返回的非空指针
+	HTTPUTIL_API void HTTPUTIL_Free(char* buffer);
+
+	// 获取状态码,必须在调HTTPUTIL_Post或HTTPUTIL_Get所在线程中调此接口
+	// return: 状态码, 详见HTTPUTIL_ERR_*或自行查阅HTTP状态码
+	HTTPUTIL_API int HTTPUTIL_GetLastStatus();
+}
+#endif

+ 31 - 0
QReplyTimeout.h

@@ -0,0 +1,31 @@
+#ifndef QREPLYTIMEOUT_H
+#define QREPLYTIMEOUT_H
+
+#include <QObject>
+#include <QTimer>
+#include <QNetworkReply>
+#include <stdio.h>
+
+class QReplayTimeout : public QObject {
+    Q_OBJECT
+public:
+    QReplayTimeout(QNetworkReply *reply, const int timeout) :QObject(reply) {
+        Q_ASSERT(reply);
+        if( reply && reply->isRunning()){
+            QTimer::singleShot(timeout,this,SLOT(onTimeout()));
+        }
+    }
+signals:
+    void net_timeout();
+private slots:
+    void onTimeout(){
+        QNetworkReply *reply = static_cast<QNetworkReply *>(parent());
+        if(reply->isRunning()){
+            reply->abort();
+            reply->deleteLater();
+            emit net_timeout();
+        }
+    }
+};
+
+#endif // QREPLYTIMEOUT_H

+ 25 - 0
agElevatorProcess/agElevatorProcess.pro

@@ -0,0 +1,25 @@
+QT += core sql network
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+TARGET = agDP0003
+
+INCLUDEPATH += ../qmqtt-master/src/mqtt/
+
+SOURCES += \
+        main.cpp \
+    logthread.cpp \
+    elevatorcore.cpp \
+    databasethread.cpp \
+    httpthread.cpp
+
+LIBS += -lQt5Qmqtt
+
+HEADERS += \
+    logthread.h \
+    ../QReplyTimeout.h \
+    elevatorcore.h \
+    databasethread.h \
+    httpthread.h

+ 88 - 0
agElevatorProcess/databasethread.cpp

@@ -0,0 +1,88 @@
+#include "databasethread.h"
+
+#define HostName "172.17.35.51"
+#define HostPort 3306
+#define UserName "usky"
+#define PassWord "Yt#75Usky"
+#define DatabaseName "usky-park"
+
+DatabaseThread::DatabaseThread(QObject *parent) : QThread(parent)
+{
+    hour = 255;
+    keep=false;
+    sqlList.clear();
+    alarmList.clear();
+
+    db = QSqlDatabase::addDatabase("QMYSQL","write_db");
+    db.setHostName(QString(HostName));
+    db.setPort(HostPort);
+    db.setUserName(QString(UserName));
+    db.setPassword(QString(PassWord));
+    db.setDatabaseName(QString(DatabaseName));
+
+
+
+}
+
+void DatabaseThread::appendSql(QString sql)
+{
+    sqlList.append(sql);
+}
+
+void DatabaseThread::appendAlarm(QString sql)
+{
+    alarmList.append(sql);
+}
+
+
+void DatabaseThread::stop()
+{
+    keep = false;
+}
+
+void DatabaseThread::run()
+{
+    keep = true;
+    while (keep) {
+
+        if(!db.open()){
+            emit dbdata_log(QString("[%1] agElevatorProcess DatabaseThread db open failed").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")));
+        }else{
+            if(sqlList.length()>0){
+                while (sqlList.length()>0) {
+
+                    emit dbdata_log(QString("[%1] agElevatorProcess sql %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).arg(sqlList.first()));
+
+                    db.exec(sqlList.first());
+
+                    sqlList.removeFirst();
+                    usleep(1000);
+                }
+            }
+            if(alarmList.length()>0){
+                while (alarmList.length()>0) {
+                    db.exec(alarmList.first());
+
+                    emit dbdata_log(QString("[%1] agElevatorProcess alarm sql %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).arg(alarmList.first()));
+
+                    alarmList.removeFirst();
+                    usleep(1000);
+                }
+            }
+        }
+        usleep(50000);
+    }
+
+
+}
+
+
+
+
+
+
+
+
+
+
+

+ 37 - 0
agElevatorProcess/databasethread.h

@@ -0,0 +1,37 @@
+#ifndef DATABASETHREAD_H
+#define DATABASETHREAD_H
+
+#include <QThread>
+#include <QDateTime>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QVariant>
+#include <QStringList>
+
+
+class DatabaseThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit DatabaseThread(QObject *parent = nullptr);
+    void run();
+    void stop();
+    void appendSql(QString sql);
+    void appendAlarm(QString sql);
+
+
+signals:
+    void dbdata_log(QString log);
+
+public slots:
+
+private:
+    int hour;
+    bool keep;
+
+    QSqlDatabase db;
+    QStringList sqlList,alarmList;
+
+};
+
+#endif // DATABASETHREAD_H

+ 118 - 0
agElevatorProcess/elevatorcore.cpp

@@ -0,0 +1,118 @@
+#include "elevatorcore.h"
+#include "../AGBoxDog/boxshm.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+AGBoxShm *agBoxShm;
+BoxDeviceShm *boxDeviceShm;
+
+void ElevatorCore::shm_init(){
+    QSqlQuery qry;
+    QString sql = QString("select mqtt_ip,mqtt_port,user_name,pass_word from yt_t_mqtt where item_name = 'data-agbox'");
+    qry = db.exec(sql);
+    while (qry.next()) {
+        ip = qry.value(0).toString();
+        port = qry.value(1).toString();
+        username = qry.value(2).toString();
+        password = qry.value(3).toString();
+    }
+    qry.clear();
+    sql.clear();
+
+}
+
+bool ElevatorCore::shm_load(){
+    key_t key;
+    int shmid;
+    if((key=ftok(SHM_PATH,static_cast<int>(SHM_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(AGBoxShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    agBoxShm = static_cast<AGBoxShm *>(shmat(shmid,nullptr,0));
+
+    if((key=ftok(VIDEO_PATH,static_cast<int>(VIDEO_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(BoxDeviceShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    boxDeviceShm = static_cast<BoxDeviceShm *>(shmat(shmid,nullptr,0));
+
+    shm_init();
+    return true;
+}
+
+ElevatorCore::ElevatorCore(QObject *parent) : QObject(parent)
+{
+    logthread = new LogThread(this);
+    logthread->start();
+
+    db = QSqlDatabase::addDatabase("QSQLITE","conf_db");
+    db.setDatabaseName(QString("/opt/db/yt_conf.db"));
+    if(!db.open()){
+        logthread->appendData(QString("[agelevator] open yt_conf.db failed"));
+    }
+    if(shm_load()){
+        logthread->appendData(QString("[agelevator] shm load success"));
+    }
+
+    mqttIdx = 1;
+    m_client = new QMQTT::Client(QHostAddress(ip),static_cast<quint16>(port.toInt()),this);
+    connect(m_client,&QMQTT::Client::connected,this,&ElevatorCore::onConnected);
+    m_client->setUsername(username);
+    m_client->setPassword(password.toLatin1());
+    m_client->setCleanSession(true);
+    m_client->connectToHost();
+
+    dbthread = new DatabaseThread(this);
+    dbthread->start();
+
+    httpthread = new HttpThread(this);
+    connect(httpthread,&HttpThread::dataLog,this,&ElevatorCore::dataLog);
+    connect(httpthread,&HttpThread::mqttData,this,&ElevatorCore::mqtt_data);
+    connect(httpthread,&HttpThread::appendSql,this,&ElevatorCore::append_sql);
+
+}
+
+
+ElevatorCore::~ElevatorCore()
+{
+    logthread->stop();
+    dbthread->stop();
+    httpthread->stop();
+}
+
+void ElevatorCore::start()
+{
+
+}
+void ElevatorCore::onConnected()
+{
+    logthread->appendData(QString("mqtt onConnected"));
+}
+
+void ElevatorCore::dataLog(QString log)
+{
+    logthread->appendData(log);
+}
+
+void ElevatorCore::mqtt_data(QString mqtt_msg)
+{
+    printf("test3333 [%s]\n",mqtt_msg.toUtf8().data());
+    if((m_client->connectionState()==QMQTT::STATE_INIT)||(m_client->connectionState()==QMQTT::STATE_DISCONNECTED)){
+        m_client->connectToHost();
+    }
+    m_client->publish(QMQTT::Message(mqttIdx++,"data-collector",mqtt_msg.toUtf8()));
+    if(mqttIdx > 9999){
+        mqttIdx = 1;
+    }
+}
+
+void ElevatorCore::append_sql(QString sql)
+{
+    dbthread->appendSql(sql);
+}
+
+
+
+

+ 48 - 0
agElevatorProcess/elevatorcore.h

@@ -0,0 +1,48 @@
+#ifndef ELEVATORCORE_H
+#define ELEVATORCORE_H
+
+
+#include <QObject>
+#include <qmqtt.h>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include "logthread.h"
+#include "httpthread.h"
+#include "databasethread.h"
+
+#include <QObject>
+
+class ElevatorCore : public QObject
+{
+    Q_OBJECT
+public:
+    explicit ElevatorCore(QObject *parent = nullptr);
+    ~ElevatorCore();
+    void start();
+    bool shm_load();
+    void shm_init();
+
+signals:
+
+public slots:
+    void onConnected();
+    void dataLog(QString log);
+    void mqtt_data(QString mqtt_msg);
+    void append_sql(QString sql);
+
+private:
+    LogThread *logthread;
+    HttpThread *httpthread;
+    DatabaseThread *dbthread;
+
+    QMQTT::Client *m_client;
+    QSqlDatabase db;
+    quint16 mqttIdx;
+    QString ip,port,username,password;
+
+signals:
+
+public slots:
+};
+
+#endif // ELEVATORCORE_H

+ 225 - 0
agElevatorProcess/httpthread.cpp

@@ -0,0 +1,225 @@
+#include "httpthread.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+#include "../AGBoxDog/boxshm.h"
+
+HttpThread::HttpThread(QObject *parent) : QObject(parent)
+{
+    minute = 255;
+    minute1 = 255;
+    keep = false;
+    isWaiting = false;
+    networkManager = new QNetworkAccessManager(this); //查询梯控历史事件信息
+    connect(networkManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot(QNetworkReply *)));
+    isWaiting1 = false;
+    networkManager1 = new QNetworkAccessManager(this); //获取梯控主机在线状态
+    connect(networkManager1,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot1(QNetworkReply *)));
+
+    timer = new QTimer(this);
+    connect(timer,&QTimer::timeout,this,&HttpThread::time_out);
+    timer->start(5000);
+
+}
+
+void HttpThread::stop()
+{
+    keep = false;
+}
+
+void  HttpThread::finishedSlot(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("event parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("rows");
+            if(list_value.isArray()){
+                emit appendSql(QString("delete from event_lc where event_time >= '%1' and event_time <= '%2';").arg(startTime).arg(endTime));
+                QJsonArray list_array = list_value.toArray();
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString device_code = list_object.value("deviceCode").toString();
+                    QString deviceName = list_object.value("deviceName").toString();
+                    QString liftName = list_object.value("liftName").toString();
+                    QString eventId = list_object.value("eventId").toString();
+                    int eventType = list_object.value("eventType").toInt();
+                    QString eventName = list_object.value("eventName").toString();
+                    QString eventTime = list_object.value("eventTime").toString();
+                    QString personId = list_object.value("personId").toString();
+                    QString cardNo = list_object.value("cardNo").toString();
+                    QString personName = list_object.value("personName").toString();
+                    QString orgId = list_object.value("orgId").toString();
+                    QString orgName = list_object.value("orgName").toString();
+                    QString receiveTime = list_object.value("receiveTime").toString();
+                    for(int i=0;i<1024;i++){
+                        if(boxDeviceShm->device[i].Enabled == 0x01){
+                            if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                emit appendSql(QString::fromLocal8Bit("insert into event_lc (device_id, device_code, device_name, lift_name, event_id, event_type, event_name, event_time, person_id, card_no, person_name, org_id, org_name, receive_time) values('%1','%2','%3','%4','%5',%6,'%7','%8','%9','%10','%11','%12','%13','%14');")
+                                              .arg(QString(boxDeviceShm->device[i].device_id)).arg(device_code).arg(deviceName).arg(liftName).arg(eventId).arg(eventType).arg(eventName).arg(eventTime).arg(personId).arg(cardNo).arg(personName).arg(orgId).arg(orgName).arg(receiveTime));
+                                break;
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+
+        }else{
+            emit dataLog(QString("event QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] event QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] event QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout()
+{
+    printf("[%s] event reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting = false;
+}
+
+void  HttpThread::finishedSlot1(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("status parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("list");
+            if(list_value.isArray()){
+                QJsonArray list_array = list_value.toArray();
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString device_code = list_object.value("indexCode").toString();
+                    int deviceStatus = list_object.value("online").toInt();
+
+                    for(int i=0;i<1024;i++){
+                        if(boxDeviceShm->device[i].Enabled == 0x01){
+                            if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                emit mqttData(QString("{\"device_id\":\"%1\",\"device_code\":\"%2\",\"product_id\":\"%3\",\"timestamp\":%4,\"tags\":{\"conn_type\":\"\",\"type\":\"\"},\"metrics\":{\"device_status\":%5},\"device_type\":\"%6-lc\"}")
+                                              .arg(QString(boxDeviceShm->device[i].device_id)).arg(device_code).arg(QString(boxDeviceShm->device[i].company_code)).arg(QDateTime::currentDateTime().toTime_t()).arg(deviceStatus).arg(boxDeviceShm->device[i].device_type));
+                                break;
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+
+        }else{
+            emit dataLog(QString("status QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] status QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] status QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting1 = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout1()
+{
+    printf("[%s] status reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting1 = false;
+}
+
+void HttpThread::time_out()
+{
+    agBoxShm->processStatus[3].t_time=QDateTime::currentDateTime().toTime_t();
+
+    if(QDateTime::currentDateTime().time().minute()!=minute){//每分钟执行一次,统计从现在算起之前10分钟时间内的人员通行记录(插入之前先执行删除这个时间端数据的命令)
+        minute = QDateTime::currentDateTime().time().minute();
+        QString tempTime1 = QDateTime::currentDateTime().addSecs(-600).toString("yyyy-MM-ddTHH:mm");
+        QString tempTime2 = QDateTime::currentDateTime().addSecs(-60).toString("yyyy-MM-ddTHH:mm");
+        startTime = QString("%1:00+08:00").arg(tempTime1);
+        endTime = QString("%1:59+08:00").arg(tempTime2);
+
+        printf("startTime: %s, endTime %s\n",startTime.toUtf8().data(),endTime.toUtf8().data());
+
+        if(!isWaiting){
+            isWaiting = true;
+            QNetworkRequest *req = new QNetworkRequest();
+            req->setUrl(QUrl("https://172.17.200.250:443/artemis/api/ecs/v1/access_events/search"));
+            req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+            req->setRawHeader("Accept","*/*");
+            req->setRawHeader("Connection","keep-alive");
+            req->setRawHeader("Cache-Control"," no-cache");
+            req->setRawHeader("X-Ca-Key","27997984");
+            req->setRawHeader("X-Ca-Signature","suViBsEUVHh0kaTWjZgGYvYuezrYoA0sJRchgMkJGSQ=");
+            req->setRawHeader("X-Ca-Signature-Headers","x-ca-key");
+            config = req->sslConfiguration();
+            config.setPeerVerifyMode(QSslSocket::VerifyNone);
+            config.setProtocol(QSsl::TlsV1_0OrLater);
+            req->setSslConfiguration(config);
+            QString postdata = QString("{\"startTime\": \"%1\",\"endTime\": \"%2\",\"pageNo\": 1,\"pageSize\": 500}").arg(startTime).arg(endTime);
+            emit dataLog(QString(" events QNetworkReply event [%1]").arg(postdata));
+            req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+            QNetworkReply *reply = networkManager->post(*req,postdata.toUtf8());
+            QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+            connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout()));
+
+        }
+    }
+
+    if(QDateTime::currentDateTime().time().minute()!=minute1){//每半个小时执行一次,同步设备状态
+      minute1 = QDateTime::currentDateTime().time().minute();
+      if(!isWaiting1 && ((minute1==00)||(minute1==30))){
+          isWaiting1 = true;
+          QNetworkRequest *req = new QNetworkRequest();
+          req->setUrl(QUrl("https://172.17.200.250:443/artemis/api/nms/v1/online/ladder_controller/get"));
+          req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+          req->setRawHeader("Accept","*/*");
+          req->setRawHeader("Connection","keep-alive");
+          req->setRawHeader("Cache-Control"," no-cache");
+          req->setRawHeader("X-Ca-Key","27997984");
+          req->setRawHeader("X-Ca-Signature","dY38jPrLDZGBz0JSowveMsRcnt8aAiEM5sjBTn9FP2k=");
+          req->setRawHeader("X-Ca-Signature-Headers","x-ca-key");
+          config = req->sslConfiguration();
+          config.setPeerVerifyMode(QSslSocket::VerifyNone);
+          config.setProtocol(QSsl::TlsV1_0OrLater);
+          req->setSslConfiguration(config);
+          QString postdata = QString("{}");
+          req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+          QNetworkReply *reply = networkManager1->post(*req,postdata.toUtf8());
+          QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+          connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout1()));
+
+      }
+  }
+
+}
+
+
+
+
+
+
+
+
+

+ 50 - 0
agElevatorProcess/httpthread.h

@@ -0,0 +1,50 @@
+#ifndef HTTPTHREAD_H
+#define HTTPTHREAD_H
+
+#include <QObject>
+#include <QDateTime>
+#include <QTimer>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QSslConfiguration>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonParseError>
+#include "../QReplyTimeout.h"
+
+class HttpThread : public QObject
+{
+    Q_OBJECT
+public:
+    explicit HttpThread(QObject *parent = nullptr);
+    void run();
+    void stop();
+
+signals:
+    void dataLog(QString log);
+    void mqttData(QString mqtt_msg);
+    void appendSql(QString sql);
+
+public slots:
+    void time_out();
+    void finishedSlot(QNetworkReply *reply);
+    void finishedSlot1(QNetworkReply *reply);
+    void reply_timeout();
+    void reply_timeout1();
+
+private:
+    bool isWaiting,isWaiting1;
+    bool keep;
+    int minute,minute1;
+    QString startTime,endTime;
+    QNetworkAccessManager *networkManager,*networkManager1;
+    QSslConfiguration config;
+    QTimer *timer;
+
+
+};
+
+#endif // HTTPTHREAD_H

+ 52 - 0
agElevatorProcess/logthread.cpp

@@ -0,0 +1,52 @@
+#include "logthread.h"
+
+LogThread::LogThread(QObject *parent) :
+    QThread(parent)
+{
+    keep = false;
+    dataList.clear();
+    QDir path("/usky/data-agbox/agelevator/log");
+    if(!path.exists()){
+        system("mkdir -p /usky/data-agbox/agelevator/log/");
+    }
+    file = new QFile("/usky/data-agbox/agelevator/log/elevator-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+    day = QDate::currentDate().day();
+}
+
+void LogThread::appendData(QString data)
+{
+    dataList.append(data);
+}
+
+void LogThread::stop()
+{
+    keep = false;
+}
+
+void LogThread::run()
+{
+    printf("log thread start\n");
+    if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+        file->write(QString("agElevatorProcess start at %1.\r\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).toUtf8());
+        file->close();
+    }
+    keep = true;
+    while(keep){
+        if(dataList.length()>0){
+            if(day!=QDate::currentDate().day()){
+                day = QDate::currentDate().day();
+                file = new QFile("/usky/data-agbox/agelevator/log/elevator-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+            }
+            if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(dataList.length()>0){
+                    file->write(dataList.first().toUtf8());
+                    file->write("\r\n");
+                    dataList.removeFirst();
+                    usleep(1000);
+                }
+                file->close();
+            }
+        }
+        usleep(50000);
+    }
+}

+ 28 - 0
agElevatorProcess/logthread.h

@@ -0,0 +1,28 @@
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QStringList>
+#include <QDate>
+#include <QDir>
+#include <QFile>
+
+class LogThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit LogThread(QObject *parent = nullptr);
+    void appendData(QString data);
+    void run();
+    void stop();
+signals:
+
+public slots:
+private:
+    QFile *file;
+    QStringList dataList;
+    int day;
+    bool keep;
+};
+
+#endif // LOGTHREAD_H

+ 12 - 0
agElevatorProcess/main.cpp

@@ -0,0 +1,12 @@
+#include <QCoreApplication>
+#include "elevatorcore.h"
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    ElevatorCore *core = new ElevatorCore(nullptr);
+    core->start();
+
+    return a.exec();
+}

+ 27 - 0
agEnvironmentProcess/agEnvironmentProcess.pro

@@ -0,0 +1,27 @@
+QT += core sql network
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+TARGET = agDP0005
+
+
+SOURCES += \
+        main.cpp \
+    logthread.cpp \
+    environmentcore.cpp \
+    mqttsub.cpp \
+    mqttpub.cpp
+
+INCLUDEPATH += ../qmqtt-master/src/mqtt/
+
+HEADERS += \
+    logthread.h \
+    environmentcore.h \
+    mqttsub.h \
+    mqttpub.h
+
+
+LIBS += -lQt5Qmqtt
+

+ 135 - 0
agEnvironmentProcess/environmentcore.cpp

@@ -0,0 +1,135 @@
+#include "environmentcore.h"
+#include "../AGBoxDog/boxshm.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+AGBoxShm *agBoxShm;
+BoxDeviceShm *boxDeviceShm;
+
+void EnvironmentCore::shm_init(){
+    QSqlQuery qry;
+    QString sql = QString("select mqtt_ip,mqtt_port,user_name,pass_word from yt_t_mqtt where item_name = 'data-agbox'");
+    qry = db.exec(sql);
+    while (qry.next()) {
+        ip = qry.value(0).toString();
+        port = qry.value(1).toString();
+        username = qry.value(2).toString();
+        password = qry.value(3).toString();
+    }
+    qry.clear();
+    sql.clear();
+
+}
+
+bool EnvironmentCore::shm_load(){
+    key_t key;
+    int shmid;
+    if((key=ftok(SHM_PATH,static_cast<int>(SHM_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(AGBoxShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    agBoxShm = static_cast<AGBoxShm *>(shmat(shmid,nullptr,0));
+
+    if((key=ftok(VIDEO_PATH,static_cast<int>(VIDEO_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(BoxDeviceShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    boxDeviceShm = static_cast<BoxDeviceShm *>(shmat(shmid,nullptr,0));
+
+    shm_init();
+    return true;
+}
+
+EnvironmentCore::EnvironmentCore(QObject *parent) : QObject(parent)
+{
+    logthread = new LogThread(this);
+    logthread->start();
+
+    db = QSqlDatabase::addDatabase("QSQLITE","conf_db");
+    db.setDatabaseName(QString("/opt/db/yt_conf.db"));
+    if(!db.open()){
+        logthread->appendData(QString("[agenvironment] open yt_conf.db failed"));
+    }
+    if(shm_load()){
+        logthread->appendData(QString("[agenvironment] shm load success"));
+    }
+
+    mqttIdx = 1;
+    m_client = new QMQTT::Client(QHostAddress(ip),static_cast<quint16>(port.toInt()),this);
+    connect(m_client,&QMQTT::Client::connected,this,&EnvironmentCore::onConnected);
+    m_client->setUsername(username);
+    m_client->setPassword(password.toLatin1());
+    m_client->setCleanSession(true);
+    m_client->connectToHost();
+
+    mqttsub = new MqttSub(this);
+    connect(mqttsub,&MqttSub::sendMqttData,this,&EnvironmentCore::receiveDevData);
+
+    mqttpub = new MqttPub(this);
+    connect(mqttpub,&MqttPub::mqttData,this,&EnvironmentCore::mqtt_data);
+    connect(mqttpub,&MqttPub::dataListLog,this,&EnvironmentCore::dataLog);
+
+    timer = new QTimer(this);
+    connect(timer,&QTimer::timeout,this,&EnvironmentCore::time_out);
+    timer->start(300000);
+
+}
+
+
+EnvironmentCore::~EnvironmentCore()
+{
+    logthread->stop();
+    mqttpub->stop();
+
+}
+
+void EnvironmentCore::start()
+{
+    mqttsub->start();
+    mqttsub->mqtt_conf(ip,port,username,password);
+
+    mqttsub->start();
+}
+
+void EnvironmentCore::time_out()
+{
+    for(int i=0;i<1024;i++){
+        if(boxDeviceShm->device[i].Enabled == 0x01){
+            uint curTime = QDateTime::currentDateTime().toTime_t();
+            if((curTime - boxDeviceShm->device[i].lastTime)>7200){
+                boxDeviceShm->device[i].lastTime = QDateTime::currentDateTime().toTime_t();
+                this->mqtt_data(QString("{\"device_id\":\"%1\",\"device_code\":\"%2\",\"product_id\":\"%3\",\"timestamp\":%4,\"tags\":{\"conn_type\":\"\",\"type\":\"\"},\"metrics\":{\"device_status\":0},\"device_type\":\"%6-ev\"}")
+                              .arg(boxDeviceShm->device[i].device_id).arg(boxDeviceShm->device[i].device_code).arg(boxDeviceShm->device[i].company_code).arg(curTime).arg(boxDeviceShm->device[i].device_type));
+            }
+        }
+    }
+}
+
+void EnvironmentCore::onConnected()
+{
+    logthread->appendData(QString("mqtt onConnected"));
+}
+
+void EnvironmentCore::dataLog(QString log)
+{
+    logthread->appendData(log);
+}
+
+void EnvironmentCore::mqtt_data(QString mqtt_msg)
+{
+    printf("test5555 [%s]\n",mqtt_msg.toUtf8().data());
+    if((m_client->connectionState()==QMQTT::STATE_INIT)||(m_client->connectionState()==QMQTT::STATE_DISCONNECTED)){
+        m_client->connectToHost();
+    }
+    m_client->publish(QMQTT::Message(mqttIdx++,"data-collector",mqtt_msg.toUtf8()));
+    if(mqttIdx > 9999){
+        mqttIdx = 1;
+    }
+}
+
+void EnvironmentCore::receiveDevData(QString topic,QByteArray data)
+{
+    mqttpub->devMessage(MqttData(topic,data));
+}

+ 45 - 0
agEnvironmentProcess/environmentcore.h

@@ -0,0 +1,45 @@
+#ifndef ENVIRONMENTCORE_H
+#define ENVIRONMENTCORE_H
+
+#include <QObject>
+#include <qmqtt.h>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QDateTime>
+#include <QTimer>
+#include "logthread.h"
+#include "mqttpub.h"
+#include "mqttsub.h"
+
+class EnvironmentCore : public QObject
+{
+    Q_OBJECT
+public:
+    explicit EnvironmentCore(QObject *parent = nullptr);
+    ~EnvironmentCore();
+    void start();
+    void shm_init();
+    bool shm_load();
+
+signals:
+
+public slots:
+    void onConnected();
+    void dataLog(QString log);
+    void receiveDevData(QString topic,QByteArray data);
+    void mqtt_data(QString mqtt_msg);
+    void time_out();
+
+private:
+    LogThread *logthread;
+    MqttPub *mqttpub;
+    MqttSub *mqttsub;
+
+    QMQTT::Client *m_client;
+    QSqlDatabase db;
+    quint16 mqttIdx;
+    QString ip,port,username,password;
+    QTimer *timer;
+};
+
+#endif // ENVIRONMENTCORE_H

+ 52 - 0
agEnvironmentProcess/logthread.cpp

@@ -0,0 +1,52 @@
+#include "logthread.h"
+
+LogThread::LogThread(QObject *parent) :
+    QThread(parent)
+{
+    keep = false;
+    dataList.clear();
+    QDir path("/usky/data-agbox/agenvironment/log");
+    if(!path.exists()){
+        system("mkdir -p /usky/data-agbox/agenvironment/log/");
+    }
+    file = new QFile("/usky/data-agbox/agenvironment/log/environment-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+    day = QDate::currentDate().day();
+}
+
+void LogThread::appendData(QString data)
+{
+    dataList.append(data);
+}
+
+void LogThread::stop()
+{
+    keep = false;
+}
+
+void LogThread::run()
+{
+    printf("log thread start\n");
+    if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+        file->write(QString("agEnvironmentProcess start at %1.\r\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).toUtf8());
+        file->close();
+    }
+    keep = true;
+    while(keep){
+        if(dataList.length()>0){
+            if(day!=QDate::currentDate().day()){
+                day = QDate::currentDate().day();
+                file = new QFile("/usky/data-agbox/agenvironment/log/environment-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+            }
+            if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(dataList.length()>0){
+                    file->write(dataList.first().toUtf8());
+                    file->write("\r\n");
+                    dataList.removeFirst();
+                    usleep(1000);
+                }
+                file->close();
+            }
+        }
+        usleep(50000);
+    }
+}

+ 28 - 0
agEnvironmentProcess/logthread.h

@@ -0,0 +1,28 @@
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QStringList>
+#include <QDate>
+#include <QDir>
+#include <QFile>
+
+class LogThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit LogThread(QObject *parent = nullptr);
+    void appendData(QString data);
+    void run();
+    void stop();
+signals:
+
+public slots:
+private:
+    QFile *file;
+    QStringList dataList;
+    int day;
+    bool keep;
+};
+
+#endif // LOGTHREAD_H

+ 12 - 0
agEnvironmentProcess/main.cpp

@@ -0,0 +1,12 @@
+#include <QCoreApplication>
+#include "environmentcore.h"
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    EnvironmentCore *core = new EnvironmentCore(nullptr);
+    core->start();
+
+    return a.exec();
+}

+ 121 - 0
agEnvironmentProcess/mqttpub.cpp

@@ -0,0 +1,121 @@
+#include "mqttpub.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+
+MqttPub::MqttPub(QObject *parent) : QThread(parent)
+{
+    keep = false;
+    mqttDataList.clear();
+
+
+}
+
+void MqttPub::stop()
+{
+    keep = false;
+
+}
+
+
+void MqttPub::run()
+{
+    keep = true;
+    while (keep) {
+        if(mqttDataList.length()>0){
+            while (mqttDataList.length()>0) {
+                MqttData md = mqttDataList.first();
+                QString topic = md.topic;
+                QByteArray data = md.data;
+
+
+                QJsonParseError parseErr;
+                QJsonDocument doc = QJsonDocument::fromJson(data,&parseErr);
+                printf("environment parseErr.error %d\n",parseErr.error);
+                if(parseErr.error==QJsonParseError::NoError){
+                    QString nodeInfo = "";
+                    QString deviceId = "";
+                    QString companyCode = "";
+                    QString deviceType = "";
+                    QJsonObject obj_doc = doc.object();
+                    QString sn = obj_doc.value("sn").toString();
+                    int ts = obj_doc.value("ts").toInt();
+                    QJsonValue dev_value = obj_doc.value("devs");
+                    if(dev_value.isArray()){
+                        QJsonArray list_array = dev_value.toArray();
+                        for(int i=0;i<list_array.size();i++){
+                            QJsonObject obj_dev = list_array.at(i).toObject();
+                            QString deviceCode = sn + "-" + obj_dev.value("dev").toString();
+                            printf("deviceCode: %s\n",deviceCode.toUtf8().data());
+                            for(int i=0;i<1024;i++){
+                                if(boxDeviceShm->device[i].Enabled == 0x01){
+                                    if(deviceCode.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                        deviceId = QString(boxDeviceShm->device[i].device_id);
+                                        companyCode = QString(boxDeviceShm->device[i].company_code);
+                                        deviceType = QString::number(boxDeviceShm->device[i].device_type);
+                                        boxDeviceShm->device->lastTime = QDateTime::currentDateTime().toTime_t();
+                                        break;
+                                    }
+                                }
+                            }
+
+                            QJsonValue d_value = obj_dev.value("d");
+                            if(d_value.isArray()){
+                                QJsonArray d_array = d_value.toArray();
+                                if(d_array.size()==8){
+                                    for(int i=0;i<d_array.size();i++){
+                                        QJsonObject list_object = d_array.at(i).toObject();
+                                        QString name = list_object.value("m").toString();
+                                        double value = list_object.value("v").toDouble();
+
+                                        for(int i=0;i<300;i++){
+                                            if(name.compare(QString(boxDeviceShm->procuctattrbute[i].attribute_name))==0){
+                                                nodeInfo.append(QString("\"%1\":%2,").arg(QString(boxDeviceShm->procuctattrbute[i].attribute_code)).arg(value));
+                                                break;
+                                            }
+                                        }
+
+                                    }
+                                    nodeInfo.append(QString("\"device_status\":1"));
+                                    emit mqttData(QString("{\"device_id\":\"%1\",\"device_code\":\"%2\",\"product_id\":\"%3\",\"timestamp\":%4,\"tags\":{\"conn_type\":\"\",\"type\":\"\"},\"metrics\":{%5},\"device_type\":\"%6-ev\"}")
+                                                  .arg(deviceId).arg(deviceCode).arg(companyCode).arg(ts).arg(nodeInfo).arg(deviceType));
+
+                                }
+                            }
+
+                        }
+                    }
+
+                }
+
+
+                mqttDataList.removeFirst();
+                usleep(1000);
+            }
+        }
+
+
+        usleep(50000);
+    }
+}
+
+void MqttPub::devMessage(MqttData dev)
+{
+    mqttDataList.append(dev);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 45 - 0
agEnvironmentProcess/mqttpub.h

@@ -0,0 +1,45 @@
+#ifndef MQTTPUB_H
+#define MQTTPUB_H
+
+#include <QThread>
+#include <QDateTime>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonParseError>
+#include <QVariantMap>
+
+class MqttData{
+public:
+    explicit MqttData(QString t="",QByteArray d=""){
+        topic = t;
+        data = d;
+    }
+    QString topic;
+    QByteArray data;
+};
+
+
+class MqttPub : public QThread
+{
+    Q_OBJECT
+public:
+    explicit MqttPub(QObject *parent = nullptr);
+    void run();
+    void stop();
+    void devMessage(MqttData dev);
+
+
+signals:
+    void mqttData(QString mqtt_msg);
+    void dataListLog(QString msg);
+
+public slots:
+
+private:
+    bool keep;
+    QList<MqttData> mqttDataList;
+};
+
+#endif // MQTTPUB_H

+ 69 - 0
agEnvironmentProcess/mqttsub.cpp

@@ -0,0 +1,69 @@
+#include "mqttsub.h"
+#include "../AGBoxDog/boxshm.h"
+
+MqttSub::MqttSub(QObject *parent) : QThread(parent)
+{
+
+    timer = new QTimer(this);
+    connect(timer,&QTimer::timeout,this,&MqttSub::time_out);
+}
+
+void MqttSub::run()
+{
+
+}
+
+void MqttSub::time_out()
+{
+    agBoxShm->processStatus[5].t_time=QDateTime::currentDateTime().toTime_t();
+
+    if((m_client->connectionState()==QMQTT::STATE_DISCONNECTED)||(m_client->connectionState()==QMQTT::STATE_INIT)){
+        m_client->connectToHost();
+    }
+}
+
+void MqttSub::mqtt_conf(QString ip,QString port,QString username,QString password)
+{
+    mqtt_ip = ip;
+    mqtt_port = port;
+    mqtt_username = username;
+    mqtt_passwd = password;
+
+
+    m_client = new QMQTT::Client(QHostAddress(mqtt_ip),static_cast<quint16>(mqtt_port.toInt()),this);
+    m_client->setUsername(mqtt_username);
+    m_client->setPassword(mqtt_passwd.toLatin1());
+    m_client->setCleanSession(true);
+    connect(m_client,&QMQTT::Client::connected,this,&MqttSub::onConnected);
+    connect(m_client,&QMQTT::Client::received,this,&MqttSub::onReceived);
+    m_client->connectToHost();
+
+
+    timer->start(1000);
+}
+
+void MqttSub::onConnected()
+{
+    m_client->subscribe("/edge/bainfo/72B4884AE5CB4407B4D5D0BACB509D79/rtg",0);
+    m_client->subscribe("/edge/bainfo/271ACE89CB504642950FC7B3C2505205/rtg",0);
+    m_client->subscribe("/edge/bainfo/9849B7BE3D204EF984D851EC067BF9C1/rtg",0);
+    m_client->subscribe("/edge/bainfo/CE1A787947914261B2ADAF5AA9FC1EBC/rtg",0);
+
+}
+
+void MqttSub::onReceived(const QMQTT::Message &message)
+{
+
+    QString topic = message.topic();
+    QByteArray data = message.payload();
+
+    emit sendMqttData(topic,data);
+}
+
+
+
+
+
+
+
+

+ 34 - 0
agEnvironmentProcess/mqttsub.h

@@ -0,0 +1,34 @@
+#ifndef MQTTSUB_H
+#define MQTTSUB_H
+
+#include <QThread>
+#include <qmqtt.h>
+#include <QDateTime>
+#include <QTimer>
+
+class MqttSub : public QThread
+{
+    Q_OBJECT
+public:
+    explicit MqttSub(QObject *parent = nullptr);
+    void run();
+    void mqtt_conf(QString ip,QString port,QString username,QString password);
+
+signals:
+    void mq_log(QString log);
+    void sendMqttData(QString topic,QByteArray data);
+
+public slots:
+    void time_out();
+    void onConnected();
+    void onReceived(const QMQTT::Message &message);
+
+private:
+    QString mqtt_ip,mqtt_port,mqtt_username,mqtt_passwd;
+    QTimer *timer;
+
+    QMQTT::Client *m_client;
+
+};
+
+#endif // MQTTSUB_H

+ 26 - 0
agGeneratorProcess/agGeneratorProcess.pro

@@ -0,0 +1,26 @@
+QT += core sql network
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+TARGET = agDP0004
+
+
+SOURCES += \
+        main.cpp \
+    logthread.cpp \
+    databasethread.cpp \
+    httpthread.cpp \
+    generatorcore.cpp
+
+INCLUDEPATH += ../qmqtt-master/src/mqtt/
+
+HEADERS += \
+    logthread.h \
+    ../QReplyTimeout.h \
+    databasethread.h \
+    httpthread.h \
+    generatorcore.h
+
+LIBS += -lQt5Qmqtt

+ 88 - 0
agGeneratorProcess/databasethread.cpp

@@ -0,0 +1,88 @@
+#include "databasethread.h"
+
+#define HostName "172.17.35.51"
+#define HostPort 3306
+#define UserName "usky"
+#define PassWord "Yt#75Usky"
+#define DatabaseName "usky-park"
+
+DatabaseThread::DatabaseThread(QObject *parent) : QThread(parent)
+{
+    hour = 255;
+    keep=false;
+    sqlList.clear();
+    alarmList.clear();
+
+    db = QSqlDatabase::addDatabase("QMYSQL","write_db");
+    db.setHostName(QString(HostName));
+    db.setPort(HostPort);
+    db.setUserName(QString(UserName));
+    db.setPassword(QString(PassWord));
+    db.setDatabaseName(QString(DatabaseName));
+
+
+
+}
+
+void DatabaseThread::appendSql(QString sql)
+{
+    sqlList.append(sql);
+}
+
+void DatabaseThread::appendAlarm(QString sql)
+{
+    alarmList.append(sql);
+}
+
+
+void DatabaseThread::stop()
+{
+    keep = false;
+}
+
+void DatabaseThread::run()
+{
+    keep = true;
+    while (keep) {
+
+        if(!db.open()){
+            emit dbdata_log(QString("[%1] agGeneratorProcess DatabaseThread db open failed").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")));
+        }else{
+            if(sqlList.length()>0){
+                while (sqlList.length()>0) {
+
+                    emit dbdata_log(QString("[%1] agGeneratorProcess sql %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).arg(sqlList.first()));
+
+                    db.exec(sqlList.first());
+
+                    sqlList.removeFirst();
+                    usleep(1000);
+                }
+            }
+            if(alarmList.length()>0){
+                while (alarmList.length()>0) {
+                    db.exec(alarmList.first());
+
+                    emit dbdata_log(QString("[%1] agGeneratorProcess alarm sql %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).arg(alarmList.first()));
+
+                    alarmList.removeFirst();
+                    usleep(1000);
+                }
+            }
+        }
+        usleep(50000);
+    }
+
+
+}
+
+
+
+
+
+
+
+
+
+
+

+ 37 - 0
agGeneratorProcess/databasethread.h

@@ -0,0 +1,37 @@
+#ifndef DATABASETHREAD_H
+#define DATABASETHREAD_H
+
+#include <QThread>
+#include <QDateTime>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QVariant>
+#include <QStringList>
+
+
+class DatabaseThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit DatabaseThread(QObject *parent = nullptr);
+    void run();
+    void stop();
+    void appendSql(QString sql);
+    void appendAlarm(QString sql);
+
+
+signals:
+    void dbdata_log(QString log);
+
+public slots:
+
+private:
+    int hour;
+    bool keep;
+
+    QSqlDatabase db;
+    QStringList sqlList,alarmList;
+
+};
+
+#endif // DATABASETHREAD_H

+ 118 - 0
agGeneratorProcess/generatorcore.cpp

@@ -0,0 +1,118 @@
+#include "generatorcore.h"
+#include "../AGBoxDog/boxshm.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+AGBoxShm *agBoxShm;
+BoxDeviceShm *boxDeviceShm;
+
+void GeneratorCore::shm_init(){
+    QSqlQuery qry;
+    QString sql = QString("select mqtt_ip,mqtt_port,user_name,pass_word from yt_t_mqtt where item_name = 'data-agbox'");
+    qry = db.exec(sql);
+    while (qry.next()) {
+        ip = qry.value(0).toString();
+        port = qry.value(1).toString();
+        username = qry.value(2).toString();
+        password = qry.value(3).toString();
+    }
+    qry.clear();
+    sql.clear();
+
+}
+
+bool GeneratorCore::shm_load(){
+    key_t key;
+    int shmid;
+    if((key=ftok(SHM_PATH,static_cast<int>(SHM_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(AGBoxShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    agBoxShm = static_cast<AGBoxShm *>(shmat(shmid,nullptr,0));
+
+    if((key=ftok(VIDEO_PATH,static_cast<int>(VIDEO_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(BoxDeviceShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    boxDeviceShm = static_cast<BoxDeviceShm *>(shmat(shmid,nullptr,0));
+
+    shm_init();
+    return true;
+}
+
+GeneratorCore::GeneratorCore(QObject *parent) : QObject(parent)
+{
+    logthread = new LogThread(this);
+    logthread->start();
+
+    db = QSqlDatabase::addDatabase("QSQLITE","conf_db");
+    db.setDatabaseName(QString("/opt/db/yt_conf.db"));
+    if(!db.open()){
+        logthread->appendData(QString("[aggenerator] open yt_conf.db failed"));
+    }
+    if(shm_load()){
+        logthread->appendData(QString("[aggenerator] shm load success"));
+    }
+
+    mqttIdx = 1;
+    m_client = new QMQTT::Client(QHostAddress(ip),static_cast<quint16>(port.toInt()),this);
+    connect(m_client,&QMQTT::Client::connected,this,&GeneratorCore::onConnected);
+    m_client->setUsername(username);
+    m_client->setPassword(password.toLatin1());
+    m_client->setCleanSession(true);
+    m_client->connectToHost();
+
+    dbthread = new DatabaseThread(this);
+    dbthread->start();
+
+    httpthread = new HttpThread(this);
+    connect(httpthread,&HttpThread::dataLog,this,&GeneratorCore::dataLog);
+    connect(httpthread,&HttpThread::mqttData,this,&GeneratorCore::mqtt_data);
+    connect(httpthread,&HttpThread::appendSql,this,&GeneratorCore::append_sql);
+
+}
+
+
+GeneratorCore::~GeneratorCore()
+{
+    logthread->stop();
+    dbthread->stop();
+    httpthread->stop();
+}
+
+void GeneratorCore::start()
+{
+
+}
+void GeneratorCore::onConnected()
+{
+    logthread->appendData(QString("mqtt onConnected"));
+}
+
+void GeneratorCore::dataLog(QString log)
+{
+    logthread->appendData(log);
+}
+
+void GeneratorCore::mqtt_data(QString mqtt_msg)
+{
+    printf("test4444 [%s]\n",mqtt_msg.toUtf8().data());
+    if((m_client->connectionState()==QMQTT::STATE_INIT)||(m_client->connectionState()==QMQTT::STATE_DISCONNECTED)){
+        m_client->connectToHost();
+    }
+    m_client->publish(QMQTT::Message(mqttIdx++,"data-collector",mqtt_msg.toUtf8()));
+    if(mqttIdx > 9999){
+        mqttIdx = 1;
+    }
+}
+
+void GeneratorCore::append_sql(QString sql)
+{
+    dbthread->appendSql(sql);
+}
+
+
+
+

+ 41 - 0
agGeneratorProcess/generatorcore.h

@@ -0,0 +1,41 @@
+#ifndef GENERATORCORE_H
+#define GENERATORCORE_H
+
+#include <QObject>
+#include <qmqtt.h>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include "logthread.h"
+#include "httpthread.h"
+#include "databasethread.h"
+
+class GeneratorCore : public QObject
+{
+    Q_OBJECT
+public:
+    explicit GeneratorCore(QObject *parent = nullptr);
+    ~GeneratorCore();
+    void start();
+    bool shm_load();
+    void shm_init();
+
+signals:
+
+public slots:
+    void onConnected();
+    void dataLog(QString log);
+    void mqtt_data(QString mqtt_msg);
+    void append_sql(QString sql);
+
+private:
+    LogThread *logthread;
+    HttpThread *httpthread;
+    DatabaseThread *dbthread;
+
+    QMQTT::Client *m_client;
+    QSqlDatabase db;
+    quint16 mqttIdx;
+    QString ip,port,username,password;
+};
+
+#endif // GENERATORCORE_H

+ 330 - 0
agGeneratorProcess/httpthread.cpp

@@ -0,0 +1,330 @@
+#include "httpthread.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+#include "../AGBoxDog/boxshm.h"
+
+HttpThread::HttpThread(QObject *parent) : QObject(parent)
+{
+    minute = 255;
+    minute1 = 255;
+    minute2 = 255;
+    list<<245<<246<<247<<248<<249<<250;
+    keep = false;
+    isWaiting = false;
+    networkManager = new QNetworkAccessManager(this); //机房系统设备心跳数据
+    connect(networkManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot(QNetworkReply *)));
+    isWaiting1 = false;
+    networkManager1 = new QNetworkAccessManager(this); //机房系统设备状态
+    connect(networkManager1,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot1(QNetworkReply *)));
+    isWaiting2 = false;
+    networkManager2 = new QNetworkAccessManager(this); //机房系统设备告警数据
+    connect(networkManager2,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot2(QNetworkReply *)));
+
+    timer = new QTimer(this);
+    connect(timer,&QTimer::timeout,this,&HttpThread::time_out);
+    timer->start(5000);
+
+}
+
+void HttpThread::stop()
+{
+    keep = false;
+}
+
+void  HttpThread::finishedSlot(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("attribute data parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QString nodeInfo = "";
+            QString deviceId = "";
+            QString companyCode = "";
+            QString deviceType = "";
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("data");
+            if(list_value.isArray()){
+                QJsonArray list_array = list_value.toArray();
+
+                QJsonObject list_object0 = list_array.at(0).toObject();
+                QString device_code = QString::number(list_object0.value("node_id").toInt());
+                printf("attribute data device_code %s\n",device_code.toUtf8().data());
+                for(int i=0;i<1024;i++){
+                    if(boxDeviceShm->device[i].Enabled == 0x01){
+                        if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                            deviceId = QString(boxDeviceShm->device[i].device_id);
+                            companyCode = QString(boxDeviceShm->device[i].company_code);
+                            deviceType = QString::number(boxDeviceShm->device[i].device_type);
+                            break;
+                        }
+                    }
+                }
+
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString name = list_object.value("name").toString();
+                    double value = list_object.value("sdata").toDouble();
+
+                    for(int j=0;j<300;j++){
+                        if(name.compare(QString(boxDeviceShm->procuctattrbute[j].attribute_name))==0){
+                            nodeInfo.append(QString("\"%1\":%2,").arg(QString(boxDeviceShm->procuctattrbute[j].attribute_code)).arg(value));
+                            break;
+                        }
+                    }
+
+                }
+                nodeInfo=nodeInfo.left(nodeInfo.length()-1);
+                emit mqttData(QString("{\"device_id\":\"%1\",\"device_code\":\"%2\",\"product_id\":\"%3\",\"timestamp\":%4,\"tags\":{\"conn_type\":\"\",\"type\":\"\"},\"metrics\":{%5},\"device_type\":\"%6-gr\"}")
+                              .arg(deviceId).arg(device_code).arg(companyCode).arg(QDateTime::currentDateTime().toTime_t()).arg(nodeInfo).arg(deviceType));
+            }
+
+        }else{
+            emit dataLog(QString("attribute data QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] attribute data QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] attribute data QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout()
+{
+    printf("[%s] attribute data reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting = false;
+}
+
+void  HttpThread::finishedSlot1(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("status parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("data");
+            if(list_value.isArray()){
+                QJsonArray list_array = list_value.toArray();
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString device_code = QString::number(list_object.value("id").toInt());
+                    QJsonValue status_value = list_object.value("data");
+                    QJsonObject status_object = status_value.toObject();
+                    QString status = status_object.value("iot_node_status").toString();
+
+                    int deviceStatus = 0;
+                    if(status.compare("在线")==0){
+                        deviceStatus = 1;
+                    }else{
+                        deviceStatus = 0;
+                    }
+                    for(int i=0;i<1024;i++){
+                        if(boxDeviceShm->device[i].Enabled == 0x01){
+                            if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                emit mqttData(QString("{\"device_id\":\"%1\",\"device_code\":\"%2\",\"product_id\":\"%3\",\"timestamp\":%4,\"tags\":{\"conn_type\":\"\",\"type\":\"\"},\"metrics\":{\"device_status\":%5},\"device_type\":\"%6-gr\"}")
+                                              .arg(QString(boxDeviceShm->device[i].device_id)).arg(device_code).arg(QString(boxDeviceShm->device[i].company_code)).arg(QDateTime::currentDateTime().toTime_t()).arg(deviceStatus).arg(boxDeviceShm->device[i].device_type));
+                                break;
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+
+        }else{
+            emit dataLog(QString("status QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] status QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] status QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting1 = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout1()
+{
+    printf("[%s] status reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting1 = false;
+}
+
+void  HttpThread::finishedSlot2(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("alarm parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("data");
+            if(list_value.isArray()){
+                emit appendSql(QString("delete from alarm_gr where alarm_time >= '%1' and alarm_time <= '%2';").arg(startTime).arg(endTime));
+                QJsonArray list_array = list_value.toArray();
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString device_name = list_object.value("node_name").toString();
+                    QString device_code = "";
+                    if(device_name.compare("温湿度监控")==0){
+                        device_code = QString("245");
+                    }else if(device_name.compare("数据采集主机")==0){
+                        device_code = QString("246");
+                    }else if(device_name.compare("市电监测")==0){
+                        device_code = QString("247");
+                    }else if(device_name.compare("UPS监测")==0){
+                        device_code = QString("248");
+                    }else if(device_name.compare("黑盾精密空调1")==0){
+                        device_code = QString("249");
+                    }else if(device_name.compare("黑盾精密空调2")==0){
+                        device_code = QString("250");
+                    }
+
+                    QJsonValue alarm_value = list_object.value("data");
+                    QJsonObject alarm_object = alarm_value.toObject();
+                    QString alarmLevel = alarm_object.value("iot_trigger_alarm_level").toString();
+                    QString handling_status = alarm_object.value("iot_trigger_alarm_level").toString();
+                    int handlingStatus = 0;
+                    if(handling_status.compare("未处理")==0){
+                        handlingStatus = 0;
+                    }else{
+                        handlingStatus = 1;
+                    }
+                    QString alarmDesc = list_object.value("description").toString();
+                    QString alarmTime = list_object.value("atimestr").toString();
+                    double alarmValue = list_object.value("sdata").toDouble();
+                    for(int i=0;i<1024;i++){
+                        if(boxDeviceShm->device[i].Enabled == 0x01){
+                            if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                emit appendSql(QString::fromLocal8Bit("insert into alarm_gr(device_id, device_code, device_name, alarm_type, alarm_desc, alarm_time, alarm_value, handling_status) values('%1','%2','%3','%4','%5','%6',%7,%8);")
+                                              .arg(QString(boxDeviceShm->device[i].device_id)).arg(device_code).arg(device_name).arg(alarmLevel).arg(alarmDesc).arg(alarmTime).arg(alarmValue).arg(handlingStatus));
+                                break;
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+
+        }else{
+            emit dataLog(QString("alarm QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] alarm QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] alarm QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting2 = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout2()
+{
+    printf("[%s] alarm reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting2 = false;
+}
+
+void HttpThread::time_out()
+{
+    agBoxShm->processStatus[4].t_time=QDateTime::currentDateTime().toTime_t();
+
+    if(QDateTime::currentDateTime().time().minute()!=minute){//每分钟执行一次,同步设备属性数据
+        minute = QDateTime::currentDateTime().time().minute();
+
+        if(!isWaiting){
+            for(int i=0;i<list.size();i++){
+                isWaiting = true;
+                QNetworkRequest *req = new QNetworkRequest();
+                req->setUrl(QUrl("http://172.17.200.209:8080/service/page/sensor.json?paged=1&pageSize=30"));
+                req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+                req->setRawHeader("USER-KEY","426aad8a150a4d85a8fa7221085edca3");
+                QString postdata = QString("{\"node_id\": %1}").arg(list.at(i));
+                req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+                QNetworkReply *reply = networkManager->post(*req,postdata.toUtf8());
+                QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+                connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout()));
+
+            }
+
+        }
+    }
+
+    if(QDateTime::currentDateTime().time().minute()!=minute1){//每半个小时执行一次,同步设备状态
+      minute1 = QDateTime::currentDateTime().time().minute();
+      if(!isWaiting1 && ((minute1==00)||(minute1==30))){
+          isWaiting1 = true;
+          QNetworkRequest *req = new QNetworkRequest();
+          req->setUrl(QUrl("http://172.17.200.209:8080/service/page/node.json?paged=1"));
+          req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+          req->setRawHeader("USER-KEY","426aad8a150a4d85a8fa7221085edca3");
+          QString postdata = QString("{\"scene_id\": 31}");
+          req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+          QNetworkReply *reply = networkManager1->post(*req,postdata.toUtf8());
+          QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+          connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout1()));
+
+      }
+  }
+
+    if(QDateTime::currentDateTime().time().minute()!=minute2){//每分钟执行一次,统计从现在算起之前10分钟时间内的机房告警记录(插入之前先执行删除这个时间端数据的命令)
+        minute2 = QDateTime::currentDateTime().time().minute();
+        QString tempTime1 = QDateTime::currentDateTime().addSecs(-600).toString("yyyy-MM-dd HH:mm");
+        QString tempTime2 = QDateTime::currentDateTime().addSecs(-60).toString("yyyy-MM-dd HH:mm");
+        startTime = QString("%1:00").arg(tempTime1);
+        endTime = QString("%1:59").arg(tempTime2);
+
+        printf("startTime: %s, endTime %s\n",startTime.toUtf8().data(),endTime.toUtf8().data());
+
+        if(!isWaiting2){
+            isWaiting2 = true;
+            QNetworkRequest *req = new QNetworkRequest();
+            req->setUrl(QUrl("http://172.17.200.209:8080/service/page/alarm.json?paged=1&pageSize=50"));
+            req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+            req->setRawHeader("USER-KEY","426aad8a150a4d85a8fa7221085edca3");
+            QString postdata = QString("{\"start_time\": \"%1\",\"end_time\": \"%2\"}").arg(startTime).arg(endTime);
+            emit dataLog(QString(" events QNetworkReply event [%1]").arg(postdata));
+            req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+            QNetworkReply *reply = networkManager2->post(*req,postdata.toUtf8());
+            QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+            connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout2()));
+
+        }
+    }
+
+}
+
+
+
+
+
+
+
+
+

+ 53 - 0
agGeneratorProcess/httpthread.h

@@ -0,0 +1,53 @@
+#ifndef HTTPTHREAD_H
+#define HTTPTHREAD_H
+
+#include <QObject>
+#include <QDateTime>
+#include <QTimer>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QSslConfiguration>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonParseError>
+#include "../QReplyTimeout.h"
+
+class HttpThread : public QObject
+{
+    Q_OBJECT
+public:
+    explicit HttpThread(QObject *parent = nullptr);
+    void run();
+    void stop();
+
+signals:
+    void dataLog(QString log);
+    void mqttData(QString mqtt_msg);
+    void appendSql(QString sql);
+
+public slots:
+    void time_out();
+    void finishedSlot(QNetworkReply *reply);
+    void finishedSlot1(QNetworkReply *reply);
+    void finishedSlot2(QNetworkReply *reply);
+    void reply_timeout();
+    void reply_timeout1();
+    void reply_timeout2();
+
+private:
+    bool isWaiting,isWaiting1,isWaiting2;
+    bool keep;
+    int minute,minute1,minute2;
+    QString startTime,endTime;
+    QList<int> list;
+    QNetworkAccessManager *networkManager,*networkManager1,*networkManager2;
+    QSslConfiguration config;
+    QTimer *timer;
+
+
+};
+
+#endif // HTTPTHREAD_H

+ 52 - 0
agGeneratorProcess/logthread.cpp

@@ -0,0 +1,52 @@
+#include "logthread.h"
+
+LogThread::LogThread(QObject *parent) :
+    QThread(parent)
+{
+    keep = false;
+    dataList.clear();
+    QDir path("/usky/data-agbox/aggenerator/log");
+    if(!path.exists()){
+        system("mkdir -p /usky/data-agbox/aggenerator/log/");
+    }
+    file = new QFile("/usky/data-agbox/aggenerator/log/generator-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+    day = QDate::currentDate().day();
+}
+
+void LogThread::appendData(QString data)
+{
+    dataList.append(data);
+}
+
+void LogThread::stop()
+{
+    keep = false;
+}
+
+void LogThread::run()
+{
+    printf("log thread start\n");
+    if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+        file->write(QString("agGeneratorProcess start at %1.\r\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).toUtf8());
+        file->close();
+    }
+    keep = true;
+    while(keep){
+        if(dataList.length()>0){
+            if(day!=QDate::currentDate().day()){
+                day = QDate::currentDate().day();
+                file = new QFile("/usky/data-agbox/aggenerator/log/generator-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+            }
+            if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(dataList.length()>0){
+                    file->write(dataList.first().toUtf8());
+                    file->write("\r\n");
+                    dataList.removeFirst();
+                    usleep(1000);
+                }
+                file->close();
+            }
+        }
+        usleep(50000);
+    }
+}

+ 28 - 0
agGeneratorProcess/logthread.h

@@ -0,0 +1,28 @@
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QStringList>
+#include <QDate>
+#include <QDir>
+#include <QFile>
+
+class LogThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit LogThread(QObject *parent = nullptr);
+    void appendData(QString data);
+    void run();
+    void stop();
+signals:
+
+public slots:
+private:
+    QFile *file;
+    QStringList dataList;
+    int day;
+    bool keep;
+};
+
+#endif // LOGTHREAD_H

+ 12 - 0
agGeneratorProcess/main.cpp

@@ -0,0 +1,12 @@
+#include <QCoreApplication>
+#include "generatorcore.h"
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    GeneratorCore *core = new GeneratorCore(nullptr);
+    core->start();
+
+    return a.exec();
+}

+ 28 - 0
agGuardProcess/agGuardProcess.pro

@@ -0,0 +1,28 @@
+QT += core sql network
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+TARGET = agDP0002
+
+
+SOURCES += \
+        main.cpp \
+    logthread.cpp \
+    databasethread.cpp \
+    httpthread.cpp \
+    guardcore.cpp
+
+INCLUDEPATH += ../qmqtt-master/src/mqtt/
+
+
+HEADERS += \
+    logthread.h \
+    ../QReplyTimeout.h \
+    databasethread.h \
+    httpthread.h \
+    guardcore.h
+
+
+LIBS += -lQt5Qmqtt

+ 88 - 0
agGuardProcess/databasethread.cpp

@@ -0,0 +1,88 @@
+#include "databasethread.h"
+
+#define HostName "172.17.35.51"
+#define HostPort 3306
+#define UserName "usky"
+#define PassWord "Yt#75Usky"
+#define DatabaseName "usky-park"
+
+DatabaseThread::DatabaseThread(QObject *parent) : QThread(parent)
+{
+    hour = 255;
+    keep=false;
+    sqlList.clear();
+    alarmList.clear();
+
+    db = QSqlDatabase::addDatabase("QMYSQL","write_db");
+    db.setHostName(QString(HostName));
+    db.setPort(HostPort);
+    db.setUserName(QString(UserName));
+    db.setPassword(QString(PassWord));
+    db.setDatabaseName(QString(DatabaseName));
+
+
+
+}
+
+void DatabaseThread::appendSql(QString sql)
+{
+    sqlList.append(sql);
+}
+
+void DatabaseThread::appendAlarm(QString sql)
+{
+    alarmList.append(sql);
+}
+
+
+void DatabaseThread::stop()
+{
+    keep = false;
+}
+
+void DatabaseThread::run()
+{
+    keep = true;
+    while (keep) {
+
+        if(!db.open()){
+            emit dbdata_log(QString("[%1] agGuardProcess DatabaseThread db open failed").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")));
+        }else{
+            if(sqlList.length()>0){
+                while (sqlList.length()>0) {
+
+                    emit dbdata_log(QString("[%1] agGuardProcess sql %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).arg(sqlList.first()));
+
+                    db.exec(sqlList.first());
+
+                    sqlList.removeFirst();
+                    usleep(1000);
+                }
+            }
+            if(alarmList.length()>0){
+                while (alarmList.length()>0) {
+                    db.exec(alarmList.first());
+
+                    emit dbdata_log(QString("[%1] agGuardProcess alarm sql %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).arg(alarmList.first()));
+
+                    alarmList.removeFirst();
+                    usleep(1000);
+                }
+            }
+        }
+        usleep(50000);
+    }
+
+
+}
+
+
+
+
+
+
+
+
+
+
+

+ 37 - 0
agGuardProcess/databasethread.h

@@ -0,0 +1,37 @@
+#ifndef DATABASETHREAD_H
+#define DATABASETHREAD_H
+
+#include <QThread>
+#include <QDateTime>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QVariant>
+#include <QStringList>
+
+
+class DatabaseThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit DatabaseThread(QObject *parent = nullptr);
+    void run();
+    void stop();
+    void appendSql(QString sql);
+    void appendAlarm(QString sql);
+
+
+signals:
+    void dbdata_log(QString log);
+
+public slots:
+
+private:
+    int hour;
+    bool keep;
+
+    QSqlDatabase db;
+    QStringList sqlList,alarmList;
+
+};
+
+#endif // DATABASETHREAD_H

+ 118 - 0
agGuardProcess/guardcore.cpp

@@ -0,0 +1,118 @@
+#include "guardcore.h"
+#include "../AGBoxDog/boxshm.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+AGBoxShm *agBoxShm;
+BoxDeviceShm *boxDeviceShm;
+
+void GuardCore::shm_init(){
+    QSqlQuery qry;
+    QString sql = QString("select mqtt_ip,mqtt_port,user_name,pass_word from yt_t_mqtt where item_name = 'data-agbox'");
+    qry = db.exec(sql);
+    while (qry.next()) {
+        ip = qry.value(0).toString();
+        port = qry.value(1).toString();
+        username = qry.value(2).toString();
+        password = qry.value(3).toString();
+    }
+    qry.clear();
+    sql.clear();
+
+}
+
+bool GuardCore::shm_load(){
+    key_t key;
+    int shmid;
+    if((key=ftok(SHM_PATH,static_cast<int>(SHM_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(AGBoxShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    agBoxShm = static_cast<AGBoxShm *>(shmat(shmid,nullptr,0));
+
+    if((key=ftok(VIDEO_PATH,static_cast<int>(VIDEO_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(BoxDeviceShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    boxDeviceShm = static_cast<BoxDeviceShm *>(shmat(shmid,nullptr,0));
+
+    shm_init();
+    return true;
+}
+
+GuardCore::GuardCore(QObject *parent) : QObject(parent)
+{
+    logthread = new LogThread(this);
+    logthread->start();
+
+    db = QSqlDatabase::addDatabase("QSQLITE","conf_db");
+    db.setDatabaseName(QString("/opt/db/yt_conf.db"));
+    if(!db.open()){
+        logthread->appendData(QString("[agguard] open yt_conf.db failed"));
+    }
+    if(shm_load()){
+        logthread->appendData(QString("[agguard] shm load success"));
+    }
+
+    mqttIdx = 1;
+    m_client = new QMQTT::Client(QHostAddress(ip),static_cast<quint16>(port.toInt()),this);
+    connect(m_client,&QMQTT::Client::connected,this,&GuardCore::onConnected);
+    m_client->setUsername(username);
+    m_client->setPassword(password.toLatin1());
+    m_client->setCleanSession(true);
+    m_client->connectToHost();
+
+    dbthread = new DatabaseThread(this);
+    dbthread->start();
+
+    httpthread = new HttpThread(this);
+    connect(httpthread,&HttpThread::dataLog,this,&GuardCore::dataLog);
+    connect(httpthread,&HttpThread::mqttData,this,&GuardCore::mqtt_data);
+    connect(httpthread,&HttpThread::appendSql,this,&GuardCore::append_sql);
+
+}
+
+
+GuardCore::~GuardCore()
+{
+    logthread->stop();
+    dbthread->stop();
+    httpthread->stop();
+}
+
+void GuardCore::start()
+{
+
+}
+void GuardCore::onConnected()
+{
+    logthread->appendData(QString("mqtt onConnected"));
+}
+
+void GuardCore::dataLog(QString log)
+{
+    logthread->appendData(log);
+}
+
+void GuardCore::mqtt_data(QString mqtt_msg)
+{
+    printf("test2222 [%s]\n",mqtt_msg.toUtf8().data());
+    if((m_client->connectionState()==QMQTT::STATE_INIT)||(m_client->connectionState()==QMQTT::STATE_DISCONNECTED)){
+        m_client->connectToHost();
+    }
+    m_client->publish(QMQTT::Message(mqttIdx++,"data-collector",mqtt_msg.toUtf8()));
+    if(mqttIdx > 9999){
+        mqttIdx = 1;
+    }
+}
+
+void GuardCore::append_sql(QString sql)
+{
+    dbthread->appendSql(sql);
+}
+
+
+
+

+ 41 - 0
agGuardProcess/guardcore.h

@@ -0,0 +1,41 @@
+#ifndef GUARDCORE_H
+#define GUARDCORE_H
+
+#include <QObject>
+#include <qmqtt.h>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include "logthread.h"
+#include "httpthread.h"
+#include "databasethread.h"
+
+class GuardCore : public QObject
+{
+    Q_OBJECT
+public:
+    explicit GuardCore(QObject *parent = nullptr);
+    ~GuardCore();
+    void start();
+    bool shm_load();
+    void shm_init();
+
+signals:
+
+public slots:
+    void onConnected();
+    void dataLog(QString log);
+    void mqtt_data(QString mqtt_msg);
+    void append_sql(QString sql);
+
+private:
+    LogThread *logthread;
+    HttpThread *httpthread;
+    DatabaseThread *dbthread;
+
+    QMQTT::Client *m_client;
+    QSqlDatabase db;
+    quint16 mqttIdx;
+    QString ip,port,username,password;
+};
+
+#endif // GUARDCORE_H

+ 226 - 0
agGuardProcess/httpthread.cpp

@@ -0,0 +1,226 @@
+#include "httpthread.h"
+#include "../agVideoProcess/boxdeviceshm.h"
+#include "../AGBoxDog/boxshm.h"
+
+HttpThread::HttpThread(QObject *parent) : QObject(parent)
+{
+    minute = 255;
+    minute1 = 255;
+    hour = 25;
+    keep = false;
+    isWaiting = false;
+    networkManager = new QNetworkAccessManager(this); //查询门禁点事件
+    connect(networkManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot(QNetworkReply *)));
+    isWaiting1 = false;
+    networkManager1 = new QNetworkAccessManager(this); //查询门禁点状态
+    connect(networkManager1,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot1(QNetworkReply *)));
+
+    timer = new QTimer(this);
+    connect(timer,&QTimer::timeout,this,&HttpThread::time_out);
+    timer->start(5000);
+
+}
+
+void HttpThread::stop()
+{
+    keep = false;
+}
+
+void  HttpThread::finishedSlot(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("event parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("list");
+            if(list_value.isArray()){
+                emit appendSql(QString("delete from event_eg where event_time >= '%1' and event_time <= '%2';").arg(startTime).arg(endTime));
+                QJsonArray list_array = list_value.toArray();
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString device_code = list_object.value("doorIndexCode").toString();
+                    QString doorName = list_object.value("doorName").toString();
+                    QString personName = list_object.value("personName").toString();
+                    QString cardNo = list_object.value("cardNo").toString();
+                    QString orgName = list_object.value("orgName").toString();
+                    int eventType = list_object.value("eventType").toInt();
+                    int inAndOutType = list_object.value("inAndOutType").toInt();
+                    QString eventTime = list_object.value("eventTime").toString();
+                    for(int i=0;i<1024;i++){
+                        if(boxDeviceShm->device[i].Enabled == 0x01){
+                            if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                emit appendSql(QString::fromLocal8Bit("insert into event_eg (id, device_id, device_code, device_name, install_address, person_name, card_no, org_name, event_type, in_out_type, event_time) values(null,'%1','%2','%3','%4','%5','%6','%7',%8,%9,'%10');")
+                                              .arg(QString(boxDeviceShm->device[i].device_id)).arg(device_code).arg(doorName).arg("").arg(personName).arg(cardNo).arg(orgName).arg(eventType).arg(inAndOutType).arg(eventTime));
+                                break;
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+
+        }else{
+            emit dataLog(QString("event QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] event QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] event QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout()
+{
+    printf("[%s] event reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting = false;
+}
+
+void  HttpThread::finishedSlot1(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("status parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("authDoorList");
+            if(list_value.isArray()){
+                QJsonArray list_array = list_value.toArray();
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString device_code = list_object.value("doorIndexCode").toString();
+                    int doorState = list_object.value("doorState").toInt();
+                    int deviceStatus = 0;
+                    if(doorState==3){
+                        deviceStatus = 0;
+                    }else{
+                        deviceStatus = 1;
+                    }
+                    for(int i=0;i<1024;i++){
+                        if(boxDeviceShm->device[i].Enabled == 0x01){
+                            if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                emit mqttData(QString("{\"device_id\":\"%1\",\"device_code\":\"%2\",\"product_id\":\"%3\",\"timestamp\":%4,\"tags\":{\"conn_type\":\"\",\"type\":\"\"},\"metrics\":{\"device_status\":%5,\"door_status\":%6},\"device_type\":\"%7-eg\"}")
+                                              .arg(QString(boxDeviceShm->device[i].device_id)).arg(device_code).arg(QString(boxDeviceShm->device[i].company_code)).arg(QDateTime::currentDateTime().toTime_t()).arg(deviceStatus).arg(doorState).arg(boxDeviceShm->device[i].device_type));
+                                break;
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+
+        }else{
+            emit dataLog(QString("status QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] status QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] status QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting1 = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout1()
+{
+    printf("[%s] status reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting1 = false;
+}
+
+void HttpThread::time_out()
+{
+    agBoxShm->processStatus[2].t_time=QDateTime::currentDateTime().toTime_t();
+
+    if(QDateTime::currentDateTime().time().minute()!=minute){//每分钟执行一次,统计从现在算起之前10分钟时间内的人员通行记录(插入之前先执行删除这个时间端数据的命令)
+        minute = QDateTime::currentDateTime().time().minute();
+        QString tempTime1 = QDateTime::currentDateTime().addSecs(-600).toString("yyyy-MM-ddTHH:mm");
+        QString tempTime2 = QDateTime::currentDateTime().addSecs(-60).toString("yyyy-MM-ddTHH:mm");
+        startTime = QString("%1:00+08:00").arg(tempTime1);
+        endTime = QString("%1:59+08:00").arg(tempTime2);
+
+        printf("startTime: %s, endTime %s\n",startTime.toUtf8().data(),endTime.toUtf8().data());
+
+        if(!isWaiting){
+            isWaiting = true;
+            QNetworkRequest *req = new QNetworkRequest();
+            req->setUrl(QUrl("https://172.17.200.250:443/artemis/api/acs/v1/door/events"));
+            req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+            req->setRawHeader("Accept","*/*");
+            req->setRawHeader("Connection","keep-alive");
+            req->setRawHeader("Cache-Control"," no-cache");
+            req->setRawHeader("X-Ca-Key","27997984");
+            req->setRawHeader("X-Ca-Signature","zocGT3eKtbbUyljDBPf4yoQPoFdN97+Mg4fCc9Ki4jE=");
+            req->setRawHeader("X-Ca-Signature-Headers","x-ca-key");
+            config = req->sslConfiguration();
+            config.setPeerVerifyMode(QSslSocket::VerifyNone);
+            config.setProtocol(QSsl::TlsV1_0OrLater);
+            req->setSslConfiguration(config);
+            QString postdata = QString("{\"startTime\": \"%1\",\"endTime\": \"%2\",\"pageNo\": 1,\"pageSize\": 500}").arg(startTime).arg(endTime);
+            emit dataLog(QString(" events QNetworkReply event [%1]").arg(postdata));
+            req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+            QNetworkReply *reply = networkManager->post(*req,postdata.toUtf8());
+            QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+            connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout()));
+
+        }
+    }
+
+    if(QDateTime::currentDateTime().time().minute()!=minute1){//每半个小时执行一次,同步设备状态
+      minute1 = QDateTime::currentDateTime().time().minute();
+      if(!isWaiting1 && ((minute1==00)||(minute1==30))){
+          isWaiting1 = true;
+          QNetworkRequest *req = new QNetworkRequest();
+          req->setUrl(QUrl("https://172.17.200.250:443/artemis/api/acs/v1/door/states"));
+          req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+          req->setRawHeader("Accept","*/*");
+          req->setRawHeader("Connection","keep-alive");
+          req->setRawHeader("Cache-Control"," no-cache");
+          req->setRawHeader("X-Ca-Key","27997984");
+          req->setRawHeader("X-Ca-Signature","FZRWBzzvzp8mDxFSpLHGdtNaot1PfNvpMbCaoT+dDLw=");
+          req->setRawHeader("X-Ca-Signature-Headers","x-ca-key");
+          config = req->sslConfiguration();
+          config.setPeerVerifyMode(QSslSocket::VerifyNone);
+          config.setProtocol(QSsl::TlsV1_0OrLater);
+          req->setSslConfiguration(config);
+          QString postdata = QString("{}");
+          req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+          QNetworkReply *reply = networkManager1->post(*req,postdata.toUtf8());
+          QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+          connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout1()));
+
+      }
+  }
+
+}
+
+
+
+
+
+
+
+
+

+ 51 - 0
agGuardProcess/httpthread.h

@@ -0,0 +1,51 @@
+#ifndef HTTPTHREAD_H
+#define HTTPTHREAD_H
+
+#include <QObject>
+#include <QDateTime>
+#include <QTimer>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QSslConfiguration>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonParseError>
+#include "../QReplyTimeout.h"
+
+class HttpThread : public QObject
+{
+    Q_OBJECT
+public:
+    explicit HttpThread(QObject *parent = nullptr);
+    void run();
+    void stop();
+
+signals:
+    void dataLog(QString log);
+    void mqttData(QString mqtt_msg);
+    void appendSql(QString sql);
+
+public slots:
+    void time_out();
+    void finishedSlot(QNetworkReply *reply);
+    void finishedSlot1(QNetworkReply *reply);
+    void reply_timeout();
+    void reply_timeout1();
+
+private:
+    bool isWaiting,isWaiting1;
+    bool keep;
+    int minute,hour,minute1;
+    QString startTime;
+    QString endTime;
+    QNetworkAccessManager *networkManager,*networkManager1;
+    QSslConfiguration config;
+    QTimer *timer;
+
+
+};
+
+#endif // HTTPTHREAD_H

+ 52 - 0
agGuardProcess/logthread.cpp

@@ -0,0 +1,52 @@
+#include "logthread.h"
+
+LogThread::LogThread(QObject *parent) :
+    QThread(parent)
+{
+    keep = false;
+    dataList.clear();
+    QDir path("/usky/data-agbox/agguard/log");
+    if(!path.exists()){
+        system("mkdir -p /usky/data-agbox/agguard/log/");
+    }
+    file = new QFile("/usky/data-agbox/agguard/log/guard-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+    day = QDate::currentDate().day();
+}
+
+void LogThread::appendData(QString data)
+{
+    dataList.append(data);
+}
+
+void LogThread::stop()
+{
+    keep = false;
+}
+
+void LogThread::run()
+{
+    printf("log thread start\n");
+    if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+        file->write(QString("agGuardProcess start at %1.\r\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).toUtf8());
+        file->close();
+    }
+    keep = true;
+    while(keep){
+        if(dataList.length()>0){
+            if(day!=QDate::currentDate().day()){
+                day = QDate::currentDate().day();
+                file = new QFile("/usky/data-agbox/agguard/log/guard-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+            }
+            if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(dataList.length()>0){
+                    file->write(dataList.first().toUtf8());
+                    file->write("\r\n");
+                    dataList.removeFirst();
+                    usleep(1000);
+                }
+                file->close();
+            }
+        }
+        usleep(50000);
+    }
+}

+ 28 - 0
agGuardProcess/logthread.h

@@ -0,0 +1,28 @@
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QStringList>
+#include <QDate>
+#include <QDir>
+#include <QFile>
+
+class LogThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit LogThread(QObject *parent = nullptr);
+    void appendData(QString data);
+    void run();
+    void stop();
+signals:
+
+public slots:
+private:
+    QFile *file;
+    QStringList dataList;
+    int day;
+    bool keep;
+};
+
+#endif // LOGTHREAD_H

+ 12 - 0
agGuardProcess/main.cpp

@@ -0,0 +1,12 @@
+#include <QCoreApplication>
+#include "guardcore.h"
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    GuardCore *core = new GuardCore(nullptr);
+    core->start();
+
+    return a.exec();
+}

+ 30 - 0
agLightingProcess/agLightingProcess.pro

@@ -0,0 +1,30 @@
+QT += core sql
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+TARGET = agDP0006
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        main.cpp \
+    logthread.cpp
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+HEADERS += \
+    logthread.h

+ 52 - 0
agLightingProcess/logthread.cpp

@@ -0,0 +1,52 @@
+#include "logthread.h"
+
+LogThread::LogThread(QObject *parent) :
+    QThread(parent)
+{
+    keep = false;
+    dataList.clear();
+    QDir path("/usky/data-agbox/aglighting/log");
+    if(!path.exists()){
+        system("mkdir -p /usky/data-agbox/aglighting/log/");
+    }
+    file = new QFile("/usky/data-agbox/aglighting/log/lighting-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+    day = QDate::currentDate().day();
+}
+
+void LogThread::appendData(QString data)
+{
+    dataList.append(data);
+}
+
+void LogThread::stop()
+{
+    keep = false;
+}
+
+void LogThread::run()
+{
+    printf("log thread start\n");
+    if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+        file->write(QString("agLightingProcess start at %1.\r\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).toUtf8());
+        file->close();
+    }
+    keep = true;
+    while(keep){
+        if(dataList.length()>0){
+            if(day!=QDate::currentDate().day()){
+                day = QDate::currentDate().day();
+                file = new QFile("/usky/data-agbox/aglighting/log/lighting-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+            }
+            if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(dataList.length()>0){
+                    file->write(dataList.first().toUtf8());
+                    file->write("\r\n");
+                    dataList.removeFirst();
+                    usleep(1000);
+                }
+                file->close();
+            }
+        }
+        usleep(50000);
+    }
+}

+ 28 - 0
agLightingProcess/logthread.h

@@ -0,0 +1,28 @@
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QStringList>
+#include <QDate>
+#include <QDir>
+#include <QFile>
+
+class LogThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit LogThread(QObject *parent = nullptr);
+    void appendData(QString data);
+    void run();
+    void stop();
+signals:
+
+public slots:
+private:
+    QFile *file;
+    QStringList dataList;
+    int day;
+    bool keep;
+};
+
+#endif // LOGTHREAD_H

+ 8 - 0
agLightingProcess/main.cpp

@@ -0,0 +1,8 @@
+#include <QCoreApplication>
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    return a.exec();
+}

+ 29 - 0
agVideoProcess/agVideoProcess.pro

@@ -0,0 +1,29 @@
+QT += core sql network websockets
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+TARGET = agDP0001
+
+
+SOURCES += \
+        main.cpp \
+    httpthread.cpp \
+    logthread.cpp \
+    videocore.cpp
+
+
+INCLUDEPATH += ../qmqtt-master/src/mqtt/
+
+
+HEADERS += \
+    httpthread.h \
+    ../QReplyTimeout.h \
+    agboxdeviceshm.h \
+    boxdeviceshm.h \
+    logthread.h \
+    videocore.h
+
+
+LIBS += -lQt5Qmqtt

+ 37 - 0
agVideoProcess/agboxdeviceshm.h

@@ -0,0 +1,37 @@
+#ifndef AGBOXDEVICESHM_H
+#define AGBOXDEVICESHM_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#define VIDEO_PORT 8523
+#define VIDEO_PATH "/"
+
+typedef struct{
+    int device_type;
+    char device_code[50];
+    char device_id[50];
+    char company_code[50];
+    char device_gateway[50];
+    unsigned int lastTime;
+    unsigned int Enabled;
+}Device;
+
+typedef struct{
+    int device_type;
+    char attribute_name[60];
+    char attribute_code[20];
+    unsigned int Enabled;
+} ProductAttribute;
+
+typedef struct{
+    Device device[1024];
+    ProductAttribute procuctattrbute[300];
+} BoxDeviceShm;
+
+
+#endif // AGBOXDEVICESHM_H

+ 8 - 0
agVideoProcess/boxdeviceshm.h

@@ -0,0 +1,8 @@
+#ifndef BOXDEVICESHM_H
+#define BOXDEVICESHM_H
+
+#include "agboxdeviceshm.h"
+
+extern BoxDeviceShm *boxDeviceShm;
+
+#endif // BOXDEVICESHM_H

+ 121 - 0
agVideoProcess/httpthread.cpp

@@ -0,0 +1,121 @@
+#include "httpthread.h"
+#include "boxdeviceshm.h"
+#include "../AGBoxDog/boxshm.h"
+
+HttpThread::HttpThread(QObject *parent) : QObject(parent)
+{
+    minute = 255;
+    hour = 25;
+    keep = false;
+    isWaiting = false;
+    networkManager = new QNetworkAccessManager(this);
+    connect(networkManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finishedSlot(QNetworkReply *)));
+
+    timer = new QTimer(this);
+    connect(timer,&QTimer::timeout,this,&HttpThread::time_out);
+    timer->start(5000);
+
+}
+
+void HttpThread::stop()
+{
+    keep = false;
+}
+
+void  HttpThread::finishedSlot(QNetworkReply *reply)
+{
+    if(reply->error()==QNetworkReply::NoError){
+        QString data = QString::fromUtf8(reply->readAll());
+        QByteArray ba = data.toLocal8Bit();
+        ba = QString::fromLocal8Bit(ba).toUtf8();
+        QJsonParseError parseError;
+        QJsonDocument doc = QJsonDocument::fromJson(ba,&parseError);
+        printf("parseError.error %d\n",parseError.error);
+        if(parseError.error == QJsonParseError::NoError){
+            QJsonObject obj_doc = doc.object();
+            QJsonValue data_value = obj_doc.value("data");
+
+            QJsonObject data_object = data_value.toObject();
+            QJsonValue list_value = data_object.value("list");
+            if(list_value.isArray()){
+                QJsonArray list_array = list_value.toArray();
+                for(int i=0;i<list_array.size();i++){
+                    QJsonObject list_object = list_array.at(i).toObject();
+                    QString device_code = list_object.value("indexCode").toString();
+                    int device_status = list_object.value("online").toInt();
+                    for(int i=0;i<1024;i++){
+                        if(boxDeviceShm->device[i].Enabled == 0x01){
+                            if(device_code.compare(QString(boxDeviceShm->device[i].device_code))==0){
+                                emit mqttData(QString("{\"device_id\":\"%1\",\"device_code\":\"%2\",\"product_id\":\"%3\",\"timestamp\":%4,\"tags\":{\"conn_type\":\"\",\"type\":\"\"},\"metrics\":{\"device_status\":%5},\"device_type\":\"%6-vd\"}")
+                                              .arg(QString(boxDeviceShm->device[i].device_id)).arg(device_code).arg(QString(boxDeviceShm->device[i].company_code)).arg(QDateTime::currentDateTime().toTime_t()).arg(device_status).arg(boxDeviceShm->device[i].device_type));
+                                break;
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+
+        }else{
+            emit dataLog(QString("QJson Parse  Error  %1").arg(parseError.error));
+        }
+
+        emit dataLog(QString("[%1] QNetworkReply Status %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(data));
+    }else{
+        emit dataLog(QString("[%1] QNetworkReply Status Err  %2").arg(QDateTime::fromTime_t(QDateTime::currentDateTime().toTime_t()).toString("yyyy-MM-dd HH:mm:ss")).arg(reply->error()));
+    }
+
+    isWaiting = false;
+    reply->abort();
+    reply->deleteLater();
+}
+
+void HttpThread::reply_timeout()
+{
+    printf("[%s] reply_timeout\n",QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toUtf8().data());
+    isWaiting = false;
+}
+
+void HttpThread::time_out()
+{
+    agBoxShm->processStatus[1].t_time=QDateTime::currentDateTime().toTime_t();
+
+//    if(((QDateTime::currentDateTime().time().minute())%5==0) && (QDateTime::currentDateTime().time().minute()!=minute)){//每5分钟执行一次
+      if(QDateTime::currentDateTime().time().minute()!=minute){//每半小时执行一次
+        minute = QDateTime::currentDateTime().time().minute();
+        if(!isWaiting && ((minute==00)||(minute==30))){
+            isWaiting = true;
+            QNetworkRequest *req = new QNetworkRequest();
+            req->setUrl(QUrl("https://172.17.200.250:443/artemis/api/nms/v1/online/camera/get"));
+            req->setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
+            req->setRawHeader("Accept","*/*");
+            req->setRawHeader("Connection","keep-alive");
+            req->setRawHeader("Cache-Control"," no-cache");
+            req->setRawHeader("X-Ca-Key","27997984");
+            req->setRawHeader("X-Ca-Signature","a9kzGHD938rFhCfWVlGB6eO0bZ0SQbhzSwXlT+FMh+Q=");
+            req->setRawHeader("X-Ca-Signature-Headers","x-ca-key");
+            config = req->sslConfiguration();
+            config.setPeerVerifyMode(QSslSocket::VerifyNone);
+            config.setProtocol(QSsl::TlsV1_0OrLater);
+            req->setSslConfiguration(config);
+            QString postdata = QString("{\"pageNo\": 1,\"pageSize\": 500}");
+            req->setRawHeader("Content_Length",QString("%1").arg(postdata.length()).toUtf8());
+            QNetworkReply *reply = networkManager->post(*req,postdata.toUtf8());
+            QReplayTimeout *pTimeout = new QReplayTimeout(reply,10000);
+            connect(pTimeout, SIGNAL(net_timeout()),this,SLOT(reply_timeout()));
+
+        }
+    }
+
+}
+
+
+
+
+
+
+
+
+

+ 46 - 0
agVideoProcess/httpthread.h

@@ -0,0 +1,46 @@
+#ifndef HTTPTHREAD_H
+#define HTTPTHREAD_H
+
+#include <QObject>
+#include <QDateTime>
+#include <QTimer>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QSslConfiguration>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonParseError>
+#include "../QReplyTimeout.h"
+
+class HttpThread : public QObject
+{
+    Q_OBJECT
+public:
+    explicit HttpThread(QObject *parent = nullptr);
+    void run();
+    void stop();
+
+signals:
+    void dataLog(QString log);
+    void mqttData(QString mqtt_msg);
+
+public slots:
+    void time_out();
+    void finishedSlot(QNetworkReply *reply);
+    void reply_timeout();
+
+private:
+    bool isWaiting;
+    bool keep;
+    int minute,hour;
+    QNetworkAccessManager *networkManager;
+    QSslConfiguration config;
+    QTimer *timer;
+
+
+};
+
+#endif // HTTPTHREAD_H

+ 52 - 0
agVideoProcess/logthread.cpp

@@ -0,0 +1,52 @@
+#include "logthread.h"
+
+LogThread::LogThread(QObject *parent) :
+    QThread(parent)
+{
+    keep = false;
+    dataList.clear();
+    QDir path("/usky/data-agbox/agvideo/log");
+    if(!path.exists()){
+        system("mkdir -p /usky/data-agbox/agvideo/log/");
+    }
+    file = new QFile("/usky/data-agbox/agvideo/log/video-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+    day = QDate::currentDate().day();
+}
+
+void LogThread::appendData(QString data)
+{
+    dataList.append(data);
+}
+
+void LogThread::stop()
+{
+    keep = false;
+}
+
+void LogThread::run()
+{
+    printf("log thread start\n");
+    if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+        file->write(QString("agVideoProcess start at %1.\r\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")).toUtf8());
+        file->close();
+    }
+    keep = true;
+    while(keep){
+        if(dataList.length()>0){
+            if(day!=QDate::currentDate().day()){
+                day = QDate::currentDate().day();
+                file = new QFile("/usky/data-agbox/agvideo/log/video-"+QDate::currentDate().toString("yyyyMMdd")+".log");
+            }
+            if(file->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
+                while(dataList.length()>0){
+                    file->write(dataList.first().toUtf8());
+                    file->write("\r\n");
+                    dataList.removeFirst();
+                    usleep(1000);
+                }
+                file->close();
+            }
+        }
+        usleep(50000);
+    }
+}

+ 28 - 0
agVideoProcess/logthread.h

@@ -0,0 +1,28 @@
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QStringList>
+#include <QDate>
+#include <QDir>
+#include <QFile>
+
+class LogThread : public QThread
+{
+    Q_OBJECT
+public:
+    explicit LogThread(QObject *parent = nullptr);
+    void appendData(QString data);
+    void run();
+    void stop();
+signals:
+
+public slots:
+private:
+    QFile *file;
+    QStringList dataList;
+    int day;
+    bool keep;
+};
+
+#endif // LOGTHREAD_H

+ 13 - 0
agVideoProcess/main.cpp

@@ -0,0 +1,13 @@
+#include <QCoreApplication>
+#include "videocore.h"
+
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    VideoCore *videocore = new VideoCore(nullptr);
+    videocore->start();
+
+    return a.exec();
+}

+ 144 - 0
agVideoProcess/videocore.cpp

@@ -0,0 +1,144 @@
+#include "videocore.h"
+#include "../AGBoxDog/boxshm.h"
+#include "boxdeviceshm.h"
+AGBoxShm *agBoxShm;
+BoxDeviceShm *boxDeviceShm;
+
+void VideoCore::shm_init(){
+    QSqlQuery qry;
+    QString sql = QString("select mqtt_ip,mqtt_port,user_name,pass_word from yt_t_mqtt where item_name = 'data-agbox'");
+    qry = db.exec(sql);
+    while (qry.next()) {
+        ip = qry.value(0).toString();
+        port = qry.value(1).toString();
+        username = qry.value(2).toString();
+        password = qry.value(3).toString();
+    }
+    qry.clear();
+    int nrow = 0;
+    sql.clear();
+    sql = QString("select device_code,device_id,device_type,company_code,device_gateway from yt_t_device");
+    qry = db.exec(sql);
+    while (qry.next()) {
+        if(nrow > 1023)
+            break;
+        boxDeviceShm->device[nrow].Enabled = 0x01;
+        sprintf(boxDeviceShm->device[nrow].device_code,"%s",qry.value(0).toString().toUtf8().data());
+        sprintf(boxDeviceShm->device[nrow].device_id,"%s",qry.value(1).toString().toUtf8().data());
+        boxDeviceShm->device[nrow].device_type = qry.value(2).toInt();
+        sprintf(boxDeviceShm->device[nrow].company_code,"%s",qry.value(3).toString().toUtf8().data());
+        sprintf(boxDeviceShm->device[nrow].device_gateway,"%s",qry.value(4).toString().toUtf8().data());
+        nrow++;
+    }
+    for(int i=nrow;i<1024;i++){
+        boxDeviceShm->device[i].Enabled = 0x00;
+    }
+    nrow = 0;
+    qry.clear();
+    sql.clear();
+    sql = QString("select device_type,attribute_name,attribute_code from yt_t_attribute");
+    qry = db.exec(sql);
+    while (qry.next()) {
+        if(nrow > 299)
+            break;
+        boxDeviceShm->procuctattrbute[nrow].Enabled = 0x01;
+        boxDeviceShm->procuctattrbute[nrow].device_type = qry.value(0).toInt();
+        sprintf(boxDeviceShm->procuctattrbute[nrow].attribute_name,"%s",qry.value(1).toString().toUtf8().data());
+        sprintf(boxDeviceShm->procuctattrbute[nrow].attribute_code,"%s",qry.value(2).toString().toUtf8().data());
+        nrow++;
+    }
+    for(int i=nrow;i<300;i++){
+        boxDeviceShm->procuctattrbute[i].Enabled = 0x00;
+    }
+}
+
+bool VideoCore::shm_load(){
+    key_t key;
+    int shmid;
+    if((key=ftok(SHM_PATH,static_cast<int>(SHM_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(AGBoxShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    agBoxShm = static_cast<AGBoxShm *>(shmat(shmid,nullptr,0));
+
+    if((key=ftok(VIDEO_PATH,static_cast<int>(VIDEO_PORT)))==-1){
+        return false;
+    }
+    if((shmid=shmget(key,sizeof(BoxDeviceShm),IPC_CREAT|0666))==-1){
+        return false;
+    }
+    boxDeviceShm = static_cast<BoxDeviceShm *>(shmat(shmid,nullptr,0));
+
+    shm_init();
+    return true;
+}
+
+
+VideoCore::VideoCore(QObject *parent) : QObject(parent)
+{
+    logthread = new LogThread(this);
+    logthread->start();
+
+    db = QSqlDatabase::addDatabase("QSQLITE","conf_db");
+    db.setDatabaseName(QString("/opt/db/yt_conf.db"));
+
+    if(!db.open()){
+        logthread->appendData(QString("[agvideo] open yt_conf.db failed"));
+    }
+    if(shm_load()){
+        logthread->appendData(QString("[agvideo] shm load success"));
+    }
+
+
+    mqttIdx = 1;
+    m_client = new QMQTT::Client(QHostAddress(ip),static_cast<quint16>(port.toInt()),this);
+    connect(m_client,&QMQTT::Client::connected,this,&VideoCore::onConnected);
+    m_client->setUsername(username);
+    m_client->setPassword(password.toLatin1());
+    m_client->setCleanSession(true);
+    m_client->connectToHost();
+
+
+    httpthread = new HttpThread(this);
+    connect(httpthread,&HttpThread::dataLog,this,&VideoCore::dataLog);
+    connect(httpthread,&HttpThread::mqttData,this,&VideoCore::mqtt_data);
+}
+
+VideoCore::~VideoCore()
+{
+    logthread->stop();
+    httpthread->stop();
+}
+
+void VideoCore::start()
+{
+
+}
+
+void VideoCore::onConnected()
+{
+    logthread->appendData(QString("mqtt onConnected"));
+}
+
+void VideoCore::dataLog(QString log)
+{
+    logthread->appendData(log);
+}
+
+void VideoCore::mqtt_data(QString mqtt_msg)
+{
+    printf("test1111 [%s]\n",mqtt_msg.toUtf8().data());
+    if((m_client->connectionState()==QMQTT::STATE_INIT)||(m_client->connectionState()==QMQTT::STATE_DISCONNECTED)){
+        m_client->connectToHost();
+    }
+    m_client->publish(QMQTT::Message(mqttIdx++,"data-collector",mqtt_msg.toUtf8()));
+    if(mqttIdx > 9999){
+        mqttIdx = 1;
+    }
+}
+
+
+
+

+ 38 - 0
agVideoProcess/videocore.h

@@ -0,0 +1,38 @@
+#ifndef VIDEOCORE_H
+#define VIDEOCORE_H
+
+#include <QObject>
+#include <qmqtt.h>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include "logthread.h"
+#include "httpthread.h"
+
+class VideoCore : public QObject
+{
+    Q_OBJECT
+public:
+    explicit VideoCore(QObject *parent = nullptr);
+    ~VideoCore();
+    void start();
+    void shm_init();
+    bool shm_load();
+
+signals:
+
+public slots:
+    void onConnected();
+    void dataLog(QString log);
+    void mqtt_data(QString mqtt_msg);
+
+private:
+    LogThread *logthread;
+    HttpThread *httpthread;
+
+    QMQTT::Client *m_client;
+    QSqlDatabase db;
+    quint16 mqttIdx;
+    QString ip,port,username,password;
+};
+
+#endif // VIDEOCORE_H

+ 10 - 0
data-agbox.pro

@@ -0,0 +1,10 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+    agVideoProcess \
+    agGuardProcess \
+    agElevatorProcess \
+    agGeneratorProcess \
+    agEnvironmentProcess \
+    agLightingProcess \
+    AGBoxDog

+ 680 - 0
data-agbox.pro.user

@@ -0,0 +1,680 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 4.7.2, 2023-04-07T17:08:09. -->
+<qtcreator>
+ <data>
+  <variable>EnvironmentId</variable>
+  <value type="QByteArray">{3617412f-ba16-4fe4-83d8-8a9ba84ea18b}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="int">0</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap">
+   <valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
+   <value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.9.7</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.9.7</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ba7ab7ec-e6d7-4239-8d06-20d6c39c5b99}</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">6</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Profile</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">AGBoxDog</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/AGBoxDog/AGBoxDog.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">AGBoxDog/AGBoxDog.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release/AGBoxDog</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">agElevatorProcess</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/agElevatorProcess/agElevatorProcess.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">agElevatorProcess/agElevatorProcess.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release/agElevatorProcess</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.2">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">agEnvironmentProcess</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/agEnvironmentProcess/agEnvironmentProcess.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">agEnvironmentProcess/agEnvironmentProcess.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release/agEnvironmentProcess</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.3">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">agGeneratorProcess</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/agGeneratorProcess/agGeneratorProcess.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">agGeneratorProcess/agGeneratorProcess.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release/agGeneratorProcess</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.4">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">agGuardProcess</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/agGuardProcess/agGuardProcess.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">agGuardProcess/agGuardProcess.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release/agGuardProcess</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.5">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">agLightingProcess</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/agLightingProcess/agLightingProcess.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">agLightingProcess/agLightingProcess.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release/agLightingProcess</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.6">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">agVideoProcess</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/agVideoProcess/agVideoProcess.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">agVideoProcess/agVideoProcess.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/build-data-agbox-Qt_5_9_7-Release/agVideoProcess</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">7</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="int">1</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">18</value>
+ </data>
+ <data>
+  <variable>Version</variable>
+  <value type="int">18</value>
+ </data>
+</qtcreator>

+ 4 - 0
qmqtt-master/.qmake.conf

@@ -0,0 +1,4 @@
+load(qt_build_config)
+CONFIG += warning_clean
+
+MODULE_VERSION = 1.0.0

+ 1 - 0
qmqtt-master/.tag

@@ -0,0 +1 @@
+c9a81f496df6d23da9b11cda367d179fee9c5cc1

+ 24 - 0
qmqtt-master/.travis.yml

@@ -0,0 +1,24 @@
+dist: xenial
+
+language: cpp
+compiler:
+ - gcc
+
+addons:
+  apt:
+    sources:
+      - sourceline: 'ppa:beineri/opt-qt571-xenial'
+    packages:
+      - qt57base
+      - qt57tools
+      - qt57websockets
+      - cmake
+
+before_install:
+ - source /opt/qt57/bin/qt57-env.sh
+
+script:
+ - qmake --version
+ - $CXX --version
+ - qmake
+ - make CXX=$CXX

+ 298 - 0
qmqtt-master/CMakeLists.txt

@@ -0,0 +1,298 @@
+cmake_minimum_required(VERSION 3.9)
+
+project( qmqtt VERSION 1.0.0 )
+
+include( GNUInstallDirs ) # needed to define vars used in install() directives.
+
+
+# ===================================================================
+# Configurable options
+
+option( ${PROJECT_NAME}_SHARED "Build a shared library.  Turn off for static." ON )
+option( ${PROJECT_NAME}_WEBSOCKETS "Enable WebSockets for MQTT" OFF )
+option( ${PROJECT_NAME}_SSL "Enable SSL support for MQTT" ON )
+
+
+if ( ${PROJECT_NAME}_SHARED )
+    set( library_build_type SHARED )
+    set( library_install_component Library )
+else()
+    set( library_build_type STATIC )
+    set( library_install_component Devel )
+endif()
+
+
+set( ws_component )
+set( ws_libname )
+set( qt5_min_version "5.3.0" )
+
+if ( ${PROJECT_NAME}_WEBSOCKETS )
+    set( ws_component WebSockets )
+    set( ws_libname   Qt5::WebSockets )
+    set( qt5_min_version "5.7.0" )
+endif()
+
+if ( NOT ${PROJECT_NAME}_SSL)
+    set( ssl_defs QT_NO_SSL )
+endif()
+
+
+find_package( Qt5 ${qt5_min_version} COMPONENTS Core Network ${ws_component} CONFIG REQUIRED )
+set( CMAKE_AUTOMOC ON )
+cmake_policy( SET CMP0020 NEW ) # Automatically link Qt executables to qtmain target on Windows.
+
+
+# ===================================================================
+# Project files
+
+set( PUBLIC_HEADERS
+    src/mqtt/qmqtt_global.h
+    src/mqtt/qmqtt.h
+    src/mqtt/qmqtt_client.h
+    src/mqtt/qmqtt_frame.h
+    src/mqtt/qmqtt_message.h
+    src/mqtt/qmqtt_routesubscription.h
+    src/mqtt/qmqtt_routedmessage.h
+    src/mqtt/qmqtt_router.h
+    src/mqtt/qmqtt_networkinterface.h
+    src/mqtt/qmqtt_socketinterface.h
+    src/mqtt/qmqtt_timerinterface.h
+)
+
+set( PRIVATE_HEADERS
+    src/mqtt/qmqtt_client_p.h
+    src/mqtt/qmqtt_message_p.h
+    src/mqtt/qmqtt_network_p.h
+    src/mqtt/qmqtt_socket_p.h
+    src/mqtt/qmqtt_timer_p.h
+)
+
+set( SOURCES
+    src/mqtt/qmqtt_client_p.cpp
+    src/mqtt/qmqtt_client.cpp
+    src/mqtt/qmqtt_frame.cpp
+    src/mqtt/qmqtt_message.cpp
+    src/mqtt/qmqtt_network.cpp
+    src/mqtt/qmqtt_routesubscription.cpp
+    src/mqtt/qmqtt_router.cpp
+    src/mqtt/qmqtt_socket.cpp
+    src/mqtt/qmqtt_timer.cpp
+)
+
+if ( ${PROJECT_NAME}_WEBSOCKETS )
+    list( APPEND PRIVATE_HEADERS
+        src/mqtt/qmqtt_websocket_p.h
+        src/mqtt/qmqtt_websocketiodevice_p.h
+    )
+    list( APPEND SOURCES
+        src/mqtt/qmqtt_websocket.cpp
+        src/mqtt/qmqtt_websocketiodevice.cpp
+    )
+endif()
+
+if ( ${PROJECT_NAME}_SSL)
+    list( APPEND PRIVATE_HEADERS
+        src/mqtt/qmqtt_ssl_socket_p.h
+    )
+    list( APPEND SOURCES
+        src/mqtt/qmqtt_ssl_socket.cpp
+    )
+endif()
+
+
+# Mark public headers as such
+set_source_files_properties( ${PUBLIC_HEADERS} PROPERTIES PUBLIC_HEADER 1 )
+
+
+# ===================================================================
+# Library target
+
+# Library has the same name as the project
+add_library( ${PROJECT_NAME} ${library_build_type} ${SOURCES} ${PUBLIC_HEADERS} ${PRIVATE_HEADERS} )
+target_link_libraries( ${PROJECT_NAME} PUBLIC Qt5::Core Qt5::Network ${ws_libname} )
+target_compile_definitions( ${PROJECT_NAME}
+    PRIVATE
+        QT_NO_CAST_FROM_ASCII
+        QT_NO_CAST_TO_ASCII
+        QT_BUILD_QMQTT_LIB
+        ${ssl_defs}
+)
+
+# Where to look for headers while compiling the target or when compiling against
+# the target.
+target_include_directories( ${PROJECT_NAME}
+    PUBLIC
+        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/mqtt>
+        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
+
+set_target_properties( ${PROJECT_NAME}
+    PROPERTIES
+        VERSION                   ${PROJECT_VERSION}
+        SOVERSION                 ${PROJECT_VERSION_MAJOR}
+        CXX_STANDARD              11
+        CXX_STANDARD_REQUIRED     OFF  # Whether CXX_STANDARD is enforced
+)
+
+if ( ${CMAKE_HOST_WIN32} )
+    # On Windows, libraries are not generally prefixed with "lib".
+    # If left unchanged, cmake will still add this prefix.
+    set_target_properties( ${PROJECT_NAME}
+        PROPERTIES
+            PREFIX        ""
+            IMPORT_PREFIX ""
+    )
+endif()
+
+
+# ===================================================================
+# Installation
+
+# Rule to install runtime components (ie: the shared library)
+install(
+    TARGETS   ${PROJECT_NAME}
+    EXPORT    ${PROJECT_NAME}
+    COMPONENT ${library_install_component}
+    RUNTIME   DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    LIBRARY   DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    ARCHIVE   DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+)
+
+install(
+    EXPORT ${PROJECT_NAME}
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+    FILE ${PROJECT_NAME}Targets.cmake
+    COMPONENT Devel
+)
+
+
+install(
+    FILES       ${PUBLIC_HEADERS}
+    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+    COMPONENT   Devel
+    OPTIONAL
+)
+
+# Generate a CMake file into the installation, to easily use the library
+install(
+    EXPORT      ${PROJECT_NAME}
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+    COMPONENT   Devel
+    OPTIONAL
+)
+
+
+
+include( CMakePackageConfigHelpers )
+
+file( WRITE "${CMAKE_CURRENT_BINARY_DIR}/qmqttConfig.cmake.in"
+      "@PACKAGE_INIT@\ninclude( \${CMAKE_CURRENT_LIST_DIR}/qmqttTargets.cmake )" )
+
+configure_package_config_file(
+    "${CMAKE_CURRENT_BINARY_DIR}/qmqttConfig.cmake.in"
+    "qmqttConfig.cmake"
+    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
+    PATH_VARS           CMAKE_INSTALL_LIBDIR
+)
+
+write_basic_package_version_file(
+    "qmqttConfigVersion.cmake"
+    VERSION       ${PROJECT_VERSION}
+    COMPATIBILITY SameMajorVersion
+)
+
+install(
+    FILES
+        ${CMAKE_CURRENT_BINARY_DIR}/qmqttConfig.cmake
+        ${CMAKE_CURRENT_BINARY_DIR}/qmqttConfigVersion.cmake
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
+    COMPONENT   Devel
+)
+
+
+# ===================================================================
+# Package creation
+
+set( CPACK_PACKAGE_NAME ${PROJECT_NAME} )
+set( CPACK_PACKAGE_VENDOR "emqtt" ) # Github project owner
+set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "mqtt client for Qt" )
+set( CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/emqtt/qmqtt" )
+set( CPACK_PACKAGE_CONTACT      "https://github.com/emqtt/qmqtt" )
+set( CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} )
+set( CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR} )
+set( CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH} )
+set( CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH} )
+set( CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME} )
+set( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/edl-v10" )
+set( CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md" )
+
+set( CPACK_COMPONENT_Library_DISPLAY_NAME "QMQTT Library" )
+set( CPACK_COMPONENT_Library_DESCRIPTION "The QMQTT binary library." )
+set( CPACK_COMPONENT_Library_REQUIRED 1 )
+set( CPACK_COMPONENT_Devel_DISPLAY_NAME "QMQTT Development Files" )
+set( CPACK_COMPONENT_Devel_DESCRIPTION "Development files for compiling against QMQTT." )
+set( CPACK_COMPONENT_Devel_REQUIRED 0 )
+
+if( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
+
+    if ( "${CPACK_PACKAGE_ARCHITECTURE}" STREQUAL "" )
+        # Note: the architecture should default to the local architecture, but it
+        # in fact comes up empty.  We call `uname -m` to ask the kernel instead.
+        EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE )
+    endif()
+
+    set( CPACK_INCLUDE_TOPLEVEL_DIRECTORY 1 )
+    set( CPACK_PACKAGE_RELEASE 1 )
+
+
+    # RPM - https://cmake.org/cmake/help/latest/cpack_gen/rpm.html
+    set( CPACK_RPM_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} )
+    set( CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_PACKAGE_ARCHITECTURE} )
+    set( CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY} )
+    set( CPACK_RPM_PACKAGE_URL ${CPACK_PACKAGE_HOMEPAGE_URL} )
+    set( CPACK_RPM_PACKAGE_LICENSE "EPL-1 AND EDL-1" )
+    set( CPACK_RPM_COMPONENT_INSTALL 1 )
+    set( CPACK_RPM_COMPRESSION_TYPE "xz" )
+    set( CPACK_RPM_PACKAGE_AUTOPROV 1 )
+
+    set( CPACK_RPM_Library_PACKAGE_SUMMARY ${CPACK_COMPONENT_Library_DESCRIPTION} )
+    set( CPACK_RPM_Library_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} )
+    set( CPACK_RPM_Library_PACKAGE_NAME ${CPACK_PACKAGE_NAME} )
+    set( CPACK_RPM_Library_FILE_NAME "RPM-DEFAULT" )
+
+    set( CPACK_RPM_Devel_PACKAGE_REQUIRES "cmake >= ${CMAKE_MINIMUM_REQUIRED_VERSION},qmqtt >= ${CPACK_PACKAGE_VERSION}" )
+    set( CPACK_RPM_Devel_PACKAGE_SUMMARY ${CPACK_COMPONENT_Devel_DESCRIPTION} )
+    set( CPACK_RPM_Devel_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} )
+    set( CPACK_RPM_Devel_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-devel" )
+    set( CPACK_RPM_Devel_FILE_NAME "RPM-DEFAULT" )
+
+
+    # DEB - https://cmake.org/cmake/help/latest/cpack_gen/deb.html
+    set( CPACK_DEBIAN_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} )
+    set( CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL} )
+    set( CPACK_DEB_COMPONENT_INSTALL 1 )
+    set( CPACK_DEBIAN_COMPRESSION_TYPE "xz")
+
+    if ( ${CPACK_PACKAGE_ARCHITECTURE} STREQUAL "x86_64" )
+        set( CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64" )  # DEB doesn't always use the kernel's arch name
+    else()
+        set( CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${CPACK_PACKAGE_ARCHITECTURE} )
+    endif()
+
+    set( CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT" ) # Use default naming scheme
+
+    set( CPACK_DEBIAN_LIBRARY_PACKAGE_NAME ${CPACK_PACKAGE_NAME} )
+    set( CPACK_DEBIAN_LIBRARY_PACKAGE_SHLIBDEPS 1 )
+
+    set( CPACK_DEBIAN_DEVEL_PACKAGE_DEPENDS "cmake (>= ${CMAKE_MINIMUM_REQUIRED_VERSION}), qmqtt (>= ${CPACK_PACKAGE_VERSION})" )
+    set( CPACK_DEBIAN_DEVEL_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-dev" )
+
+elseif( ${CMAKE_HOST_WIN32} )
+    set( CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON )
+    set( CPACK_NSIS_DISPLAY_NAME ${PROJECT_NAME} )
+    set( CPACK_NSIS_PACKAGE_NAME ${PROJECT_NAME} )
+    set( CPACK_NSIS_URL_INFO_ABOUT ${CPACK_PACKAGE_HOMEPAGE_URL} )
+endif()
+
+# This must always be last!
+include(CPack)

+ 2 - 0
qmqtt-master/LICENSE

@@ -0,0 +1,2 @@
+This project is dual licensed under the Eclipse Public License 1.0 and the
+Eclipse Distribution License 1.0 as described in the epl-v10 and edl-v10 files.

+ 139 - 0
qmqtt-master/README.md

@@ -0,0 +1,139 @@
+QMQTT
+=====
+
+mqtt client for Qt
+
+**Please compile the library with Qt >= 5.3 version. On Windows you need to specify `CONFIG += NO_UNIT_TESTS`, since gtest is not supported.**
+
+SSL is enabled by default, if the version of OpenSSL < 1.0.2, SSL may not be supported. 
+
+Disable the SSL in CMakeLists.txt (cmake):
+
+    option( ${PROJECT_NAME}_SSL "Enable SSL support for MQTT" OFF )
+
+Disable the SSL with src/mqtt/qmqtt.pro (qmake):
+
+    CONFIG+=QMQTT_NO_SSL
+
+To add websocket support, compile the library with Qt >= 5.7, and specify 'CONFIG += QMQTT_WEBSOCKETS'.
+This also works when compiling qmqtt for WebAssembly.
+
+Usage
+=====
+
+In your QMake project, add:
+
+    QT += qmqtt
+
+Connect using TCP:
+
+    #include "qmqtt.h"
+
+    QMQTT::Client *client = new QMQTT::Client(QHostAddress::LocalHost, 1883);
+    client->setClientId("clientId");
+    client->setUsername("user");
+    client->setPassword("password");
+    client->connectToHost();
+
+Connect using SSL:
+
+    QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
+    // Add custom SSL options here (for example extra certificates)
+    QMQTT::Client *client = new QMQTT::Client("example.com", 8883, sslConfig);
+    client->setClientId("clientId");
+    client->setUsername("user");
+    client->setPassword("password");
+    // Optionally, set ssl errors you want to ignore. Be careful, because this may weaken security.
+    // See QSslSocket::ignoreSslErrors(const QList<QSslError> &) for more information.
+    client->ignoreSslErrors(<list of expected ssl errors>)
+    client->connectToHost();
+    // Here's another option to suppress SSL errors (again, be careful)
+    QObject::connect(client, &QMQTT::Client::sslErrors, [&](const QList<QSslError> &errors) {
+        // Investigate the errors here, if you find no serious problems, call ignoreSslErrors()
+        // to continue connecting.
+        client->ignoreSslErrors();
+    });
+
+Connect using WebSockets:
+
+    QMQTT::Client *client = new QMQTT::Client("ws://www.example.com/mqtt", "<origin>", QWebSocketProtocol::VersionLatest);
+    client->setClientId("clientId");
+    client->setUsername("user");
+    client->setPassword("password");
+    client->connectToHost();
+
+Slots
+=====
+
+    void setHost(const QHostAddress& host);
+    void setPort(const quint16 port);
+    void setClientId(const QString& clientId);
+    void setUsername(const QString& username);
+    void setPassword(const QString& password);
+    void setKeepAlive(const int keepAlive);
+    void setCleanSession(const bool cleansess);
+    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 QString& willMessage);
+
+    void connectToHost();
+    void disconnectFromHost();
+
+    quint16 subscribe(const QString& topic, const quint8 qos);
+    void unsubscribe(const QString& topic);
+
+    quint16 publish(const Message& message);
+
+Signals
+=======
+
+    void connected();
+    void disconnected();
+    void error(const QMQTT::ClientError error);
+
+    void subscribed(const QString& topic, const quint8 qos);
+    void unsubscribed(const QString& topic);
+    void published(const quint16 msgid, const quint8 qos);
+    void pingresp();
+    void received(const QMQTT::Message& message);
+
+
+License
+=======
+
+New BSD License
+
+
+Contributors
+=============
+
+[@Kampfgnom](https://github.com/Kampfgnom)
+
+[@rafaeldelucena](https://github.com/rafaeldelucena)
+
+[@Vortex375](https://github.com/Vortex375)
+
+[@mwallnoefer](https://github.com/mwallnoefer)
+
+[@KonstantinRitt](https://github.com/KonstantinRitt)
+
+[@cncap](https://github.com/cncap)
+
+[@Psy-Kai](https://github.com/Psy-Kai)
+
+[@ejvr](https://github.com/ejvr)
+
+[@keytee](https://github.com/keytee)
+
+
+Authors
+=======
+
+[@emqplus](https://github.com/emqplus) Feng Lee <feng@emqtt.io>
+
+[@wguynes](https://github.com/wguynes) William Guynes <wguynes@gmail.com>
+
+[@wuming123057](https://github.com/wuming123057) Xuan <huacai123057@163.com>

+ 30 - 0
qmqtt-master/edl-v10

@@ -0,0 +1,30 @@
+Eclipse Distribution License - v 1.0
+
+Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
+
+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 the Eclipse Foundation, Inc. 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.

+ 220 - 0
qmqtt-master/epl-v10

@@ -0,0 +1,220 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+
+1. DEFINITIONS
+
+"Contribution" means:
+  a) in the case of the initial Contributor, the initial code and
+     documentation distributed under this Agreement, and
+
+  b) in the case of each subsequent Contributor:
+
+     i) changes to the Program, and
+     ii) additions to the Program; 
+
+where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates' from a
+Contributor if it was added to the Program by such Contributor itself or anyone
+acting on such Contributor's behalf. Contributions do not include additions to
+the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are
+not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+
+2. GRANT OF RIGHTS
+
+  a) Subject to the terms of this Agreement, each Contributor hereby grants
+     Recipient a non-exclusive, worldwide, royalty-free copyright license to
+     reproduce, prepare derivative works of, publicly display, publicly
+     perform, distribute and sublicense the Contribution of such Contributor,
+     if any, and such derivative works, in source code and object code form.
+
+  b) Subject to the terms of this Agreement, each Contributor hereby grants
+     Recipient a non-exclusive, worldwide, royalty-free patent license under
+     Licensed Patents to make, use, sell, offer to sell, import and otherwise
+     transfer the Contribution of such Contributor, if any, in source code and
+     object code form. This patent license shall apply to the combination of the
+     Contribution and the Program if, at the time the Contribution is added by the
+     Contributor, such addition of the Contribution causes such combination to be
+     covered by the Licensed Patents. The patent license shall not apply to any
+     other combinations which include the Contribution. No hardware per se is
+     licensed hereunder.
+
+  c) Recipient understands that although each Contributor grants the licenses
+     to its Contributions set forth herein, no assurances are provided by any
+     Contributor that the Program does not infringe the patent or other
+     intellectual property rights of any other entity. Each Contributor disclaims
+     any liability to Recipient for claims brought by any other entity based on
+     infringement of intellectual property rights or otherwise. As a condition to
+     exercising the rights and licenses granted hereunder, each Recipient hereby
+     assumes sole responsibility to secure any other intellectual property rights
+     needed, if any. For example, if a third party patent license is required to
+     allow Recipient to distribute the Program, it is Recipient's responsibility
+     to acquire that license before distributing the Program.
+
+  d) Each Contributor represents that to its knowledge it has sufficient
+     copyright rights in its Contribution, if any, to grant the copyright license
+     set forth in this Agreement.
+
+
+3. REQUIREMENTS
+
+  A Contributor may choose to distribute the Program in object code form under
+  its own license agreement, provided that:
+
+  a) it complies with the terms and conditions of this Agreement; and
+
+  b) its license agreement:
+
+     i) effectively disclaims on behalf of all Contributors all warranties and
+        conditions, express and implied, including warranties or conditions of
+        title and non-infringement, and implied warranties or conditions of
+        merchantability and fitness for a particular purpose;
+
+    ii) effectively excludes on behalf of all Contributors all liability for
+        damages, including direct, indirect, special, incidental and consequential
+        damages, such as lost profits;
+
+   iii) states that any provisions which differ from this Agreement are offered
+        by that Contributor alone and not by any other party; and
+
+    iv) states that source code for the Program is available from such
+        Contributor, and informs licensees how to obtain it in a reasonable manner
+        on or through a medium customarily used for software exchange. 
+
+  When the Program is made available in source code form:
+
+    a) it must be made available under this Agreement; and
+
+    b) a copy of this Agreement must be included with each copy of the Program. 
+
+  Contributors may not remove or alter any copyright notices contained within
+  the Program.
+
+  Each Contributor must identify itself as the originator of its Contribution,
+  if any, in a manner that reasonably allows subsequent Recipients to identify
+  the originator of the Contribution.
+
+
+4. COMMERCIAL DISTRIBUTION
+
+  Commercial distributors of software may accept certain responsibilities with
+  respect to end users, business partners and the like. While this license is
+  intended to facilitate the commercial use of the Program, the Contributor who
+  includes the Program in a commercial product offering should do so in a
+  manner which does not create potential liability for other Contributors.
+  Therefore, if a Contributor includes the Program in a commercial product
+  offering, such Contributor ("Commercial Contributor") hereby agrees to defend
+  and indemnify every other Contributor ("Indemnified Contributor") against any
+  losses, damages and costs (collectively "Losses") arising from claims,
+  lawsuits and other legal actions brought by a third party against the
+  Indemnified Contributor to the extent caused by the acts or omissions of such
+  Commercial Contributor in connection with its distribution of the Program in
+  a commercial product offering. The obligations in this section do not apply
+  to any claims or Losses relating to any actual or alleged intellectual
+  property infringement. In order to qualify, an Indemnified Contributor must:
+  a) promptly notify the Commercial Contributor in writing of such claim, and
+  b) allow the Commercial Contributor to control, and cooperate with the
+  Commercial Contributor in, the defense and any related settlement
+  negotiations. The Indemnified Contributor may participate in any such claim
+  at its own expense.
+
+  For example, a Contributor might include the Program in a commercial product
+  offering, Product X. That Contributor is then a Commercial Contributor. If
+  that Commercial Contributor then makes performance claims, or offers
+  warranties related to Product X, those performance claims and warranties are
+  such Commercial Contributor's responsibility alone. Under this section, the
+  Commercial Contributor would have to defend claims against the other
+  Contributors related to those performance claims and warranties, and if a
+  court requires any other Contributor to pay any damages as a result, the
+  Commercial Contributor must pay those damages.
+
+
+5. NO WARRANTY
+
+  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
+  AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
+  EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
+  CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
+  PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
+  appropriateness of using and distributing the Program and assumes all risks
+  associated with its exercise of rights under this Agreement , including but
+  not limited to the risks and costs of program errors, compliance with
+  applicable laws, damage to or loss of data, programs or equipment, and
+  unavailability or interruption of operations.
+
+
+6. DISCLAIMER OF LIABILITY
+
+  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+  CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
+  LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE
+  EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
+  OF SUCH DAMAGES.
+
+
+7. GENERAL
+
+  If any provision of this Agreement is invalid or unenforceable under
+  applicable law, it shall not affect the validity or enforceability of the
+  remainder of the terms of this Agreement, and without further action by the
+  parties hereto, such provision shall be reformed to the minimum extent
+  necessary to make such provision valid and enforceable.
+
+  If Recipient institutes patent litigation against any entity (including a
+  cross-claim or counterclaim in a lawsuit) alleging that the Program itself
+  (excluding combinations of the Program with other software or hardware)
+  infringes such Recipient's patent(s), then such Recipient's rights granted
+  under Section 2(b) shall terminate as of the date such litigation is filed.
+
+  All Recipient's rights under this Agreement shall terminate if it fails to
+  comply with any of the material terms or conditions of this Agreement and
+  does not cure such failure in a reasonable period of time after becoming
+  aware of such noncompliance. If all Recipient's rights under this Agreement
+  terminate, Recipient agrees to cease use and distribution of the Program as
+  soon as reasonably practicable. However, Recipient's obligations under this
+  Agreement and any licenses granted by Recipient relating to the Program shall
+  continue and survive.
+
+  Everyone is permitted to copy and distribute copies of this Agreement, but in
+  order to avoid inconsistency the Agreement is copyrighted and may only be
+  modified in the following manner. The Agreement Steward reserves the right to
+  publish new versions (including revisions) of this Agreement from time to
+  time. No one other than the Agreement Steward has the right to modify this
+  Agreement. The Eclipse Foundation is the initial Agreement Steward. The
+  Eclipse Foundation may assign the responsibility to serve as the Agreement
+  Steward to a suitable separate entity. Each new version of the Agreement will
+  be given a distinguishing version number. The Program (including
+  Contributions) may always be distributed subject to the version of the
+  Agreement under which it was received. In addition, after a new version of
+  the Agreement is published, Contributor may elect to distribute the Program
+  (including its Contributions) under the new version. Except as expressly
+  stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
+  licenses to the intellectual property of any Contributor under this
+  Agreement, whether expressly, by implication, estoppel or otherwise. All
+  rights in the Program not expressly granted under this Agreement are
+  reserved.
+
+  This Agreement is governed by the laws of the State of New York and the
+  intellectual property laws of the United States of America. No party to this
+  Agreement will bring a legal action under this Agreement more than one year
+  after the cause of action arose. Each party waives its rights to a jury trial
+  in any resulting litigation.

+ 3 - 0
qmqtt-master/examples/examples.pro

@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS += \
+    qmqtt

+ 9 - 0
qmqtt-master/examples/examples.qbs

@@ -0,0 +1,9 @@
+import qbs
+
+Project {
+    name: "Examples"
+
+    references: [
+        "qmqtt"
+    ]
+}

+ 9 - 0
qmqtt-master/examples/qmqtt/client/client.pro

@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET = qmqtt_example
+QT = core network qmqtt
+
+SOURCES += \
+    example.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/qmqtt/client
+INSTALLS += target

+ 28 - 0
qmqtt-master/examples/qmqtt/client/client.qbs

@@ -0,0 +1,28 @@
+import qbs
+
+QtApplication {
+    name: "Client"
+    targetName: "qmqtt_example"
+
+    files: [
+        "example.cpp"
+    ]
+
+    Depends {
+        name: "Qt"
+        submodules: [
+            "core",
+            "network",
+        ]
+    }
+
+    Depends {
+        name: "qmqtt"
+    }
+
+    Group {
+        fileTagsFilter: "application"
+        qbs.install: true
+        qbs.installDir: "bin"
+    }
+}

+ 132 - 0
qmqtt-master/examples/qmqtt/client/example.cpp

@@ -0,0 +1,132 @@
+/*
+ * example.cpp - qmqtt example
+ *
+ * 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.
+ *
+ */
+#include <qmqtt.h>
+#include <QCoreApplication>
+#include <QTimer>
+
+const QHostAddress EXAMPLE_HOST = QHostAddress::LocalHost;
+const quint16 EXAMPLE_PORT = 1883;
+const QString EXAMPLE_TOPIC = "qmqtt/exampletopic";
+
+class Publisher : public QMQTT::Client
+{
+    Q_OBJECT
+public:
+    explicit Publisher(const QHostAddress& host = EXAMPLE_HOST,
+                       const quint16 port = EXAMPLE_PORT,
+                       QObject* parent = NULL)
+        : QMQTT::Client(host, port, parent)
+        , _number(0)
+    {
+        connect(this, &Publisher::connected, this, &Publisher::onConnected);
+        connect(&_timer, &QTimer::timeout, this, &Publisher::onTimeout);
+        connect(this, &Publisher::disconnected, this, &Publisher::onDisconnected);
+    }
+    virtual ~Publisher() {}
+
+    QTimer _timer;
+    quint16 _number;
+
+public slots:
+    void onConnected()
+    {
+        subscribe(EXAMPLE_TOPIC, 0);
+        _timer.start(1000);
+    }
+
+    void onTimeout()
+    {
+        QMQTT::Message message(_number, EXAMPLE_TOPIC,
+                               QString("Number is %1").arg(_number).toUtf8());
+        publish(message);
+        _number++;
+        if(_number >= 10)
+        {
+            _timer.stop();
+            disconnectFromHost();
+        }
+    }
+
+    void onDisconnected()
+    {
+        QTimer::singleShot(0, qApp, &QCoreApplication::quit);
+    }
+};
+
+class Subscriber : public QMQTT::Client
+{
+    Q_OBJECT
+public:
+    explicit Subscriber(const QHostAddress& host = EXAMPLE_HOST,
+                        const quint16 port = EXAMPLE_PORT,
+                        QObject* parent = NULL)
+        : QMQTT::Client(host, port, parent)
+        , _qout(stdout)
+    {
+        connect(this, &Subscriber::connected, this, &Subscriber::onConnected);
+        connect(this, &Subscriber::subscribed, this, &Subscriber::onSubscribed);
+        connect(this, &Subscriber::received, this, &Subscriber::onReceived);
+    }
+    virtual ~Subscriber() {}
+
+    QTextStream _qout;
+
+public slots:
+    void onConnected()
+    {
+        _qout << "connected" << endl;
+        subscribe(EXAMPLE_TOPIC, 0);
+    }
+
+    void onSubscribed(const QString& topic)
+    {
+        _qout << "subscribed " << topic << endl;
+    }
+
+    void onReceived(const QMQTT::Message& message)
+    {
+        _qout << "publish received: \"" << QString::fromUtf8(message.payload())
+              << "\"" << endl;
+    }
+};
+
+int main(int argc, char** argv)
+{
+    QCoreApplication app(argc, argv);
+    Subscriber subscriber;
+    subscriber.connectToHost();
+    Publisher publisher;
+    publisher.connectToHost();
+    return app.exec();
+}
+
+#include "example.moc"

+ 3 - 0
qmqtt-master/examples/qmqtt/qmqtt.pro

@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS += \
+    client

+ 9 - 0
qmqtt-master/examples/qmqtt/qmqtt.qbs

@@ -0,0 +1,9 @@
+import qbs
+
+Project {
+    name: "qmqtt"
+
+    references: [
+        "client"
+    ]
+}

+ 62 - 0
qmqtt-master/qmqtt.pri

@@ -0,0 +1,62 @@
+#
+# Add the source folder to the include directories to be searched while
+# compiling a project, this allows developers to write "#include <qmqtt.h>" in
+# their respective projects.
+#
+INCLUDEPATH += $$PWD/src/mqtt
+
+#
+# Do not add DLL import/export symbols as we are compiling QMQTT source code
+# directly with the source code of the project that includes this file.
+#
+DEFINES += MQTT_PROJECT_INCLUDE_SRC
+
+#
+# Add header files
+#
+HEADERS += \
+    $$PWD/src/mqtt/qmqtt.h \
+    $$PWD/src/mqtt/qmqtt_client.h \
+    $$PWD/src/mqtt/qmqtt_client_p.h \
+    $$PWD/src/mqtt/qmqtt_frame.h \
+    $$PWD/src/mqtt/qmqtt_global.h \
+    $$PWD/src/mqtt/qmqtt_message.h \
+    $$PWD/src/mqtt/qmqtt_message_p.h \
+    $$PWD/src/mqtt/qmqtt_network_p.h \
+    $$PWD/src/mqtt/qmqtt_networkinterface.h \
+    $$PWD/src/mqtt/qmqtt_routedmessage.h \
+    $$PWD/src/mqtt/qmqtt_router.h \
+    $$PWD/src/mqtt/qmqtt_routesubscription.h \
+    $$PWD/src/mqtt/qmqtt_socket_p.h \
+    $$PWD/src/mqtt/qmqtt_socketinterface.h \
+    $$PWD/src/mqtt/qmqtt_timer_p.h \
+    $$PWD/src/mqtt/qmqtt_timerinterface.h \
+    $$PWD/src/mqtt/qmqtt_ssl_socket_p.h
+
+#
+# Add source files
+#
+SOURCES += \
+    $$PWD/src/mqtt/qmqtt_client.cpp \
+    $$PWD/src/mqtt/qmqtt_client_p.cpp \
+    $$PWD/src/mqtt/qmqtt_frame.cpp \
+    $$PWD/src/mqtt/qmqtt_message.cpp \
+    $$PWD/src/mqtt/qmqtt_network.cpp \
+    $$PWD/src/mqtt/qmqtt_router.cpp \
+    $$PWD/src/mqtt/qmqtt_routesubscription.cpp \
+    $$PWD/src/mqtt/qmqtt_socket.cpp \
+    $$PWD/src/mqtt/qmqtt_timer.cpp \
+    $$PWD/src/mqtt/qmqtt_ssl_socket.cpp
+
+#
+# Add support for websockets
+#
+QMQTT_WEBSOCKETS {
+    PRIVATE_HEADERS += \
+        $$PWD/src/mqtt/qmqtt_websocket_p.h \
+        $$PWD/src/mqtt/qmqtt_websocketiodevice_p.h
+
+    SOURCES += \
+        $$PWD/src/mqtt/qmqtt_websocket.cpp \
+        $$PWD/src/mqtt/qmqtt_websocketiodevice.cpp
+}

+ 1 - 0
qmqtt-master/qmqtt.pro

@@ -0,0 +1 @@
+load(qt_parts)

+ 656 - 0
qmqtt-master/qmqtt.pro.user

@@ -0,0 +1,656 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 4.7.2, 2023-03-23T20:50:26. -->
+<qtcreator>
+ <data>
+  <variable>EnvironmentId</variable>
+  <value type="QByteArray">{3617412f-ba16-4fe4-83d8-8a9ba84ea18b}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="int">1</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap">
+   <valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
+   <value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.9.7</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.9.7</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ba7ab7ec-e6d7-4239-8d06-20d6c39c5b99}</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/DataProcessService/build-qmqtt-Qt_5_9_7-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/DataProcessService/build-qmqtt-Qt_5_9_7-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/DataProcessService/build-qmqtt-Qt_5_9_7-Profile</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">client</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">client2</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/qmqtt-master/examples/qmqtt/client/client.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">examples/qmqtt/client/client.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/DataProcessService/build-qmqtt-Qt_5_9_7-Release/examples/qmqtt/client</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">message</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">message2</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/qmqtt-master/tests/benchmarks/message/message.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">tests/benchmarks/message/message.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/DataProcessService/build-qmqtt-Qt_5_9_7-Release/tests/benchmarks/message</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.2">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">tests</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">tests2</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/qmqtt-master/tests/gtest/tests/tests.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">tests/gtest/tests/tests.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/DataProcessService/build-qmqtt-Qt_5_9_7-Release/tests/gtest/tests</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">3</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.1</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.8.5 (qt4.8.5)</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 4.8.5 (qt4.8.5)</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{c71f0fab-d0aa-4280-a6f6-3e59c2dc8640}</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/data-agbox/build-qmqtt-Qt_4_8_5_qt4_8_5-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/yt/Qt/data-agbox/build-qmqtt-Qt_4_8_5_qt4_8_5-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmqtt</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/yt/Qt/data-agbox/qmqtt-master/qmqtt.pro</value>
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">qmqtt.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/yt/Qt/data-agbox/build-qmqtt-Qt_4_8_5_qt4_8_5-Release</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="int">2</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">18</value>
+ </data>
+ <data>
+  <variable>Version</variable>
+  <value type="int">18</value>
+ </data>
+</qtcreator>

+ 11 - 0
qmqtt-master/qmqtt.qbs

@@ -0,0 +1,11 @@
+import qbs
+
+Project {
+    name: "QMQTT"
+
+    references: [
+        "examples",
+        "src",
+        "tests",
+    ]
+}

+ 38 - 0
qmqtt-master/src/mqtt/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

+ 48 - 0
qmqtt-master/src/mqtt/qmqtt.pri

@@ -0,0 +1,48 @@
+INCLUDEPATH += $$PWD
+
+PUBLIC_HEADERS += \
+    $$PWD/qmqtt_client.h \
+    $$PWD/qmqtt_frame.h \
+    $$PWD/qmqtt_message.h \
+    $$PWD/qmqtt_routesubscription.h \
+    $$PWD/qmqtt_routedmessage.h \
+    $$PWD/qmqtt_router.h \
+    $$PWD/qmqtt_networkinterface.h \
+    $$PWD/qmqtt_socketinterface.h \
+    $$PWD/qmqtt_timerinterface.h
+
+PRIVATE_HEADERS += \
+    $$PWD/qmqtt_client_p.h \
+    $$PWD/qmqtt_message_p.h \
+    $$PWD/qmqtt_network_p.h \
+    $$PWD/qmqtt_socket_p.h \
+    $$PWD/qmqtt_timer_p.h
+
+SOURCES += \
+    $$PWD/qmqtt_client_p.cpp \
+    $$PWD/qmqtt_client.cpp \
+    $$PWD/qmqtt_frame.cpp \
+    $$PWD/qmqtt_message.cpp \
+    $$PWD/qmqtt_network.cpp \
+    $$PWD/qmqtt_routesubscription.cpp \
+    $$PWD/qmqtt_router.cpp \
+    $$PWD/qmqtt_socket.cpp \
+    $$PWD/qmqtt_timer.cpp
+
+QMQTT_WEBSOCKETS {
+    PRIVATE_HEADERS += \
+        $$PWD/qmqtt_websocket_p.h \
+        $$PWD/qmqtt_websocketiodevice_p.h
+
+    SOURCES += \
+        $$PWD/qmqtt_websocket.cpp \
+        $$PWD/qmqtt_websocketiodevice.cpp
+}
+
+!contains(CONFIG, QMQTT_NO_SSL) {
+    PRIVATE_HEADERS += \
+        $$PWD/qmqtt_ssl_socket_p.h
+
+    SOURCES += \
+        $$PWD/qmqtt_ssl_socket.cpp
+}

+ 17 - 0
qmqtt-master/src/mqtt/qmqtt.pro

@@ -0,0 +1,17 @@
+TARGET = QtQmqtt
+QT = core network
+qtHaveModule(websockets): QMQTT_WEBSOCKETS: QT += websockets
+
+DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
+
+# CONFIG += QMQTT_NO_SSL
+
+HEADERS += \
+    $$PWD/qmqtt_global.h \
+    $$PWD/qmqtt.h
+
+include(qmqtt.pri)
+
+HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
+
+load(qt_module)

+ 134 - 0
qmqtt-master/src/mqtt/qmqtt.qbs

@@ -0,0 +1,134 @@
+import qbs
+import qbs.TextFile
+import qbs.FileInfo
+
+Product {
+    name: "qmqtt"
+    type: [libraryType]
+    property bool webSocketSupport: false
+    property string libraryType: "dynamiclibrary"
+    targetName: "qmqtt"
+    version: "1.0.0"
+
+    cpp.defines: [
+        "QT_BUILD_QMQTT_LIB",
+        "QT_NO_CAST_TO_ASCII",
+        "QT_NO_CAST_FROM_ASCII",
+    ]
+
+    cpp.includePaths: sourceDirectory
+
+    files: [
+        "*.cpp"
+    ]
+
+    Group {
+        name: "Public Headers"
+        fileTags: [
+            "hpp",
+            "public_headers"
+        ]
+        files: [
+            "*.h"
+        ]
+        excludeFiles: privateHeaders.files
+    }
+
+    Group {
+        id: privateHeaders
+        name: "Private Headers"
+        fileTags: [
+            "hpp",
+            "private_headers",
+        ]
+        files: [
+            "*_p.h"
+        ]
+    }
+
+    Group {
+        fileTagsFilter: libraryType
+        qbs.install: true
+        qbs.installDir: "lib"
+    }
+
+    Group {
+        fileTagsFilter: "public_headers"
+        qbs.install: true
+        qbs.installDir: FileInfo.joinPaths("include", product.name)
+    }
+
+    Group {
+        fileTagsFilter: "private_headers"
+        qbs.install: true
+        qbs.installDir: FileInfo.joinPaths("include", product.name, version, product.name)
+    }
+
+    Group {
+        fileTagsFilter: "Exporter.qbs.module"
+        qbs.installDir: FileInfo.joinPaths("qbs", "modules", product.name, "private")
+        qbs.install: true
+    }
+
+    Group {
+        fileTagsFilter: "Exporter.pkgconfig.pc"
+        qbs.installDir: FileInfo.joinPaths("lib" ,"pkgconfig")
+        qbs.install: true
+    }
+
+    Depends {
+        name: "cpp"
+    }
+
+    Depends {
+        name: "Qt"
+        property var baseModules: ["core", "network"]
+
+        Properties {
+            condition: webSocketSupport
+            submodules: baseModules.concat(["websockets"])
+        }
+        Properties {
+            condition: !webSocketSupport
+            submodules: baseModules
+        }
+    }
+
+    Depends {
+        name: "Exporter.qbs"
+    }
+    Depends {
+        name: "Exporter.pkgconfig"
+    }
+
+    Export {
+        Depends {
+            name: "cpp"
+        }
+
+        Depends {
+            name: "Qt"
+            property var baseModules: ["core", "network"]
+            Properties {
+                condition: product.webSocketSupport
+                submodules: baseModules.concat(["websockets"])
+            }
+            Properties {
+                condition: !product.webSocketSupport
+                submodules: baseModules
+            }
+        }
+
+        cpp.includePaths: [
+            product.sourceDirectory,
+            FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, "include"),
+        ]
+        prefixMapping: [
+            {
+                prefix: product.sourceDirectory,
+                replacement: FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, "include",
+                                                product.name)
+            }
+        ]
+    }
+}

+ 412 - 0
qmqtt-master/src/mqtt/qmqtt_client.cpp

@@ -0,0 +1,412 @@
+/*
+ * qmqtt_client.cpp - qmqtt client
+ *
+ * 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.
+ *
+ */
+
+#include "qmqtt_client.h"
+#include "qmqtt_client_p.h"
+
+QMQTT::Client::Client(const QHostAddress& host,
+                      const quint16 port,
+                      QObject* parent)
+    : QObject(parent)
+    , d_ptr(new ClientPrivate(this))
+{
+    Q_D(Client);
+    d->init(host, port);
+}
+
+#ifndef QT_NO_SSL
+QMQTT::Client::Client(const QString &hostName,
+                      const quint16 port,
+                      const QSslConfiguration &config,
+                      const bool ignoreSelfSigned, QObject *parent)
+    : QObject(parent)
+    , d_ptr(new ClientPrivate(this))
+{
+    Q_D(Client);
+    d->init(hostName, port, config, ignoreSelfSigned);
+}
+#endif // QT_NO_SSL
+
+QMQTT::Client::Client(const QString &hostName,
+                      const quint16 port,
+                      const bool ssl,
+                      const bool ignoreSelfSigned,
+                      QObject* parent)
+    : QObject(parent)
+    , d_ptr(new ClientPrivate(this))
+{
+    Q_D(Client);
+    d->init(hostName, port, ssl, ignoreSelfSigned);
+}
+
+#ifdef QT_WEBSOCKETS_LIB
+QMQTT::Client::Client(const QString& url,
+                      const QString& origin,
+                      QWebSocketProtocol::Version version,
+                      bool ignoreSelfSigned,
+                      QObject* parent)
+    : QObject(parent)
+    , d_ptr(new ClientPrivate(this))
+{
+    Q_D(Client);
+#ifndef QT_NO_SSL
+    d->init(url, origin, version, NULL, ignoreSelfSigned);
+#else
+    Q_UNUSED(ignoreSelfSigned)
+    d->init(url, origin, version);
+#endif // QT_NO_SSL
+}
+
+#ifndef QT_NO_SSL
+QMQTT::Client::Client(const QString& url,
+                      const QString& origin,
+                      QWebSocketProtocol::Version version,
+                      const QSslConfiguration& sslConfig,
+                      const bool ignoreSelfSigned,
+                      QObject* parent)
+    : QObject(parent)
+    , d_ptr(new ClientPrivate(this))
+{
+    Q_D(Client);
+    d->init(url, origin, version, &sslConfig, ignoreSelfSigned);
+}
+#endif // QT_NO_SSL
+#endif // QT_WEBSOCKETS_LIB
+
+QMQTT::Client::Client(NetworkInterface* network,
+                      const QHostAddress& host,
+                      const quint16 port,
+                      QObject* parent)
+    : QObject(parent)
+    , d_ptr(new ClientPrivate(this))
+{
+    Q_D(Client);
+    d->init(host, port, network);
+}
+
+QMQTT::Client::~Client()
+{
+}
+
+QHostAddress QMQTT::Client::host() const
+{
+    Q_D(const Client);
+    return d->host();
+}
+
+void QMQTT::Client::setHost(const QHostAddress& host)
+{
+    Q_D(Client);
+    d->setHost(host);
+}
+
+QString QMQTT::Client::hostName() const
+{
+    Q_D(const Client);
+    return d->hostName();
+}
+
+void QMQTT::Client::setHostName(const QString &hostName)
+{
+    Q_D(Client);
+    d->setHostName(hostName);
+}
+
+quint16 QMQTT::Client::port() const
+{
+    Q_D(const Client);
+    return d->port();
+}
+
+void QMQTT::Client::setPort(const quint16 port)
+{
+    Q_D(Client);
+    d->setPort(port);
+}
+
+QString QMQTT::Client::clientId() const
+{
+    Q_D(const Client);
+    return d->clientId();
+}
+
+void QMQTT::Client::setClientId(const QString& clientId)
+{
+    Q_D(Client);
+    d->setClientId(clientId);
+}
+
+QString QMQTT::Client::username() const
+{
+    Q_D(const Client);
+    return d->username();
+}
+
+void QMQTT::Client::setUsername(const QString& username)
+{
+    Q_D(Client);
+    d->setUsername(username);
+}
+
+QMQTT::MQTTVersion QMQTT::Client::version() const
+{
+    Q_D(const Client);
+    return d->version();
+}
+
+void QMQTT::Client::setVersion(const QMQTT::MQTTVersion version)
+{
+    Q_D(Client);
+    d->setVersion(version);
+}
+
+QByteArray QMQTT::Client::password() const
+{
+    Q_D(const Client);
+    return d->password();
+}
+
+void QMQTT::Client::setPassword(const QByteArray &password)
+{
+    Q_D(Client);
+    d->setPassword(password);
+}
+
+quint16 QMQTT::Client::keepAlive() const
+{
+    Q_D(const Client);
+    return d->keepAlive();
+}
+
+void QMQTT::Client::setKeepAlive(const quint16 keepAlive)
+{
+    Q_D(Client);
+    d->setKeepAlive(keepAlive);
+}
+
+bool QMQTT::Client::cleanSession() const
+{
+    Q_D(const Client);
+    return d->cleanSession();
+}
+
+void QMQTT::Client::setCleanSession(const bool cleanSession)
+{
+    Q_D(Client);
+    d->setCleanSession(cleanSession);
+}
+
+bool QMQTT::Client::autoReconnect() const
+{
+    Q_D(const Client);
+    return d->autoReconnect();
+}
+
+void QMQTT::Client::setAutoReconnect(const bool value)
+{
+    Q_D(Client);
+    d->setAutoReconnect(value);
+}
+
+int QMQTT::Client::autoReconnectInterval() const
+{
+    Q_D(const Client);
+    return d->autoReconnectInterval();
+}
+
+void QMQTT::Client::setAutoReconnectInterval(const int autoReconnectInterval)
+{
+    Q_D(Client);
+    d->setAutoReconnectInterval(autoReconnectInterval);
+}
+
+QString QMQTT::Client::willTopic() const
+{
+    Q_D(const Client);
+    return d->willTopic();
+}
+
+void QMQTT::Client::setWillTopic(const QString& willTopic)
+{
+    Q_D(Client);
+    d->setWillTopic(willTopic);
+}
+
+quint8 QMQTT::Client::willQos() const
+{
+    Q_D(const Client);
+    return d->willQos();
+}
+
+void QMQTT::Client::setWillQos(const quint8 willQos)
+{
+    Q_D(Client);
+    d->setWillQos(willQos);
+}
+
+bool QMQTT::Client::willRetain() const
+{
+    Q_D(const Client);
+    return d->willRetain();
+}
+
+void QMQTT::Client::setWillRetain(const bool willRetain)
+{
+    Q_D(Client);
+    d->setWillRetain(willRetain);
+}
+
+QByteArray QMQTT::Client::willMessage() const
+{
+    Q_D(const Client);
+    return d->willMessage();
+}
+
+void QMQTT::Client::setWillMessage(const QByteArray &willMessage)
+{
+    Q_D(Client);
+    d->setWillMessage(willMessage);
+}
+
+QMQTT::ConnectionState QMQTT::Client::connectionState() const
+{
+    Q_D(const Client);
+    return d->connectionState();
+}
+
+bool QMQTT::Client::isConnectedToHost() const
+{
+    Q_D(const Client);
+    return d->isConnectedToHost();
+}
+
+#ifndef QT_NO_SSL
+QSslConfiguration QMQTT::Client::sslConfiguration() const
+{
+    Q_D(const Client);
+    return d->sslConfiguration();
+}
+
+void QMQTT::Client::setSslConfiguration(const QSslConfiguration& config)
+{
+    Q_D(Client);
+    d->setSslConfiguration(config);
+}
+#endif // QT_NO_SSL
+
+void QMQTT::Client::connectToHost()
+{
+    Q_D(Client);
+    d->connectToHost();
+}
+
+void QMQTT::Client::onNetworkConnected()
+{    
+    Q_D(Client);
+    d->onNetworkConnected();
+}
+
+quint16 QMQTT::Client::publish(const Message& message)
+{
+    Q_D(Client);
+    return d->publish(message);
+}
+
+void QMQTT::Client::subscribe(const QString& topic, const quint8 qos)
+{
+    Q_D(Client);
+    d->subscribe(topic, qos);
+}
+
+void QMQTT::Client::unsubscribe(const QString& topic)
+{
+    Q_D(Client);
+    d->unsubscribe(topic);
+}
+
+void QMQTT::Client::onTimerPingReq()
+{
+    Q_D(Client);
+    d->onTimerPingReq();
+}
+
+void QMQTT::Client::onPingTimeout()
+{
+    Q_D(Client);
+    d->onPingTimeout();
+}
+
+void QMQTT::Client::disconnectFromHost()
+{
+    Q_D(Client);
+    d->disconnectFromHost();
+}
+
+void QMQTT::Client::onNetworkReceived(const QMQTT::Frame& frame)
+{
+    Q_D(Client);
+    d->onNetworkReceived(frame);
+}
+
+void QMQTT::Client::onNetworkDisconnected()
+{
+    Q_D(Client);
+    d->onNetworkDisconnected();
+}
+
+void QMQTT::Client::onNetworkError(QAbstractSocket::SocketError error)
+{
+    Q_D(Client);
+    d->onNetworkError(error);
+}
+
+#ifndef QT_NO_SSL
+void QMQTT::Client::onSslErrors(const QList<QSslError>& errors)
+{
+    Q_D(Client);
+    d->onSslErrors(errors);
+}
+#endif // QT_NO_SSL
+
+#ifndef QT_NO_SSL
+void QMQTT::Client::ignoreSslErrors()
+{
+    Q_D(Client);
+    d->ignoreSslErrors();
+}
+
+void QMQTT::Client::ignoreSslErrors(const QList<QSslError>& errors)
+{
+    Q_D(Client);
+    d->ignoreSslErrors(errors);
+}
+#endif // QT_NO_SSL

+ 286 - 0
qmqtt-master/src/mqtt/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(QString _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 = NULL);
+
+#ifndef QT_NO_SSL
+    Client(const QString& hostName,
+           const quint16 port,
+           const QSslConfiguration& config,
+           const bool ignoreSelfSigned=false,
+           QObject* parent = NULL);
+#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 = NULL);
+
+#ifdef QT_WEBSOCKETS_LIB
+    // Create a connection over websockets
+    Client(const QString& url,
+           const QString& origin,
+           QWebSocketProtocol::Version version,
+           bool ignoreSelfSigned = false,
+           QObject* parent = NULL);
+
+#ifndef QT_NO_SSL
+    Client(const QString& url,
+           const QString& origin,
+           QWebSocketProtocol::Version version,
+           const QSslConfiguration& config,
+           const bool ignoreSelfSigned = false,
+           QObject* parent = NULL);
+#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 = NULL);
+
+    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 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
+
+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 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

+ 811 - 0
qmqtt-master/src/mqtt/qmqtt_client_p.cpp

@@ -0,0 +1,811 @@
+/*
+ * qmqtt_client_p.cpp - qmqtt client private
+ *
+ * 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.
+ *
+ */
+
+#include "qmqtt_client_p.h"
+#include "qmqtt_network_p.h"
+#include "qmqtt_frame.h"
+#include "qmqtt_message.h"
+
+#include <QLoggingCategory>
+#include <QUuid>
+#ifndef QT_NO_SSL
+#include <QFile>
+#include <QSslConfiguration>
+#include <QSslKey>
+#endif // QT_NO_SSL
+
+Q_LOGGING_CATEGORY(client, "qmqtt.client")
+
+static const quint8 QOS0 = 0x00;
+static const quint8 QOS1 = 0x01;
+static const quint8 QOS2 = 0x02;
+
+QMQTT::ClientPrivate::ClientPrivate(Client* qq_ptr)
+    : _host(QHostAddress::LocalHost)
+    , _port(1883)
+    , _gmid(1)
+    , _version(MQTTVersion::V3_1_0)
+    , _clientId(QUuid::createUuid().toString())
+    , _cleanSession(false)
+    , _connectionState(STATE_INIT)
+    , _willQos(0)
+    , _willRetain(false)
+    , q_ptr(qq_ptr)
+{
+    setKeepAlive(300);
+}
+
+QMQTT::ClientPrivate::~ClientPrivate()
+{
+}
+
+void QMQTT::ClientPrivate::init(const QHostAddress& host, const quint16 port, NetworkInterface* network)
+{
+    Q_Q(Client);
+    _host = host;
+    _port = port;
+    if(network == NULL)
+    {
+        init(new Network(q));
+    }
+    else
+    {
+        init(network);
+    }
+}
+
+#ifndef QT_NO_SSL
+void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port,
+                                const QSslConfiguration &config, const bool ignoreSelfSigned)
+{
+    Q_Q(Client);
+    _hostName = hostName;
+    _port = port;
+    _ignoreSelfSigned = ignoreSelfSigned;
+    init(new Network(config, q));
+    QObject::connect(_network.data(), &QMQTT::Network::sslErrors, q, &QMQTT::Client::onSslErrors);
+}
+#endif // QT_NO_SSL
+
+void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port, const bool ssl,
+                                const bool ignoreSelfSigned)
+{
+    Q_Q(Client);
+    _hostName = hostName;
+    _port = port;
+    if (ssl)
+    {
+#ifndef QT_NO_SSL
+        QSslConfiguration sslConf = QSslConfiguration::defaultConfiguration();
+        QList<QSslCertificate> certs = QSslCertificate::fromPath(QStringLiteral("./cert.crt"));
+        if (!certs.isEmpty())
+            sslConf.setLocalCertificate(certs.first());
+        QFile file(QStringLiteral("./cert.key"));
+        if (file.open(QIODevice::ReadOnly)) {
+            sslConf.setPrivateKey(QSslKey(file.readAll(), QSsl::Rsa));
+        }
+        sslConf.setPeerVerifyMode(QSslSocket::VerifyNone);
+        init(hostName, port, sslConf, ignoreSelfSigned);
+#else
+        Q_UNUSED(ignoreSelfSigned)
+        qCritical() << "SSL not supported in this QT build";
+#endif // QT_NO_SSL
+    }
+    else
+    {
+        init(new Network(q));
+    }
+}
+
+#ifdef QT_WEBSOCKETS_LIB
+#ifndef QT_NO_SSL
+void QMQTT::ClientPrivate::init(const QString& url,
+                                const QString& origin,
+                                QWebSocketProtocol::Version version,
+                                const QSslConfiguration* sslConfig,
+                                bool ignoreSelfSigned)
+{
+    Q_Q(Client);
+    _hostName = url;
+    _ignoreSelfSigned = ignoreSelfSigned;
+    init(new Network(origin, version, sslConfig, q));
+}
+#endif // QT_NO_SSL
+
+void QMQTT::ClientPrivate::init(const QString& url,
+                                const QString& origin,
+                                QWebSocketProtocol::Version version)
+{
+    Q_Q(Client);
+    _hostName = url;
+    init(new Network(origin, version, q));
+}
+#endif // QT_WEBSOCKETS_LIB
+
+void QMQTT::ClientPrivate::init(NetworkInterface* network)
+{
+    Q_Q(Client);
+
+    _network.reset(network);
+    _timer.setSingleShot(true);
+    _pingResponseTimer.setSingleShot(true);
+
+    QObject::connect(&_timer, &QTimer::timeout, q, &Client::onTimerPingReq);
+    QObject::connect(&_pingResponseTimer, &QTimer::timeout, q, &Client::onPingTimeout);
+    QObject::connect(_network.data(), &Network::connected,
+                     q, &Client::onNetworkConnected);
+    QObject::connect(_network.data(), &Network::disconnected,
+                     q, &Client::onNetworkDisconnected);
+    QObject::connect(_network.data(), &Network::received,
+                     q, &Client::onNetworkReceived);
+    QObject::connect(_network.data(), &Network::error,
+                     q, &Client::onNetworkError);
+}
+
+void QMQTT::ClientPrivate::connectToHost()
+{
+    _connectionState = ConnectionState::STATE_CONNECTING;
+    if (_hostName.isEmpty())
+    {
+        _network->connectToHost(_host, _port);
+    }
+    else
+    {
+        _network->connectToHost(_hostName, _port);
+    }
+}
+
+void QMQTT::ClientPrivate::onNetworkConnected()
+{
+    sendConnect();
+}
+
+void QMQTT::ClientPrivate::sendConnect()
+{
+    quint8 header = CONNECT;
+    quint8 flags = 0;
+
+    //header
+    Frame frame(header);
+
+    //flags
+    flags = FLAG_CLEANSESS(flags, _cleanSession ? 1 : 0 );
+    flags = FLAG_WILL(flags, willTopic().isEmpty() ? 0 : 1);
+    if (!willTopic().isEmpty())
+    {
+        flags = FLAG_WILLQOS(flags, willQos());
+        flags = FLAG_WILLRETAIN(flags, willRetain() ? 1 : 0);
+    }
+    if (!username().isEmpty())
+    {
+        flags = FLAG_USERNAME(flags, 1);
+        flags = FLAG_PASSWD(flags, !password().isEmpty() ? 1 : 0);
+    }
+
+    //payload
+    if(_version == V3_1_1)
+    {
+        frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_1));
+    }
+    else
+    {
+        frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_0));
+    }
+    frame.writeChar(_version);
+    frame.writeChar(flags);
+    frame.writeInt(keepAlive());
+    frame.writeString(_clientId);
+    if(!willTopic().isEmpty())
+    {
+        frame.writeString(willTopic());
+        // According to the specs (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718031)
+        // the will message gets always sent together with the topic, also when it is empty which is perfectly valid.
+        frame.writeByteArray(_willMessage); 
+    }
+    if (!_username.isEmpty())
+    {
+        frame.writeString(_username);
+        if (!_password.isEmpty())
+        {
+            frame.writeByteArray(_password);
+        }
+    }
+    sendFrame(frame);
+}
+
+quint16 QMQTT::ClientPrivate::sendPublish(const Message &message)
+{
+    quint16 msgid = message.id();
+
+    quint8 header = PUBLISH;
+    header = SETRETAIN(header, message.retain() ? 1 : 0);
+    header = SETQOS(header, message.qos());
+    header = SETDUP(header, message.dup() ? 1 : 0);
+    Frame frame(header);
+    frame.writeString(message.topic());
+    if(message.qos() > QOS0) {
+        if (msgid == 0)
+            msgid = nextmid();
+        frame.writeInt(msgid);
+    }
+    if(!message.payload().isEmpty()) {
+        frame.writeRawData(message.payload());
+    }
+    sendFrame(frame);
+    return msgid;
+}
+
+void QMQTT::ClientPrivate::sendPuback(const quint8 type, const quint16 mid)
+{
+    Frame frame(type);
+    frame.writeInt(mid);
+    sendFrame(frame);
+}
+
+quint16 QMQTT::ClientPrivate::sendSubscribe(const QString & topic, const quint8 qos)
+{
+    quint16 mid = nextmid();
+    Frame frame(SETQOS(SUBSCRIBE, QOS1));
+    frame.writeInt(mid);
+    frame.writeString(topic);
+    frame.writeChar(qos);
+    sendFrame(frame);
+    return mid;
+}
+
+quint16 QMQTT::ClientPrivate::sendUnsubscribe(const QString &topic)
+{
+    quint16 mid = nextmid();
+    Frame frame(SETQOS(UNSUBSCRIBE, QOS1));
+    frame.writeInt(mid);
+    frame.writeString(topic);
+    sendFrame(frame);
+    return mid;
+}
+
+void QMQTT::ClientPrivate::onTimerPingReq()
+{
+    if (!isConnectedToHost())
+        return;
+    Frame frame(PINGREQ);
+    sendFrame(frame);
+    _pingResponseTimer.start();
+}
+
+void QMQTT::ClientPrivate::onPingTimeout()
+{
+    Q_Q(Client);
+    emit q->error(MqttNoPingResponse);
+    disconnectFromHost();
+}
+
+void QMQTT::ClientPrivate::disconnectFromHost()
+{
+    _connectionState = ConnectionState::STATE_DISCONNECTED;
+    sendDisconnect();
+    _network->disconnectFromHost();
+}
+
+void QMQTT::ClientPrivate::sendDisconnect()
+{
+    Frame frame(DISCONNECT);
+    sendFrame(frame);
+}
+
+void QMQTT::ClientPrivate::sendFrame(const Frame &frame)
+{
+    _network->sendFrame(frame);
+    _timer.start();
+}
+
+void QMQTT::ClientPrivate::stopKeepAlive()
+{
+    _timer.stop();
+    _pingResponseTimer.stop();
+}
+
+quint16 QMQTT::ClientPrivate::nextmid()
+{
+    return _gmid++;
+}
+
+quint16 QMQTT::ClientPrivate::publish(const Message& message)
+{
+    Q_Q(Client);
+    quint16 msgid = sendPublish(message);
+
+    // Emit published only at QOS0
+    if (message.qos() == QOS0)
+        emit q->published(message, msgid);
+    else
+        _midToMessage[msgid] = message;
+
+    return msgid;
+}
+
+void QMQTT::ClientPrivate::puback(const quint8 type, const quint16 msgid)
+{
+    sendPuback(type, msgid);
+}
+
+void QMQTT::ClientPrivate::subscribe(const QString& topic, const quint8 qos)
+{
+    quint16 msgid = sendSubscribe(topic, qos);
+    _midToTopic[msgid] = topic;
+}
+
+void QMQTT::ClientPrivate::unsubscribe(const QString& topic)
+{
+    quint16 msgid = sendUnsubscribe(topic);
+    _midToTopic[msgid] = topic;
+}
+
+void QMQTT::ClientPrivate::onNetworkDisconnected()
+{
+    Q_Q(Client);
+
+    stopKeepAlive();
+    _midToTopic.clear();
+    _midToMessage.clear();
+    emit q->disconnected();
+}
+
+void QMQTT::ClientPrivate::onNetworkReceived(const QMQTT::Frame& frm)
+{
+    QMQTT::Frame frame(frm);
+    quint8 qos = 0;
+    bool retain, dup;
+    QString topic;
+    quint16 mid = 0;
+    quint8 header = frame.header();
+    quint8 type = GETTYPE(header);
+
+    switch(type)
+    {
+    case CONNACK:
+        frame.readChar();
+        handleConnack(frame.readChar());
+        break;
+    case PUBLISH:
+        qos = GETQOS(header);
+        retain = GETRETAIN(header);
+        dup = GETDUP(header);
+        topic = frame.readString();
+        if( qos > QOS0) {
+            mid = frame.readInt();
+        }
+        handlePublish(Message(mid, topic, frame.data(), qos, retain, dup));
+        break;
+    case PUBACK:
+    case PUBREC:
+    case PUBREL:
+    case PUBCOMP:
+        mid = frame.readInt();
+        handlePuback(type, mid);
+        break;
+    case SUBACK:
+        mid = frame.readInt();
+        topic = _midToTopic.take(mid);
+        qos = frame.readChar();
+        handleSuback(topic, qos);
+        break;
+    case UNSUBACK:
+        mid = frame.readInt();
+        topic = _midToTopic.take(mid);
+        handleUnsuback(topic);
+        break;
+    case PINGRESP:
+        handlePingresp();
+        break;
+    default:
+        break;
+    }
+}
+
+void QMQTT::ClientPrivate::handleConnack(const quint8 ack)
+{
+    Q_Q(Client);
+
+    switch (ack)
+    {
+    case 0:
+        _connectionState = ConnectionState::STATE_CONNECTED;
+        emit q->connected();
+        break;
+    case 1:
+        emit q->error(MqttUnacceptableProtocolVersionError);
+        break;
+    case 2:
+        emit q->error(MqttIdentifierRejectedError);
+        break;
+    case 3:
+        emit q->error(MqttServerUnavailableError);
+        break;
+    case 4:
+        emit q->error(MqttBadUserNameOrPasswordError);
+        break;
+    case 5:
+        emit q->error(MqttNotAuthorizedError);
+        break;
+    default:
+        emit q->error(UnknownError);
+        break;
+    }
+}
+
+void QMQTT::ClientPrivate::handlePublish(const Message& message)
+{
+    Q_Q(Client);
+
+    if(message.qos() == QOS1)
+    {
+        sendPuback(PUBACK, message.id());
+    }
+    else if(message.qos() == QOS2)
+    {
+        sendPuback(PUBREC, message.id());
+    }
+    emit q->received(message);
+}
+
+void QMQTT::ClientPrivate::handlePuback(const quint8 type, const quint16 msgid)
+{
+    Q_Q(Client);
+
+    switch (type)
+    {
+    case PUBREC:
+        sendPuback(SETQOS(PUBREL, QOS1), msgid);
+        break;
+    case PUBREL:
+        sendPuback(PUBCOMP, msgid);
+        break;
+    case PUBACK:
+    case PUBCOMP:
+        // Emit published on PUBACK at QOS1 and on PUBCOMP at QOS2
+        emit q->published(_midToMessage.take(msgid), msgid);
+        break;
+    }
+}
+
+void QMQTT::ClientPrivate::handlePingresp()
+{
+    // Stop the ping response timer to prevent disconnection. It will be restarted when the next
+    // ping request has been sent.
+    _pingResponseTimer.stop();
+    Q_Q(Client);
+    emit q->pingresp();
+}
+
+void QMQTT::ClientPrivate::handleSuback(const QString &topic, const quint8 qos)
+{
+    Q_Q(Client);
+    emit q->subscribed(topic, qos);
+}
+
+void QMQTT::ClientPrivate::handleUnsuback(const QString &topic) {
+    Q_Q(Client);
+    emit q->unsubscribed(topic);
+}
+
+bool QMQTT::ClientPrivate::autoReconnect() const
+{
+    return _network->autoReconnect();
+}
+
+void QMQTT::ClientPrivate::setAutoReconnect(const bool autoReconnect)
+{
+    _network->setAutoReconnect(autoReconnect);
+}
+
+int QMQTT::ClientPrivate::autoReconnectInterval() const
+{
+    return _network->autoReconnectInterval();
+}
+
+void QMQTT::ClientPrivate::setAutoReconnectInterval(const int autoReconnectInterval)
+{
+    _network->setAutoReconnectInterval(autoReconnectInterval);
+}
+
+bool QMQTT::ClientPrivate::isConnectedToHost() const
+{
+    return _network->isConnectedToHost();
+}
+
+QMQTT::ConnectionState QMQTT::ClientPrivate::connectionState() const
+{
+    return _connectionState;
+}
+
+void QMQTT::ClientPrivate::setCleanSession(const bool cleanSession)
+{
+    _cleanSession = cleanSession;
+}
+
+bool QMQTT::ClientPrivate::cleanSession() const
+{
+    return _cleanSession;
+}
+
+void QMQTT::ClientPrivate::setKeepAlive(const quint16 keepAlive)
+{
+    // _timer will be started when a message is sent.
+    _timer.setInterval(keepAlive*1000);
+    // The MQTT specification does not mention a timeout value in this case, so we use 10% of the
+    // keep alive interval.
+    _pingResponseTimer.setInterval(qBound(keepAlive * 100, 10000, keepAlive * 1000));
+}
+
+quint16 QMQTT::ClientPrivate::keepAlive() const
+{
+    return _timer.interval() / 1000;
+}
+
+void QMQTT::ClientPrivate::setPassword(const QByteArray& password)
+{
+    _password = password;
+}
+
+QByteArray QMQTT::ClientPrivate::password() const
+{
+    return _password;
+}
+
+void QMQTT::ClientPrivate::setUsername(const QString& username)
+{
+    _username = username;
+}
+
+QString QMQTT::ClientPrivate::username() const
+{
+    return _username;
+}
+
+void QMQTT::ClientPrivate::setVersion(const MQTTVersion version)
+{
+    _version = version;
+}
+
+QMQTT::MQTTVersion QMQTT::ClientPrivate::version() const
+{
+    return _version;
+}
+
+void QMQTT::ClientPrivate::setClientId(const QString& clientId)
+{
+    if(clientId.isEmpty())
+    {
+        _clientId = QUuid::createUuid().toString();
+    }
+    else
+    {
+        _clientId = clientId;
+    }
+}
+
+QString QMQTT::ClientPrivate::clientId() const
+{
+    return _clientId;
+}
+
+void QMQTT::ClientPrivate::setPort(const quint16 port)
+{
+    _port = port;
+}
+
+quint16 QMQTT::ClientPrivate::port() const
+{
+    return _port;
+}
+
+void QMQTT::ClientPrivate::setHost(const QHostAddress& host)
+{
+    _host = host;
+}
+
+QHostAddress QMQTT::ClientPrivate::host() const
+{
+    return _host;
+}
+
+void QMQTT::ClientPrivate::setHostName(const QString& hostName)
+{
+    _hostName = hostName;
+}
+
+QString QMQTT::ClientPrivate::hostName() const
+{
+    return _hostName;
+}
+
+QString QMQTT::ClientPrivate::willTopic() const
+{
+    return _willTopic;
+}
+
+void QMQTT::ClientPrivate::setWillTopic(const QString& willTopic)
+{
+    _willTopic = willTopic;
+}
+
+quint8 QMQTT::ClientPrivate::willQos() const
+{
+    return _willQos;
+}
+
+void QMQTT::ClientPrivate::setWillQos(const quint8 willQos)
+{
+    _willQos = willQos;
+}
+
+bool QMQTT::ClientPrivate::willRetain() const
+{
+    return _willRetain;
+}
+
+void QMQTT::ClientPrivate::setWillRetain(const bool willRetain)
+{
+    _willRetain = willRetain;
+}
+
+QByteArray QMQTT::ClientPrivate::willMessage() const
+{
+    return _willMessage;
+}
+
+void QMQTT::ClientPrivate::setWillMessage(const QByteArray& willMessage)
+{
+    _willMessage = willMessage;
+}
+
+void QMQTT::ClientPrivate::onNetworkError(QAbstractSocket::SocketError socketError)
+{
+    Q_Q(Client);
+
+    switch (socketError)
+    {
+    case QAbstractSocket::ConnectionRefusedError:
+        emit q->error(SocketConnectionRefusedError);
+        break;
+    case QAbstractSocket::RemoteHostClosedError:
+        emit q->error(SocketRemoteHostClosedError);
+        break;
+    case QAbstractSocket::HostNotFoundError:
+        emit q->error(SocketHostNotFoundError);
+        break;
+    case QAbstractSocket::SocketAccessError:
+        emit q->error(SocketAccessError);
+        break;
+    case QAbstractSocket::SocketResourceError:
+        emit q->error(SocketResourceError);
+        break;
+    case QAbstractSocket::SocketTimeoutError:
+        emit q->error(SocketTimeoutError);
+        break;
+    case QAbstractSocket::DatagramTooLargeError:
+        emit q->error(SocketDatagramTooLargeError);
+        break;
+    case QAbstractSocket::NetworkError:
+        emit q->error(SocketNetworkError);
+        break;
+    case QAbstractSocket::AddressInUseError:
+        emit q->error(SocketAddressInUseError);
+        break;
+    case QAbstractSocket::SocketAddressNotAvailableError:
+        emit q->error(SocketAddressNotAvailableError);
+        break;
+    case QAbstractSocket::UnsupportedSocketOperationError:
+        emit q->error(SocketUnsupportedSocketOperationError);
+        break;
+    case QAbstractSocket::UnfinishedSocketOperationError:
+        emit q->error(SocketUnfinishedSocketOperationError);
+        break;
+    case QAbstractSocket::ProxyAuthenticationRequiredError:
+        emit q->error(SocketProxyAuthenticationRequiredError);
+        break;
+    case QAbstractSocket::SslHandshakeFailedError:
+        emit q->error(SocketSslHandshakeFailedError);
+        break;
+    case QAbstractSocket::ProxyConnectionRefusedError:
+        emit q->error(SocketProxyConnectionRefusedError);
+        break;
+    case QAbstractSocket::ProxyConnectionClosedError:
+        emit q->error(SocketProxyConnectionClosedError);
+        break;
+    case QAbstractSocket::ProxyConnectionTimeoutError:
+        emit q->error(SocketProxyConnectionTimeoutError);
+        break;
+    case QAbstractSocket::ProxyNotFoundError:
+        emit q->error(SocketProxyNotFoundError);
+        break;
+    case QAbstractSocket::ProxyProtocolError:
+        emit q->error(SocketProxyProtocolError);
+        break;
+    case QAbstractSocket::OperationError:
+        emit q->error(SocketOperationError);
+        break;
+    case QAbstractSocket::SslInternalError:
+        emit q->error(SocketSslInternalError);
+        break;
+    case QAbstractSocket::SslInvalidUserDataError:
+        emit q->error(SocketSslInvalidUserDataError);
+        break;
+    case QAbstractSocket::TemporaryError:
+        emit q->error(SocketTemporaryError);
+        break;
+    default:
+        emit q->error(UnknownError);
+        break;
+    }
+}
+
+#ifndef QT_NO_SSL
+void QMQTT::ClientPrivate::ignoreSslErrors()
+{
+    _network->ignoreSslErrors();
+}
+
+void QMQTT::ClientPrivate::ignoreSslErrors(const QList<QSslError>& errors)
+{
+    _network->ignoreSslErrors(errors);
+}
+
+QSslConfiguration QMQTT::ClientPrivate::sslConfiguration() const
+{
+    return _network->sslConfiguration();
+}
+
+void QMQTT::ClientPrivate::setSslConfiguration(const QSslConfiguration& config)
+{
+    _network->setSslConfiguration(config);
+}
+
+void QMQTT::ClientPrivate::onSslErrors(const QList<QSslError>& errors)
+{
+    Q_Q(Client);
+
+    emit q->sslErrors(errors);
+
+    if (!_ignoreSelfSigned)
+        return;
+    foreach (QSslError error, errors)
+    {
+        if (error.error() != QSslError::SelfSignedCertificate &&
+            error.error() != QSslError::SelfSignedCertificateInChain)
+        {
+            return;
+        }
+    }
+    ignoreSslErrors();
+}
+#endif // QT_NO_SSL

+ 183 - 0
qmqtt-master/src/mqtt/qmqtt_client_p.h

@@ -0,0 +1,183 @@
+/*
+ * qmqtt_client_p.h - qmqtt client private 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_P_H
+#define QMQTT_CLIENT_P_H
+
+#include <qmqtt_client.h>
+
+#include <QHostAddress>
+#include <QString>
+#include <QByteArray>
+#include <QHash>
+#include <QTimer>
+#include <QAbstractSocket>
+
+#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
+
+namespace QMQTT {
+
+class NetworkInterface;
+
+class ClientPrivate
+{
+public:
+    ClientPrivate(Client* qq_ptr);
+    ~ClientPrivate();
+
+    void init(const QHostAddress& host, const quint16 port, NetworkInterface* network = NULL);
+#ifndef QT_NO_SSL
+    void init(const QString& hostName, const quint16 port, const QSslConfiguration& config,
+              const bool ignoreSelfSigned=false);
+#endif // QT_NO_SSL
+    void init(const QString& hostName, const quint16 port, const bool ssl, const bool ignoreSelfSigned);
+#ifdef QT_WEBSOCKETS_LIB
+#ifndef QT_NO_SSL
+    void init(const QString& url,
+              const QString& origin,
+              QWebSocketProtocol::Version version,
+              const QSslConfiguration* sslConfig,
+              bool ignoreSelfSigned);
+#endif // QT_NO_SSL
+    void init(const QString& url,
+              const QString& origin,
+              QWebSocketProtocol::Version version);
+#endif // QT_WEBSOCKETS_LIB
+    void init(NetworkInterface* network);
+
+    QHostAddress _host;
+    QString _hostName;
+    quint16 _port;
+#ifdef QT_WEBSOCKETS_LIB
+    QWebSocketProtocol::Version _webSocketVersion;
+#endif // QT_WEBSOCKETS_LIB
+#ifndef QT_NO_SSL
+    bool _ignoreSelfSigned;
+#endif // QT_NO_SSL
+    quint16 _gmid;
+    MQTTVersion _version;
+    QString _clientId;
+    QString _username;
+    QByteArray _password;
+    bool _cleanSession;
+    ConnectionState _connectionState;
+    QScopedPointer<NetworkInterface> _network;
+    QTimer _timer;
+    QTimer _pingResponseTimer;
+    QString _willTopic;
+    quint8 _willQos;
+    bool _willRetain;
+    QByteArray _willMessage;
+    QHash<quint16, QString> _midToTopic;
+    QHash<quint16, Message> _midToMessage;
+
+    Client* const q_ptr;
+
+    quint16 nextmid();
+    void connectToHost();
+    void sendConnect();
+    void onTimerPingReq();
+    void onPingTimeout();
+    quint16 sendUnsubscribe(const QString &topic);
+    quint16 sendSubscribe(const QString &topic, const quint8 qos);
+    quint16 sendPublish(const Message &message);
+    void sendPuback(const quint8 type, const quint16 mid);
+    void sendDisconnect();
+    void sendFrame(const Frame &frame);
+    void disconnectFromHost();
+    void stopKeepAlive();
+    void onNetworkConnected();
+    void onNetworkDisconnected();
+    quint16 publish(const Message& message);
+    void puback(const quint8 type, const quint16 msgid);
+    void subscribe(const QString& topic, const quint8 qos);
+    void unsubscribe(const QString& topic);
+    void onNetworkReceived(const QMQTT::Frame& frame);
+    void handleConnack(const quint8 ack);
+    void handlePublish(const Message& message);
+    void handlePuback(const quint8 type, const quint16 msgid);
+    void handleSuback(const QString& topic, const quint8 qos);
+    void handleUnsuback(const QString& topic);
+    void handlePingresp();
+    bool autoReconnect() const;
+    void setAutoReconnect(const bool autoReconnect);
+    int autoReconnectInterval() const;
+    void setAutoReconnectInterval(const int autoReconnectInterval);
+    bool isConnectedToHost() const;
+    QMQTT::ConnectionState connectionState() const;
+    void setCleanSession(const bool cleanSession);
+    bool cleanSession() const;
+    void setKeepAlive(const quint16 keepAlive);
+    quint16 keepAlive() const;
+    void setPassword(const QByteArray& password);
+    QByteArray password() const;
+    void setUsername(const QString& username);
+    QString username() const;
+    void setVersion(const MQTTVersion);
+    MQTTVersion version() const;
+    void setClientId(const QString& clientId);
+    QString clientId() const;
+    void setPort(const quint16 port);
+    quint16 port() const;
+    void setHost(const QHostAddress& host);
+    QHostAddress host() const;
+    void setHostName(const QString& hostName);
+    QString hostName() const;
+    void setWillTopic(const QString& willTopic);
+    void setWillQos(const quint8 willQos);
+    void setWillRetain(const bool willRetain);
+    void setWillMessage(const QByteArray& willMessage);
+    QString willTopic() const;
+    quint8 willQos() const;
+    bool willRetain() const;
+    QByteArray willMessage() const;
+    void onNetworkError(QAbstractSocket::SocketError error);
+#ifndef QT_NO_SSL
+    void ignoreSslErrors();
+    void ignoreSslErrors(const QList<QSslError>& errors);
+    QSslConfiguration sslConfiguration() const;
+    void setSslConfiguration(const QSslConfiguration& config);
+    void onSslErrors(const QList<QSslError>& errors);
+#endif // QT_NO_SSL
+
+    Q_DECLARE_PUBLIC(Client)
+};
+
+} // namespace QMQTT
+
+#endif // QMQTT_CLIENT_P_H

+ 209 - 0
qmqtt-master/src/mqtt/qmqtt_frame.cpp

@@ -0,0 +1,209 @@
+/*
+ * qmqtt_frame.cpp - qmqtt frame
+ *
+ * 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.
+ *
+ */
+
+#include "qmqtt_frame.h"
+
+#include <QLoggingCategory>
+#include <QDataStream>
+
+namespace QMQTT {
+
+Q_LOGGING_CATEGORY(frame, "qmqtt.frame")
+
+Frame::Frame()
+    : _header(0)
+    , _data(QByteArray())
+{
+}
+
+Frame::Frame(const quint8 header)
+    : _header(header)
+    , _data(QByteArray())
+{
+}
+
+Frame::Frame(const quint8 header, const QByteArray &data)
+    : _header(header)
+    , _data(data)
+{
+}
+
+Frame::Frame(const Frame& other)
+{
+    _header = other._header;
+    _data = other._data;
+}
+
+Frame& Frame::operator=(const Frame& other)
+{
+    _header = other._header;
+    _data = other._data;
+    return *this;
+}
+
+bool Frame::operator==(const Frame& other) const
+{
+  return _header == other._header
+      && _data == other._data;
+}
+
+
+Frame::~Frame()
+{
+}
+
+quint8 Frame::header() const
+{
+    return _header;
+}
+
+QByteArray Frame::data() const
+{
+    return _data;
+}
+
+quint8 Frame::readChar()
+{
+    char c = _data.at(0);
+    _data.remove(0, 1);
+    return c;
+}
+
+quint16 Frame::readInt()
+{
+    quint8 msb = static_cast<quint8>(_data.at(0));
+    quint8 lsb = static_cast<quint8>(_data.at(1));
+    _data.remove(0, 2);
+    return (msb << 8) | lsb;
+}
+
+QByteArray Frame::readByteArray()
+{
+    quint16 len = readInt();
+    QByteArray data = _data.left(len);
+    _data.remove(0, len);
+    return data;
+}
+
+QString Frame::readString()
+{
+    quint16 len = readInt();
+    QString s = QString::fromUtf8(_data.left(len));
+    _data.remove(0, len);
+    return s;
+}
+
+void Frame::writeInt(const quint16 i)
+{
+    _data.append(MSB(i));
+    _data.append(LSB(i));
+}
+
+void Frame::writeByteArray(const QByteArray &data)
+{
+    if (data.size() > (int)USHRT_MAX)
+    {
+        qCritical("qmqtt: Binary data size bigger than %u bytes, truncate it!", USHRT_MAX);
+        writeInt(USHRT_MAX);
+        _data.append(data.left(USHRT_MAX));
+        return;
+    }
+
+    writeInt(data.size());
+    _data.append(data);
+}
+
+void Frame::writeString(const QString &string)
+{
+    QByteArray data = string.toUtf8();
+    if (data.size() > (int)USHRT_MAX)
+    {
+        qCritical("qmqtt: String size bigger than %u bytes, truncate it!", USHRT_MAX);
+        data.resize(USHRT_MAX);
+    }
+    writeInt(data.size());
+    _data.append(data);
+}
+
+void Frame::writeChar(const quint8 c)
+{
+    _data.append(c);
+}
+
+void Frame::writeRawData(const QByteArray &data)
+{
+    _data.append(data);
+}
+
+void Frame::write(QDataStream &stream) const
+{
+    QByteArray lenbuf;
+
+    if (!encodeLength(lenbuf, _data.size()))
+    {
+        qCritical("qmqtt: Control packet bigger than 256 MB, dropped!");
+        return;
+    }
+
+    stream << (quint8)_header;
+    if(_data.size() == 0) {
+        stream << (quint8)0;
+        return;
+    }
+    if (stream.writeRawData(lenbuf.data(), lenbuf.size()) != lenbuf.size())
+    {
+        qCritical("qmqtt: Control packet write error!");
+        return;
+    }
+    if (stream.writeRawData(_data.data(), _data.size()) != _data.size())
+    {
+        qCritical("qmqtt: Control packet write error!");
+    }
+}
+
+bool Frame::encodeLength(QByteArray &lenbuf, int length) const
+{
+    lenbuf.clear();
+    quint8 d;
+    do {
+        d = length % 128;
+        length /= 128;
+        if (length > 0) {
+            d |= 0x80;
+        }
+        lenbuf.append(d);
+    } while (length > 0);
+
+    return lenbuf.size() <= 4;
+}
+
+} // namespace QMQTT

+ 137 - 0
qmqtt-master/src/mqtt/qmqtt_frame.h

@@ -0,0 +1,137 @@
+/*
+ * qmqtt_frame.h - qmqtt frame 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_FRAME_H
+#define QMQTT_FRAME_H
+
+#include <qmqtt_global.h>
+
+#include <QMetaType>
+#include <QByteArray>
+#include <QString>
+
+QT_FORWARD_DECLARE_CLASS(QDataStream)
+
+#define PROTOCOL_MAGIC_3_1_0 "MQIsdp"
+#define PROTOCOL_MAGIC_3_1_1 "MQTT"
+
+#define RANDOM_CLIENT_PREFIX "QMQTT-"
+
+#define CONNECT 0x10
+#define CONNACK 0x20
+#define PUBLISH 0x30
+#define PUBACK 0x40
+#define PUBREC 0x50
+#define PUBREL 0x60
+#define PUBCOMP 0x70
+#define SUBSCRIBE 0x80
+#define SUBACK 0x90
+#define UNSUBSCRIBE 0xA0
+#define UNSUBACK 0xB0
+#define PINGREQ 0xC0
+#define PINGRESP 0xD0
+#define DISCONNECT 0xE0
+
+#define LSB(A) quint8(A & 0x00FF)
+#define MSB(A) quint8((A & 0xFF00) >> 8)
+
+/*
+|--------------------------------------
+| 7 6 5 4 |     3    |  2 1  | 0      |
+|  Type   | DUP flag |  QoS  | RETAIN |
+|--------------------------------------
+*/
+#define GETTYPE(HDR)		(HDR & 0xF0)
+#define SETQOS(HDR, Q)		(HDR | ((Q) << 1))
+#define GETQOS(HDR)			((HDR & 0x06) >> 1)
+#define SETDUP(HDR, D)		(HDR | ((D) << 3))
+#define GETDUP(HDR)			((HDR & 0x08) >> 3)
+#define SETRETAIN(HDR, R)	(HDR | (R))
+#define GETRETAIN(HDR)		(HDR & 0x01)
+
+/*
+|----------------------------------------------------------------------------------
+|     7    |    6     |      5     |  4   3  |     2    |       1      |     0    |
+| username | password | willretain | willqos | willflag | cleansession | reserved |
+|----------------------------------------------------------------------------------
+*/
+#define FLAG_CLEANSESS(F, C)	(F | ((C) << 1))
+#define FLAG_WILL(F, W)			(F | ((W) << 2))
+#define FLAG_WILLQOS(F, Q)		(F | ((Q) << 3))
+#define FLAG_WILLRETAIN(F, R) 	(F | ((R) << 5))
+#define FLAG_PASSWD(F, P)		(F | ((P) << 6))
+#define FLAG_USERNAME(F, U)		(F | ((U) << 7))
+
+namespace QMQTT {
+
+class Q_MQTT_EXPORT Frame
+{
+public:
+    explicit Frame();
+    explicit Frame(const quint8 header);
+    explicit Frame(const quint8 header, const QByteArray &data);
+    virtual ~Frame();
+
+    Frame(const Frame& other);
+    Frame& operator=(const Frame& other);
+
+    bool operator==(const Frame& other) const;
+    inline bool operator!=(const Frame& other) const
+    { return !operator==(other); }
+
+    quint8 header() const;
+    QByteArray data() const;
+
+    quint16 readInt();
+    quint8 readChar();
+    QByteArray readByteArray();
+    QString readString();
+
+    void writeInt(const quint16 i);
+    void writeChar(const quint8 c);
+    void writeByteArray(const QByteArray &data);
+    void writeString(const QString &string);
+    void writeRawData(const QByteArray &data);
+
+    //TODO: FIXME LATER
+    void write(QDataStream &stream) const;
+    bool encodeLength(QByteArray &lenbuf, int length) const;
+
+private:
+    quint8 _header;
+    QByteArray _data;
+};
+
+} // namespace QMQTT
+
+Q_DECLARE_METATYPE(QMQTT::Frame)
+
+#endif // QMQTT_FRAME_H

+ 48 - 0
qmqtt-master/src/mqtt/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
+

+ 136 - 0
qmqtt-master/src/mqtt/qmqtt_message.cpp

@@ -0,0 +1,136 @@
+/*
+ * qmqtt_message.cpp - qmqtt message
+ *
+ * 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.
+ *
+ */
+
+#include "qmqtt_message.h"
+#include "qmqtt_message_p.h"
+
+namespace QMQTT {
+
+Message::Message()
+    : d(new MessagePrivate)
+{
+}
+
+Message::Message(const quint16 id, const QString &topic, const QByteArray &payload,
+                 const quint8 qos, const bool retain, const bool dup)
+    : d(new MessagePrivate(id, topic, payload, qos, retain, dup))
+{
+}
+
+Message::Message(const Message &other)
+    : d(other.d)
+{
+}
+
+Message::~Message()
+{
+}
+
+Message &Message::operator=(const Message &other)
+{
+    d = other.d;
+    return *this;
+}
+
+bool Message::operator==(const Message &other) const
+{
+    if (d == other.d)
+        return true;
+    return d->id == other.d->id
+            && d->qos == other.d->qos
+            && d->retain == other.d->retain
+            && d->dup == other.d->dup
+            && d->topic == other.d->topic
+            && d->payload == other.d->payload;
+}
+
+quint16 Message::id() const
+{
+    return d->id;
+}
+
+void Message::setId(const quint16 id)
+{
+    d->id = id;
+}
+
+quint8 Message::qos() const
+{
+    return d->qos;
+}
+
+void Message::setQos(const quint8 qos)
+{
+    d->qos = qos;
+}
+
+bool Message::retain() const
+{
+    return d->retain;
+}
+
+void Message::setRetain(const bool retain)
+{
+    d->retain = retain;
+}
+
+bool Message::dup() const
+{
+    return d->dup;
+}
+
+void Message::setDup(const bool dup)
+{
+    d->dup = dup;
+}
+
+QString Message::topic() const
+{
+    return d->topic;
+}
+
+void Message::setTopic(const QString &topic)
+{
+    d->topic = topic;
+}
+
+QByteArray Message::payload() const
+{
+    return d->payload;
+}
+
+void Message::setPayload(const QByteArray &payload)
+{
+    d->payload = payload;
+}
+
+} // namespace QMQTT

+ 96 - 0
qmqtt-master/src/mqtt/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

+ 83 - 0
qmqtt-master/src/mqtt/qmqtt_message_p.h

@@ -0,0 +1,83 @@
+/*
+ * qmqtt_message.h - qmqtt message private 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_P_H
+#define QMQTT_MESSAGE_P_H
+
+#include <QSharedData>
+#include <QString>
+#include <QByteArray>
+
+namespace QMQTT {
+
+class MessagePrivate : public QSharedData
+{
+public:
+    inline MessagePrivate()
+        : QSharedData(),
+          id(0),
+          qos(0),
+          retain(false),
+          dup(false)
+    {}
+
+    inline MessagePrivate(const MessagePrivate &other)
+        : QSharedData(other),
+          id(other.id),
+          qos(other.qos),
+          retain(other.retain),
+          dup(other.dup),
+          topic(other.topic),
+          payload(other.payload)
+    {}
+
+    inline MessagePrivate(quint16 id, const QString &topic, const QByteArray &payload,
+                          quint8 qos, bool retain, bool dup)
+        : QSharedData(),
+          id(id),
+          qos(qos),
+          retain(retain),
+          dup(dup),
+          topic(topic),
+          payload(payload)
+    {}
+
+    quint16 id;
+    quint8 qos : 2;
+    quint8 retain: 1;
+    quint8 dup: 1;
+    QString topic;
+    QByteArray payload;
+};
+
+} // namespace QMQTT
+
+#endif // QMQTT_MESSAGE_P_H

+ 295 - 0
qmqtt-master/src/mqtt/qmqtt_network.cpp

@@ -0,0 +1,295 @@
+/*
+ * qmqtt_network.cpp - qmqtt network
+ *
+ * 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.
+ *
+ */
+
+#include "qmqtt_network_p.h"
+#include "qmqtt_socket_p.h"
+#include "qmqtt_ssl_socket_p.h"
+#include "qmqtt_timer_p.h"
+#include "qmqtt_websocket_p.h"
+#include "qmqtt_frame.h"
+
+#include <QDataStream>
+
+const quint16 DEFAULT_PORT = 1883;
+const quint16 DEFAULT_SSL_PORT = 8883;
+const bool DEFAULT_AUTORECONNECT = false;
+const int DEFAULT_AUTORECONNECT_INTERVAL_MS = 5000;
+
+QMQTT::Network::Network(QObject* parent)
+    : NetworkInterface(parent)
+    , _port(DEFAULT_PORT)
+    , _autoReconnect(DEFAULT_AUTORECONNECT)
+    , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
+    , _socket(new QMQTT::Socket)
+    , _autoReconnectTimer(new QMQTT::Timer)
+    , _readState(Header)
+{
+    initialize();
+}
+
+#ifndef QT_NO_SSL
+QMQTT::Network::Network(const QSslConfiguration& config, QObject *parent)
+    : NetworkInterface(parent)
+    , _port(DEFAULT_SSL_PORT)
+    , _autoReconnect(DEFAULT_AUTORECONNECT)
+    , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
+    , _socket(new QMQTT::SslSocket(config))
+    , _autoReconnectTimer(new QMQTT::Timer)
+    , _readState(Header)
+{
+    initialize();
+    connect(_socket, &QMQTT::SslSocket::sslErrors, this, &QMQTT::Network::sslErrors);
+}
+#endif // QT_NO_SSL
+
+#ifdef QT_WEBSOCKETS_LIB
+#ifndef QT_NO_SSL
+QMQTT::Network::Network(const QString& origin,
+                        QWebSocketProtocol::Version version,
+                        const QSslConfiguration* sslConfig,
+                        QObject* parent)
+    : NetworkInterface(parent)
+    , _port(DEFAULT_SSL_PORT)
+    , _autoReconnect(DEFAULT_AUTORECONNECT)
+    , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
+    , _socket(new QMQTT::WebSocket(origin, version, sslConfig))
+    , _autoReconnectTimer(new QMQTT::Timer)
+    , _readState(Header)
+{
+    initialize();
+}
+#endif // QT_NO_SSL
+
+QMQTT::Network::Network(const QString& origin,
+                        QWebSocketProtocol::Version version,
+                        QObject* parent)
+    : NetworkInterface(parent)
+    , _port(DEFAULT_PORT)
+    , _autoReconnect(DEFAULT_AUTORECONNECT)
+    , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
+    , _socket(new QMQTT::WebSocket(origin, version))
+    , _autoReconnectTimer(new QMQTT::Timer)
+    , _readState(Header)
+{
+    initialize();
+}
+#endif // QT_WEBSOCKETS_LIB
+
+QMQTT::Network::Network(SocketInterface* socketInterface, TimerInterface* timerInterface,
+                        QObject* parent)
+    : NetworkInterface(parent)
+    , _port(DEFAULT_PORT)
+    , _autoReconnect(DEFAULT_AUTORECONNECT)
+    , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
+    , _socket(socketInterface)
+    , _autoReconnectTimer(timerInterface)
+    , _readState(Header)
+{
+    initialize();
+}
+
+void QMQTT::Network::initialize()
+{
+    _socket->setParent(this);
+    _autoReconnectTimer->setParent(this);
+    _autoReconnectTimer->setSingleShot(true);
+    _autoReconnectTimer->setInterval(_autoReconnectInterval);
+
+    QObject::connect(_socket, &SocketInterface::connected, this, &Network::connected);
+    QObject::connect(_socket, &SocketInterface::disconnected, this, &Network::onDisconnected);
+    QObject::connect(_socket->ioDevice(), &QIODevice::readyRead, this, &Network::onSocketReadReady);
+    QObject::connect(
+        _autoReconnectTimer, &TimerInterface::timeout,
+        this, static_cast<void (Network::*)()>(&Network::connectToHost));    
+    QObject::connect(_socket,
+        static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error),
+        this, &Network::onSocketError);
+}
+
+QMQTT::Network::~Network()
+{
+}
+
+bool QMQTT::Network::isConnectedToHost() const
+{
+    return _socket->state() == QAbstractSocket::ConnectedState;
+}
+
+void QMQTT::Network::connectToHost(const QHostAddress& host, const quint16 port)
+{
+    // Reset the hostname, because if it is not empty connectToHost() will use it instead of _host.
+    _hostName.clear();
+    _host = host;
+    _port = port;
+    connectToHost();
+}
+
+void QMQTT::Network::connectToHost(const QString& hostName, const quint16 port)
+{
+    _hostName = hostName;
+    _port = port;
+    connectToHost();
+}
+
+void QMQTT::Network::connectToHost()
+{
+    _readState = Header;
+    if (_hostName.isEmpty())
+    {
+        _socket->connectToHost(_host, _port);
+    }
+    else
+    {
+        _socket->connectToHost(_hostName, _port);
+    }
+}
+
+void QMQTT::Network::onSocketError(QAbstractSocket::SocketError socketError)
+{
+    emit error(socketError);
+    if(_autoReconnect)
+    {
+        _autoReconnectTimer->start();
+    }
+}
+
+void QMQTT::Network::sendFrame(const Frame& frame)
+{
+    if(_socket->state() == QAbstractSocket::ConnectedState)
+    {
+        QDataStream out(_socket->ioDevice());
+        frame.write(out);
+    }
+}
+
+void QMQTT::Network::disconnectFromHost()
+{
+    _socket->disconnectFromHost();
+}
+
+QAbstractSocket::SocketState QMQTT::Network::state() const
+{
+    return _socket->state();
+}
+
+bool QMQTT::Network::autoReconnect() const
+{
+    return _autoReconnect;
+}
+
+void QMQTT::Network::setAutoReconnect(const bool autoReconnect)
+{
+    _autoReconnect = autoReconnect;
+}
+
+int QMQTT::Network::autoReconnectInterval() const
+{
+    return _autoReconnectInterval;
+}
+
+void QMQTT::Network::setAutoReconnectInterval(const int autoReconnectInterval)
+{
+    _autoReconnectInterval = autoReconnectInterval;
+    _autoReconnectTimer->setInterval(_autoReconnectInterval);
+}
+
+void QMQTT::Network::onSocketReadReady()
+{
+    QIODevice *ioDevice = _socket->ioDevice();
+    // Only read the available (cached) bytes, so the read will never block.
+    QByteArray data = ioDevice->read(ioDevice->bytesAvailable());
+    foreach(char byte, data) {
+        switch (_readState) {
+        case Header:
+            _header = static_cast<quint8>(byte);
+            _readState = Length;
+            _length = 0;
+            _shift = 0;
+            _data.resize(0); // keep allocated buffer
+            break;
+        case Length:
+            _length |= (byte & 0x7F) << _shift;
+            _shift += 7;
+            if ((byte & 0x80) != 0)
+                break;
+            if (_length == 0) {
+                _readState = Header;
+                Frame frame(_header, _data);
+                emit received(frame);
+                break;
+            }
+            _readState = PayLoad;
+            _data.reserve(_length);
+            break;
+        case PayLoad:
+            _data.append(byte);
+            --_length;
+            if (_length > 0)
+                break;
+            _readState = Header;
+            Frame frame(_header, _data);
+            emit received(frame);
+            break;
+        }
+    }
+}
+
+void QMQTT::Network::onDisconnected()
+{
+    emit disconnected();
+    if(_autoReconnect)
+    {
+        _autoReconnectTimer->start();
+    }
+}
+
+#ifndef QT_NO_SSL
+void QMQTT::Network::ignoreSslErrors(const QList<QSslError>& errors)
+{
+    _socket->ignoreSslErrors(errors);
+}
+
+void QMQTT::Network::ignoreSslErrors()
+{
+    _socket->ignoreSslErrors();
+}
+
+QSslConfiguration QMQTT::Network::sslConfiguration() const
+{
+    return _socket->sslConfiguration();
+}
+
+void QMQTT::Network::setSslConfiguration(const QSslConfiguration& config)
+{
+    _socket->setSslConfiguration(config);
+}
+#endif // QT_NO_SSL

Some files were not shown because too many files changed in this diff