Project: Update and bug fix.

1. Optimize static build.
2. Fix Config couldn't be used in QML.
3. Fix RibbonMessageListView's slide lag bug.
4. Add FrameChooser to let user customize DataFrame.
5. Fix EventHistoryList display bug.
6. Add Slider for ListTable.
This commit is contained in:
Mentalflow 2024-03-11 00:21:37 +08:00
parent cc08435a3a
commit 93c11e7ecf
Signed by: Mentalflow
GPG Key ID: 5AE68D4401A2EE71
19 changed files with 586 additions and 115 deletions

2
3rdparty/RibbonUI vendored

@ -1 +1 @@
Subproject commit 43240eab1f351a90afdc843119743b0aca4d311c
Subproject commit 18edf9f0fdf0f11663d328a8166486226246e656

View File

@ -2,13 +2,23 @@ cmake_minimum_required(VERSION 3.21)
project(ProtocolParser VERSION ${CMAKE_PROJECT_VERSION} LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
qt_standard_project_setup()
qt_policy(SET QTP0001 NEW)
else()
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
endif()
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
set(QML_IMPORT_PATH ${CMAKE_BINARY_DIR}/app_source CACHE STRING "Qt Creator extra QML import paths" FORCE)
set(PROJECT_COMPANY "Mentalflow's Lab")
set(PROJECT_COPYRIGHT "Copyright (c) 2023 Mentalflow's Lab. All rights reserved.")
set(PROJECT_DOMAIN "dev.ourdocs.cn.protocolparser")
@ -36,7 +46,7 @@ set(
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
qml/components/EventsHistoryList.qml qml/components/FrameChooser.qml
)
INCLUDE_DIRECTORIES(dlln3x include)

View File

@ -9,17 +9,18 @@ class Config : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_NAMED_ELEMENT(Config)
public:
static Config* instance();
static Config* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
Q_INVOKABLE void Set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
Q_INVOKABLE void SetArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
Q_INVOKABLE QVariant Get(QString qstrnodename,QString qstrkeyname);
Q_INVOKABLE QVariant GetArray(QString qstrnodename,QString qstrkeyname);
Q_INVOKABLE void set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
Q_INVOKABLE void setArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
Q_INVOKABLE QVariant get(QString qstrnodename,QString qstrkeyname);
Q_INVOKABLE QVariant getArray(QString qstrnodename,QString qstrkeyname);
void Clear();
private:
Config(QString qstrfilename = "");
explicit Config(QString qstrfilename = "");
~Config(void);
Q_DISABLE_COPY_MOVE(Config)
QString m_qstrFileName;

View File

@ -24,6 +24,7 @@ private:
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);
QString sensor_data_reader(void **data,QString type);
zigbee_protocol::Protocol* _protocol = nullptr;
QString _self_addr;
QMap<uint16_t, QPair<device,device>> nodes;

View File

@ -33,9 +33,9 @@ public:
QList<uint16_t> wait_queue(){if(!_resolver)_resolver=ZigBeeDataResolver::instance();return _resolver->get_wait_queue();};
void setWait_queue(QList<uint16_t> wait_queue){if(!_resolver)_resolver=ZigBeeDataResolver::instance();QList<uint16_t> &a=_resolver->get_wait_queue();a=wait_queue;emit wait_queueChanged();};
QString hmac_verify_key(){ return _protocol->hmac_verify_key;};
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;};
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();};
static ZigBeeParser* instance();
static ZigBeeParser* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
void message_parser(QJsonObject message);

View File

@ -10,7 +10,9 @@ import "components"
RibbonWindow {
id:root
width: 1200
minimumWidth: 1200
height: 800
minimumHeight: 800
title: qsTr("Protocol Parser") + ` V${PPAPP_Version}`
TabBar{

View File

@ -7,7 +7,7 @@ import ProtocolParser
Item {
id:obj
property var header_items: ["序号","事件"]
property var header_items_width: [100,400]
property var header_items_width: [100,700]
property var data_source: []
implicitHeight: list_layout.height
implicitWidth: list_layout.width
@ -21,7 +21,7 @@ Item {
var data = []
for (var i = 0; i < EventsBus.event_history.length; i++)
{
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history)})
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history[i])})
}
data_source = data
}
@ -32,7 +32,7 @@ Item {
var data = []
for (var i = 0; i < EventsBus.event_history.length; i++)
{
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history)})
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history[i])})
}
data_source = data
}

View File

@ -0,0 +1,373 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import RibbonUI
import ProtocolParser
Item {
clip: true
id: root
implicitWidth: layout.width + margins*2
implicitHeight: layout.height + margins*2
property double margins: 30
property int object_width: 30
ListModel{
id: frame_model
ListElement{
name:"温度"
type:"float"
}
ListElement{
name:"湿度"
type:"float"
}
ListElement{
name:"气体浓度"
type:"float"
}
ListElement{
name:"火焰指数"
type:"float"
}
}
Component.onCompleted: {
let result = Config.getArray('Protocol', 'data_frame_name')
if (result)
{
frame_model.clear()
var name_array=[],type_array=[]
name_array = Config.getArray('Protocol', 'data_frame_name')
type_array = Config.getArray('Protocol', 'data_frame_type')
for (var i=0;i<name_array.length;i++)
{
frame_model.append({
name:name_array[i],
type:type_array[i]
})
}
}
else
{
let name_array=[],type_array=[]
for (let i=0;i<frame_model.count;i++)
{
name_array[i] = frame_model.get(i).name
type_array[i] = frame_model.get(i).type
}
Config.setArray('Protocol', 'data_frame_name', name_array)
Config.setArray('Protocol', 'data_frame_type', type_array)
}
}
RibbonButton{
anchors{
top:parent.top
margins: 4
right:parent.right
}
show_bg: false
show_hovered_bg: false
icon_source: RibbonIcons.Dismiss
onClicked: window_popup.close()
}
ColumnLayout{
id:layout
anchors{
top:parent.top
horizontalCenter: parent.horizontalCenter
margins: margins
}
RibbonText{
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
width: implicitWidth > parent.width ? parent.width : implicitWidth
text: qsTr("自定义传感器数据结构")
font.pixelSize: 20
wrapMode: RibbonText.WordWrap
view_only: true
}
RibbonText{
Layout.topMargin: margins/2
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
width: implicitWidth > parent.width ? parent.width : implicitWidth
text: qsTr("传感器数据帧结构组成:")
wrapMode: RibbonText.WordWrap
view_only: true
}
Rectangle{
id: frame_bg
radius: 5
Layout.preferredHeight: object_width + frame.anchors.leftMargin*2
Layout.preferredWidth: object_width * 16 + frame.anchors.leftMargin*2
color: RibbonTheme.dark_mode ? '#2A2C31' : '#F2F4F7'
ListView{
id: frame
property int current_size: 0
property bool is_full: current_size === 16
property int has_selected: 0
clip: true
model: frame_model
orientation: ListView.Horizontal
implicitHeight: object_width
implicitWidth: contentWidth
anchors{
leftMargin: 2
left: parent.left
verticalCenter: parent.verticalCenter
}
delegate:RibbonRectangle{
id: bg
topLeftRadius: index === 0 ? 5 : 0
bottomLeftRadius: topLeftRadius
topRightRadius: frame.current_size === 16 && (index + 1) === frame.count ? 5 : 0
bottomRightRadius: topRightRadius
implicitHeight: object_width
implicitWidth: object_width
color: bg.selected || mouse.containsMouse ? "#506BBD" : RibbonTheme.dark_mode ? '#3A4045' : "white"
property bool selected: false
property bool is_focused: frame.currentIndex === index
onIs_focusedChanged: {
if (!is_focused && selected)
bg.selected = !bg.selected
}
onSelectedChanged: frame.has_selected += bg.selected ? 1 : -1
property string type: model.type
property int data_size
onTypeChanged: {
data_size = cal_size(model.type)
implicitWidth = object_width * data_size
}
RibbonText{
anchors.centerIn: parent
width: implicitWidth > parent.width ? parent.width : implicitWidth
text: model.name
wrapMode: RibbonText.WordWrap
view_only: true
color:{
if(!RibbonTheme.dark_mode)
{
if(mouse.containsMouse&&!bg.selected)
return 'black'
else if(mouse.containsMouse&&bg.selected)
return 'white'
else if(!mouse.containsMouse&&bg.selected)
return 'black'
else
return 'black'
}
else
{
if(mouse.containsMouse&&!bg.selected)
return 'white'
else if(mouse.containsMouse&&bg.selected)
return 'black'
else if(!mouse.containsMouse&&bg.selected)
return 'white'
else
return 'white'
}
}
}
Rectangle{
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
width: 1
height: parent.height - frame.anchors.leftMargin * 2
visible: index + 1 !== frame.count
color: RibbonTheme.dark_mode ? "#525252" : "#D4D4D4"
Behavior on color {
ColorAnimation {
duration: 60
easing.type: Easing.OutSine
}
}
}
RibbonToolTip{
text: qsTr(`${bg.type}, ${bg.data_size}B`)
visible: text && mouse.containsMouse
}
MouseArea{
id: mouse
anchors.fill: parent
hoverEnabled: true
onClicked:
{
frame.currentIndex = index
bg.selected = !bg.selected
}
}
ListView.onRemove: cal_size(type,true)
function cal_size(type,is_remove)
{
let size = frame.judge_size(type);
if(!is_remove)
frame.current_size += size
else
frame.current_size -= size
return size
}
}
function judge_size(type)
{
let size = 0
switch(type)
{
case "float":
size = 4
break
case "double":
size = 8
break
case "int64_t":
size = 8
break
case "int32_t":
size = 4
break
case "int16_t":
size = 2
break
case "int8_t":
size = 1
break
case "uint64_t":
size = 8
break
case "uint32_t":
size = 4
break
case "uint16_t":
size = 2
break
case "uint8_t":
size = 1
break
}
return size
}
}
}
RowLayout{
Layout.preferredWidth: parent.width
Layout.topMargin: margins/2
Layout.alignment: Qt.AlignHCenter
spacing: margins/3
RibbonText{
text: qsTr("类型:")
view_only: true
}
RibbonComboBox{
id: type_combo
Layout.preferredWidth: 100
model: ListModel {
ListElement { text: "float" }
ListElement { text: "double" }
ListElement { text: "int64_t" }
ListElement { text: "int32_t" }
ListElement { text: "int16_t" }
ListElement { text: "int8_t" }
ListElement { text: "uint64_t" }
ListElement { text: "uint32_t" }
ListElement { text: "uint16_t" }
ListElement { text: "uint8_t" }
}
enabled: frame.current_size !==16
}
RibbonText{
text: qsTr("名称:")
view_only: true
}
RibbonLineEdit{
id: name_edit
Layout.preferredWidth: 120
placeholderText: qsTr("请输入数据名称")
onCommit: save_btn.clicked()
enabled: frame.current_size !==16
}
RibbonButton{
id: add_btn
icon_source: RibbonIcons.Add
text: qsTr("添加")
show_tooltip: false
enabled: {
if (frame.judge_size(type_combo.currentText)+frame.current_size>16)
return false
else
return true
}
onClicked: {
frame_model.append({
type:type_combo.currentText,
name:name_edit.text
})
}
}
RibbonButton{
id: delete_btn
icon_source: RibbonIcons.Delete
text: qsTr("删除")
show_tooltip: false
enabled: frame.has_selected !== 0
onClicked: {
frame_model.remove(frame.currentIndex)
}
}
}
RowLayout{
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: margins/2
spacing: margins
RibbonButton{
id: save_btn
Layout.preferredWidth: 150
Layout.alignment: Qt.AlignHCenter
icon_source: RibbonIcons.Save
text: qsTr("保存")
show_tooltip: false
onClicked: {
if (!type_combo.enabled && !name_edit.enabled && frame.current_size > 0)
{
let name_array=[],type_array=[]
for (let i=0;i<frame_model.count;i++)
{
name_array[i] = frame_model.get(i).name
type_array[i] = frame_model.get(i).type
}
Config.setArray('Protocol', 'data_frame_name', name_array)
Config.setArray('Protocol', 'data_frame_type', type_array)
}
else
{
name_edit.text = qsTr("请检查数据长度")
}
}
}
RibbonButton{
id: reset_btn
Layout.preferredWidth: 150
icon_source: RibbonIcons.ArrowReset
text: qsTr("还原默认值")
show_tooltip: false
onClicked: {
frame_model.clear()
frame_model.append([{
name:"温度",
type:"float"
},{
name:"湿度",
type:"float"
},{
name:"气体浓度",
type:"float"
},{
name:"火焰指数",
type:"float"
}])
}
}
}
}
}

View File

@ -93,7 +93,30 @@ Item {
view_only: true
text: modelData.data
wrapMode: RibbonText.WordWrap
color: RibbonTheme.dark_mode ? mouse.containsMouse ? 'black' : 'white' : mouse.containsMouse ? 'white':'black'
color: {
if(RibbonTheme.dark_mode)
{
if(mouse.containsMouse&&!row_bg.selected)
return 'black'
else if(mouse.containsMouse&&row_bg.selected)
return 'white'
else if(!mouse.containsMouse&&row_bg.selected)
return 'black'
else
return 'white'
}
else
{
if(mouse.containsMouse&&!row_bg.selected)
return 'white'
else if(mouse.containsMouse&&row_bg.selected)
return 'black'
else if(!mouse.containsMouse&&row_bg.selected)
return 'white'
else
return 'black'
}
}
}
}
}
@ -114,6 +137,11 @@ Item {
add: Transition {
NumberAnimation { properties: "y"; from: list_table.height; duration: 200 }
}
ScrollBar.vertical: ScrollBar {
anchors.right: list_table.right
anchors.rightMargin: 2
}
}
function getRowValues(index) {

View File

@ -8,11 +8,12 @@ Rectangle{
color: "transparent"
property double padding: 10
default property alias content: message_layout.data
property var data_model:model
property var data_model: model
property int font_size: 13
property string sender_text: "sender"
width: ListView.view.width
height: bubble_layout.height + padding*2
ColumnLayout{
id: bubble_layout
anchors{

View File

@ -12,80 +12,53 @@ RibbonView{
spacing: 0
property int max_msg_num: 10
property bool auto_scroll_to_bottom: false
property int animation_time: 200
property alias delegate: message_list.delegate
property alias message_model: message_model
property alias view: message_list
ListModel{
id: message_model
property int begin_index: 0
property int end_index: 0
onCountChanged: {
if (end_index == count - 2 || begin_index == end_index)
{
while(show_model.count > max_msg_num)
{
show_model.remove(0)
begin_index++
}
show_model.append(message_model.get(count - 1))
end_index = count-1
//console.log('append:',begin_index,end_index)
}
if(count===0)
show_model.clear()
}
onCountChanged: auto_scroll_btn_timer.restart()
}
ListModel{
id: show_model
Timer{
id: auto_scroll_btn_timer
interval: animation_time
repeat: false
onTriggered: {
if(view.auto_scroll_to_bottom)
view.scroll_to_bottom()
}
}
ListView{
id: message_list
cacheBuffer: message_list.height * 2
Layout.alignment: Qt.AlignHCenter
Layout.preferredHeight: contentHeight
Layout.preferredHeight: parent.height
Layout.preferredWidth: parent.width
interactive: false
model: show_model
model: message_model
add: Transition {
NumberAnimation { properties: "y"; from: message_list.height; duration: 100 }
NumberAnimation {
properties: "y"
from: message_list.height
duration: animation_time
}
}
displaced: Transition {
NumberAnimation { properties: "y"; duration: 100 }
ScrollBar.vertical: ScrollBar {
anchors.right: message_list.right
anchors.rightMargin: 2
}
}
Connections{
target: view
function onPull_up_triggered()
{
for(let i = message_model.begin_index - 1, count = 0;
i >= 0 && count < max_msg_num; i--,count++ )
{
show_model.insert(0,message_model.get(i))
message_model.begin_index = i
if (show_model.count > max_msg_num + 2)
{
show_model.remove(show_model.count - 1)
message_model.end_index--
}
}
//console.log('up:',message_model.begin_index,message_model.end_index)
}
function onPull_down_triggered()
{
for(let i = message_model.end_index + 1, count = 0;
i < message_model.count && count < max_msg_num; i++,count++ )
{
show_model.append(message_model.get(i))
message_model.end_index = i
if (show_model.count > max_msg_num)
{
show_model.remove(0)
message_model.begin_index++
}
}
//console.log('down:',message_model.begin_index,message_model.end_index)
}
function scroll_to_up(){
message_list.positionViewAtBeginning()
}
function scroll_to_bottom(){
message_list.positionViewAtEnd()
}
}

View File

@ -14,22 +14,23 @@ Item{
property double bottom_padding: 0
property bool handle_serial: true
onAuto_scroll_to_bottomChanged: if(auto_scroll_to_bottom) serial_view.scroll_to_bottom()
onAuto_scroll_to_bottomChanged: {
serial_view.auto_scroll_to_bottom = auto_scroll_to_bottom
if(auto_scroll_to_bottom)
serial_view.scroll_to_bottom()
}
RibbonMessageListView{
id: serial_view
anchors.fill: parent
top_padding: serial_title_bar.height + control.top_padding + (!RibbonTheme.modern_style ? 10 : 0)
bottom_padding: message_sender.height + control.bottom_padding
auto_scroll_to_bottom: control.auto_scroll_to_bottom
delegate: ZigBeeMessage{
sender_text: `${model.time} ${model.recieved ? '收' : '发'}`
show_tooltip: control.show_tooltip
component_width: serial_view.width / 2
}
view.onHeightChanged: {
if (control.auto_scroll_to_bottom)
scroll_to_bottom()
}
Connections{
target: SerialPortManager
function onRecved(data)

View File

@ -404,8 +404,8 @@ RibbonTabBar {
}
let repeat_count = 16
let t = `FF 29 ${get_rand_byte()}${get_rand_byte()} 83 56 56 `+
`AA AD 56 56 52 48 23 32 01 00 17 00 00 00 AA AA 01 10 00 FF FF `
let t = `FF 2B ${get_rand_byte()}${get_rand_byte()} 83 56 56 `+
`AA AD 56 56 EE EE 56 56 01 00 26 00 00 00 AA AA 01 FF 10 00 FF FF `
for (let j=0;j<repeat_count;j++){
t+=` ${get_rand_byte()}${get_rand_byte()}`
}
@ -458,5 +458,27 @@ RibbonTabBar {
}
}
}
RibbonTabGroup{
text: qsTr("数据结构自定义")
width: frame_custom_layout.width + 30
RowLayout{
id: frame_custom_layout
anchors.centerIn: parent
height: parent.height
spacing: 10
ColumnLayout{
spacing: 10
RibbonButton{
Layout.fillWidth: true
icon_source: RibbonIcons.CodeTextEdit
text: qsTr("自定义数据帧")
tip_text: qsTr("自定义传感器数据帧结构")
onClicked: {
show_popup("components/FrameChooser.qml")
}
}
}
}
}
}
}

View File

@ -43,7 +43,10 @@ Item{
identify_view.scroll_to_bottom()
data_view.scroll_to_bottom()
}
identify_view.auto_scroll_to_bottom = auto_scroll_to_bottom
data_view.auto_scroll_to_bottom = auto_scroll_to_bottom
}
Item{
anchors{
top:parent.top
@ -56,14 +59,11 @@ Item{
anchors.fill: parent
top_padding: control.top_padding + identify_title_bar.height + (!RibbonTheme.modern_style ? 10 : 0)
bottom_padding: control.bottom_padding
auto_scroll_to_bottom: control.auto_scroll_to_bottom
delegate: ZigBeeMessage{
show_tooltip: control.show_tooltip
component_width: identify_view.width / 2
}
view.onHeightChanged: {
if (control.auto_scroll_to_bottom)
scroll_to_bottom()
}
Event{
id:identify_view_event
type: "zigbee_identify_data_view"

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.21)
project(sm_crypto VERSION 1.0.0.0)
project(sm_crypto VERSION 1.0.0)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)

View File

@ -35,12 +35,12 @@ Config* Config::instance()
return singleton;
}
void Config::Set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
void Config::set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
{
m_psetting->setValue(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname), qvarvalue);
}
void Config::SetArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
void Config::setArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
{
m_psetting->beginWriteArray(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname));
QList<QVariant> list = qvarvalue.toList();
@ -52,13 +52,13 @@ void Config::SetArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalu
m_psetting->endArray();
}
QVariant Config::Get(QString qstrnodename,QString qstrkeyname)
QVariant Config::get(QString qstrnodename,QString qstrkeyname)
{
QVariant qvar = m_psetting->value(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname));
return qvar;
}
QVariant Config::GetArray(QString qstrnodename,QString qstrkeyname)
QVariant Config::getArray(QString qstrnodename,QString qstrkeyname)
{
QList<QVariant> list;
int size = m_psetting->beginReadArray(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname));

View File

@ -31,9 +31,6 @@ int main(int argc, char *argv[])
QList<int> verl = {PROTOCOLPARSER_VERSION};
QString version = QString::number(verl[0])+'.'+QString::number(verl[1])+'.'+QString::number(verl[2]);
engine.rootContext()->setContextProperty("PPAPP_Version",version);
#ifdef RIBBONUI_BUILD_STATIC_LIB
engine.addImportPath("qrc:/");
#endif
const QUrl url(u"qrc:/qt/qml/ProtocolParser/Main.qml"_qs);
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {

View File

@ -5,20 +5,18 @@ using namespace zigbee_protocol;
Protocol::Protocol(){
_config = Config::instance();
if (_config->Get("Protocol","hmac_verify_key").toString().isEmpty())
_config->Set("Protocol","hmac_verify_key",hmac_verify_key);
if (_config->get("Protocol","hmac_verify_key").toString().isEmpty())
_config->set("Protocol","hmac_verify_key",hmac_verify_key);
else
hmac_verify_key = _config->Get("Protocol","hmac_verify_key").toString();
if (_config->GetArray("Protocol","pre_hmac_verify_key").toStringList().isEmpty())
_config->SetArray("Protocol","pre_hmac_verify_key",pre_hmac_verify_key);
hmac_verify_key = _config->get("Protocol","hmac_verify_key").toString();
if (_config->getArray("Protocol","pre_hmac_verify_key").toStringList().isEmpty())
_config->setArray("Protocol","pre_hmac_verify_key",pre_hmac_verify_key);
else
pre_hmac_verify_key = _config->GetArray("Protocol","pre_hmac_verify_key").toStringList();
pre_hmac_verify_key = _config->getArray("Protocol","pre_hmac_verify_key").toStringList();
}
Protocol::~Protocol()
{
_config->Set("Protocol","hmac_verify_key",hmac_verify_key);
_config->SetArray("Protocol","pre_hmac_verify_key",pre_hmac_verify_key);
}
Protocol* Protocol::getInstance()

View File

@ -221,6 +221,7 @@ void ZigBeeDataResolver::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, b
QJsonObject object;
if (node->first.verified)
{
QString note_text;
new_data_frame(72) ndata;
uint8_t data_len = 0;
memset(&ndata,0,sizeof(ndata));
@ -231,7 +232,7 @@ void ZigBeeDataResolver::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, b
object.insert("type","zigbee_recv_data");
if (*(u16 *)frame == CRYPTO_ZDATA_FRAME_HEAD)
{
QString note_text = "解密数据为按照未加密传输重新打包的原始数据,因此数据长度会有差异\n";
note_text = "解密数据为按照未加密传输重新打包的原始数据,因此数据长度会有差异\n";
new_base_frame(sizeof(ndata)) nbframe;
memcpy(&nbframe, bframe, BASE_FRAME_PREFIX_LEN);
zigbee_protocol::ZigbeeFrame nzframe = zframe;
@ -242,22 +243,29 @@ void ZigBeeDataResolver::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, b
nzframe.setData((char*)&nbframe,nbframe.length);
zdata = QByteArray((char *)nzframe.data(), nzframe.size());
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
switch (ndata.type) {
case SENSOR_DATA_TYPE:
{
note_text += "传感器数据:";
sensor_data* sdata = (sensor_data*)ndata.data;
note_text += "PPM:" + QString::number(sdata->ppm) + ' ';
note_text += "Temperature:" + QString::number(sdata->temp) + ' ';
note_text += "Humidity:" + QString::number(sdata->humi) + ' ';
note_text += "Flare:" + QString::number(sdata->flare) + ' ';
break;
}
default:
break;
}
object.insert("note_text",QJsonValue(note_text));
ddata = (data_frame*)&ndata;
}
else{
ddata = (data_frame*)frame;
}
switch (ddata->type) {
case SENSOR_DATA_TYPE:
{
QStringList name_list, type_list;
name_list = Config::instance()->getArray("Protocol", "data_frame_name").toStringList();
type_list = Config::instance()->getArray("Protocol", "data_frame_type").toStringList();
note_text += "传感器数据:";
void* pdata = (void *)ddata->data;
for (uint8_t i = 0; i < name_list.length(); i++)
{
note_text += name_list[i]+ ":" + sensor_data_reader(&pdata,type_list[i]) + ' ';
}
break;
}
default:
break;
}
object.insert("note_text",QJsonValue(note_text));
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);
@ -353,3 +361,59 @@ void ZigBeeDataResolver::message_parser(QJsonObject message, QString self_addr)
data_parser(zf, message["type"] == "demo_recv_data");
}
}
QString ZigBeeDataResolver::sensor_data_reader(void **data,QString type)
{
QString d;
uint8_t** pdata = (uint8_t**)(data);
if (type.contains("64"))
{
if(type.contains("u"))
d = QString::number(*(uint64_t*)(*data));
else
d = QString::number(*(int64_t*)(*data));
*pdata += sizeof(uint64_t);
return d;
}
else if (type.contains("32"))
{
if(type.contains("u"))
d = QString::number(*(uint32_t*)(*data));
else
d = QString::number(*(int32_t*)(*data));
*pdata += sizeof(uint32_t);
return d;
}
else if (type.contains("16"))
{
if(type.contains("u"))
d = QString::number(*(uint16_t*)(*data));
else
d = QString::number(*(int16_t*)(*data));
*pdata += sizeof(uint16_t);
return d;
}
else if (type.contains("8"))
{
if(type.contains("u"))
d = QString::number(*(uint8_t*)(*data));
else
d = QString::number(*(int8_t*)(*data));
*pdata += sizeof(uint8_t);
return d;
}
else if (type=="float")
{
d = QString::number(*(float*)(*data), 'g', 1);
*pdata += sizeof(float);
return d;
}
else if (type=="double")
{
d = QString::number(*(double*)(*data), 'g', 1);
*pdata += sizeof(double);
return d;
}
else
return d;
}