510 lines
12 KiB
C++
510 lines
12 KiB
C++
#include "zigateplugin.h"
|
||
|
||
using namespace std;
|
||
|
||
ZigatePlugin zigatePlugin;
|
||
SerialManager serialManager;
|
||
|
||
QHash <QString, ResponseProperties*> responseListIndex
|
||
{
|
||
{"004D", nullptr},
|
||
{"8000", nullptr},
|
||
{"8001", nullptr},
|
||
{"8002", nullptr},
|
||
{"8003", nullptr},
|
||
{"8004", nullptr},
|
||
{"8005", nullptr},
|
||
{"8006", nullptr},
|
||
{"8007", nullptr},
|
||
{"8010", nullptr},
|
||
{"8014", nullptr},
|
||
{"8024", nullptr},
|
||
{"8030", nullptr},
|
||
{"8031", nullptr},
|
||
{"8040", nullptr},
|
||
{"8041", nullptr},
|
||
{"8042", nullptr},
|
||
{"8043", nullptr},
|
||
{"8044", nullptr},
|
||
{"8045", nullptr},
|
||
{"8046", nullptr},
|
||
{"802B", nullptr},
|
||
{"802C", nullptr},
|
||
{"8047", nullptr},
|
||
{"8048", nullptr},
|
||
{"804A", nullptr},
|
||
{"804B", nullptr},
|
||
{"804E", nullptr},
|
||
{"8140", nullptr},
|
||
{"8008", nullptr},
|
||
{"8009", nullptr},
|
||
{"8011", nullptr},
|
||
{"8012", nullptr},
|
||
{"8015", nullptr},
|
||
{"8017", nullptr},
|
||
{"8028", nullptr},
|
||
{"8035", nullptr},
|
||
{"8049", nullptr},
|
||
{"8052", nullptr},
|
||
{"8060", nullptr},
|
||
{"8061", nullptr},
|
||
{"8062", nullptr},
|
||
{"8063", nullptr},
|
||
{"8085", nullptr},
|
||
{"8095", nullptr},
|
||
{"80A0", nullptr},
|
||
{"80A1", nullptr},
|
||
{"80A2", nullptr},
|
||
{"80A3", nullptr},
|
||
{"80A4", nullptr},
|
||
{"80A6", nullptr},
|
||
{"80A7", nullptr},
|
||
{"8100", nullptr},
|
||
{"8101", nullptr},
|
||
{"8102", nullptr},
|
||
{"8110", nullptr},
|
||
{"8120", nullptr},
|
||
{"8122", nullptr},
|
||
{"8531", nullptr},
|
||
{"8701", nullptr},
|
||
{"8702", nullptr},
|
||
{"9999", nullptr}
|
||
};
|
||
|
||
QByteArray ZigatePlugin::checksum(QByteArray msgType, QByteArray length, QByteArray datas)
|
||
{
|
||
quint16 temp = 0;
|
||
int i;
|
||
QString str;
|
||
|
||
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);
|
||
for (i=0;i<=(datas.count());i+=2)
|
||
{
|
||
str = datas.mid(i,2);
|
||
temp ^= str.toInt(nullptr, 16);
|
||
}
|
||
return QByteArray::number(temp, 16);
|
||
}
|
||
|
||
QByteArray ZigatePlugin::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);
|
||
if (byte.toUInt(nullptr, 16) > 15)
|
||
{
|
||
msg += byte;
|
||
}else
|
||
{
|
||
msg.append("02");
|
||
msg.append(QByteArray::number(byte.toUInt(nullptr, 16) ^ 16, 16));
|
||
}
|
||
}
|
||
return msg;
|
||
}
|
||
|
||
QByteArray ZigatePlugin::unTranscode(QByteArray datas)
|
||
{
|
||
QByteArray result;
|
||
int i;
|
||
char tmp;
|
||
|
||
if (datas.isEmpty())
|
||
{
|
||
return "-1";
|
||
}
|
||
|
||
for (i=0;i<=datas.count()-1;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;
|
||
}
|
||
|
||
void ZigatePlugin::sendCmd(QByteArray cmd, QByteArray datas)
|
||
{
|
||
QByteArray msg;
|
||
QByteArray len;
|
||
|
||
len = QByteArray::number(datas.count()/2, 16).insert(0,"000").right(4);
|
||
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{
|
||
msg += QByteArray::fromHex(checksum(cmd, len, ""));
|
||
}
|
||
msg += QByteArray::fromHex("03");
|
||
serialManager.write2serial(msg);
|
||
}
|
||
|
||
void ZigatePlugin::interpretResult(QByteArray payload)
|
||
{
|
||
//uint tab = 0;
|
||
uint length = 0;
|
||
quint8 crctmp = 0;
|
||
uint i = 0;
|
||
//int datasResultLength = 0;
|
||
ResponseProperties * responseObject;
|
||
QByteArray type;
|
||
uint ln;
|
||
quint8 crc;
|
||
QByteArray datas;
|
||
QByteArray quality;
|
||
QByteArray payloadD;
|
||
payloadD = unTranscode(payload);
|
||
if (this->datas.count() >= 1)
|
||
{
|
||
cout << "inserting: " << this->datas.toHex(' ').toStdString() << endl;
|
||
payloadD.insert(0, this->datas);
|
||
}
|
||
length = payloadD.count();
|
||
|
||
while(length > 5)
|
||
{
|
||
cout << "Interpreting datas =>" << payload.left(1).toHex(' ').toStdString() << endl;
|
||
cout << "PayloadD : " << payloadD.toHex(' ').toStdString() << endl;
|
||
while(payloadD.left(1).toHex() != "01")
|
||
{
|
||
payloadD.remove(0,1);
|
||
}
|
||
payloadD.remove(0,1);crctmp = 0;
|
||
//type de message
|
||
type = payloadD.mid(0, 2);
|
||
ln = payloadD.mid(2, 2).toHex().toUInt(nullptr, 16);
|
||
if (ln + 6 > length)
|
||
{
|
||
cout << "storing payloadD: " << payloadD.toHex(' ').toStdString() << endl;
|
||
this->datas = payloadD;
|
||
break;
|
||
}else
|
||
{
|
||
if ((unsigned char)type[0] == 128 or (unsigned char)type[0] == 0 or (unsigned char)type[0] == 153)
|
||
{
|
||
crctmp = crctmp ^ payloadD.at(0) ^ payloadD.at(1);
|
||
crctmp = crctmp ^ payloadD.at(2) ^ payloadD.at(3);
|
||
//acquisition du CRC
|
||
crc = payloadD.at(4);
|
||
//datasResult
|
||
datas = "";
|
||
|
||
for(i=0;i<ln;i+=1)
|
||
{
|
||
datas += payloadD.at(5+i);
|
||
crctmp ^= payloadD.at(5+i);
|
||
}
|
||
quality = payloadD.right(1);
|
||
|
||
//datasResultLength = datasResult.count();
|
||
|
||
//verification du CRC
|
||
if (crc == crctmp)
|
||
{
|
||
responseObject = responseListIndex[type.toHex()];
|
||
if (responseObject->manager != nullptr)
|
||
{
|
||
responseObject->code = type;
|
||
responseObject->datas = datas;
|
||
//responseObject.properties = responseListIndex[type]->properties
|
||
responseObject->manager(responseObject);
|
||
|
||
}else
|
||
{
|
||
cout << "unknown command or command not implemented :" << type.toHex().toStdString() << endl;
|
||
}
|
||
}else
|
||
{
|
||
//tab = -2;
|
||
}
|
||
}else
|
||
{
|
||
cout << "unknown type of datagram type: " << type.toHex().toStdString() << endl;
|
||
}
|
||
}
|
||
payloadD.remove(0,ln+6);
|
||
length = payloadD.count();
|
||
cout << "---------------" << endl;
|
||
}
|
||
//return tab;
|
||
}
|
||
|
||
|
||
void defaultManager(ResponseProperties *responseObject)
|
||
{
|
||
int nbyte;
|
||
int isValue;
|
||
int offset = 0;
|
||
int i;
|
||
|
||
QByteArray datas = responseObject->datas;
|
||
QByteArray result;
|
||
//QByteArray code = responseObject->code.toHex();
|
||
|
||
//cout << responseObject->code.toHex().toStdString() << endl;
|
||
int n = responseObject->properties.count();
|
||
QMap<uint, QList<QVariant>> propertyList;
|
||
QMap<uint, QString> propertyDetail;
|
||
QMap<uint,QString> var;
|
||
QList<QVariant> property;
|
||
QMap<uint,QString>::iterator j;
|
||
//int propertyListKey;
|
||
|
||
propertyList = responseObject->properties;
|
||
infoOutput(responseObject);
|
||
for(i=0;i<n;i+=1)
|
||
//while (i != zigatePlugin.responseListIndex[code].properties.end())
|
||
{
|
||
property = propertyList.value(i);
|
||
cout << property.at(0).toString().toStdString() << ": ";
|
||
nbyte = property.at(1).toInt();
|
||
isValue = property.at(2).toInt();
|
||
result = datas.mid(offset, nbyte);
|
||
offset += nbyte;
|
||
propertyDetail = responseObject->propertyDetail.value(i);
|
||
|
||
switch (isValue)
|
||
{
|
||
case 0:
|
||
cout << result.toHex().toStdString() << endl;
|
||
break;
|
||
case 1:
|
||
cout << result.toHex().toStdString() << endl;
|
||
j = propertyDetail.begin();
|
||
while(j != propertyDetail.end())
|
||
{
|
||
if (result.toUInt(nullptr,16) & var[0].toUInt(nullptr,16))
|
||
{
|
||
cout << var[1].toStdString() << endl;
|
||
}
|
||
}
|
||
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:
|
||
responseObject->propertyManagerList[i](result);
|
||
break;
|
||
case 4:
|
||
cout << "Liste" << endl;
|
||
break;
|
||
case 5:
|
||
cout << result.toStdString() << endl;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void macCapabilityManager(QByteArray mac)
|
||
{
|
||
cout << "macCapabilityManger" << mac.toStdString() << endl;
|
||
}
|
||
|
||
|
||
/* void deviceAnnounceManager()
|
||
{
|
||
infoOutput(responseListIndex(""));
|
||
}
|
||
*/
|
||
|
||
void dataIndicationManager(ResponseProperties * response)
|
||
{
|
||
infoOutput(response);
|
||
}
|
||
|
||
|
||
void clustersListManager(ResponseProperties * 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(ResponseProperties * 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(ResponseProperties * response)
|
||
{
|
||
infoOutput(response);
|
||
}
|
||
|
||
void iEEEAddressManager(ResponseProperties * response)
|
||
{
|
||
infoOutput(response);
|
||
}
|
||
|
||
void nodeDescriptorManager(ResponseProperties * response)
|
||
{
|
||
infoOutput(response);
|
||
}
|
||
|
||
void simpleDescriptorManager(ResponseProperties * 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);
|
||
}
|
||
*/
|