326 lines
15 KiB
C++
326 lines
15 KiB
C++
#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");
|
||
}
|
||
}
|