1
0
This repository has been archived on 2023-11-30. You can view files and clone it, but cannot push or open issues or pull requests.
dtux__zigbeemanager/zigateBackend.cpp

430 lines
9.5 KiB
C++
Raw Permalink Normal View History

2023-04-29 15:15:19 +02:00
#include "main.h"
2023-04-08 15:06:36 +02:00
#include <unistd.h>
2023-04-29 15:15:19 +02:00
#include <QFutureWatcher>
#include "serial.inc.h"
2023-04-08 15:06:36 +02:00
2023-04-29 15:15:19 +02:00
class BackEnds;
extern SerialManager serialManager;
extern QMap <QString, BackEnds> backends;
2023-04-08 15:06:36 +02:00
using namespace std;
2023-04-20 13:42:00 +02:00
ZigateBackend zigateBkd;
2023-04-08 15:06:36 +02:00
ZigateBackend::ZigateBackend()
{
2023-04-29 15:15:19 +02:00
BackEnds zigate;
backends["Zigate"] = zigate;
backends["zigate"].name = "Zigate";
backends["zigate"].device = "ZIGATE";
2023-04-08 15:06:36 +02:00
}
ZigateBackend::~ZigateBackend()
{
}
QByteArray ZigateBackend::checksum(QByteArray msgType, QByteArray length, QByteArray datas)
{
quint16 temp = 0;
int i;
2023-04-13 00:27:20 +02:00
QString str;
2023-04-08 15:06:36 +02:00
2023-04-13 00:27:20 +02:00
str = msgType.mid(0,2);
temp ^= str.toInt(nullptr, 16);
str = msgType.mid(2,2);
temp ^= str.toInt(nullptr, 16);
str = length.mid(0,2);
temp ^= str.toInt(nullptr, 16);
str = length.mid(2,2);
temp ^= str.toInt(nullptr, 16);
2023-04-08 15:06:36 +02:00
for (i=0;i<=(datas.count());i+=2)
{
2023-04-13 00:27:20 +02:00
str = datas.mid(i,2);
temp ^= str.toInt(nullptr, 16);
2023-04-08 15:06:36 +02:00
}
return QByteArray::number(temp, 16);
}
QByteArray ZigateBackend::transcode(QByteArray datas)
{
QByteArray msg = "";
int i;
QByteArray byte;
if (datas.count()%2 != 0)
{
return "-1";
}
for (i=0;i<datas.count();i+=2)
{
byte = datas.mid(i,2);
2023-04-13 00:27:20 +02:00
if (byte.toUInt(nullptr, 16) > 15)
2023-04-08 15:06:36 +02:00
{
msg += byte;
}else
{
msg.append("02");
2023-04-13 00:27:20 +02:00
msg.append(QByteArray::number(byte.toUInt(nullptr, 16) ^ 16, 16));
2023-04-08 15:06:36 +02:00
}
}
return msg;
}
2023-04-20 13:42:00 +02:00
QByteArray ZigateBackend::unTranscode(QByteArray datas)
{
QByteArray result;
int i;
char tmp;
if (datas.isEmpty())
{
return "-1";
}
for (i=1;i<=datas.count()-2;i++)
{
tmp = datas.at(i);
if (tmp == 0x02)
{
i++;
result.append(datas[i] ^ 16);
}else
{
if (tmp != 0 and tmp != 1)
{
result += tmp;
}
}
}
cout << result.toHex(' ').toStdString() << endl;
return result;
}
2023-04-13 00:27:20 +02:00
void ZigateBackend::sendCmd(QByteArray cmd, QByteArray datas)
2023-04-08 15:06:36 +02:00
{
QByteArray msg;
2023-04-13 00:27:20 +02:00
QByteArray len;
2023-04-08 15:06:36 +02:00
2023-04-20 13:42:00 +02:00
len = QByteArray::number(datas.count()/2, 16).insert(0,"000").right(4);
2023-04-08 15:06:36 +02:00
msg = QByteArray::fromHex("01");
msg += QByteArray::fromHex(transcode(cmd));
msg += QByteArray::fromHex(transcode(len));
if (!datas.isEmpty())
{
msg += QByteArray::fromHex(checksum(cmd, len, datas));
msg += QByteArray::fromHex(transcode(datas));
}else{
2023-04-20 13:42:00 +02:00
msg += QByteArray::fromHex(checksum(cmd, len, ""));
2023-04-08 15:06:36 +02:00
}
msg += QByteArray::fromHex("03");
2023-04-29 15:15:19 +02:00
serialManager.write(msg);
if (!serialManager.waitForBytesWritten(10000))
2023-04-13 00:27:20 +02:00
{
cout << "error : no acknoledge of bytes written" << endl;
}
2023-04-20 13:42:00 +02:00
//this->interpretResult(this->dataRead);
}
2023-04-29 15:15:19 +02:00
/*void ZigateBackend::getResponse()
2023-04-20 13:42:00 +02:00
{
2023-04-29 15:15:19 +02:00
//this->getData();
2023-04-13 00:27:20 +02:00
this->interpretResult(this->dataRead);
2023-04-29 15:15:19 +02:00
this->dataRead.clear();
}*/
2023-04-08 15:06:36 +02:00
2023-04-29 15:15:19 +02:00
void ZigateBackend::interpretResult(QByteArray payload)
2023-04-08 15:06:36 +02:00
{
2023-04-13 00:27:20 +02:00
uint tab = 0;
2023-04-20 13:42:00 +02:00
int length = 0;
quint8 crctmp = 0;
uint i = 0;
int datasResultLength = 0;
2023-04-24 21:57:35 +02:00
Response responseObject;
2023-04-13 00:27:20 +02:00
QByteArray type;
2023-04-20 13:42:00 +02:00
uint ln;
quint8 crc;
QByteArray datasResult;
2023-04-13 00:27:20 +02:00
QByteArray quality;
2023-04-20 13:42:00 +02:00
QByteArray payloadD;
payloadD = unTranscode(payload);
length = payloadD.count();
while(length > 5)
2023-04-08 15:06:36 +02:00
{
2023-04-13 00:27:20 +02:00
crctmp = 0;
//type de message
2023-04-20 13:42:00 +02:00
type = payloadD.mid(0, 2);
ln = payloadD.mid(2, 2).toHex().toUInt(nullptr, 16);
2023-04-29 15:15:19 +02:00
if ((unsigned char)type[0] == 128 or (unsigned char)type[0] == 0 or (unsigned char)type[0] == 153)
2023-04-08 15:06:36 +02:00
{
2023-04-24 21:57:35 +02:00
crctmp = crctmp ^ payloadD.at(0) ^ payloadD.at(1);
crctmp = crctmp ^ payloadD.at(2) ^ payloadD.at(3);
//acquisition du CRC
crc = payloadD.at(4);
//datasResult
datasResult = "";
for(i=0;i<ln;i++)
{
datasResult += payloadD.at(5+i);
crctmp ^= payloadD.at(5+i);
}
quality = payloadD.right(1);
2023-04-13 00:27:20 +02:00
2023-04-24 21:57:35 +02:00
datasResultLength = datasResult.count();
2023-04-13 00:27:20 +02:00
2023-04-24 21:57:35 +02:00
//verification du CRC
if (crc == crctmp)
2023-04-13 00:27:20 +02:00
{
2023-04-24 21:57:35 +02:00
if (responseListIndex[type.toHex()]->manager != nullptr)
{
responseObject.code = type;
responseObject.datas = datasResult;
// responseObject.properties = responseListIndex[type]->properties
responseListIndex[type.toHex()]->manager(&responseObject);
}else
{
cout << "unknown command or command not implemented :" << type.toHex().toStdString() << endl;
}
2023-04-20 13:42:00 +02:00
}else
{
2023-04-24 21:57:35 +02:00
tab=-2;
2023-04-20 13:42:00 +02:00
}
2023-04-13 00:27:20 +02:00
}
2023-04-24 21:57:35 +02:00
payloadD.remove(0,ln+6);
2023-04-20 13:42:00 +02:00
length = payloadD.count();
2023-04-08 15:06:36 +02:00
}
2023-04-29 15:15:19 +02:00
//return tab;
}
void defaultManager(Response *responseObject)
{
int nbyte;
int isValue;
int offset = 0;
QByteArray datas = responseObject->datas;
QByteArray result;
QByteArray code = responseObject->code.toHex();
cout << responseObject->code.toStdString() << endl;
QMap <uint, QList<QVariant>>::iterator i = zigateBkd.responseListIndex[code]->properties.begin();
QList <QVariant> propertyList;
QMap <uint, QString> propertyDetail;
QMap<uint,QString> var;
infoOutput(responseObject);
while (i != zigateBkd.responseListIndex[code]->properties.end())
{
propertyList = i.value();
propertyDetail = zigateBkd.responseListIndex[code]->propertyDetail.value(i.key());
cout << propertyList.at(0).toString().toStdString() << ": ";
nbyte = propertyList.at(1).toInt();
isValue = propertyList.at(2).toInt();
result = datas.mid(offset, nbyte);
offset += nbyte;
switch (isValue)
{
case 0:
cout << result.toHex().toStdString() << endl;
break;
case 1:
cout << result.toHex().toStdString() << endl;
//foreach (var, propertyDetail)
//{
//}
break;
case 2:
if (propertyDetail.contains(result.toUInt()))
{
cout << propertyDetail.value(result.toUInt()).toStdString() << endl;
}else if (propertyDetail.contains(-1))
{
cout << propertyDetail.value(-1).toStdString() << endl;
}
break;
case 3:
zigateBkd.responseListIndex[responseObject->code]->propertyManagerList[i.key()](result);
break;
case 4:
cout << "Liste" << endl;
break;
case 5:
cout << result.toStdString() << endl;
break;
}
i++;
}
}
void macCapabilityManager(QByteArray mac)
{
cout << "macCapabilityManger" << mac.toStdString() << endl;
}
/* void deviceAnnounceManager()
{
infoOutput(responseListIndex(""));
}
*/
void dataIndicationManager(Response * response)
{
infoOutput(response);
}
void clustersListManager(Response * response)
{
infoOutput(response);
}
/*
void attributesListManager()
{
infoOutput(attributesList);
}
void commandsListManager()
{
infoOutput(commandsList);
}
void statusManager()
{
infoOutput(status);
}
void status2Manager()
{
}
void versionListManager()
{
infoOutput(versionList);
}
// ****************************************************************************
// 0 - Off
// 1 - On
// *******************************************************************************
void permitJoinManager()
{
infoOutput(permitJoin);
}
void networkJoinedFormedManager()
{
infoOutput(networkJoinedFormed);
}
*/
void deviceListManager(Response * response)
{
infoOutput(response);
// **************************************************************
// <device list data each entry is 13 bytes>
// <ID: uint8_t>
// <Short address: uint16_t>
// <IEEE address: uint64_t>
// <Power source: bool_t> 0 battery 1- AC power
// <LinkQuality : uint8_t> 1-255
// **************************************************************
}
/*
void bindResponseManager()
{
infoOutput(bindResponse);
}
void unbindResponseManager()
{
infoOutput(unbindResponse);
}
*/
void networkAddressManager(Response * response)
{
infoOutput(response);
}
void iEEEAddressManager(Response * response)
{
infoOutput(response);
}
void nodeDescriptorManager(Response * response)
{
infoOutput(response);
}
void simpleDescriptorManager(Response * response)
{
infoOutput(response);
}
/*
void powerDescriptorManager()
{
infoOutput(powerDescriptor);
}
void activeEndpointManager()
{
infoOutput(activeEndpoint);
}
void matchDescriptorManager()
{
infoOutput(matchDescriptor);
}
void userDescriptorNotifyManager()
{
infoOutput(userDescriptorNotify);
}
void userDescriptorManager()
{
infoOutput(userDescriptor);
}
void complexDescriptorManager()
{
infoOutput(complexDescriptor);
}
void managementLeaveManager()
{
infoOutput(managementLeave);
}
void leaveIndicationManager()
{
infoOutput(leaveIndication);
}
void managementNetworkUpdateManager()
{
infoOutput(managementNetworkUpdate);
}
void systemServerDiscoveryManager()
{
infoOutput(systemServerDiscovery);
}
// ********************************* //
// Bitmask according to spec". //
// ********************************* //
void managementLQIManager()
{
infoOutput(managementLQI);
}
void attributeDiscoveryManager()
{
infoOutput(attributeDiscovery);
2023-04-13 00:27:20 +02:00
}
2023-04-29 15:15:19 +02:00
*/