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
|
|
|
|
*/
|