Merge branch 'nxp-backend' of github.com:guh/nymea-zigbee into nxp-backend
This commit is contained in:
commit
cb4347f9b5
@ -9,7 +9,8 @@ class Nxp
|
|||||||
public:
|
public:
|
||||||
enum Command {
|
enum Command {
|
||||||
CommandGetVersion = 0x00,
|
CommandGetVersion = 0x00,
|
||||||
CommandGetDeviceState = 0x01
|
CommandGetDeviceState = 0x01,
|
||||||
|
CommandSoftReset = 0x02
|
||||||
};
|
};
|
||||||
Q_ENUM(Command)
|
Q_ENUM(Command)
|
||||||
|
|
||||||
@ -27,6 +28,17 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(Status)
|
Q_ENUM(Status)
|
||||||
|
|
||||||
|
enum LogLevel {
|
||||||
|
LogLevelEmergency = 0x00,
|
||||||
|
LogLevelAlert = 0x01,
|
||||||
|
LogLevelCritical = 0x02,
|
||||||
|
LogLevelError = 0x03,
|
||||||
|
LogLevelWarning = 0x04,
|
||||||
|
LogLevelNotice = 0x05,
|
||||||
|
LogLevelInfo = 0x06,
|
||||||
|
LogLevelDebug = 0x07
|
||||||
|
};
|
||||||
|
Q_ENUM(LogLevel)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NXP_H
|
#endif // NXP_H
|
||||||
|
|||||||
@ -163,6 +163,7 @@ void ZigbeeInterfaceNxp::onReadyRead()
|
|||||||
// Read each byte until we get END byte, then unescape the package
|
// Read each byte until we get END byte, then unescape the package
|
||||||
for (int i = 0; i < data.length(); i++) {
|
for (int i = 0; i < data.length(); i++) {
|
||||||
quint8 byte = static_cast<quint8>(data.at(i));
|
quint8 byte = static_cast<quint8>(data.at(i));
|
||||||
|
qCDebug(dcZigbeeInterfaceTraffic()) << ZigbeeUtils::convertByteToHexString(byte);
|
||||||
if (byte == ProtocolByteEnd) {
|
if (byte == ProtocolByteEnd) {
|
||||||
// If there is no data...continue since it might be a starting END byte
|
// If there is no data...continue since it might be a starting END byte
|
||||||
if (m_dataBuffer.isEmpty())
|
if (m_dataBuffer.isEmpty())
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "zigbeebridgecontrollernxp.h"
|
#include "zigbeebridgecontrollernxp.h"
|
||||||
#include "loggingcategory.h"
|
#include "loggingcategory.h"
|
||||||
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
|
||||||
@ -22,19 +23,31 @@ ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestVersion()
|
|||||||
QDataStream stream(&message, QIODevice::WriteOnly);
|
QDataStream stream(&message, QIODevice::WriteOnly);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint8>(Nxp::CommandGetVersion);
|
stream << static_cast<quint8>(Nxp::CommandGetVersion);
|
||||||
stream << static_cast<quint8>(m_sequenceNumber);
|
stream << static_cast<quint8>(m_sequenceNumber++);
|
||||||
stream << static_cast<quint16>(0); // Frame length
|
stream << static_cast<quint16>(0); // Frame length
|
||||||
|
|
||||||
m_sequenceNumber++;
|
return createReply(Nxp::CommandGetVersion, m_sequenceNumber, "Request controller version", message, this);
|
||||||
return createReply(Nxp::CommandGetVersion, "Request controller version", message, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::createReply(Nxp::Command command, const QString &requestName, const QByteArray &requestData, QObject *parent)
|
ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestSoftResetController()
|
||||||
|
{
|
||||||
|
QByteArray message;
|
||||||
|
QDataStream stream(&message, QIODevice::WriteOnly);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << static_cast<quint8>(Nxp::CommandSoftReset);
|
||||||
|
stream << static_cast<quint8>(m_sequenceNumber++);
|
||||||
|
stream << static_cast<quint16>(0); // Frame length
|
||||||
|
|
||||||
|
return createReply(Nxp::CommandSoftReset, m_sequenceNumber, "Request soft reset controller", message, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::createReply(Nxp::Command command, quint8 sequenceNumber, const QString &requestName, const QByteArray &requestData, QObject *parent)
|
||||||
{
|
{
|
||||||
// Create the reply
|
// Create the reply
|
||||||
ZigbeeInterfaceNxpReply *reply = new ZigbeeInterfaceNxpReply(command, parent);
|
ZigbeeInterfaceNxpReply *reply = new ZigbeeInterfaceNxpReply(command, parent);
|
||||||
reply->m_requestName = requestName;
|
reply->m_requestName = requestName;
|
||||||
reply->m_requestData = requestData;
|
reply->m_requestData = requestData;
|
||||||
|
reply->m_sequenceNumber = sequenceNumber;
|
||||||
|
|
||||||
// Make sure we clean up on timeout
|
// Make sure we clean up on timeout
|
||||||
connect(reply, &ZigbeeInterfaceNxpReply::timeout, this, [reply](){
|
connect(reply, &ZigbeeInterfaceNxpReply::timeout, this, [reply](){
|
||||||
@ -46,8 +59,8 @@ ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::createReply(Nxp::Command com
|
|||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_pendingReplies.insert(sequenceNumber, reply);
|
||||||
m_interface->sendPackage(requestData);
|
m_interface->sendPackage(requestData);
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +72,54 @@ void ZigbeeBridgeControllerNxp::onInterfaceAvailableChanged(bool available)
|
|||||||
|
|
||||||
void ZigbeeBridgeControllerNxp::onInterfacePackageReceived(const QByteArray &package)
|
void ZigbeeBridgeControllerNxp::onInterfacePackageReceived(const QByteArray &package)
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeController()) << "Interface package received" << package;
|
QDataStream stream(package);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
quint8 commandInt = 0; quint8 sequenceNumber = 0;
|
||||||
|
stream >> commandInt >> sequenceNumber;
|
||||||
|
|
||||||
|
// Note: commands >= 0x7D are notifications
|
||||||
|
if (commandInt >= 0x7D) {
|
||||||
|
quint16 payloadLength = 0;
|
||||||
|
stream >> payloadLength;
|
||||||
|
QByteArray data = package.mid(4, payloadLength);
|
||||||
|
if (package.length() < payloadLength + 4) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Invalid package length received" << ZigbeeUtils::convertByteArrayToHexString(package) << payloadLength;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Nxp::Notification notification = static_cast<Nxp::Notification>(commandInt);
|
||||||
|
//qCDebug(dcZigbeeController()) << "Interface notification received" << notification << "SQN:" << sequenceNumber << ZigbeeUtils::convertByteArrayToHexString(data);
|
||||||
|
if (notification == Nxp::NotificationDebugMessage) {
|
||||||
|
if (data.isEmpty()) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Received empty debug log notification";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Nxp::LogLevel logLevel = static_cast<Nxp::LogLevel>(data.at(0));
|
||||||
|
qCDebug(dcZigbeeController()) << "DEBUG" << logLevel << qUtf8Printable(data.right(data.length() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit interfaceNotificationReceived(notification, data);
|
||||||
|
} else {
|
||||||
|
quint8 statusInt = 0; quint16 payloadLength = 0;
|
||||||
|
stream >> statusInt >> payloadLength;
|
||||||
|
if (package.length() < payloadLength + 5) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Invalid package length received" << ZigbeeUtils::convertByteArrayToHexString(package) << payloadLength;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QByteArray data = package.mid(5, payloadLength);
|
||||||
|
Nxp::Command command = static_cast<Nxp::Command>(commandInt);
|
||||||
|
Nxp::Status status = static_cast<Nxp::Status>(statusInt);
|
||||||
|
qCDebug(dcZigbeeController()) << "Interface response received" << command << "SQN:" << sequenceNumber << status << ZigbeeUtils::convertByteArrayToHexString(data);
|
||||||
|
if (m_pendingReplies.keys().contains(sequenceNumber)) {
|
||||||
|
ZigbeeInterfaceNxpReply * reply = m_pendingReplies.take(sequenceNumber);
|
||||||
|
if (reply->command() == command) {
|
||||||
|
reply->m_status = status;
|
||||||
|
reply->m_responseData = data;
|
||||||
|
} else {
|
||||||
|
qCWarning(dcZigbeeController()) << "Received interface response for a pending sequence number but the command does not match the request." << command << reply->command();
|
||||||
|
}
|
||||||
|
reply->finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZigbeeBridgeControllerNxp::enable(const QString &serialPort, qint32 baudrate)
|
bool ZigbeeBridgeControllerNxp::enable(const QString &serialPort, qint32 baudrate)
|
||||||
|
|||||||
@ -23,14 +23,18 @@ public:
|
|||||||
|
|
||||||
// Controllere requests
|
// Controllere requests
|
||||||
ZigbeeInterfaceNxpReply *requestVersion();
|
ZigbeeInterfaceNxpReply *requestVersion();
|
||||||
|
ZigbeeInterfaceNxpReply *requestSoftResetController();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void interfaceNotificationReceived(Nxp::Notification notification, const QByteArray &data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeInterfaceNxp *m_interface = nullptr;
|
ZigbeeInterfaceNxp *m_interface = nullptr;
|
||||||
quint8 m_sequenceNumber = 0;
|
quint8 m_sequenceNumber = 0;
|
||||||
|
|
||||||
ZigbeeInterfaceNxpReply *createReply(Nxp::Command command, const QString &requestName, const QByteArray &requestData, QObject *parent);
|
QHash<quint8, ZigbeeInterfaceNxpReply *> m_pendingReplies;
|
||||||
|
ZigbeeInterfaceNxpReply *createReply(Nxp::Command command, quint8 sequenceNumber, const QString &requestName, const QByteArray &requestData, QObject *parent);
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onInterfaceAvailableChanged(bool available);
|
void onInterfaceAvailableChanged(bool available);
|
||||||
|
|||||||
@ -38,10 +38,12 @@ void ZigbeeNetworkNxp::onControllerAvailableChanged(bool available)
|
|||||||
qCDebug(dcZigbeeNetwork()) << "Controller is" << (available ? "now available" : "not available any more");
|
qCDebug(dcZigbeeNetwork()) << "Controller is" << (available ? "now available" : "not available any more");
|
||||||
|
|
||||||
if (available) {
|
if (available) {
|
||||||
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
reset();
|
||||||
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [](){
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Version reply finished";
|
// ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
||||||
});
|
// connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [](){
|
||||||
|
// qCDebug(dcZigbeeNetwork()) << "Version reply finished";
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +77,10 @@ void ZigbeeNetworkNxp::stopNetwork()
|
|||||||
|
|
||||||
void ZigbeeNetworkNxp::reset()
|
void ZigbeeNetworkNxp::reset()
|
||||||
{
|
{
|
||||||
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSoftResetController();
|
||||||
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [](){
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Soft reset reply finished";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkNxp::factoryResetNetwork()
|
void ZigbeeNetworkNxp::factoryResetNetwork()
|
||||||
|
|||||||
Reference in New Issue
Block a user