diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DeviceHub/device/TimeReplicator.cpp b/DeviceHub/device/TimeReplicator.cpp new file mode 100644 index 0000000..1ba0db4 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.cpp @@ -0,0 +1,78 @@ +#include "TimeReplicator.h" + +#include +#include + +TimeReplicator::TimeReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeReplicator::~TimeReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); +} + +void TimeReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void TimeReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DeviceHub/device/TimeReplicator.cpp b/DeviceHub/device/TimeReplicator.cpp new file mode 100644 index 0000000..1ba0db4 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.cpp @@ -0,0 +1,78 @@ +#include "TimeReplicator.h" + +#include +#include + +TimeReplicator::TimeReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeReplicator::~TimeReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); +} + +void TimeReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void TimeReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeReplicator.h b/DeviceHub/device/TimeReplicator.h new file mode 100644 index 0000000..5acf6d9 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.h @@ -0,0 +1,24 @@ +#ifndef TIMEREPLICATOR_H +#define TIMEREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class TimeReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeReplicator(QObject *parent = nullptr); + ~TimeReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // TIMEREPLICATOR_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DeviceHub/device/TimeReplicator.cpp b/DeviceHub/device/TimeReplicator.cpp new file mode 100644 index 0000000..1ba0db4 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.cpp @@ -0,0 +1,78 @@ +#include "TimeReplicator.h" + +#include +#include + +TimeReplicator::TimeReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeReplicator::~TimeReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); +} + +void TimeReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void TimeReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeReplicator.h b/DeviceHub/device/TimeReplicator.h new file mode 100644 index 0000000..5acf6d9 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.h @@ -0,0 +1,24 @@ +#ifndef TIMEREPLICATOR_H +#define TIMEREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class TimeReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeReplicator(QObject *parent = nullptr); + ~TimeReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // TIMEREPLICATOR_H diff --git a/DeviceHub/device/TimeSwitcher.cpp b/DeviceHub/device/TimeSwitcher.cpp new file mode 100644 index 0000000..ecf4d5a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.cpp @@ -0,0 +1,78 @@ +#include "TimeSwitcher.h" + +#include +#include + +TimeSwitcher::TimeSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeSwitcher::~TimeSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); +} + +void TimeSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void TimeSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DeviceHub/device/TimeReplicator.cpp b/DeviceHub/device/TimeReplicator.cpp new file mode 100644 index 0000000..1ba0db4 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.cpp @@ -0,0 +1,78 @@ +#include "TimeReplicator.h" + +#include +#include + +TimeReplicator::TimeReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeReplicator::~TimeReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); +} + +void TimeReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void TimeReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeReplicator.h b/DeviceHub/device/TimeReplicator.h new file mode 100644 index 0000000..5acf6d9 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.h @@ -0,0 +1,24 @@ +#ifndef TIMEREPLICATOR_H +#define TIMEREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class TimeReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeReplicator(QObject *parent = nullptr); + ~TimeReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // TIMEREPLICATOR_H diff --git a/DeviceHub/device/TimeSwitcher.cpp b/DeviceHub/device/TimeSwitcher.cpp new file mode 100644 index 0000000..ecf4d5a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.cpp @@ -0,0 +1,78 @@ +#include "TimeSwitcher.h" + +#include +#include + +TimeSwitcher::TimeSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeSwitcher::~TimeSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); +} + +void TimeSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void TimeSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeSwitcher.h b/DeviceHub/device/TimeSwitcher.h new file mode 100644 index 0000000..0ac7e3a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.h @@ -0,0 +1,26 @@ +#ifndef TIMESWITCHER_H +#define TIMESWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/TimeSwitcherProtocolBM.h" + +class TimeSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeSwitcher(QObject *parent = nullptr); + ~TimeSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // TIMESWITCHER_H diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DeviceHub/device/TimeReplicator.cpp b/DeviceHub/device/TimeReplicator.cpp new file mode 100644 index 0000000..1ba0db4 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.cpp @@ -0,0 +1,78 @@ +#include "TimeReplicator.h" + +#include +#include + +TimeReplicator::TimeReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeReplicator::~TimeReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); +} + +void TimeReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void TimeReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeReplicator.h b/DeviceHub/device/TimeReplicator.h new file mode 100644 index 0000000..5acf6d9 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.h @@ -0,0 +1,24 @@ +#ifndef TIMEREPLICATOR_H +#define TIMEREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class TimeReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeReplicator(QObject *parent = nullptr); + ~TimeReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // TIMEREPLICATOR_H diff --git a/DeviceHub/device/TimeSwitcher.cpp b/DeviceHub/device/TimeSwitcher.cpp new file mode 100644 index 0000000..ecf4d5a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.cpp @@ -0,0 +1,78 @@ +#include "TimeSwitcher.h" + +#include +#include + +TimeSwitcher::TimeSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeSwitcher::~TimeSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); +} + +void TimeSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void TimeSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeSwitcher.h b/DeviceHub/device/TimeSwitcher.h new file mode 100644 index 0000000..0ac7e3a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.h @@ -0,0 +1,26 @@ +#ifndef TIMESWITCHER_H +#define TIMESWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/TimeSwitcherProtocolBM.h" + +class TimeSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeSwitcher(QObject *parent = nullptr); + ~TimeSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // TIMESWITCHER_H diff --git a/DeviceHub/device/device.pri b/DeviceHub/device/device.pri new file mode 100644 index 0000000..c9cc393 --- /dev/null +++ b/DeviceHub/device/device.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/DeviceBase.h +HEADERS += $$PWD/SignalGenerator.h +HEADERS += $$PWD/FrequencyTuning.h +HEADERS += $$PWD/TimeSwitcher.h +HEADERS += $$PWD/FreqSwitcher.h +HEADERS += $$PWD/TimeReplicator.h +HEADERS += $$PWD/FreqReplicator.h +HEADERS += $$PWD/BCodeTerminal.h + +SOURCES += $$PWD/DeviceBase.cpp +SOURCES += $$PWD/SignalGenerator.cpp +SOURCES += $$PWD/FrequencyTuning.cpp +SOURCES += $$PWD/TimeSwitcher.cpp +SOURCES += $$PWD/FreqSwitcher.cpp +SOURCES += $$PWD/TimeReplicator.cpp +SOURCES += $$PWD/FreqReplicator.cpp +SOURCES += $$PWD/BCodeTerminal.cpp diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DeviceHub/device/TimeReplicator.cpp b/DeviceHub/device/TimeReplicator.cpp new file mode 100644 index 0000000..1ba0db4 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.cpp @@ -0,0 +1,78 @@ +#include "TimeReplicator.h" + +#include +#include + +TimeReplicator::TimeReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeReplicator::~TimeReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); +} + +void TimeReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void TimeReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeReplicator.h b/DeviceHub/device/TimeReplicator.h new file mode 100644 index 0000000..5acf6d9 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.h @@ -0,0 +1,24 @@ +#ifndef TIMEREPLICATOR_H +#define TIMEREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class TimeReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeReplicator(QObject *parent = nullptr); + ~TimeReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // TIMEREPLICATOR_H diff --git a/DeviceHub/device/TimeSwitcher.cpp b/DeviceHub/device/TimeSwitcher.cpp new file mode 100644 index 0000000..ecf4d5a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.cpp @@ -0,0 +1,78 @@ +#include "TimeSwitcher.h" + +#include +#include + +TimeSwitcher::TimeSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeSwitcher::~TimeSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); +} + +void TimeSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void TimeSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeSwitcher.h b/DeviceHub/device/TimeSwitcher.h new file mode 100644 index 0000000..0ac7e3a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.h @@ -0,0 +1,26 @@ +#ifndef TIMESWITCHER_H +#define TIMESWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/TimeSwitcherProtocolBM.h" + +class TimeSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeSwitcher(QObject *parent = nullptr); + ~TimeSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // TIMESWITCHER_H diff --git a/DeviceHub/device/device.pri b/DeviceHub/device/device.pri new file mode 100644 index 0000000..c9cc393 --- /dev/null +++ b/DeviceHub/device/device.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/DeviceBase.h +HEADERS += $$PWD/SignalGenerator.h +HEADERS += $$PWD/FrequencyTuning.h +HEADERS += $$PWD/TimeSwitcher.h +HEADERS += $$PWD/FreqSwitcher.h +HEADERS += $$PWD/TimeReplicator.h +HEADERS += $$PWD/FreqReplicator.h +HEADERS += $$PWD/BCodeTerminal.h + +SOURCES += $$PWD/DeviceBase.cpp +SOURCES += $$PWD/SignalGenerator.cpp +SOURCES += $$PWD/FrequencyTuning.cpp +SOURCES += $$PWD/TimeSwitcher.cpp +SOURCES += $$PWD/FreqSwitcher.cpp +SOURCES += $$PWD/TimeReplicator.cpp +SOURCES += $$PWD/FreqReplicator.cpp +SOURCES += $$PWD/BCodeTerminal.cpp diff --git a/DeviceHub/main.cpp b/DeviceHub/main.cpp new file mode 100644 index 0000000..4d3374f --- /dev/null +++ b/DeviceHub/main.cpp @@ -0,0 +1,11 @@ +#include "DeviceHubWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + DeviceHubWindow w; + w.show(); + return a.exec(); +} diff --git a/DevStatusAcq/common/common.pri b/DevStatusAcq/common/common.pri index 18b9b5d..339b7a6 100644 --- a/DevStatusAcq/common/common.pri +++ b/DevStatusAcq/common/common.pri @@ -1,20 +1,20 @@ -SOURCES += $$PWD/utils/SettingConfig.cpp \ - $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/HttpRequestController.cpp -HEADERS += $$PWD/utils/SettingConfig.h \ - $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/SettingConfig.h HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h diff --git a/DeviceHub/.gitignore b/DeviceHub/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/DeviceHub/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/DeviceHub/DeviceHub.pro b/DeviceHub/DeviceHub.pro new file mode 100644 index 0000000..2211193 --- /dev/null +++ b/DeviceHub/DeviceHub.pro @@ -0,0 +1,38 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has 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 it uses 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 +SOURCES += DeviceHubWindow.cpp + +HEADERS += DeviceHubWindow.h + +FORMS += DeviceHubWindow.ui + +DISTFILES += conf/config.ini + +include(common/common.pri) +include(device/device.pri) + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ + +INCLUDEPATH += $$PWD/include/librdkafka +DEPENDPATH += $$PWD/include/librdkafka diff --git a/DeviceHub/DeviceHubWindow.cpp b/DeviceHub/DeviceHubWindow.cpp new file mode 100644 index 0000000..3a7a74a --- /dev/null +++ b/DeviceHub/DeviceHubWindow.cpp @@ -0,0 +1,15 @@ +#include "DeviceHubWindow.h" +#include "ui_DeviceHubWindow.h" + +DeviceHubWindow::DeviceHubWindow(QWidget *parent) + : QWidget(parent) + , ui(new Ui::DeviceHubWindow) +{ + ui->setupUi(this); +} + +DeviceHubWindow::~DeviceHubWindow() +{ + delete ui; +} + diff --git a/DeviceHub/DeviceHubWindow.h b/DeviceHub/DeviceHubWindow.h new file mode 100644 index 0000000..9b914a7 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.h @@ -0,0 +1,21 @@ +#ifndef DEVICEHUBWINDOW_H +#define DEVICEHUBWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class DeviceHubWindow; } +QT_END_NAMESPACE + +class DeviceHubWindow : public QWidget +{ + Q_OBJECT + +public: + DeviceHubWindow(QWidget *parent = nullptr); + ~DeviceHubWindow(); + +private: + Ui::DeviceHubWindow *ui; +}; +#endif // DEVICEHUBWINDOW_H diff --git a/DeviceHub/DeviceHubWindow.ui b/DeviceHub/DeviceHubWindow.ui new file mode 100644 index 0000000..3558013 --- /dev/null +++ b/DeviceHub/DeviceHubWindow.ui @@ -0,0 +1,19 @@ + + + DeviceHubWindow + + + + 0 + 0 + 800 + 600 + + + + DeviceHubWindow + + + + + diff --git a/DeviceHub/common/ConstCache.h b/DeviceHub/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/DeviceHub/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/DeviceHub/common/HttpRequestController.cpp b/DeviceHub/common/HttpRequestController.cpp new file mode 100644 index 0000000..7b905b7 --- /dev/null +++ b/DeviceHub/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceTypes.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDeviceList(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", ""); + + qDebug() << url; + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} diff --git a/DeviceHub/common/HttpRequestController.h b/DeviceHub/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/DeviceHub/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/DeviceHub/common/common.pri b/DeviceHub/common/common.pri new file mode 100644 index 0000000..6ac9b59 --- /dev/null +++ b/DeviceHub/common/common.pri @@ -0,0 +1,24 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp \ + $$PWD/utils/QKafkaProducer.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +SOURCES += +SOURCES += $$PWD/utils/QKafkaConsumer.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h \ + $$PWD/utils/QKafkaProducer.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +HEADERS += +HEADERS += $$PWD/utils/QKafkaConsumer.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/DeviceHub/common/utils/DefHead.h b/DeviceHub/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/DeviceHub/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/DeviceHub/common/utils/HttpRequestUtil.cpp b/DeviceHub/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/DeviceHub/common/utils/HttpRequestUtil.h b/DeviceHub/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/DeviceHub/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/DeviceHub/common/utils/MD5.cpp b/DeviceHub/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/DeviceHub/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/DeviceHub/common/utils/MD5.h b/DeviceHub/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/DeviceHub/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/DeviceHub/common/utils/QByteUtil.cpp b/DeviceHub/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/DeviceHub/common/utils/QByteUtil.h b/DeviceHub/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/DeviceHub/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/DeviceHub/common/utils/QKafkaConsumer.cpp b/DeviceHub/common/utils/QKafkaConsumer.cpp new file mode 100644 index 0000000..2ce6d03 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.cpp @@ -0,0 +1,116 @@ +#include "QKafkaConsumer.h" +#include + +static volatile int runFlag = 1; +static bool exit_eof = false; + +QKafkaConsumer::QKafkaConsumer(QObject *parent) : QThread(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + this->tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + + conf->set("enable.partition.eof", "true", errStr); +} + +void QKafkaConsumer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaConsumer::setTopic(QString topic) +{ + this->topic = topic; +} + +int QKafkaConsumer::createConsumer() +{ + int ret = conf->set("metadata.broker.list", brokers.toStdString(), errStr); + if (ret != RdKafka::Conf::CONF_OK) + { + std::cerr << "RdKafka conf set brokerlist failed :" << errStr.c_str() << std::endl; + } + + consumer = RdKafka::Consumer::create(conf, errStr); + if (!consumer) { + std::cerr << "Failed to create consumer: " << errStr << std::endl; + return -1; + } + + std::cout << "% Created consumer " << consumer->name() << std::endl; + + return 1; +} + +void QKafkaConsumer::run() +{ + RdKafka::Topic * topic = RdKafka::Topic::create(consumer, this->topic.toStdString(), tconf, errStr); + if (!topic) { + std::cerr << "Failed to create topic: " << errStr << std::endl; + } + + RdKafka::ErrorCode resp = consumer->start(topic, 0, RdKafka::Topic::OFFSET_END); + if (resp != RdKafka::ERR_NO_ERROR) { + std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; + } + + while (runFlag) + { + RdKafka::Message * message = consumer->consume(topic, 0, 200); + messageConsume(message); + } +} + +void QKafkaConsumer::messageConsume(RdKafka::Message* message) { + const RdKafka::Headers *headers; + + switch (message->err()) { + case RdKafka::ERR__TIMED_OUT: + break; + + case RdKafka::ERR_NO_ERROR: + { + /* Real message */ +// std::cout << "Read msg at offset " << message->offset() << std::endl; +// printf("%.*s\n", static_cast(message->len()), static_cast(message->payload())); + + QString messageStr = static_cast(message->payload()); + emit messageRecieved(messageStr); + + if (message->key()) { + std::cout << "Key: " << *message->key() << std::endl; + } + headers = message->headers(); + if (headers) { + std::vector hdrs = headers->get_all(); + for (size_t i = 0 ; i < hdrs.size() ; i++) { + const RdKafka::Headers::Header hdr = hdrs[i]; + + if (hdr.value() != NULL) + printf(" Header: %s = \"%.*s\"\n", + hdr.key().c_str(), + (int)hdr.value_size(), (const char *)hdr.value()); + else + printf(" Header: %s = NULL\n", hdr.key().c_str()); + } + } + break; + } + + case RdKafka::ERR__PARTITION_EOF: + /* Last message */ + if (exit_eof) { + runFlag = 0; + } + break; + + case RdKafka::ERR__UNKNOWN_TOPIC: + case RdKafka::ERR__UNKNOWN_PARTITION: + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + break; + + default: + /* Errors */ + std::cerr << "Consume failed: " << message->errstr() << std::endl; + runFlag = 0; + } +} diff --git a/DeviceHub/common/utils/QKafkaConsumer.h b/DeviceHub/common/utils/QKafkaConsumer.h new file mode 100644 index 0000000..f278676 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaConsumer.h @@ -0,0 +1,38 @@ +#ifndef QKAFKACONSUMER_H +#define QKAFKACONSUMER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaConsumer : public QThread +{ + Q_OBJECT +public: + explicit QKafkaConsumer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createConsumer(); + void run(); + + void messageConsume(RdKafka::Message * message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + RdKafka::Conf * tconf; + + RdKafka::Consumer * consumer = 0; + +signals: + void messageRecieved(QString message); + +}; + +#endif // QKAFKACONSUMER_H diff --git a/DeviceHub/common/utils/QKafkaProducer.cpp b/DeviceHub/common/utils/QKafkaProducer.cpp new file mode 100644 index 0000000..c0db128 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.cpp @@ -0,0 +1,78 @@ +#include "QKafkaProducer.h" +#include + +QKafkaProducer::QKafkaProducer(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaProducer::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaProducer::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaProducer::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaProducer::produceMessage(QString message) +{ + auto retCode = producer->produce(this->topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} + +int QKafkaProducer::produceMessage(QString topic, QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/DeviceHub/common/utils/QKafkaProducer.h b/DeviceHub/common/utils/QKafkaProducer.h new file mode 100644 index 0000000..bd0cc15 --- /dev/null +++ b/DeviceHub/common/utils/QKafkaProducer.h @@ -0,0 +1,34 @@ +#ifndef QKAFKAPRODUCER_H +#define QKAFKAPRODUCER_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaProducer : public QObject +{ + Q_OBJECT +public: + explicit QKafkaProducer(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + int produceMessage(QString topic, QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAPRODUCER_H diff --git a/DeviceHub/common/utils/QLogUtil.cpp b/DeviceHub/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "/"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/DeviceHub/common/utils/QLogUtil.h b/DeviceHub/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/DeviceHub/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + static void writeInfoLog(QString message); + static void writeDebugLog(QString message); + + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); +signals: + +}; + +#endif // QLOGUTIL_H diff --git a/DeviceHub/common/utils/QSerialPortUtil.cpp b/DeviceHub/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..0138158 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,117 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + +// if (open == true) +// { + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000 * 10); +// } + + this->mockReceivData(portName); + +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + std::cout << data.toStdString() << std::endl; + if (this->open == true) + { + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData(QString portName) +{ + QByteArray buffer; + buffer.clear(); + + if (portName == "SignalGenerator") + { + + // signal generator + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + buffer.append("$GLF,1,0,20210929,1,1,1,-0.01,20000,0,2,50,1*48").append("\r\n"); + buffer.append("$GPZDA,192157.00,01,01,2000,0,01*5C").append("\r\n"); + buffer.append("$GPMJD,192157.00,51544,0,01*73").append("\r\n"); + buffer.append("$GLC,0,0*48").append("\r\n"); + + } else if (portName == "FrequencyTuning") + { + // frequency tuning + buffer.append("$GLN,0,192.168.1.126,255.255.255.0,192.168.1.1,255.255.255.255,3000,2000,2001*71").append("\r\n"); + buffer.append("$GLF,0,0,0,0,00000,0,0,0,0,0,0,0,0,0,0,0,1900,2355,0,0,0,0,0,1,1,1*4C").append("\r\n"); + buffer.append("$GLP,0,1000,0,100,20000*45").append("\r\n"); + } else if (portName == "TimeSwitcher") + { + // time switcher + buffer.append("$GPZDA,211219.00,01,01,2000,0,01*5D").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLF,1,1,1,010,100,100,000,000,0,-235136964.75,-235136959.89,0,0,0,5,50,-16390,-16710,-15660,-16700,-17300,11111,11111,11111*51").append("\r\n"); + buffer.append("$GLN,0,192.168.000.126,255.255.255.000,192.168.000.001,192.168.001.126,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "FreqSwitcher") + { + // freq switcher + buffer.append("$GLF,0,4,0,0,22000,-745,-776,0,0,0,0,0,100,100,0,0,0,1,00000,111111,111111*54").append("\r\n"); + buffer.append("$GLC,0*54").append("\r\n"); + buffer.append("$GLN,0,192.168.000.123,255.255.255.000,192.168.000.001,192.168.001.123,255.255.255.000,192.168.001.001,255.255.255.255,3000,2000,2001*75").append("\r\n"); + } else if (portName == "BCodeTerminal") + { + // b-code terminal + buffer.append("$2621304-20 210100112100f90210.035422*"); + buffer.append("$3e21304-20 2101001111304-20 2101001210801H.1.00S.1.030008432*"); + } else if (portName == "TimeReplicator") + { + // time replicator + buffer.append("$2B21308-13 21010012200000000000000000faf0*"); + buffer.append("$3C21308-13 2101008220322222222111111110000000000000000ca24*"); + buffer.append("$3C21308-13 21010052207111111111111111111111111000000005984*"); + buffer.append("$3C21308-13 2101005121511111111111111111111111111111111bcfe*"); + buffer.append("$3E21308-13 2101001211308-13 2101001210929H.1.00S.1.00000292b*"); + } else if (portName == "FreqReplicator") + { + // freq replicator + buffer = QByteUtil::hexStringToBytes("AA550015010001000101010101010101010101010101010101EB"); + buffer.append(QByteUtil::hexStringToBytes("AA550015020001000101010101010101010101010101010101E8")); + } + + emit dataRecieved(buffer); +} diff --git a/DeviceHub/common/utils/QSerialPortUtil.h b/DeviceHub/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..eccc370 --- /dev/null +++ b/DeviceHub/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open = false; + + void mockReceivData(QString portName); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/DeviceHub/common/utils/SettingConfig.cpp b/DeviceHub/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..8768fbc --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.cpp @@ -0,0 +1,28 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + PORT_NAMES = getProperty("com", "portNames").toString(); + BAUD_RATE = getProperty("com", "baudRate").toUInt(); + DEV_CODES = getProperty("com", "devCodes").toString(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/DeviceHub/common/utils/SettingConfig.h b/DeviceHub/common/utils/SettingConfig.h new file mode 100644 index 0000000..a49191b --- /dev/null +++ b/DeviceHub/common/utils/SettingConfig.h @@ -0,0 +1,52 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + QString PORT_NAMES; + int BAUD_RATE; + QString DEV_CODES; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/DeviceHub/conf/config.ini b/DeviceHub/conf/config.ini new file mode 100644 index 0000000..c37ba1c --- /dev/null +++ b/DeviceHub/conf/config.ini @@ -0,0 +1,17 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" + +[client] +clientId="dev-status" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/DevStatus/logs/" diff --git a/DeviceHub/device/BCodeTerminal.cpp b/DeviceHub/device/BCodeTerminal.cpp new file mode 100644 index 0000000..19d33fd --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.cpp @@ -0,0 +1,78 @@ +#include "BCodeTerminal.h" + +#include +#include + +BCodeTerminal::BCodeTerminal(QObject* parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +BCodeTerminal::~BCodeTerminal() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &BCodeTerminal::dataReceivedHandler); +} + +void BCodeTerminal::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void BCodeTerminal::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/BCodeTerminal.h b/DeviceHub/device/BCodeTerminal.h new file mode 100644 index 0000000..b3aa5cb --- /dev/null +++ b/DeviceHub/device/BCodeTerminal.h @@ -0,0 +1,24 @@ +#ifndef BCODETERMINAL_H +#define BCODETERMINAL_H + +#include + +#include "device/DeviceBase.h" + +class BCodeTerminal : public DeviceBase +{ + Q_OBJECT +public: + explicit BCodeTerminal(QObject *parent = nullptr); + ~BCodeTerminal(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // BCODETERMINAL_H diff --git a/DeviceHub/device/DeviceBase.cpp b/DeviceHub/device/DeviceBase.cpp new file mode 100644 index 0000000..573401c --- /dev/null +++ b/DeviceHub/device/DeviceBase.cpp @@ -0,0 +1,44 @@ +#include "DeviceBase.h" +#include + +DeviceBase::DeviceBase(QObject *parent) : QObject(parent) +{ + +} + +void DeviceBase::setComName(QString comName) +{ + this->comName = comName; +} +void DeviceBase::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString DeviceBase::getDevCode() +{ + return this->devCode; +} +void DeviceBase::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void DeviceBase::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool DeviceBase::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void DeviceBase::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void DeviceBase::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); +} diff --git a/DeviceHub/device/DeviceBase.h b/DeviceHub/device/DeviceBase.h new file mode 100644 index 0000000..8cd10d6 --- /dev/null +++ b/DeviceHub/device/DeviceBase.h @@ -0,0 +1,44 @@ +#ifndef DEVICEBASE_H +#define DEVICEBASE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QKafkaUtil.h" +#include "common/utils/QByteUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" + +#include "protocol/dto/DeviceFrameBaseDto.h" +#include "protocol/DeviceStatusProtocolBase.h" + +class DeviceBase : public QObject +{ + Q_OBJECT +public: + explicit DeviceBase(QObject *parent = nullptr); + + void setComName(QString comName); + void setBaudRate(int baudRate); + QString getDevCode(); + void setDevCode(QString devCode); + void setDeviceId(QString deviceId); + + void initSerialPort(); + bool isSerialOpen(); + virtual void sendDataToSerial(QByteArray data); + virtual void afterFramePhase(DeviceFrameBaseDto * frameDto) = 0; + + DeviceStatusProtocolBase * protocol; + +protected: + QString deviceId; + QString devCode; + QString comName; + int baudRate; + + QSerialPortUtil serialUtil; + QKafkaUtil kafkaUtil; + QByteArray dataBuff; +}; + +#endif // DEVICEBASE_H diff --git a/DeviceHub/device/FreqReplicator.cpp b/DeviceHub/device/FreqReplicator.cpp new file mode 100644 index 0000000..b4046fe --- /dev/null +++ b/DeviceHub/device/FreqReplicator.cpp @@ -0,0 +1,78 @@ +#include "FreqReplicator.h" + +#include +#include + +FreqReplicator::FreqReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqReplicator::~FreqReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqReplicator::dataReceivedHandler); +} + +void FreqReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(dataBuff).toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void FreqReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << QByteUtil::binToHexString(frameDto->rawFrame).toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/FreqReplicator.h b/DeviceHub/device/FreqReplicator.h new file mode 100644 index 0000000..221924f --- /dev/null +++ b/DeviceHub/device/FreqReplicator.h @@ -0,0 +1,24 @@ +#ifndef FREQREPLICATOR_H +#define FREQREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class FreqReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqReplicator(QObject *parent = nullptr); + ~FreqReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQREPLICATOR_H diff --git a/DeviceHub/device/FreqSwitcher.cpp b/DeviceHub/device/FreqSwitcher.cpp new file mode 100644 index 0000000..57b440d --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.cpp @@ -0,0 +1,80 @@ +#include "FreqSwitcher.h" + +#include +#include + +FreqSwitcher::FreqSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FreqSwitcher::~FreqSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FreqSwitcher::dataReceivedHandler); +} + +void FreqSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void FreqSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} + + diff --git a/DeviceHub/device/FreqSwitcher.h b/DeviceHub/device/FreqSwitcher.h new file mode 100644 index 0000000..67f06f8 --- /dev/null +++ b/DeviceHub/device/FreqSwitcher.h @@ -0,0 +1,25 @@ +#ifndef FREQSWITCHER_H +#define FREQSWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FreqSwitcherProtocolBM.h" + +class FreqSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit FreqSwitcher(QObject *parent = nullptr); + ~FreqSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // FREQSWITCHER_H diff --git a/DeviceHub/device/FrequencyTuning.cpp b/DeviceHub/device/FrequencyTuning.cpp new file mode 100644 index 0000000..8e36d3a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.cpp @@ -0,0 +1,113 @@ +#include "FrequencyTuning.h" +#include +#include + +FrequencyTuning::FrequencyTuning(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +FrequencyTuning::~FrequencyTuning() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &FrequencyTuning::dataReceivedHandler); +} + + + +void FrequencyTuning::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * ftFrameDto = protocol->frameFactory(frameType); + if (ftFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, ftFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + ftFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + ftFrameDto->milisecond = now.toMSecsSinceEpoch(); + ftFrameDto->rawFrame = frameByte; + + ftFrameDto->devCode = devCode; + + this->afterFramePhase(ftFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete ftFrameDto; + } + } + } +} + +void FrequencyTuning::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 0. 输出到日志文件中 + QString date = frameDto->timestamp.mid(0, 10); + + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = frameDto->timestamp + " [recv] " + frameDto->rawFrame.left(frameDto->rawFrame.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2. 解析后的json数据 + QString frameFilename = "frame_" + devCode + ".log"; + QString frameContent = frameDto->timestamp + " [recv] " + QJsonDocument(frameDto->toJSON()).toJson(QJsonDocument::Compact); + QLogUtil::writeChannelDataLogByDate(date, frameFilename, frameContent); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(frameDto); +} + +void FrequencyTuning::sendDataToSerial(QByteArray data) +{ + data.append(FRAME_TAIL); + this->serialUtil.sendData(data); + + // 记录日志 + // 0. 输出到日志文件中 + QDateTime now = QDateTime::currentDateTime(); + QString date = now.toString("yyyy-MM-dd"); + + // 1. 原始字节数组数据 + QString filename = "raw_" + getDevCode() + ".log"; + QString content = now.toString("yyyy-MM-dd HH:mm:ss.zzz") + " [send] " + data.left(data.size() - FRAME_TAIL.size()); + QLogUtil::writeRawDataLogByDate(date, filename, content); +} diff --git a/DeviceHub/device/FrequencyTuning.h b/DeviceHub/device/FrequencyTuning.h new file mode 100644 index 0000000..50e171a --- /dev/null +++ b/DeviceHub/device/FrequencyTuning.h @@ -0,0 +1,27 @@ +#ifndef FREQUENCYTUNING_H +#define FREQUENCYTUNING_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/FrequencyTuningProtocolBM.h" + +class FrequencyTuning : public DeviceBase +{ + Q_OBJECT +public: + explicit FrequencyTuning(QObject *parent = nullptr); + ~FrequencyTuning(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto) override; + void sendDataToSerial(QByteArray data) override; + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // FREQUENCYTUNING_H diff --git a/DeviceHub/device/SignalGenerator.cpp b/DeviceHub/device/SignalGenerator.cpp new file mode 100644 index 0000000..577db52 --- /dev/null +++ b/DeviceHub/device/SignalGenerator.cpp @@ -0,0 +1,79 @@ +#include "SignalGenerator.h" + +#include +#include + +SignalGenerator::SignalGenerator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +SignalGenerator::~SignalGenerator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &SignalGenerator::dataReceivedHandler); +} + + +void SignalGenerator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * sgFrameDto = protocol->frameFactory(frameType); + if (sgFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, sgFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + sgFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + sgFrameDto->milisecond = now.toMSecsSinceEpoch(); + sgFrameDto->rawFrame = frameByte; + + this->afterFramePhase(sgFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete sgFrameDto; + } + } + } +} + +void SignalGenerator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/SignalGenerator.h b/DeviceHub/device/SignalGenerator.h new file mode 100644 index 0000000..839f22b --- /dev/null +++ b/DeviceHub/device/SignalGenerator.h @@ -0,0 +1,26 @@ +#ifndef SIGNALGENERATOR_H +#define SIGNALGENERATOR_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/SignalGeneratorProtocolBM.h" + +class SignalGenerator : public DeviceBase +{ + Q_OBJECT +public: + explicit SignalGenerator(QObject *parent = nullptr); + ~SignalGenerator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // SIGNALGENERATOR_H diff --git a/DeviceHub/device/TimeReplicator.cpp b/DeviceHub/device/TimeReplicator.cpp new file mode 100644 index 0000000..1ba0db4 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.cpp @@ -0,0 +1,78 @@ +#include "TimeReplicator.h" + +#include +#include + +TimeReplicator::TimeReplicator(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeReplicator::~TimeReplicator() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeReplicator::dataReceivedHandler); +} + +void TimeReplicator::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * frameDto = protocol->frameFactory(frameType); + if (frameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, frameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + frameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + frameDto->milisecond = now.toMSecsSinceEpoch(); + frameDto->rawFrame = frameByte; + + this->afterFramePhase(frameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete frameDto; + } + } + } +} + +void TimeReplicator::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeReplicator.h b/DeviceHub/device/TimeReplicator.h new file mode 100644 index 0000000..5acf6d9 --- /dev/null +++ b/DeviceHub/device/TimeReplicator.h @@ -0,0 +1,24 @@ +#ifndef TIMEREPLICATOR_H +#define TIMEREPLICATOR_H + +#include + +#include "device/DeviceBase.h" + +class TimeReplicator : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeReplicator(QObject *parent = nullptr); + ~TimeReplicator(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); +}; + +#endif // TIMEREPLICATOR_H diff --git a/DeviceHub/device/TimeSwitcher.cpp b/DeviceHub/device/TimeSwitcher.cpp new file mode 100644 index 0000000..ecf4d5a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.cpp @@ -0,0 +1,78 @@ +#include "TimeSwitcher.h" + +#include +#include + +TimeSwitcher::TimeSwitcher(QObject *parent) : DeviceBase(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); + + kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); + kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); + kafkaUtil.createProducer(); + + this->protocol = DeviceStatusProtocolBase::deviceStatusProtocolFactory(typeid (this).name()); +} + +TimeSwitcher::~TimeSwitcher() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &TimeSwitcher::dataReceivedHandler); +} + +void TimeSwitcher::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << dataBuff.toStdString() << std::endl; + + QList frameList = protocol->extractFrameList(this->dataBuff); + + if (frameList.size() > 0) + { + for (int i = 0; i < frameList.size(); i++) + { + QByteArray frameByte = frameList.at(i); + + int frameType = protocol->checkFrame(frameByte); + DeviceFrameBaseDto * tsFrameDto = protocol->frameFactory(frameType); + if (tsFrameDto != nullptr) + { + // ★解析成数据对象 + bool parse = protocol->parseDeviceFrameData(frameByte, tsFrameDto, frameType); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + tsFrameDto->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + tsFrameDto->milisecond = now.toMSecsSinceEpoch(); + tsFrameDto->rawFrame = frameByte; + + this->afterFramePhase(tsFrameDto); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete tsFrameDto; + } + } + } +} + +void TimeSwitcher::afterFramePhase(DeviceFrameBaseDto * frameDto) +{ + std::cout << "frame type: " << typeid(* frameDto).name() << std::endl; + std::cout << frameDto->rawFrame.toStdString() << std::endl; + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = frameDto->toJSON(); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); + kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } +} diff --git a/DeviceHub/device/TimeSwitcher.h b/DeviceHub/device/TimeSwitcher.h new file mode 100644 index 0000000..0ac7e3a --- /dev/null +++ b/DeviceHub/device/TimeSwitcher.h @@ -0,0 +1,26 @@ +#ifndef TIMESWITCHER_H +#define TIMESWITCHER_H + +#include + +#include "device/DeviceBase.h" +#include "protocol/TimeSwitcherProtocolBM.h" + +class TimeSwitcher : public DeviceBase +{ + Q_OBJECT +public: + explicit TimeSwitcher(QObject *parent = nullptr); + ~TimeSwitcher(); + + void afterFramePhase(DeviceFrameBaseDto * frameDto); + +signals: + void sendDataToDraw(DeviceFrameBaseDto * frameData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // TIMESWITCHER_H diff --git a/DeviceHub/device/device.pri b/DeviceHub/device/device.pri new file mode 100644 index 0000000..c9cc393 --- /dev/null +++ b/DeviceHub/device/device.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/DeviceBase.h +HEADERS += $$PWD/SignalGenerator.h +HEADERS += $$PWD/FrequencyTuning.h +HEADERS += $$PWD/TimeSwitcher.h +HEADERS += $$PWD/FreqSwitcher.h +HEADERS += $$PWD/TimeReplicator.h +HEADERS += $$PWD/FreqReplicator.h +HEADERS += $$PWD/BCodeTerminal.h + +SOURCES += $$PWD/DeviceBase.cpp +SOURCES += $$PWD/SignalGenerator.cpp +SOURCES += $$PWD/FrequencyTuning.cpp +SOURCES += $$PWD/TimeSwitcher.cpp +SOURCES += $$PWD/FreqSwitcher.cpp +SOURCES += $$PWD/TimeReplicator.cpp +SOURCES += $$PWD/FreqReplicator.cpp +SOURCES += $$PWD/BCodeTerminal.cpp diff --git a/DeviceHub/main.cpp b/DeviceHub/main.cpp new file mode 100644 index 0000000..4d3374f --- /dev/null +++ b/DeviceHub/main.cpp @@ -0,0 +1,11 @@ +#include "DeviceHubWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + DeviceHubWindow w; + w.show(); + return a.exec(); +} diff --git a/ZXSSCJ.pro b/ZXSSCJ.pro index ec3c2e5..6e384bc 100644 --- a/ZXSSCJ.pro +++ b/ZXSSCJ.pro @@ -6,4 +6,5 @@ #SUBDIRS += CounterAcq #计数器数据采集 #SUBDIRS += PhaseCompAcq #比相仪数据采集 SUBDIRS += DevStatusAcq +SUBDIRS += DeviceHub #SUBDIRS += HClockAcq #氢钟状态数据采集