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 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 "main.h"
#include <unistd.h>
#include <QFutureWatcher>
#include "serial.inc.h"
class BackEnds;
extern SerialManager serialManager;
extern QMap <QString, BackEnds> backends;
using namespace std;
ZigateBackend zigateBkd;
ZigateBackend::ZigateBackend()
{
BackEnds zigate;
backends["Zigate"] = zigate;
backends["zigate"].name = "Zigate";
backends["zigate"].device = "ZIGATE";
}
ZigateBackend::~ZigateBackend()
{
}
QByteArray ZigateBackend::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 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);
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 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;
}
void ZigateBackend::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.write(msg);
if (!serialManager.waitForBytesWritten(10000))
{
cout << "error : no acknoledge of bytes written" << endl;
}
//this->interpretResult(this->dataRead);
}
/*void ZigateBackend::getResponse()
{
//this->getData();
this->interpretResult(this->dataRead);
this->dataRead.clear();
}*/
void ZigateBackend::interpretResult(QByteArray payload)
{
uint tab = 0;
int length = 0;
quint8 crctmp = 0;
uint i = 0;
int datasResultLength = 0;
Response responseObject;
QByteArray type;
uint ln;
quint8 crc;
QByteArray datasResult;
QByteArray quality;
QByteArray payloadD;
payloadD = unTranscode(payload);
length = payloadD.count();
while(length > 5)
{
crctmp = 0;
//type de message
type = payloadD.mid(0, 2);
ln = payloadD.mid(2, 2).toHex().toUInt(nullptr, 16);
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
datasResult = "";
for(i=0;i<ln;i++)
{
datasResult += payloadD.at(5+i);
crctmp ^= payloadD.at(5+i);
}
quality = payloadD.right(1);
datasResultLength = datasResult.count();
//verification du CRC
if (crc == crctmp)
{
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;
}
}else
{
tab=-2;
}
}
payloadD.remove(0,ln+6);
length = payloadD.count();
}
//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);
}
*/