431 lines
9.5 KiB
C++
431 lines
9.5 KiB
C++
#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);
|
||
}
|
||
*/
|