SerialPort and ZigBee: Use QThread and bump to 1.0.2.
This commit is contained in:
parent
75bee1a451
commit
7bda54063c
|
@ -1 +1 @@
|
||||||
Subproject commit aa3604579b8864efe9e777c7dec96209d7b8ee72
|
Subproject commit 43240eab1f351a90afdc843119743b0aca4d311c
|
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
project(ProtocolParser_APP VERSION 0.1 LANGUAGES CXX)
|
project(ProtocolParser_APP VERSION 1.0.2 LANGUAGES CXX)
|
||||||
|
|
||||||
add_definitions(-DFRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT)
|
add_definitions(-DFRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT)
|
||||||
add_definitions(-DFRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT)
|
add_definitions(-DFRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.21)
|
cmake_minimum_required(VERSION 3.21)
|
||||||
|
|
||||||
project(ProtocolParser VERSION 1.0.1 LANGUAGES CXX)
|
project(ProtocolParser VERSION ${CMAKE_PROJECT_VERSION} LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
@ -13,8 +13,8 @@ set(PROJECT_COMPANY "Mentalflow's Lab")
|
||||||
set(PROJECT_COPYRIGHT "Copyright (c) 2023 Mentalflow's Lab. All rights reserved.")
|
set(PROJECT_COPYRIGHT "Copyright (c) 2023 Mentalflow's Lab. All rights reserved.")
|
||||||
set(PROJECT_DOMAIN "dev.ourdocs.cn.protocolparser")
|
set(PROJECT_DOMAIN "dev.ourdocs.cn.protocolparser")
|
||||||
set(PROJECT_BUNDLE_NAME ${PROJECT_NAME})
|
set(PROJECT_BUNDLE_NAME ${PROJECT_NAME})
|
||||||
|
set(version_str "${CMAKE_PROJECT_VERSION_MAJOR},${CMAKE_PROJECT_VERSION_MINOR},${CMAKE_PROJECT_VERSION_PATCH}")
|
||||||
add_definitions(-DPROTOCOLPARSER_VERSION=1,0,1)
|
add_definitions(-DPROTOCOLPARSER_VERSION=${version_str})
|
||||||
|
|
||||||
find_package(Qt6 COMPONENTS Quick SerialPort LinguistTools REQUIRED)
|
find_package(Qt6 COMPONENTS Quick SerialPort LinguistTools REQUIRED)
|
||||||
|
|
||||||
|
@ -24,8 +24,18 @@ set(
|
||||||
include/zigbeeparser.h source/zigbeeparser.cpp source/crypto.cpp include/crypto.h
|
include/zigbeeparser.h source/zigbeeparser.cpp source/crypto.cpp include/crypto.h
|
||||||
include/protocol.h source/protocol.cpp include/protocol_data.h
|
include/protocol.h source/protocol.cpp include/protocol_data.h
|
||||||
include/config.h source/config.cpp
|
include/config.h source/config.cpp
|
||||||
|
include/serialdataresolver.h source/serialdataresolver.cpp
|
||||||
|
include/zigbeedataresolver.h source/zigbeedataresolver.cpp
|
||||||
languages/zh_CN.ts languages/en_US.ts
|
languages/zh_CN.ts languages/en_US.ts
|
||||||
# dlln3x_handler.h dlln3x_handler.cpp
|
)
|
||||||
|
|
||||||
|
set(
|
||||||
|
qml_files qml/Main.qml qml/components/RibbonWindow.qml qml/components/ZigBeeFrame.qml
|
||||||
|
qml/components/RibbonMessageListView.qml qml/components/RibbonMessage.qml
|
||||||
|
qml/components/ZigBeeMessage.qml qml/components/SerialPortAssistant.qml
|
||||||
|
qml/components/ZigBeeDataView.qml qml/components/TabBar.qml qml/components/CenterView.qml
|
||||||
|
qml/components/ListTable.qml qml/components/DeviceList.qml qml/components/KeysList.qml
|
||||||
|
qml/components/EventsHistoryList.qml
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(dlln3x include)
|
INCLUDE_DIRECTORIES(dlln3x include)
|
||||||
|
@ -43,19 +53,19 @@ if (WIN32)
|
||||||
${sources_files}
|
${sources_files}
|
||||||
resources/icon.rc
|
resources/icon.rc
|
||||||
)
|
)
|
||||||
file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
|
file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
set(DLLPATH ../3rdparty/msvc/*.dll)
|
set(DLLPATH ../3rdparty/msvc/*.dll)
|
||||||
else()
|
else()
|
||||||
set(DLLPATH ../3rdparty/mingw/*.dll)
|
set(DLLPATH ../3rdparty/mingw/*.dll)
|
||||||
endif()
|
endif()
|
||||||
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
|
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
|
||||||
file(GLOB DLL_FILES ${DLLPATH})
|
file(GLOB DLL_FILES ${DLLPATH})
|
||||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
${DLL_FILES}
|
${DLL_FILES}
|
||||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||||
)
|
)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
set(MACOSX_BUNDLE_ICON_FILE AppIcon)
|
set(MACOSX_BUNDLE_ICON_FILE AppIcon)
|
||||||
set(App_ICON "resources/imgs/AppIcon.icns")
|
set(App_ICON "resources/imgs/AppIcon.icns")
|
||||||
|
@ -71,15 +81,16 @@ else ()
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
foreach(qmlfile ${qml_files})
|
||||||
|
string(REPLACE "qml/" "" fixedfile ${qmlfile})
|
||||||
|
set_source_files_properties(${qmlfile} PROPERTIES QT_RESOURCE_ALIAS ${fixedfile})
|
||||||
|
endforeach(qmlfile)
|
||||||
|
|
||||||
qt_add_qml_module(${PROJECT_NAME}
|
qt_add_qml_module(${PROJECT_NAME}
|
||||||
URI ${PROJECT_NAME}
|
URI ${PROJECT_NAME}
|
||||||
VERSION 1.0
|
QML_FILES ${qml_files}
|
||||||
QML_FILES qml/Main.qml qml/components/RibbonWindow.qml qml/components/ZigBeeFrame.qml
|
RESOURCE_PREFIX "/qt/qml/"
|
||||||
qml/components/RibbonMessageListView.qml qml/components/RibbonMessage.qml
|
VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}
|
||||||
qml/components/ZigBeeMessage.qml qml/components/SerialPortAssistant.qml
|
|
||||||
qml/components/ZigBeeDataView.qml qml/components/TabBar.qml qml/components/CenterView.qml
|
|
||||||
qml/components/ListTable.qml qml/components/DeviceList.qml qml/components/KeysList.qml
|
|
||||||
qml/components/EventsHistoryList.qml
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
@ -94,9 +105,9 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_add_translations(${PROJECT_NAME}
|
qt_add_translations(${PROJECT_NAME}
|
||||||
TS_FILES languages/zh_CN.ts languages/en_US.ts
|
TS_FILES languages/zh_CN.ts languages/en_US.ts
|
||||||
RESOURCE_PREFIX "/translations"
|
RESOURCE_PREFIX "/translations"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(RIBBONUI_BUILD_STATIC_LIB)
|
if(RIBBONUI_BUILD_STATIC_LIB)
|
||||||
add_definitions(-DRIBBONUI_BUILD_STATIC_LIB)
|
add_definitions(-DRIBBONUI_BUILD_STATIC_LIB)
|
||||||
|
|
|
@ -7,7 +7,6 @@ using namespace zigbee_protocol;
|
||||||
DLLN3X::DLLN3X(QObject *parent)
|
DLLN3X::DLLN3X(QObject *parent)
|
||||||
: QObject{parent}
|
: QObject{parent}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLN3X* DLLN3X::instance(){
|
DLLN3X* DLLN3X::instance(){
|
||||||
|
@ -60,6 +59,8 @@ ZigbeeFrame DLLN3X::recv(bool non_blocked)
|
||||||
|
|
||||||
bool DLLN3X::send(ZigbeeFrame zf)
|
bool DLLN3X::send(ZigbeeFrame zf)
|
||||||
{
|
{
|
||||||
|
if(!_DSerial->isOpen())
|
||||||
|
return false;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
uint8_t len = zf.size();
|
uint8_t len = zf.size();
|
||||||
if (zf.getSrcPort() < 0x80 || len > 66)
|
if (zf.getSrcPort() < 0x80 || len > 66)
|
||||||
|
@ -281,7 +282,7 @@ enum DLLN3X::PIN_CONTROL DLLN3X::pin_control(PIN pin, PIN_CONTROL cmd)
|
||||||
|
|
||||||
void DLLN3X::loop()
|
void DLLN3X::loop()
|
||||||
{
|
{
|
||||||
if (_DSerial->bytesAvailable() > 7 && !_recv_lock) {
|
if (_DSerial && _DSerial->bytesAvailable() > 7 && !_recv_lock) {
|
||||||
ZigbeeFrame zf = recv();
|
ZigbeeFrame zf = recv();
|
||||||
printf("Message: ");
|
printf("Message: ");
|
||||||
for (int i = 0; i < zf.size(); i++) {
|
for (int i = 0; i < zf.size(); i++) {
|
||||||
|
@ -303,7 +304,8 @@ int DLLN3X::readBytesUntil(uint8_t delimiter, uint8_t* buffer, qint64 maxSize)
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
qint64 bytesRead = 0;
|
qint64 bytesRead = 0;
|
||||||
|
if(!_DSerial->isOpen())
|
||||||
|
return bytesRead;
|
||||||
if (_DSerial->bytesAvailable() || _DSerial->waitForReadyRead(2000))
|
if (_DSerial->bytesAvailable() || _DSerial->waitForReadyRead(2000))
|
||||||
while (bytesRead < maxSize)
|
while (bytesRead < maxSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,8 @@ private:
|
||||||
const QSerialPort::BaudRate _baud_rate_list[7] = {QSerialPort::Baud2400, QSerialPort::Baud4800, QSerialPort::Baud9600,
|
const QSerialPort::BaudRate _baud_rate_list[7] = {QSerialPort::Baud2400, QSerialPort::Baud4800, QSerialPort::Baud9600,
|
||||||
QSerialPort::Baud19200, QSerialPort::Baud38400, QSerialPort::Baud57600, QSerialPort::Baud115200};
|
QSerialPort::Baud19200, QSerialPort::Baud38400, QSerialPort::Baud57600, QSerialPort::Baud115200};
|
||||||
QSerialPort* _DSerial;
|
QSerialPort* _DSerial;
|
||||||
|
explicit DLLN3X(QObject *parent = nullptr);
|
||||||
|
Q_DISABLE_COPY_MOVE(DLLN3X)
|
||||||
void (*_callback)(ZigbeeFrame& zf) = nullptr;
|
void (*_callback)(ZigbeeFrame& zf) = nullptr;
|
||||||
int readBytesUntil(uint8_t delimiter, uint8_t* buf, qint64 maxSize);
|
int readBytesUntil(uint8_t delimiter, uint8_t* buf, qint64 maxSize);
|
||||||
void _sleep(int msec);
|
void _sleep(int msec);
|
||||||
|
@ -33,7 +35,6 @@ public:
|
||||||
};
|
};
|
||||||
enum PIN_CONTROL{ OUT_HIGH = 0x11, OUT_LOW = 0x10, READ_PIN = 0x12};
|
enum PIN_CONTROL{ OUT_HIGH = 0x11, OUT_LOW = 0x10, READ_PIN = 0x12};
|
||||||
enum PIN{ DLLN3X_PIN4 = 0x44, DLLN3X_PIN5 = 0x45};
|
enum PIN{ DLLN3X_PIN4 = 0x44, DLLN3X_PIN5 = 0x45};
|
||||||
explicit DLLN3X(QObject *parent = nullptr);
|
|
||||||
static DLLN3X* instance();
|
static DLLN3X* instance();
|
||||||
void init(QSerialPort* DSerial, uint32_t baudrate = 115200);
|
void init(QSerialPort* DSerial, uint32_t baudrate = 115200);
|
||||||
ZigbeeFrame recv(bool non_blocked = true);
|
ZigbeeFrame recv(bool non_blocked = true);
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Config(QString qstrfilename = "");
|
Config(QString qstrfilename = "");
|
||||||
~Config(void);
|
~Config(void);
|
||||||
|
Q_DISABLE_COPY_MOVE(Config)
|
||||||
QString m_qstrFileName;
|
QString m_qstrFileName;
|
||||||
QSettings *m_psetting=nullptr;
|
QSettings *m_psetting=nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
#ifndef DLLN3X_HANDLER_H
|
|
||||||
#define DLLN3X_HANDLER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QQmlEngine>
|
|
||||||
#include <QSerialPort>
|
|
||||||
#include "DLLN3X.h"
|
|
||||||
#include "3rdparty/RibbonUI/lib_source/definitions.h"
|
|
||||||
|
|
||||||
class DLLN3X_Handler : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_ELEMENT
|
|
||||||
QML_SINGLETON
|
|
||||||
QML_NAMED_ELEMENT(DLLN3XHandler)
|
|
||||||
Q_PROPERTY_RW(bool, handle_serial);
|
|
||||||
Q_PROPERTY_RW(QSerialPort*, serial);
|
|
||||||
public:
|
|
||||||
explicit DLLN3X_Handler(QObject *parent = nullptr);
|
|
||||||
Q_INVOKABLE bool send(QString data);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void zigbee_recved(QByteArray data, QByteArray sender);
|
|
||||||
|
|
||||||
private:
|
|
||||||
zigbee_protocol::DLLN3X* _zigbee=nullptr;
|
|
||||||
void zigbee_callback(zigbee_protocol::ZigbeeFrame zframe);
|
|
||||||
void close();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DLLN3X_HANDLER_H
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
Q_INVOKABLE void unreg_event(Event* event);
|
Q_INVOKABLE void unreg_event(Event* event);
|
||||||
private:
|
private:
|
||||||
explicit EventsBus(QObject *parent = nullptr);
|
explicit EventsBus(QObject *parent = nullptr);
|
||||||
|
Q_DISABLE_COPY_MOVE(EventsBus);
|
||||||
QList<Event*> _events;
|
QList<Event*> _events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Protocol();
|
Protocol();
|
||||||
~Protocol();
|
~Protocol();
|
||||||
|
Q_DISABLE_COPY_MOVE(Protocol)
|
||||||
Config* _config = nullptr;
|
Config* _config = nullptr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef SERIALDATARESOLVER_H
|
||||||
|
#define SERIALDATARESOLVER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QSerialPort>
|
||||||
|
#include "DLLN3X.h"
|
||||||
|
|
||||||
|
class SerialDataResolver : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum class SendType{
|
||||||
|
Blank=0,
|
||||||
|
WithCarriageEnter=1,
|
||||||
|
WithLineFeed=2,
|
||||||
|
WithCarriageEnterAndLineFeed=3
|
||||||
|
};
|
||||||
|
Q_ENUM(SendType)
|
||||||
|
void open(QString port_name, QString baudrate, QString databits,
|
||||||
|
QString parity, QString stopbits);
|
||||||
|
void close();
|
||||||
|
bool handled_by_manager();
|
||||||
|
void handled_by_manager(bool handled_by_manager);
|
||||||
|
bool recv_hex();
|
||||||
|
void recv_hex(bool recv_hex);
|
||||||
|
bool serial_opened();
|
||||||
|
static SerialDataResolver* instance();
|
||||||
|
public slots:
|
||||||
|
void write_data(QString data, SendType type, bool send_hex);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit SerialDataResolver(QObject *parent = nullptr);
|
||||||
|
~SerialDataResolver();
|
||||||
|
Q_DISABLE_COPY_MOVE(SerialDataResolver)
|
||||||
|
void readHandler();
|
||||||
|
void zigbee_callback(zigbee_protocol::ZigbeeFrame zframe);
|
||||||
|
void serial_opened(bool serial_opened);
|
||||||
|
zigbee_protocol::DLLN3X* _zigbee=nullptr;
|
||||||
|
QSerialPort* _serial=nullptr;
|
||||||
|
bool _quit = false, _handled_by_manager = false, _recv_hex = false,
|
||||||
|
_serial_opened = false,_serial_want_open = false;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void error(const QString &s);
|
||||||
|
void recved(const QByteArray &data);
|
||||||
|
void recved_zframe(zigbee_protocol::ZigbeeFrame zframe);
|
||||||
|
void handled_by_managerChanged();
|
||||||
|
void recv_hexChanged();
|
||||||
|
void serial_openedChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SERIALDATARESOLVER_H
|
|
@ -5,9 +5,9 @@
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QSerialPort>
|
#include <QSerialPort>
|
||||||
#include "DLLN3X.h"
|
#include <QThread>
|
||||||
|
#include "serialdataresolver.h"
|
||||||
#include "../3rdparty/RibbonUI/lib_source/definitions.h"
|
#include "../3rdparty/RibbonUI/lib_source/definitions.h"
|
||||||
#include "zigbeeparser.h"
|
|
||||||
#include "eventsbus.h"
|
#include "eventsbus.h"
|
||||||
|
|
||||||
class SerialPortManager : public QObject
|
class SerialPortManager : public QObject
|
||||||
|
@ -27,10 +27,8 @@ public:
|
||||||
WithCarriageEnterAndLineFeed=3
|
WithCarriageEnterAndLineFeed=3
|
||||||
};
|
};
|
||||||
Q_ENUM(SendType)
|
Q_ENUM(SendType)
|
||||||
|
|
||||||
Q_PROPERTY_RW(int, available_ports_count)
|
Q_PROPERTY_RW(int, available_ports_count)
|
||||||
Q_PROPERTY_RW(bool, opened)
|
Q_PROPERTY_RW(bool, opened)
|
||||||
Q_PROPERTY_RW(bool, closed)
|
|
||||||
Q_PROPERTY_RW(bool, readyRead)
|
Q_PROPERTY_RW(bool, readyRead)
|
||||||
Q_PROPERTY_RW(bool, handledBymanager)
|
Q_PROPERTY_RW(bool, handledBymanager)
|
||||||
Q_PROPERTY_RW(bool, recv_hex)
|
Q_PROPERTY_RW(bool, recv_hex)
|
||||||
|
@ -41,25 +39,30 @@ public:
|
||||||
static SerialPortManager* instance();
|
static SerialPortManager* instance();
|
||||||
static SerialPortManager* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
|
static SerialPortManager* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
|
||||||
QList<QString> available_ports();
|
QList<QString> available_ports();
|
||||||
Q_INVOKABLE bool open(QString port_name, QString baudrate, QString databits,
|
Q_INVOKABLE void open(QString port_name, QString baudrate, QString databits,
|
||||||
QString parity, QString stopbits);
|
QString parity, QString stopbits);
|
||||||
Q_INVOKABLE void close();
|
Q_INVOKABLE void close();
|
||||||
Q_INVOKABLE QByteArray read();
|
Q_INVOKABLE void write(QString data);
|
||||||
Q_INVOKABLE bool write(QString data);
|
|
||||||
Q_INVOKABLE QSerialPort* get_serial();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void available_portsChanged(QList<QString> ports);
|
void available_portsChanged(QList<QString> ports);
|
||||||
|
void recved(QString data);
|
||||||
|
void serial_open(QString port_name, QString baudrate, QString databits,
|
||||||
|
QString parity, QString stopbits);
|
||||||
|
void serial_close();
|
||||||
|
void serial_write(QString data, SerialDataResolver::SendType type, bool send_hex);
|
||||||
private:
|
private:
|
||||||
explicit SerialPortManager(QObject *parent = nullptr);
|
explicit SerialPortManager(QObject *parent = nullptr);
|
||||||
~SerialPortManager();
|
~SerialPortManager();
|
||||||
|
Q_DISABLE_COPY_MOVE(SerialPortManager)
|
||||||
QTimer _serial_port_scanner;
|
QTimer _serial_port_scanner;
|
||||||
QSerialPort _serial_port;
|
|
||||||
zigbee_protocol::DLLN3X* _zigbee=nullptr;
|
|
||||||
void _ready_for_read();
|
|
||||||
void zigbee_callback(zigbee_protocol::ZigbeeFrame zframe);
|
|
||||||
Event _event;
|
Event _event;
|
||||||
EventsBus* _bus = nullptr;
|
EventsBus* _bus = nullptr;
|
||||||
|
SerialDataResolver* _resolver = nullptr;
|
||||||
|
QThread* _thread = nullptr;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void zigbee_callback(zigbee_protocol::ZigbeeFrame zframe);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SERIALPORTMANAGER_H
|
#endif // SERIALPORTMANAGER_H
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef ZIGBEEDATARESOLVER_H
|
||||||
|
#define ZIGBEEDATARESOLVER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include "zigbeeframe.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
|
class ZigBeeDataResolver : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static ZigBeeDataResolver* instance();
|
||||||
|
public slots:
|
||||||
|
void message_parser(QJsonObject message, QString self_addr, QList<uint16_t> allow_list, QList<uint16_t> deny_list, QList<uint16_t> wait_queue);
|
||||||
|
private:
|
||||||
|
explicit ZigBeeDataResolver(QObject *parent = nullptr);
|
||||||
|
~ZigBeeDataResolver();
|
||||||
|
Q_DISABLE_COPY_MOVE(ZigBeeDataResolver)
|
||||||
|
void data_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
||||||
|
void src_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
||||||
|
void des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
||||||
|
void remote_addr_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
||||||
|
zigbee_protocol::Protocol* _protocol = nullptr;
|
||||||
|
QString _self_addr;
|
||||||
|
QMap<uint16_t, QPair<device,device>> nodes;
|
||||||
|
QList<uint16_t> _allow_list,_deny_list,_wait_queue;
|
||||||
|
signals:
|
||||||
|
void data_send(QString type, QJsonObject data, QList<uint16_t> allow_list, QList<uint16_t> deny_list, QList<uint16_t> wait_queue);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ZIGBEEDATARESOLVER_H
|
|
@ -11,6 +11,7 @@
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "eventsbus.h"
|
#include "eventsbus.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "zigbeedataresolver.h"
|
||||||
|
|
||||||
class ZigBeeParser : public QObject
|
class ZigBeeParser : public QObject
|
||||||
{
|
{
|
||||||
|
@ -30,24 +31,25 @@ public:
|
||||||
void setHmac_verify_key(QString key){ _config->Set("Protocol","hmac_verify_key",key); _protocol->hmac_verify_key = key;emit hmac_verify_keyChanged();};
|
void setHmac_verify_key(QString key){ _config->Set("Protocol","hmac_verify_key",key); _protocol->hmac_verify_key = key;emit hmac_verify_keyChanged();};
|
||||||
QStringList pre_hmac_verify_key(){ return _protocol->pre_hmac_verify_key;};
|
QStringList pre_hmac_verify_key(){ return _protocol->pre_hmac_verify_key;};
|
||||||
void setPre_hmac_verify_key(QStringList keys){ _config->SetArray("Protocol","pre_hmac_verify_key",keys); _protocol->pre_hmac_verify_key = keys;emit pre_hmac_verify_keyChanged();};
|
void setPre_hmac_verify_key(QStringList keys){ _config->SetArray("Protocol","pre_hmac_verify_key",keys); _protocol->pre_hmac_verify_key = keys;emit pre_hmac_verify_keyChanged();};
|
||||||
void data_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
|
||||||
void message_parser(QJsonObject message);
|
|
||||||
static ZigBeeParser* instance();
|
static ZigBeeParser* instance();
|
||||||
static ZigBeeParser* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
|
static ZigBeeParser* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
|
||||||
|
void message_parser(QJsonObject message);
|
||||||
signals:
|
signals:
|
||||||
void hmac_verify_keyChanged();
|
void hmac_verify_keyChanged();
|
||||||
void pre_hmac_verify_keyChanged();
|
void pre_hmac_verify_keyChanged();
|
||||||
|
void message_recved(QJsonObject message, QString self_addr, QList<uint16_t> allow_list, QList<uint16_t> deny_list, QList<uint16_t> wait_queue);
|
||||||
private:
|
private:
|
||||||
explicit ZigBeeParser(QObject *parent = nullptr);
|
explicit ZigBeeParser(QObject *parent = nullptr);
|
||||||
~ZigBeeParser();
|
~ZigBeeParser();
|
||||||
void src_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
Q_DISABLE_COPY_MOVE(ZigBeeParser)
|
||||||
void des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
|
||||||
void remote_addr_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
|
||||||
QMap<uint16_t, QPair<device,device>> nodes;
|
|
||||||
Event _event;
|
Event _event;
|
||||||
EventsBus *_bus = nullptr;
|
EventsBus *_bus = nullptr;
|
||||||
zigbee_protocol::Protocol* _protocol = nullptr;
|
zigbee_protocol::Protocol* _protocol = nullptr;
|
||||||
QString _self_addr = QString::number(DEFAULT_SELF_ADDR,16).toUpper();
|
QString _self_addr = QString::number(DEFAULT_SELF_ADDR,16).toUpper();
|
||||||
Config* _config = nullptr;
|
Config* _config = nullptr;
|
||||||
|
ZigBeeDataResolver* _resolver = nullptr;
|
||||||
|
QThread *_thread = nullptr;
|
||||||
|
private slots:
|
||||||
|
void bus_data_send(QString type, QJsonObject data, QList<uint16_t> allow_list, QList<uint16_t> deny_list, QList<uint16_t> wait_queue);
|
||||||
};
|
};
|
||||||
#endif // ZIGBEEPARSER_H
|
#endif // ZIGBEEPARSER_H
|
||||||
|
|
|
@ -32,16 +32,13 @@ Item{
|
||||||
}
|
}
|
||||||
Connections{
|
Connections{
|
||||||
target: SerialPortManager
|
target: SerialPortManager
|
||||||
function onReadyReadChanged(){
|
function onRecved(data)
|
||||||
if (control.handle_serial && SerialPortManager.readyRead)
|
{
|
||||||
{
|
serial_view.message_model.append({
|
||||||
var d = SerialPortManager.read()
|
time: Qt.formatDateTime(new Date(), "yyyy-MM-dd hh:mm:ss.zzz"),
|
||||||
serial_view.message_model.append({
|
note_text: data.toString(),
|
||||||
note_text: d.toString(),
|
recieved: true,
|
||||||
recieved: true,
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,13 +185,14 @@ Item{
|
||||||
SerialPortManager.send_hex = tab_bar.send_hex
|
SerialPortManager.send_hex = tab_bar.send_hex
|
||||||
SerialPortManager.send_type = serial_send_type_combo.currentText === "无" ? SerialPortManager.Blank
|
SerialPortManager.send_type = serial_send_type_combo.currentText === "无" ? SerialPortManager.Blank
|
||||||
: serial_send_type_combo.currentText === "回车" ? SerialPortManager.WithCarriageEnter
|
: serial_send_type_combo.currentText === "回车" ? SerialPortManager.WithCarriageEnter
|
||||||
: serial_send_type_combo.currentText === "换行" ? SerialPortManager.WithLineFeed
|
: serial_send_type_combo.currentText === "换行" ? SerialPortManager.WithLineFeed
|
||||||
: SerialPortManager.WithCarriageEnterAndLineFeed
|
: SerialPortManager.WithCarriageEnterAndLineFeed
|
||||||
SerialPortManager.write(message_sender_textbox.text)
|
SerialPortManager.write(message_sender_textbox.text)
|
||||||
serial_view.message_model.append({
|
serial_view.message_model.append({
|
||||||
note_text: message_sender_textbox.text,
|
time: Qt.formatDateTime(new Date(), "yyyy-MM-dd hh:mm:ss.zzz"),
|
||||||
recieved: false,
|
note_text: message_sender_textbox.text,
|
||||||
})
|
recieved: false,
|
||||||
|
})
|
||||||
message_sender_textbox.textedit.clear()
|
message_sender_textbox.textedit.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ RibbonTabBar {
|
||||||
}
|
}
|
||||||
icon_source: RibbonIcons.SerialPort
|
icon_source: RibbonIcons.SerialPort
|
||||||
currentIndex: 0
|
currentIndex: 0
|
||||||
enabled: SerialPortManager.closed
|
enabled: !SerialPortManager.opened
|
||||||
Connections{
|
Connections{
|
||||||
target: SerialPortManager
|
target: SerialPortManager
|
||||||
function onAvailable_portsChanged(ports){
|
function onAvailable_portsChanged(ports){
|
||||||
|
@ -70,7 +70,7 @@ RibbonTabBar {
|
||||||
ListElement { text: "57600" }
|
ListElement { text: "57600" }
|
||||||
ListElement { text: "115200" }
|
ListElement { text: "115200" }
|
||||||
}
|
}
|
||||||
enabled: SerialPortManager.closed
|
enabled: !SerialPortManager.opened
|
||||||
currentIndex: 6
|
currentIndex: 6
|
||||||
icon_source: RibbonIcons.NumberSymbol
|
icon_source: RibbonIcons.NumberSymbol
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ RibbonTabBar {
|
||||||
ListElement { text: "7" }
|
ListElement { text: "7" }
|
||||||
ListElement { text: "8" }
|
ListElement { text: "8" }
|
||||||
}
|
}
|
||||||
enabled: SerialPortManager.closed
|
enabled: !SerialPortManager.opened
|
||||||
currentIndex: 3
|
currentIndex: 3
|
||||||
icon_source: RibbonIcons.DataWhisker
|
icon_source: RibbonIcons.DataWhisker
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ RibbonTabBar {
|
||||||
ListElement { text: qsTr("EVEN") }
|
ListElement { text: qsTr("EVEN") }
|
||||||
ListElement { text: qsTr("ODD") }
|
ListElement { text: qsTr("ODD") }
|
||||||
}
|
}
|
||||||
enabled: SerialPortManager.closed
|
enabled: !SerialPortManager.opened
|
||||||
icon_source: RibbonIcons.DataWhisker
|
icon_source: RibbonIcons.DataWhisker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ RibbonTabBar {
|
||||||
ListElement { text: "1.5" }
|
ListElement { text: "1.5" }
|
||||||
ListElement { text: "2" }
|
ListElement { text: "2" }
|
||||||
}
|
}
|
||||||
enabled: SerialPortManager.closed
|
enabled: !SerialPortManager.opened
|
||||||
icon_source: RibbonIcons.DataWhisker
|
icon_source: RibbonIcons.DataWhisker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,12 +150,13 @@ RibbonTabBar {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
icon_source: RibbonIcons.Open
|
icon_source: RibbonIcons.Open
|
||||||
show_tooltip: false
|
show_tooltip: false
|
||||||
text: SerialPortManager.closed ? qsTr("打开串口") : qsTr("关闭串口")
|
text: SerialPortManager.opened ? qsTr("关闭串口") : qsTr("打开串口")
|
||||||
onClicked: SerialPortManager.open(serial_port_combo.currentText,
|
onClicked: !SerialPortManager.opened ? SerialPortManager.open(serial_port_combo.currentText,
|
||||||
serial_baudrate_combo.currentText,
|
serial_baudrate_combo.currentText,
|
||||||
serial_databits_combo.currentText,
|
serial_databits_combo.currentText,
|
||||||
serial_parity_combo.currentText,
|
serial_parity_combo.currentText,
|
||||||
serial_stopbits_combo.currentText)
|
serial_stopbits_combo.currentText) :
|
||||||
|
SerialPortManager.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
#include "dlln3x_handler.h"
|
|
||||||
|
|
||||||
DLLN3X_Handler::DLLN3X_Handler(QObject *parent)
|
|
||||||
: QObject{parent}
|
|
||||||
{
|
|
||||||
_zigbee = zigbee_protocol::DLLN3X::instance();
|
|
||||||
handle_serial(false);
|
|
||||||
serial(nullptr);
|
|
||||||
connect(this, &DLLN3X_Handler::handle_serialChanged, this, [=](){
|
|
||||||
if (_handle_serial&&_serial!=nullptr)
|
|
||||||
{
|
|
||||||
_zigbee->init(_serial, _serial->baudRate());
|
|
||||||
connect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &DLLN3X_Handler::zigbee_callback);
|
|
||||||
connect(_serial, &QSerialPort::readyRead, _zigbee, &zigbee_protocol::DLLN3X::loop);
|
|
||||||
connect(_serial, &QSerialPort::aboutToClose, this, &DLLN3X_Handler::close);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void DLLN3X_Handler::zigbee_callback(zigbee_protocol::ZigbeeFrame zframe)
|
|
||||||
{
|
|
||||||
QByteArray zf = QByteArray((char *)zframe.data(),zframe.size());
|
|
||||||
QByteArray hex = zf.toHex(' ');
|
|
||||||
QByteArray data = hex.toUpper();
|
|
||||||
QByteArray num = QByteArray::number(zframe.getRemoteAddr(),16);
|
|
||||||
QByteArray sender = num.toUpper();
|
|
||||||
emit zigbee_recved(data, sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DLLN3X_Handler::close()
|
|
||||||
{
|
|
||||||
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &DLLN3X_Handler::zigbee_callback);
|
|
||||||
disconnect(_serial, &QSerialPort::readyRead, _zigbee, &zigbee_protocol::DLLN3X::loop);
|
|
||||||
disconnect(_serial, &QSerialPort::aboutToClose, this, &DLLN3X_Handler::close);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DLLN3X_Handler::send(QString data)
|
|
||||||
{
|
|
||||||
if (_handle_serial)
|
|
||||||
{
|
|
||||||
QByteArray bdata;
|
|
||||||
QStringList td = data.split(' ');
|
|
||||||
for (auto item : td)
|
|
||||||
bdata += QByteArray::fromHex(item.toLatin1());
|
|
||||||
|
|
||||||
zigbee_protocol::ZigbeeFrame zf(bdata.data(),bdata.length());
|
|
||||||
|
|
||||||
return _zigbee->send(zf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -35,7 +35,7 @@ int main(int argc, char *argv[])
|
||||||
#ifdef RIBBONUI_BUILD_STATIC_LIB
|
#ifdef RIBBONUI_BUILD_STATIC_LIB
|
||||||
engine.addImportPath("qrc:/");
|
engine.addImportPath("qrc:/");
|
||||||
#endif
|
#endif
|
||||||
const QUrl url(u"qrc:/ProtocolParser/qml/Main.qml"_qs);
|
const QUrl url(u"qrc:/qt/qml/ProtocolParser/Main.qml"_qs);
|
||||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||||
if (!obj && url == objUrl)
|
if (!obj && url == objUrl)
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
#include "serialdataresolver.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
SerialDataResolver::SerialDataResolver(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
|
||||||
|
_serial = new QSerialPort(this);
|
||||||
|
_zigbee = zigbee_protocol::DLLN3X::instance();
|
||||||
|
recv_hex(false);
|
||||||
|
handled_by_manager(true);
|
||||||
|
connect(this, &SerialDataResolver::handled_by_managerChanged, this, [=](){
|
||||||
|
if (!_handled_by_manager && _serial->isOpen())
|
||||||
|
{
|
||||||
|
_zigbee->init(_serial, _serial->baudRate());
|
||||||
|
zigbee_protocol::Protocol::getInstance()->self_addr = _zigbee->read_addr();
|
||||||
|
connect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialDataResolver::~SerialDataResolver()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
delete _serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialDataResolver* SerialDataResolver::instance()
|
||||||
|
{
|
||||||
|
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
|
||||||
|
static QMutex mutex;
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
static SerialDataResolver *singleton = nullptr;
|
||||||
|
if (!singleton) {
|
||||||
|
singleton = new SerialDataResolver();
|
||||||
|
}
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::open(QString port_name, QString baudrate, QString databits,
|
||||||
|
QString parity, QString stopbits)
|
||||||
|
{
|
||||||
|
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
|
||||||
|
QMutex mutex;
|
||||||
|
const QMutexLocker locker(&mutex);
|
||||||
|
_serial->setPortName(port_name);
|
||||||
|
|
||||||
|
if (!_serial->open(QIODevice::ReadWrite))
|
||||||
|
{
|
||||||
|
emit error(tr("串口%1打开失败, 错误代码:%2")
|
||||||
|
.arg(port_name).arg(_serial->error()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serial_opened(true);
|
||||||
|
_serial->setBaudRate(baudrate.toInt());
|
||||||
|
switch (databits.toInt())
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
_serial->setDataBits( QSerialPort::Data5 ); // 设置数据位(数据位为5位)
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
_serial->setDataBits( QSerialPort::Data6 ); // 设置数据位(数据位为6位)
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
_serial->setDataBits( QSerialPort::Data7 ); // 设置数据位(数据位为7位)
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
_serial->setDataBits( QSerialPort::Data8 ); // 设置数据位(数据位为8位)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (parity=="NONE")
|
||||||
|
{
|
||||||
|
_serial->setParity( QSerialPort::NoParity ); // 设置校验位(无校验位)
|
||||||
|
}
|
||||||
|
else if (parity=="EVEN")
|
||||||
|
{
|
||||||
|
_serial->setParity( QSerialPort::EvenParity ); // 设置校验位(奇校验位)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_serial->setParity( QSerialPort::OddParity ); // 设置校验位(偶校验位)
|
||||||
|
}
|
||||||
|
if (stopbits=="1")
|
||||||
|
{
|
||||||
|
_serial->setStopBits( QSerialPort::OneStop ); // 设置停止位(停止位为1)
|
||||||
|
}
|
||||||
|
else if (stopbits=="1.5")
|
||||||
|
{
|
||||||
|
_serial->setStopBits( QSerialPort::OneAndHalfStop ); // 设置停止位(停止位为1.5)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_serial->setStopBits( QSerialPort::TwoStop ); // 设置停止位(停止位为2)
|
||||||
|
}
|
||||||
|
_serial->setFlowControl( QSerialPort::NoFlowControl ); // 设置流控制(无数据流控制)
|
||||||
|
connect(_serial,&QSerialPort::aboutToClose, this, &SerialDataResolver::close);
|
||||||
|
connect(_serial,&QSerialPort::readyRead, this, &SerialDataResolver::readHandler);
|
||||||
|
if (!_handled_by_manager)
|
||||||
|
{
|
||||||
|
_zigbee->init(_serial, _serial->baudRate());
|
||||||
|
zigbee_protocol::Protocol::getInstance()->self_addr = _zigbee->read_addr();
|
||||||
|
connect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialDataResolver::handled_by_manager()
|
||||||
|
{
|
||||||
|
return _handled_by_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::handled_by_manager(bool handled_by_manager)
|
||||||
|
{
|
||||||
|
QMutex mutex;
|
||||||
|
const QMutexLocker locker(&mutex);
|
||||||
|
_handled_by_manager = handled_by_manager;
|
||||||
|
emit handled_by_managerChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialDataResolver::recv_hex()
|
||||||
|
{
|
||||||
|
return _recv_hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::recv_hex(bool recv_hex)
|
||||||
|
{
|
||||||
|
QMutex mutex;
|
||||||
|
const QMutexLocker locker(&mutex);
|
||||||
|
_recv_hex = recv_hex;
|
||||||
|
emit recv_hexChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialDataResolver::serial_opened()
|
||||||
|
{
|
||||||
|
return _serial_opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::serial_opened(bool serial_opened)
|
||||||
|
{
|
||||||
|
QMutex mutex;
|
||||||
|
const QMutexLocker locker(&mutex);
|
||||||
|
_serial_opened = serial_opened;
|
||||||
|
emit serial_openedChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::readHandler()
|
||||||
|
{
|
||||||
|
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
|
||||||
|
if (_handled_by_manager)
|
||||||
|
{
|
||||||
|
QByteArray bdata;
|
||||||
|
if (_serial->isOpen() && _handled_by_manager)
|
||||||
|
{
|
||||||
|
while(true){
|
||||||
|
bdata += _serial->readAll();
|
||||||
|
if (!_serial->waitForReadyRead(20))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (_recv_hex)
|
||||||
|
{
|
||||||
|
emit recved(bdata.toHex(' ').toUpper());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emit recved(bdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emit recved(bdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_zigbee->loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::close()
|
||||||
|
{
|
||||||
|
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
|
||||||
|
serial_opened(false);
|
||||||
|
disconnect(_serial,&QSerialPort::aboutToClose,this,&SerialDataResolver::close);
|
||||||
|
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback);
|
||||||
|
if(_serial->isOpen())
|
||||||
|
{
|
||||||
|
_serial->clear();
|
||||||
|
_serial->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::write_data(QString data, SendType type, bool send_hex)
|
||||||
|
{
|
||||||
|
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
|
||||||
|
QByteArray bdata;
|
||||||
|
if (!_serial->isOpen())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_handled_by_manager)
|
||||||
|
{
|
||||||
|
|
||||||
|
QStringList td = data.split(' ');
|
||||||
|
for (auto item : td)
|
||||||
|
bdata += QByteArray::fromHex(item.toLatin1());
|
||||||
|
zigbee_protocol::ZigbeeFrame zf;
|
||||||
|
zf.load_package((uint8_t*)bdata.data(),bdata.length());
|
||||||
|
_zigbee->send(zf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(send_hex)
|
||||||
|
{
|
||||||
|
QStringList td = data.split(' ');
|
||||||
|
for (auto item : td)
|
||||||
|
bdata += QByteArray::fromHex(item.toLatin1());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bdata = data.toUtf8();
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case SendType::WithCarriageEnter:
|
||||||
|
bdata += "\n";
|
||||||
|
break;
|
||||||
|
case SendType::WithLineFeed:
|
||||||
|
bdata += "\r";
|
||||||
|
break;
|
||||||
|
case SendType::WithCarriageEnterAndLineFeed:
|
||||||
|
bdata += "\r\n";
|
||||||
|
break;
|
||||||
|
case SendType::Blank:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_serial->write(bdata);
|
||||||
|
_serial->flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDataResolver::zigbee_callback(zigbee_protocol::ZigbeeFrame zframe)
|
||||||
|
{
|
||||||
|
emit recved_zframe(zframe);
|
||||||
|
}
|
|
@ -1,48 +1,62 @@
|
||||||
#include "serialportmanager.h"
|
#include "serialportmanager.h"
|
||||||
#include <QSerialPortInfo>
|
#include <QSerialPortInfo>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include "zigbeeparser.h"
|
||||||
|
|
||||||
SerialPortManager::SerialPortManager(QObject *parent)
|
SerialPortManager::SerialPortManager(QObject *parent)
|
||||||
: QObject{parent}
|
: QObject{parent}
|
||||||
{
|
{
|
||||||
_zigbee = zigbee_protocol::DLLN3X::instance();
|
_resolver = SerialDataResolver::instance();
|
||||||
|
_thread = new QThread();
|
||||||
|
_resolver->moveToThread(_thread);
|
||||||
_bus = EventsBus::instance();
|
_bus = EventsBus::instance();
|
||||||
ZigBeeParser::instance(); // 让ZigBeeParser在QML引擎中实例化
|
ZigBeeParser::instance(); // 让ZigBeeParser在QML引擎中实例化
|
||||||
_event.type("serial_port");
|
_event.type("serial_port");
|
||||||
_bus->reg_event(&_event);
|
_bus->reg_event(&_event);
|
||||||
closed(true);
|
|
||||||
opened(false);
|
opened(false);
|
||||||
handledBymanager(true);
|
handledBymanager(true);
|
||||||
recv_hex(false);
|
recv_hex(false);
|
||||||
send_hex(false);
|
send_hex(false);
|
||||||
send_type(SendType::Blank);
|
send_type(SendType::Blank);
|
||||||
|
|
||||||
_serial_port_scanner.setInterval(1000);
|
|
||||||
_serial_port_scanner.start();
|
|
||||||
connect(&_serial_port_scanner, &QTimer::timeout, this, [=](){
|
connect(&_serial_port_scanner, &QTimer::timeout, this, [=](){
|
||||||
available_ports();
|
available_ports();
|
||||||
});
|
});
|
||||||
connect(this, &SerialPortManager::handledBymanagerChanged, this, [=](){
|
|
||||||
if (!_handledBymanager && _serial_port.isOpen())
|
|
||||||
{
|
|
||||||
_zigbee->init(&_serial_port, _serial_port.baudRate());
|
|
||||||
zigbee_protocol::Protocol::getInstance()->self_addr = _zigbee->read_addr();
|
|
||||||
connect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialPortManager::zigbee_callback);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialPortManager::zigbee_callback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(&_event, &Event::triggered, this, [=](QJsonObject data){
|
connect(&_event, &Event::triggered, this, [=](QJsonObject data){
|
||||||
write(data["text"].toString());
|
write(data["text"].toString());
|
||||||
});
|
});
|
||||||
|
connect(_resolver,&SerialDataResolver::recved, this, [=](const QByteArray &data){
|
||||||
|
emit recved(data);
|
||||||
|
});
|
||||||
|
connect(_resolver,&SerialDataResolver::recved_zframe, this, &SerialPortManager::zigbee_callback);
|
||||||
|
connect(this, &SerialPortManager::recv_hexChanged, this, [=](){
|
||||||
|
_resolver->recv_hex(recv_hex());
|
||||||
|
});
|
||||||
|
connect(this, &SerialPortManager::handledBymanagerChanged, this, [=](){
|
||||||
|
_resolver->handled_by_manager(handledBymanager());
|
||||||
|
});
|
||||||
|
connect(_resolver,&SerialDataResolver::serial_openedChanged, this, [=](){
|
||||||
|
opened(_resolver->serial_opened());
|
||||||
|
});
|
||||||
|
connect(this, &SerialPortManager::serial_close, _resolver, &SerialDataResolver::close);
|
||||||
|
connect(this, &SerialPortManager::serial_open, _resolver, &SerialDataResolver::open);
|
||||||
|
connect(this, &SerialPortManager::serial_write, _resolver, &SerialDataResolver::write_data);
|
||||||
|
connect(_thread, &QThread::finished, this, [=](){
|
||||||
|
_thread->deleteLater();
|
||||||
|
_resolver->deleteLater();
|
||||||
|
});
|
||||||
|
_serial_port_scanner.setInterval(1000);
|
||||||
|
_serial_port_scanner.start();
|
||||||
|
_thread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
SerialPortManager::~SerialPortManager()
|
SerialPortManager::~SerialPortManager()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
_bus->unreg_event(&_event);
|
_bus->unreg_event(&_event);
|
||||||
|
if(_thread->isRunning())
|
||||||
|
{
|
||||||
|
_thread->quit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SerialPortManager* SerialPortManager::instance(){
|
SerialPortManager* SerialPortManager::instance(){
|
||||||
|
@ -68,182 +82,29 @@ QList<QString> SerialPortManager::available_ports(){
|
||||||
return newPortStringList;
|
return newPortStringList;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SerialPortManager::open(QString port_name, QString baudrate, QString databits,
|
void SerialPortManager::open(QString port_name, QString baudrate, QString databits,
|
||||||
QString parity, QString stopbits)
|
QString parity, QString stopbits)
|
||||||
{
|
{
|
||||||
_serial_port.setPortName(port_name);
|
emit serial_open(port_name,baudrate,databits,parity,stopbits);
|
||||||
if (_serial_port.isOpen())
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_serial_port.open(QIODevice::ReadWrite))
|
|
||||||
{
|
|
||||||
_serial_port.setBaudRate(baudrate.toInt());
|
|
||||||
switch (databits.toInt())
|
|
||||||
{
|
|
||||||
case 5:
|
|
||||||
_serial_port.setDataBits( QSerialPort::Data5 ); // 设置数据位(数据位为5位)
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
_serial_port.setDataBits( QSerialPort::Data6 ); // 设置数据位(数据位为6位)
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
_serial_port.setDataBits( QSerialPort::Data7 ); // 设置数据位(数据位为7位)
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
_serial_port.setDataBits( QSerialPort::Data8 ); // 设置数据位(数据位为8位)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (parity=="NONE")
|
|
||||||
{
|
|
||||||
_serial_port.setParity( QSerialPort::NoParity ); // 设置校验位(无校验位)
|
|
||||||
}
|
|
||||||
else if (parity=="EVEN")
|
|
||||||
{
|
|
||||||
_serial_port.setParity( QSerialPort::EvenParity ); // 设置校验位(奇校验位)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_serial_port.setParity( QSerialPort::OddParity ); // 设置校验位(偶校验位)
|
|
||||||
}
|
|
||||||
if (stopbits=="1")
|
|
||||||
{
|
|
||||||
_serial_port.setStopBits( QSerialPort::OneStop ); // 设置停止位(停止位为1)
|
|
||||||
}
|
|
||||||
else if (stopbits=="1.5")
|
|
||||||
{
|
|
||||||
_serial_port.setStopBits( QSerialPort::OneAndHalfStop ); // 设置停止位(停止位为1.5)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_serial_port.setStopBits( QSerialPort::TwoStop ); // 设置停止位(停止位为2)
|
|
||||||
}
|
|
||||||
_serial_port.setFlowControl( QSerialPort::NoFlowControl ); // 设置流控制(无数据流控制)
|
|
||||||
// 当下位机中有数据发送过来时就会响应这个槽函数
|
|
||||||
connect(&_serial_port,&QSerialPort::readyRead,this,&SerialPortManager::_ready_for_read);
|
|
||||||
connect(&_serial_port,&QSerialPort::aboutToClose,this,&SerialPortManager::close);
|
|
||||||
opened(true);
|
|
||||||
closed(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialPortManager::close()
|
void SerialPortManager::close()
|
||||||
{
|
{
|
||||||
disconnect(&_serial_port,&QSerialPort::aboutToClose,this,&SerialPortManager::close);
|
emit serial_close();
|
||||||
disconnect(&_serial_port,&QSerialPort::readyRead,this,&SerialPortManager::_ready_for_read);
|
|
||||||
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialPortManager::zigbee_callback);
|
|
||||||
if(_opened)
|
|
||||||
{
|
|
||||||
_serial_port.clear();
|
|
||||||
_serial_port.close();
|
|
||||||
}
|
|
||||||
readyRead(false);
|
|
||||||
closed(true);
|
|
||||||
opened(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray SerialPortManager::read()
|
void SerialPortManager::write(QString data)
|
||||||
{
|
{
|
||||||
QByteArray bdata;
|
emit serial_write(data,static_cast<SerialDataResolver::SendType>(send_type()),send_hex());
|
||||||
if (_opened && _handledBymanager)
|
|
||||||
{
|
|
||||||
readyRead(false);
|
|
||||||
while(true){
|
|
||||||
bdata += _serial_port.readAll();
|
|
||||||
if (!_serial_port.waitForReadyRead(20))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (_recv_hex)
|
|
||||||
{
|
|
||||||
return bdata.toHex(' ').toUpper();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return bdata;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return bdata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialPortManager::_ready_for_read()
|
void SerialPortManager::zigbee_callback(zigbee_protocol::ZigbeeFrame zframe)
|
||||||
{
|
|
||||||
if (_handledBymanager)
|
|
||||||
readyRead(true);
|
|
||||||
if (!_handledBymanager)
|
|
||||||
_zigbee->loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SerialPortManager::write(QString data)
|
|
||||||
{
|
|
||||||
if (_closed)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( !_handledBymanager)
|
|
||||||
{
|
|
||||||
QByteArray bdata;
|
|
||||||
QStringList td = data.split(' ');
|
|
||||||
for (auto item : td)
|
|
||||||
bdata += QByteArray::fromHex(item.toLatin1());
|
|
||||||
|
|
||||||
zigbee_protocol::ZigbeeFrame zf;
|
|
||||||
zf.load_package((uint8_t*)bdata.data(),bdata.length());
|
|
||||||
|
|
||||||
return _zigbee->send(zf);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray bdata;
|
|
||||||
if(_send_hex)
|
|
||||||
{
|
|
||||||
QStringList td = data.split(' ');
|
|
||||||
for (auto item : td)
|
|
||||||
bdata += QByteArray::fromHex(item.toLatin1());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bdata = data.toUtf8();
|
|
||||||
switch(_send_type)
|
|
||||||
{
|
|
||||||
case SendType::WithCarriageEnter:
|
|
||||||
bdata += "\n";
|
|
||||||
break;
|
|
||||||
case SendType::WithLineFeed:
|
|
||||||
bdata += "\r";
|
|
||||||
break;
|
|
||||||
case SendType::WithCarriageEnterAndLineFeed:
|
|
||||||
bdata += "\r\n";
|
|
||||||
break;
|
|
||||||
case SendType::Blank:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bool status = _serial_port.write(bdata);
|
|
||||||
status = _serial_port.flush();
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerialPortManager::zigbee_callback(zigbee_protocol::ZigbeeFrame zframe)
|
|
||||||
{
|
{
|
||||||
QJsonObject object;
|
QJsonObject object;
|
||||||
QByteArray zf = QByteArray((char *)zframe.data(),zframe.size());
|
QByteArray zf = QByteArray((char *)zframe.data(),zframe.size());
|
||||||
QByteArray hex = zf.toHex(' ');
|
QByteArray hex = zf.toHex(' ');
|
||||||
QByteArray data = hex.toUpper();
|
QByteArray data = hex.toUpper();
|
||||||
readyRead(false);
|
|
||||||
object.insert("data_hex", QJsonValue(QString(data)));
|
object.insert("data_hex", QJsonValue(QString(data)));
|
||||||
object.insert("type","zigbee_raw_data");
|
object.insert("type","zigbee_raw_data");
|
||||||
_bus->push_data("zigbee_parser", object);
|
_bus->push_data("zigbee_parser", object);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSerialPort* SerialPortManager::get_serial()
|
|
||||||
{
|
|
||||||
if (!_handledBymanager)
|
|
||||||
return &_serial_port;
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,325 @@
|
||||||
|
#include "zigbeedataresolver.h"
|
||||||
|
#include "crypto.h"
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
ZigBeeDataResolver::ZigBeeDataResolver(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
_protocol = zigbee_protocol::Protocol::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigBeeDataResolver::~ZigBeeDataResolver()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigBeeDataResolver* ZigBeeDataResolver::instance()
|
||||||
|
{
|
||||||
|
static QMutex mutex;
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
static ZigBeeDataResolver *singleton = nullptr;
|
||||||
|
if (!singleton) {
|
||||||
|
singleton = new ZigBeeDataResolver();
|
||||||
|
}
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigBeeDataResolver::data_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
||||||
|
{
|
||||||
|
src_port_parser(zframe,is_demo);
|
||||||
|
des_port_parser(zframe, is_demo);
|
||||||
|
remote_addr_parser(zframe, is_demo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigBeeDataResolver::src_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
||||||
|
{
|
||||||
|
switch (zframe.getSrcPort()) {
|
||||||
|
case 0x81:
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigBeeDataResolver::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
||||||
|
{
|
||||||
|
if (zframe.size() <= 7)
|
||||||
|
{
|
||||||
|
qDebug()<<"ZigBee: recved package is corrupted, dropped.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void *frame = nullptr;
|
||||||
|
base_frame *bframe=nullptr;
|
||||||
|
hmac_frame *hframe=nullptr;
|
||||||
|
crypto_zdata_frame *czdata = nullptr;
|
||||||
|
data_frame *ddata = nullptr;
|
||||||
|
QByteArray zdata((char *)zframe.data(), zframe.size());
|
||||||
|
QString sender = QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper();
|
||||||
|
device temp,self;
|
||||||
|
QPair<device,device>* node = nullptr;
|
||||||
|
memset(&temp,0,sizeof(temp));
|
||||||
|
memset(&temp,0,sizeof(self));
|
||||||
|
self.addr = _protocol->self_addr;
|
||||||
|
if (!nodes.contains(((base_frame *)zframe.getData().data())->ori_addr))
|
||||||
|
{
|
||||||
|
temp.addr=((base_frame *)zframe.getData().data())->ori_addr;
|
||||||
|
temp.id = 0;
|
||||||
|
temp.online = 1;
|
||||||
|
temp.rand_num = 0;
|
||||||
|
temp.verified = 0;
|
||||||
|
nodes.insert(temp.addr,qMakePair(temp,self));
|
||||||
|
}
|
||||||
|
node = &nodes[((base_frame *)zframe.getData().data())->ori_addr];
|
||||||
|
bframe = (base_frame*)zframe.getData().data();
|
||||||
|
if (is_demo || bframe->des_addr == _protocol->self_addr && (node->first.id == 0||bframe->reset_num==0xDD||((bframe->id > node->first.id && bframe->id<=BASE_FRAME_RESET_NUM))))
|
||||||
|
{
|
||||||
|
node->first.addr = bframe->ori_addr;
|
||||||
|
node->first.id = bframe->id;
|
||||||
|
node->first.rand_num = bframe->rand_num;
|
||||||
|
frame = (void*)bframe->data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QJsonObject object;
|
||||||
|
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("note_text",QJsonValue("请注意,节点0x"+QString::number(node->first.addr,16).toUpper()+"发送的该数据包损坏"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (zframe.getDesPort()) {
|
||||||
|
case 0x81:
|
||||||
|
{
|
||||||
|
hframe = (hmac_frame*)frame;
|
||||||
|
QJsonObject object;
|
||||||
|
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("note_text",QJsonValue("收到节点0x"+ sender +"发送的验证信息"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
if (_allow_list.contains(node->first.addr))
|
||||||
|
{
|
||||||
|
u8 hmac[33]="";
|
||||||
|
QByteArray key = QByteArray::fromHex(_protocol->hmac_verify_key.toLatin1());
|
||||||
|
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(),16,&hframe->value,1,hmac);
|
||||||
|
if (_protocol->bytecmp(hframe->hmac,hmac,32))
|
||||||
|
{
|
||||||
|
new_data_frame(15) data;
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
_protocol->protocal_wrapper((data_frame *)&data, 0, 10, (u8 *)"Identified", 0);
|
||||||
|
node->first.verified = 1;
|
||||||
|
new_base_frame(15 + DATA_FRAME_PREFIX_LEN + BASE_FRAME_PREFIX_LEN) bframe;
|
||||||
|
memset(&bframe, 0, sizeof(bframe));
|
||||||
|
_protocol->base_frame_maker(&data, (base_frame *)&bframe, node->first.addr,&node->second);
|
||||||
|
zigbee_protocol::ZigbeeFrame zf(zframe.getSrcPort(),zframe.getDesPort(),zframe.getRemoteAddr(),(uint8_t *)&bframe,bframe.length);
|
||||||
|
QByteArray bdata((char *)&bframe, bframe.length);
|
||||||
|
QByteArray zdata((char *)zf.data(), zf.size());
|
||||||
|
QJsonObject object;
|
||||||
|
object.insert("baseframe_data",QJsonValue(QString(bdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("note_text",QJsonValue("向0x"+QString::number(node->first.addr,16).toUpper()+"节点发送验证通过回复信息"));
|
||||||
|
object.insert("recieved", false);
|
||||||
|
object.insert("sender", QString::number(_protocol->self_addr,16).toUpper());
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
if(!is_demo)
|
||||||
|
emit data_send("serial_port",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8 hmac[33]="";
|
||||||
|
QJsonObject object;
|
||||||
|
QByteArray latest_key = QByteArray::fromHex(_protocol->hmac_verify_key.toLatin1());
|
||||||
|
for (auto key_str : _protocol->pre_hmac_verify_key)
|
||||||
|
{
|
||||||
|
QByteArray key = QByteArray::fromHex(key_str.toLatin1());
|
||||||
|
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(),16,&hframe->value,1,hmac);
|
||||||
|
if (_protocol->bytecmp(hframe->hmac,hmac,32))
|
||||||
|
{
|
||||||
|
zigbee_protocol::ZigbeeFrame zf(0x82,0x82,node->first.addr);
|
||||||
|
new_crypto_zdata_frame(32) zdata;
|
||||||
|
memset(&zdata, 0, sizeof(zdata));
|
||||||
|
_protocol->zigbee_data_encrypt((u8*)latest_key.data(), 16, (crypto_zdata_frame *)&zdata, Crypto::SM4_encrypt, key_str);
|
||||||
|
new_base_frame(sizeof(zdata) + BASE_FRAME_PREFIX_LEN) bframe;
|
||||||
|
memset(&bframe, 0, sizeof(bframe));
|
||||||
|
_protocol->base_frame_maker(&zdata, (base_frame *)&bframe, node->first.addr, &node->second);
|
||||||
|
zf.setData((u8 *)&bframe, bframe.length);
|
||||||
|
QByteArray bdata((char *)&bframe, bframe.length);
|
||||||
|
QByteArray zfdata((char *)zf.data(), zf.size());
|
||||||
|
object.insert("baseframe_data",QJsonValue(QString(bdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("text",QJsonValue(QString(zfdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("note_text",QJsonValue("节点0x"+QString::number(node->first.addr,16).toUpper()+"正在使用旧密钥,发送密钥更新指令"));
|
||||||
|
object.insert("recieved", false);
|
||||||
|
object.insert("sender", QString::number(_protocol->self_addr,16).toUpper());
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
if(!is_demo)
|
||||||
|
emit data_send("serial_port",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object.insert("note_text",QJsonValue("节点0x"+QString::number(node->first.addr,16).toUpper()+"验证不通过,请考虑移出认证列表"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(_deny_list.contains(node->first.addr))
|
||||||
|
{
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("text","");
|
||||||
|
object.insert("note_text",QJsonValue("节点0x"+QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper()+"被禁止接入"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!_wait_queue.contains(node->first.addr))
|
||||||
|
{
|
||||||
|
_wait_queue.append(node->first.addr);
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("text","");
|
||||||
|
object.insert("note_text",QJsonValue("节点0x"+QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper()+"进入等待队列"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("text","");
|
||||||
|
object.insert("note_text",QJsonValue("节点0x"+QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper()+"已在等待队列"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("type","zigbee_identify_data");
|
||||||
|
emit data_send("zigbee_identify_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x82:
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
case 0x83:
|
||||||
|
{
|
||||||
|
QJsonObject object;
|
||||||
|
if (node->first.verified)
|
||||||
|
{
|
||||||
|
zigbee_protocol::ZigbeeFrame dzf = zframe;
|
||||||
|
new_data_frame(72) ndata;
|
||||||
|
uint8_t data_len = 0;
|
||||||
|
memset(&ndata,0,sizeof(ndata));
|
||||||
|
if (*(u16 *)frame == CRYPTO_ZDATA_FRAME_HEAD)
|
||||||
|
{
|
||||||
|
czdata = (crypto_zdata_frame*)frame;
|
||||||
|
_protocol->zigbee_data_dectypt((uint8_t*)&ndata, &data_len, czdata, Crypto::SM4_decrypt);
|
||||||
|
dzf.setData((char*)&ndata,ndata.data_length + DATA_FRAME_PREFIX_LEN);
|
||||||
|
zdata = QByteArray((char *)dzf.data(), dzf.size());
|
||||||
|
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||||
|
}
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("note_text",QJsonValue("收到节点0x"+sender+"发送的数据"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("type","zigbee_recv_data");
|
||||||
|
if (QRandomGenerator::global()->bounded(2)!=0 && is_demo)
|
||||||
|
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||||
|
emit data_send("zigbee_recv_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
object.insert("sender", sender);
|
||||||
|
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("note_text",QJsonValue("收到节点0x"+sender+"发送的数据,但节点并未认证"));
|
||||||
|
object.insert("recieved", true);
|
||||||
|
object.insert("type","zigbee_recv_data");
|
||||||
|
emit data_send("zigbee_recv_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
node->second.id=0;
|
||||||
|
new_data_frame(5) dframe;
|
||||||
|
memset(&dframe,0,sizeof (dframe));
|
||||||
|
_protocol->protocal_wrapper((data_frame *)&dframe, 0, 5, (u8 *)"RESET", false);
|
||||||
|
new_base_frame(5 + DATA_FRAME_PREFIX_LEN + BASE_FRAME_PREFIX_LEN) bframe;
|
||||||
|
memset(&bframe, 0, sizeof(bframe));
|
||||||
|
_protocol->base_frame_maker(&dframe, (base_frame *)&bframe, node->first.addr,&node->second);
|
||||||
|
zigbee_protocol::ZigbeeFrame zf(0x83,0x83,node->first.addr,(char *)&bframe,bframe.length);
|
||||||
|
QByteArray zfdata((char *)zf.data(),zf.size());
|
||||||
|
QJsonObject object;
|
||||||
|
object.insert("sender", QString::number(_protocol->self_addr,16).toUpper());
|
||||||
|
object.insert("text",QJsonValue(QString(zfdata.toHex(' ').toUpper())));
|
||||||
|
object.insert("note_text",QJsonValue("向节点0x"+sender+"发送重置命令"));
|
||||||
|
object.insert("recieved", false);
|
||||||
|
object.insert("type","zigbee_recv_data");
|
||||||
|
emit data_send("zigbee_recv_data_view",object,_allow_list,_deny_list,_wait_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigBeeDataResolver::remote_addr_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
||||||
|
{
|
||||||
|
switch (zframe.getRemoteAddr()) {
|
||||||
|
case 0xAAAA:
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigBeeDataResolver::message_parser(QJsonObject message, QString self_addr, QList<uint16_t> allow_list, QList<uint16_t> deny_list, QList<uint16_t> wait_queue)
|
||||||
|
{
|
||||||
|
_self_addr = self_addr;
|
||||||
|
_allow_list = allow_list;
|
||||||
|
_deny_list = deny_list;
|
||||||
|
_wait_queue = wait_queue;
|
||||||
|
if (message["type"] == "demo_verify_request")
|
||||||
|
{
|
||||||
|
hmac_frame frame;
|
||||||
|
frame.value = QRandomGenerator::global()->bounded(256);
|
||||||
|
frame.head = HMAC_FRAME_HEAD;
|
||||||
|
frame.length = 32 + HMAC_FRAME_PREFIX_LEN;
|
||||||
|
QByteArray key = QByteArray::fromHex(_protocol->hmac_verify_key.toLatin1());
|
||||||
|
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(), 16, &frame.value, 1, frame.hmac);
|
||||||
|
new_base_frame(50 + BASE_FRAME_PREFIX_LEN) bframe;
|
||||||
|
device test;
|
||||||
|
test.addr = 0x5656;
|
||||||
|
_protocol->base_frame_maker(&frame, (base_frame *)&bframe, _protocol->self_addr, &test);
|
||||||
|
zigbee_protocol::ZigbeeFrame zf(0x81,0x81,0x5656,(char*)&bframe,bframe.length);
|
||||||
|
data_parser(zf, true);
|
||||||
|
}
|
||||||
|
if (message["type"] == "demo_verify_key_update")
|
||||||
|
{
|
||||||
|
hmac_frame frame;
|
||||||
|
frame.value = QRandomGenerator::global()->bounded(256);
|
||||||
|
frame.head = HMAC_FRAME_HEAD;
|
||||||
|
frame.length = 32 + HMAC_FRAME_PREFIX_LEN;
|
||||||
|
QByteArray key = QByteArray::fromHex(_protocol->pre_hmac_verify_key[QRandomGenerator::global()->bounded(_protocol->pre_hmac_verify_key.length())].toLatin1());
|
||||||
|
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(), 16, &frame.value, 1, frame.hmac);
|
||||||
|
new_base_frame(50 + BASE_FRAME_PREFIX_LEN) bframe;
|
||||||
|
device test;
|
||||||
|
test.addr = 0x5656;
|
||||||
|
_protocol->base_frame_maker(&frame, (base_frame *)&bframe, _protocol->self_addr, &test);
|
||||||
|
zigbee_protocol::ZigbeeFrame zf(0x81,0x81,0x5656,(char*)&bframe,bframe.length);
|
||||||
|
data_parser(zf, true);
|
||||||
|
}
|
||||||
|
if (message["type"] == "demo_recv_data" || message["type"] == "zigbee_raw_data")
|
||||||
|
{
|
||||||
|
QString data = message["data_hex"].toString();
|
||||||
|
QByteArray bdata;
|
||||||
|
QStringList td = data.split(' ');
|
||||||
|
for (auto item : td)
|
||||||
|
bdata += QByteArray::fromHex(item.toLatin1());
|
||||||
|
zigbee_protocol::ZigbeeFrame zf;
|
||||||
|
zf.load_package((uint8_t*)bdata.data(),bdata.length());
|
||||||
|
data_parser(zf, message["type"] == "demo_recv_data");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,23 +1,38 @@
|
||||||
#include "zigbeeparser.h"
|
#include "zigbeeparser.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QThread>
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
|
|
||||||
ZigBeeParser::ZigBeeParser(QObject *parent)
|
ZigBeeParser::ZigBeeParser(QObject *parent)
|
||||||
: QObject{parent}
|
: QObject{parent}
|
||||||
{
|
{
|
||||||
_config = Config::instance();
|
|
||||||
_protocol = zigbee_protocol::Protocol::getInstance();
|
_protocol = zigbee_protocol::Protocol::getInstance();
|
||||||
|
_thread = new QThread();
|
||||||
|
_resolver = ZigBeeDataResolver::instance();
|
||||||
|
_resolver->moveToThread(_thread);
|
||||||
|
_config = Config::instance();
|
||||||
_bus = EventsBus::instance();
|
_bus = EventsBus::instance();
|
||||||
_event.type("zigbee_parser");
|
_event.type("zigbee_parser");
|
||||||
_bus->reg_event(&_event);
|
_bus->reg_event(&_event);
|
||||||
connect(&_event,&Event::triggered,this,&ZigBeeParser::message_parser);
|
connect(&_event,&Event::triggered,this,&ZigBeeParser::message_parser);
|
||||||
|
connect(this, &ZigBeeParser::message_recved, _resolver, &ZigBeeDataResolver::message_parser);
|
||||||
|
connect(_resolver, &ZigBeeDataResolver::data_send, this, &ZigBeeParser::bus_data_send);
|
||||||
|
connect(_thread, &QThread::finished, this, [=](){
|
||||||
|
_thread->deleteLater();
|
||||||
|
_resolver->deleteLater();
|
||||||
|
});
|
||||||
|
_thread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigBeeParser::~ZigBeeParser()
|
ZigBeeParser::~ZigBeeParser()
|
||||||
{
|
{
|
||||||
_bus->unreg_event(&_event);
|
_bus->unreg_event(&_event);
|
||||||
disconnect(&_event,&Event::triggered,this,&ZigBeeParser::message_parser);
|
disconnect(&_event,&Event::triggered,this,&ZigBeeParser::message_parser);
|
||||||
|
if(_thread->isRunning())
|
||||||
|
{
|
||||||
|
_thread->quit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigBeeParser* ZigBeeParser::instance()
|
ZigBeeParser* ZigBeeParser::instance()
|
||||||
|
@ -32,296 +47,15 @@ ZigBeeParser* ZigBeeParser::instance()
|
||||||
return singleton;
|
return singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigBeeParser::data_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
|
||||||
{
|
|
||||||
src_port_parser(zframe,is_demo);
|
|
||||||
des_port_parser(zframe, is_demo);
|
|
||||||
remote_addr_parser(zframe, is_demo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigBeeParser::src_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
|
||||||
{
|
|
||||||
switch (zframe.getSrcPort()) {
|
|
||||||
case 0x81:
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigBeeParser::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
|
||||||
{
|
|
||||||
if (zframe.size() <= 7)
|
|
||||||
{
|
|
||||||
qDebug()<<"ZigBee: recved package is corrupted, dropped.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void *frame = nullptr;
|
|
||||||
base_frame *bframe=nullptr;
|
|
||||||
hmac_frame *hframe=nullptr;
|
|
||||||
crypto_zdata_frame *czdata = nullptr;
|
|
||||||
data_frame *ddata = nullptr;
|
|
||||||
QByteArray zdata((char *)zframe.data(), zframe.size());
|
|
||||||
QString sender = QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper();
|
|
||||||
device temp,self;
|
|
||||||
QPair<device,device>* node = nullptr;
|
|
||||||
memset(&temp,0,sizeof(temp));
|
|
||||||
memset(&temp,0,sizeof(self));
|
|
||||||
self.addr = _protocol->self_addr;
|
|
||||||
if (!nodes.contains(((base_frame *)zframe.getData().data())->ori_addr))
|
|
||||||
{
|
|
||||||
temp.addr=((base_frame *)zframe.getData().data())->ori_addr;
|
|
||||||
temp.id = 0;
|
|
||||||
temp.online = 1;
|
|
||||||
temp.rand_num = 0;
|
|
||||||
temp.verified = 0;
|
|
||||||
nodes.insert(temp.addr,qMakePair(temp,self));
|
|
||||||
}
|
|
||||||
node = &nodes[((base_frame *)zframe.getData().data())->ori_addr];
|
|
||||||
bframe = (base_frame*)zframe.getData().data();
|
|
||||||
if (is_demo || bframe->des_addr == _protocol->self_addr && (node->first.id == 0||bframe->reset_num==0xDD||((bframe->id > node->first.id && bframe->id<=BASE_FRAME_RESET_NUM))))
|
|
||||||
{
|
|
||||||
node->first.addr = bframe->ori_addr;
|
|
||||||
node->first.id = bframe->id;
|
|
||||||
node->first.rand_num = bframe->rand_num;
|
|
||||||
frame = (void*)bframe->data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QJsonObject object;
|
|
||||||
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("note_text",QJsonValue("请注意,节点0x"+QString::number(node->first.addr,16).toUpper()+"发送的该数据包损坏"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (zframe.getDesPort()) {
|
|
||||||
case 0x81:
|
|
||||||
{
|
|
||||||
hframe = (hmac_frame*)frame;
|
|
||||||
QJsonObject object;
|
|
||||||
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("note_text",QJsonValue("收到节点0x"+ sender +"发送的验证信息"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
if (_allow_list.contains(node->first.addr))
|
|
||||||
{
|
|
||||||
u8 hmac[33]="";
|
|
||||||
QByteArray key = QByteArray::fromHex(_protocol->hmac_verify_key.toLatin1());
|
|
||||||
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(),16,&hframe->value,1,hmac);
|
|
||||||
if (_protocol->bytecmp(hframe->hmac,hmac,32))
|
|
||||||
{
|
|
||||||
new_data_frame(15) data;
|
|
||||||
memset(&data, 0, sizeof(data));
|
|
||||||
_protocol->protocal_wrapper((data_frame *)&data, 0, 10, (u8 *)"Identified", 0);
|
|
||||||
node->first.verified = 1;
|
|
||||||
new_base_frame(15 + DATA_FRAME_PREFIX_LEN + BASE_FRAME_PREFIX_LEN) bframe;
|
|
||||||
memset(&bframe, 0, sizeof(bframe));
|
|
||||||
_protocol->base_frame_maker(&data, (base_frame *)&bframe, node->first.addr,&node->second);
|
|
||||||
zigbee_protocol::ZigbeeFrame zf(zframe.getSrcPort(),zframe.getDesPort(),zframe.getRemoteAddr(),(uint8_t *)&bframe,bframe.length);
|
|
||||||
QByteArray bdata((char *)&bframe, bframe.length);
|
|
||||||
QByteArray zdata((char *)zf.data(), zf.size());
|
|
||||||
QJsonObject object;
|
|
||||||
object.insert("baseframe_data",QJsonValue(QString(bdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("note_text",QJsonValue("向0x"+QString::number(node->first.addr,16).toUpper()+"节点发送验证通过回复信息"));
|
|
||||||
object.insert("recieved", false);
|
|
||||||
object.insert("sender", QString::number(_protocol->self_addr,16).toUpper());
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
if(!is_demo)
|
|
||||||
_bus->push_data("serial_port",object);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u8 hmac[33]="";
|
|
||||||
QJsonObject object;
|
|
||||||
QByteArray latest_key = QByteArray::fromHex(_protocol->hmac_verify_key.toLatin1());
|
|
||||||
for (auto key_str : _protocol->pre_hmac_verify_key)
|
|
||||||
{
|
|
||||||
QByteArray key = QByteArray::fromHex(key_str.toLatin1());
|
|
||||||
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(),16,&hframe->value,1,hmac);
|
|
||||||
if (_protocol->bytecmp(hframe->hmac,hmac,32))
|
|
||||||
{
|
|
||||||
zigbee_protocol::ZigbeeFrame zf(0x82,0x82,node->first.addr);
|
|
||||||
new_crypto_zdata_frame(32) zdata;
|
|
||||||
memset(&zdata, 0, sizeof(zdata));
|
|
||||||
_protocol->zigbee_data_encrypt((u8*)latest_key.data(), 16, (crypto_zdata_frame *)&zdata, Crypto::SM4_encrypt, key_str);
|
|
||||||
new_base_frame(sizeof(zdata) + BASE_FRAME_PREFIX_LEN) bframe;
|
|
||||||
memset(&bframe, 0, sizeof(bframe));
|
|
||||||
_protocol->base_frame_maker(&zdata, (base_frame *)&bframe, node->first.addr, &node->second);
|
|
||||||
zf.setData((u8 *)&bframe, bframe.length);
|
|
||||||
QByteArray bdata((char *)&bframe, bframe.length);
|
|
||||||
QByteArray zfdata((char *)zf.data(), zf.size());
|
|
||||||
object.insert("baseframe_data",QJsonValue(QString(bdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("text",QJsonValue(QString(zfdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("note_text",QJsonValue("节点0x"+QString::number(node->first.addr,16).toUpper()+"正在使用旧密钥,发送密钥更新指令"));
|
|
||||||
object.insert("recieved", false);
|
|
||||||
object.insert("sender", QString::number(_protocol->self_addr,16).toUpper());
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
if(!is_demo)
|
|
||||||
_bus->push_data("serial_port",object);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
object.insert("note_text",QJsonValue("节点0x"+QString::number(node->first.addr,16).toUpper()+"验证不通过,请考虑移出认证列表"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(_deny_list.contains(node->first.addr))
|
|
||||||
{
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("text","");
|
|
||||||
object.insert("note_text",QJsonValue("节点0x"+QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper()+"被禁止接入"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!_wait_queue.contains(node->first.addr))
|
|
||||||
{
|
|
||||||
_wait_queue.append(node->first.addr);
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("text","");
|
|
||||||
object.insert("note_text",QJsonValue("节点0x"+QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper()+"进入等待队列"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("text","");
|
|
||||||
object.insert("note_text",QJsonValue("节点0x"+QString::number(((base_frame *)zframe.getData().data())->ori_addr,16).toUpper()+"已在等待队列"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("type","zigbee_identify_data");
|
|
||||||
_bus->push_data("zigbee_identify_data_view",object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x82:
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
case 0x83:
|
|
||||||
{
|
|
||||||
QJsonObject object;
|
|
||||||
if (node->first.verified)
|
|
||||||
{
|
|
||||||
zigbee_protocol::ZigbeeFrame dzf = zframe;
|
|
||||||
new_data_frame(72) ndata;
|
|
||||||
uint8_t data_len = 0;
|
|
||||||
memset(&ndata,0,sizeof(ndata));
|
|
||||||
if (*(u16 *)frame == CRYPTO_ZDATA_FRAME_HEAD)
|
|
||||||
{
|
|
||||||
czdata = (crypto_zdata_frame*)frame;
|
|
||||||
_protocol->zigbee_data_dectypt((uint8_t*)&ndata, &data_len, czdata, Crypto::SM4_decrypt);
|
|
||||||
dzf.setData((char*)&ndata,ndata.data_length + DATA_FRAME_PREFIX_LEN);
|
|
||||||
zdata = QByteArray((char *)dzf.data(), dzf.size());
|
|
||||||
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
|
||||||
}
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("note_text",QJsonValue("收到节点0x"+sender+"发送的数据"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("type","zigbee_recv_data");
|
|
||||||
if (QRandomGenerator::global()->bounded(2)!=0 && is_demo)
|
|
||||||
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
|
||||||
_bus->push_data("zigbee_recv_data_view",object);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
object.insert("sender", sender);
|
|
||||||
object.insert("text",QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("note_text",QJsonValue("收到节点0x"+sender+"发送的数据,但节点并未认证"));
|
|
||||||
object.insert("recieved", true);
|
|
||||||
object.insert("type","zigbee_recv_data");
|
|
||||||
_bus->push_data("zigbee_recv_data_view",object);
|
|
||||||
node->second.id=0;
|
|
||||||
new_data_frame(5) dframe;
|
|
||||||
memset(&dframe,0,sizeof (dframe));
|
|
||||||
_protocol->protocal_wrapper((data_frame *)&dframe, 0, 5, (u8 *)"RESET", false);
|
|
||||||
new_base_frame(5 + DATA_FRAME_PREFIX_LEN + BASE_FRAME_PREFIX_LEN) bframe;
|
|
||||||
memset(&bframe, 0, sizeof(bframe));
|
|
||||||
_protocol->base_frame_maker(&dframe, (base_frame *)&bframe, node->first.addr,&node->second);
|
|
||||||
zigbee_protocol::ZigbeeFrame zf(0x83,0x83,node->first.addr,(char *)&bframe,bframe.length);
|
|
||||||
QByteArray zfdata((char *)zf.data(),zf.size());
|
|
||||||
QJsonObject object;
|
|
||||||
object.insert("sender", QString::number(_protocol->self_addr,16).toUpper());
|
|
||||||
object.insert("text",QJsonValue(QString(zfdata.toHex(' ').toUpper())));
|
|
||||||
object.insert("note_text",QJsonValue("向节点0x"+sender+"发送重置命令"));
|
|
||||||
object.insert("recieved", false);
|
|
||||||
object.insert("type","zigbee_recv_data");
|
|
||||||
_bus->push_data("zigbee_recv_data_view",object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigBeeParser::remote_addr_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo)
|
|
||||||
{
|
|
||||||
switch (zframe.getRemoteAddr()) {
|
|
||||||
case 0xAAAA:
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZigBeeParser::message_parser(QJsonObject message)
|
void ZigBeeParser::message_parser(QJsonObject message)
|
||||||
{
|
{
|
||||||
if (message["type"] == "demo_verify_request")
|
emit message_recved(message, _self_addr, _allow_list, _deny_list, _wait_queue);
|
||||||
{
|
}
|
||||||
hmac_frame frame;
|
|
||||||
frame.value = QRandomGenerator::global()->bounded(256);
|
void ZigBeeParser::bus_data_send(QString type, QJsonObject data, QList<uint16_t> allow_list, QList<uint16_t> deny_list, QList<uint16_t> wait_queue)
|
||||||
frame.head = HMAC_FRAME_HEAD;
|
{
|
||||||
frame.length = 32 + HMAC_FRAME_PREFIX_LEN;
|
_bus->push_data(type, data);
|
||||||
QByteArray key = QByteArray::fromHex(_protocol->hmac_verify_key.toLatin1());
|
_allow_list = allow_list;
|
||||||
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(), 16, &frame.value, 1, frame.hmac);
|
_deny_list = deny_list;
|
||||||
new_base_frame(50 + BASE_FRAME_PREFIX_LEN) bframe;
|
_wait_queue = wait_queue;
|
||||||
device test;
|
|
||||||
test.addr = 0x5656;
|
|
||||||
_protocol->base_frame_maker(&frame, (base_frame *)&bframe, _protocol->self_addr, &test);
|
|
||||||
zigbee_protocol::ZigbeeFrame zf(0x81,0x81,0x5656,(char*)&bframe,bframe.length);
|
|
||||||
data_parser(zf, true);
|
|
||||||
}
|
|
||||||
if (message["type"] == "demo_verify_key_update")
|
|
||||||
{
|
|
||||||
hmac_frame frame;
|
|
||||||
frame.value = QRandomGenerator::global()->bounded(256);
|
|
||||||
frame.head = HMAC_FRAME_HEAD;
|
|
||||||
frame.length = 32 + HMAC_FRAME_PREFIX_LEN;
|
|
||||||
QByteArray key = QByteArray::fromHex(_protocol->pre_hmac_verify_key[QRandomGenerator::global()->bounded(_protocol->pre_hmac_verify_key.length())].toLatin1());
|
|
||||||
Crypto::getInstance()->SM3_HMAC((u8 *)key.data(), 16, &frame.value, 1, frame.hmac);
|
|
||||||
new_base_frame(50 + BASE_FRAME_PREFIX_LEN) bframe;
|
|
||||||
device test;
|
|
||||||
test.addr = 0x5656;
|
|
||||||
_protocol->base_frame_maker(&frame, (base_frame *)&bframe, _protocol->self_addr, &test);
|
|
||||||
zigbee_protocol::ZigbeeFrame zf(0x81,0x81,0x5656,(char*)&bframe,bframe.length);
|
|
||||||
data_parser(zf, true);
|
|
||||||
}
|
|
||||||
if (message["type"] == "demo_recv_data" || message["type"] == "zigbee_raw_data")
|
|
||||||
{
|
|
||||||
QString data = message["data_hex"].toString();
|
|
||||||
QByteArray bdata;
|
|
||||||
QStringList td = data.split(' ');
|
|
||||||
for (auto item : td)
|
|
||||||
bdata += QByteArray::fromHex(item.toLatin1());
|
|
||||||
zigbee_protocol::ZigbeeFrame zf;
|
|
||||||
zf.load_package((uint8_t*)bdata.data(),bdata.length());
|
|
||||||
data_parser(zf, message["type"] == "demo_recv_data");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue