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/zigateplugin/zigateplugin.cpp

510 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}
*/