Test get version command for initial communication tests

This commit is contained in:
Simon Stürz 2020-09-25 13:42:55 +02:00
parent 1d3eb034e4
commit 9ef73e407b
17 changed files with 496 additions and 271 deletions

View File

@ -36,6 +36,8 @@
ZigbeeBridgeControllerDeconz::ZigbeeBridgeControllerDeconz(QObject *parent) :
ZigbeeBridgeController(parent)
{
qRegisterMetaType<QSerialPort::SerialPortError>();
m_interface = new ZigbeeInterfaceDeconz(this);
connect(m_interface, &ZigbeeInterfaceDeconz::availableChanged, this, &ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged);
connect(m_interface, &ZigbeeInterfaceDeconz::packageReceived, this, &ZigbeeBridgeControllerDeconz::onInterfacePackageReceived);

View File

@ -36,6 +36,8 @@
ZigbeeInterfaceNxp::ZigbeeInterfaceNxp(QObject *parent) : QObject(parent)
{
qRegisterMetaType<QSerialPort::SerialPortError>();
m_reconnectTimer = new QTimer(this);
m_reconnectTimer->setSingleShot(true);
m_reconnectTimer->setInterval(5000);
@ -62,7 +64,7 @@ quint8 ZigbeeInterfaceNxp::calculateCrc(const QByteArray &data)
{
quint8 crc = 0;
for(int i = 0; i < data.length(); i++) {
crc ^= data[i];
crc ^= static_cast<quint8>(data.at(i));
}
return crc;
@ -171,13 +173,9 @@ void ZigbeeInterfaceNxp::onReadyRead()
if (frame.isNull()) {
qCWarning(dcZigbeeInterface()) << "Received inconsistant message. Ignoring data" << ZigbeeUtils::convertByteArrayToHexString(m_dataBuffer);
} else {
QByteArray package = frame.left(frame.length() - 2);
QByteArray checksumBytes = frame.right(2);
QDataStream stream(&checksumBytes, QIODevice::ReadOnly);
stream.setByteOrder(QDataStream::LittleEndian);
quint16 receivedChecksum = 0;
stream >> receivedChecksum;
quint16 calculatedChecksum = calculateCrc(package);
QByteArray package = frame.left(frame.length() - 1);
quint8 receivedChecksum = frame.at(frame.length() - 1);
quint8 calculatedChecksum = calculateCrc(package);
if (receivedChecksum != calculatedChecksum) {
qCWarning(dcZigbeeInterfaceTraffic()) << "Checksum verification failed for frame" << ZigbeeUtils::convertByteArrayToHexString(m_dataBuffer) << receivedChecksum << "!=" << calculatedChecksum;
m_dataBuffer.clear();
@ -228,7 +226,7 @@ void ZigbeeInterfaceNxp::sendPackage(const QByteArray &package)
// Build transport data
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << static_cast<quint8>(ProtocolByteEnd); // Start with SLIP END character
//stream << static_cast<quint8>(ProtocolByteEnd); // Start with SLIP END character
for (int i = 0; i < serializedData.length(); i++)
stream << static_cast<quint8>(serializedData.at(i));

View File

@ -0,0 +1,76 @@
#include "zigbeeinterfacenxpreply.h"
ZigbeeNetworkRequest ZigbeeInterfaceNxpReply::networkRequest() const
{
return m_networkRequest;
}
QString ZigbeeInterfaceNxpReply::requestName()
{
return m_requestName;
}
Nxp::Command ZigbeeInterfaceNxpReply::command() const
{
return m_command;
}
quint8 ZigbeeInterfaceNxpReply::sequenceNumber() const
{
return m_sequenceNumber;
}
QByteArray ZigbeeInterfaceNxpReply::requestData() const
{
return m_requestData;
}
QByteArray ZigbeeInterfaceNxpReply::responseData() const
{
return m_responseData;
}
Nxp::Status ZigbeeInterfaceNxpReply::status() const
{
return m_status;
}
bool ZigbeeInterfaceNxpReply::timendOut() const
{
return m_timeout;
}
bool ZigbeeInterfaceNxpReply::aborted() const
{
return m_aborted;
}
void ZigbeeInterfaceNxpReply::abort()
{
m_timer->stop();
m_aborted = true;
emit finished();
}
ZigbeeInterfaceNxpReply::ZigbeeInterfaceNxpReply(Nxp::Command command, QObject *parent) :
QObject(parent),
m_timer(new QTimer(this)),
m_command(command)
{
m_timer->setInterval(5000);
m_timer->setSingleShot(true);
connect(m_timer, &QTimer::timeout, this, &ZigbeeInterfaceNxpReply::onTimeout);
}
void ZigbeeInterfaceNxpReply::onTimeout()
{
m_timeout = true;
emit timeout();
emit finished();
}
QDebug operator<<(QDebug debug, ZigbeeInterfaceNxpReply *reply)
{
debug.nospace() << "InterfaceReply(" << reply->requestName() << ", " << reply->sequenceNumber() << ")";
return debug.space();
}

View File

@ -0,0 +1,62 @@
#ifndef ZIGBEEINTERFACENXPREPLY_H
#define ZIGBEEINTERFACENXPREPLY_H
#include <QObject>
#include <QTimer>
#include "nxp.h"
#include "zigbeenetworkrequest.h"
class ZigbeeInterfaceNxpReply : public QObject
{
Q_OBJECT
friend class ZigbeeBridgeControllerNxp;
public:
// Request content
ZigbeeNetworkRequest networkRequest() const;
QString requestName();
Nxp::Command command() const;
quint8 sequenceNumber() const;
QByteArray requestData() const;
QByteArray responseData() const;
// Response content
Nxp::Status status() const;
bool timendOut() const;
bool aborted() const;
void abort();
private:
explicit ZigbeeInterfaceNxpReply(Nxp::Command command, QObject *parent = nullptr);
ZigbeeNetworkRequest m_networkRequest;
QTimer *m_timer = nullptr;
bool m_timeout = false;
bool m_aborted = false;
// Request content
QString m_requestName;
Nxp::Command m_command;
quint8 m_sequenceNumber = 0;
QByteArray m_requestData;
// Response content
Nxp::Status m_status = Nxp::StatusUnknownCommand; // FIXME
QByteArray m_responseData;
private slots:
void onTimeout();
signals:
void timeout();
void finished();
};
QDebug operator<<(QDebug debug, ZigbeeInterfaceNxpReply *reply);
#endif // ZIGBEEINTERFACENXPREPLY_H

View File

@ -1,9 +1,65 @@
#include "zigbeebridgecontrollernxp.h"
#include "loggingcategory.h"
#include <QDataStream>
ZigbeeBridgeControllerNxp::ZigbeeBridgeControllerNxp(QObject *parent) :
ZigbeeBridgeController(parent)
{
m_interface = new ZigbeeInterfaceNxp(this);
connect(m_interface, &ZigbeeInterfaceNxp::availableChanged, this, &ZigbeeBridgeControllerNxp::onInterfaceAvailableChanged);
connect(m_interface, &ZigbeeInterfaceNxp::packageReceived, this, &ZigbeeBridgeControllerNxp::onInterfacePackageReceived);
}
ZigbeeBridgeControllerNxp::~ZigbeeBridgeControllerNxp()
{
qCDebug(dcZigbeeController()) << "Destroy controller";
}
ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::requestVersion()
{
QByteArray message;
QDataStream stream(&message, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::LittleEndian);
stream << static_cast<quint8>(Nxp::CommandGetVersion);
stream << static_cast<quint8>(m_sequenceNumber);
stream << static_cast<quint16>(0); // Frame length
m_sequenceNumber++;
return createReply(Nxp::CommandGetVersion, "Request controller version", message, this);
}
ZigbeeInterfaceNxpReply *ZigbeeBridgeControllerNxp::createReply(Nxp::Command command, const QString &requestName, const QByteArray &requestData, QObject *parent)
{
// Create the reply
ZigbeeInterfaceNxpReply *reply = new ZigbeeInterfaceNxpReply(command, parent);
reply->m_requestName = requestName;
reply->m_requestData = requestData;
// Make sure we clean up on timeout
connect(reply, &ZigbeeInterfaceNxpReply::timeout, this, [reply](){
qCWarning(dcZigbeeController()) << "Reply timeout" << reply;
});
// Auto delete the object on finished
connect(reply, &ZigbeeInterfaceNxpReply::finished, reply, [reply](){
reply->deleteLater();
});
m_interface->sendPackage(requestData);
return reply;
}
void ZigbeeBridgeControllerNxp::onInterfaceAvailableChanged(bool available)
{
qCDebug(dcZigbeeController()) << "Interface available changed" << available;
setAvailable(available);
}
void ZigbeeBridgeControllerNxp::onInterfacePackageReceived(const QByteArray &package)
{
qCDebug(dcZigbeeController()) << "Interface package received" << package;
}
bool ZigbeeBridgeControllerNxp::enable(const QString &serialPort, qint32 baudrate)

View File

@ -12,6 +12,7 @@
#include "zigbeenetworkrequest.h"
#include "zigbeebridgecontroller.h"
#include "interface/zigbeeinterfacenxp.h"
#include "interface/zigbeeinterfacenxpreply.h"
class ZigbeeBridgeControllerNxp : public ZigbeeBridgeController
{
@ -20,12 +21,21 @@ public:
explicit ZigbeeBridgeControllerNxp(QObject *parent = nullptr);
~ZigbeeBridgeControllerNxp() override;
// Controllere requests
ZigbeeInterfaceNxpReply *requestVersion();
signals:
private:
ZigbeeInterfaceNxp *m_interface = nullptr;
quint8 m_sequenceNumber = 0;
ZigbeeInterfaceNxpReply *createReply(Nxp::Command command, const QString &requestName, const QByteArray &requestData, QObject *parent);
private slots:
void onInterfaceAvailableChanged(bool available);
void onInterfacePackageReceived(const QByteArray &package);
public slots:
bool enable(const QString &serialPort, qint32 baudrate);
void disable();

View File

@ -36,6 +36,18 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::setPermitJoin(quint16 shortAddress, quint8
void ZigbeeNetworkNxp::onControllerAvailableChanged(bool available)
{
qCDebug(dcZigbeeNetwork()) << "Controller is" << (available ? "now available" : "not available any more");
if (available) {
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [](){
qCDebug(dcZigbeeNetwork()) << "Version reply finished";
});
}
}
void ZigbeeNetworkNxp::setPermitJoiningInternal(bool permitJoining)
{
qCDebug(dcZigbeeNetwork()) << "Set permit join internal" << permitJoining;
}
void ZigbeeNetworkNxp::startNetwork()
@ -53,7 +65,7 @@ void ZigbeeNetworkNxp::startNetwork()
m_permitJoining = false;
emit permitJoiningChanged(m_permitJoining);
// Wait for the network to be started
// Get current state and load information
}
void ZigbeeNetworkNxp::stopNetwork()

View File

@ -20,8 +20,6 @@ public:
ZigbeeNetworkReply *setPermitJoin(quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, quint8 duration = 0xfe);
private:
ZigbeeBridgeControllerNxp *m_controller = nullptr;
bool m_networkRunning = false;
@ -29,6 +27,10 @@ private:
private slots:
void onControllerAvailableChanged(bool available);
protected:
void setPermitJoiningInternal(bool permitJoining) override;
signals:
public slots:

View File

@ -9,6 +9,7 @@ SOURCES += \
backends/deconz/zigbeebridgecontrollerdeconz.cpp \
backends/deconz/zigbeenetworkdeconz.cpp \
backends/nxp/interface/zigbeeinterfacenxp.cpp \
backends/nxp/interface/zigbeeinterfacenxpreply.cpp \
backends/nxp/zigbeebridgecontrollernxp.cpp \
backends/nxp/zigbeenetworknxp.cpp \
zcl/general/zigbeeclusteridentify.cpp \
@ -64,6 +65,7 @@ HEADERS += \
backends/deconz/zigbeenetworkdeconz.h \
backends/nxp/interface/nxp.h \
backends/nxp/interface/zigbeeinterfacenxp.h \
backends/nxp/interface/zigbeeinterfacenxpreply.h \
backends/nxp/zigbeebridgecontrollernxp.h \
backends/nxp/zigbeenetworknxp.h \
zcl/general/zigbeeclusteridentify.h \

View File

@ -28,13 +28,14 @@
#include "zigbeenetworkmanager.h"
#include "loggingcategory.h"
#include "backends/nxp/zigbeenetworknxp.h"
#include "backends/deconz/zigbeenetworkdeconz.h"
#include <QDateTime>
QStringList ZigbeeNetworkManager::availableBackendTypes()
{
return {"deCONZ"};
return {"deCONZ", "NXP"};
}
ZigbeeNetwork *ZigbeeNetworkManager::createZigbeeNetwork(ZigbeeNetworkManager::BackendType backend, QObject *parent)
@ -43,8 +44,8 @@ ZigbeeNetwork *ZigbeeNetworkManager::createZigbeeNetwork(ZigbeeNetworkManager::B
srand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000));
switch (backend) {
// case BackendTypeNxp:
// return qobject_cast<ZigbeeNetwork *>(new ZigbeeNetworkNxp(parent));
case BackendTypeNxp:
return qobject_cast<ZigbeeNetwork *>(new ZigbeeNetworkNxp(parent));
case BackendTypeDeconz:
return qobject_cast<ZigbeeNetwork *>(new ZigbeeNetworkDeconz(parent));
}

View File

@ -34,13 +34,13 @@
class ZigbeeNetworkManager
{
Q_GADGET
public:
//Q_GADGET
enum BackendType {
BackendTypeDeconz
BackendTypeDeconz,
BackendTypeNxp
};
//Q_ENUM(BackendType)
Q_ENUM(BackendType)
static QStringList availableBackendTypes();
static ZigbeeNetwork *createZigbeeNetwork(BackendType backend, QObject *parent = nullptr);

View File

@ -1,4 +1,4 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += libnymea-zigbee #zigbee-cli
SUBDIRS += libnymea-zigbee zigbee-cli

View File

@ -12,177 +12,183 @@ Core::Core(const QString &serialPort, qint32 baudrate, const int &channel, QObje
m_channelMask = 0;
m_channelMask |= 1 << (channel);
ZigbeeBridgeController *controller = new ZigbeeBridgeController(this);
controller->enable(serialPort, baudrate);
m_network = ZigbeeNetworkManager::createZigbeeNetwork(ZigbeeNetworkManager::BackendTypeNxp, this);
m_network->setSerialPortName(serialPort);
m_network->setSerialBaudrate(baudrate);
m_network->setSettingsFileName("/tmp/zigbee.conf");
qDebug() << "Starting network";
m_network->startNetwork();
//m_manager = new ZigbeeNetworkManager(channel, controller, this);
// Set commands
TerminalCommand runCommand("run", "Run the zigbee controller in a normal non interactive mode.");
QStringList optionalParams;
optionalParams.append("router");
optionalParams.append("coordinator");
runCommand.setOptionalParameters(optionalParams);
// TerminalCommand runCommand("run", "Run the zigbee controller in a normal non interactive mode.");
// QStringList optionalParams;
// optionalParams.append("router");
// optionalParams.append("coordinator");
// runCommand.setOptionalParameters(optionalParams);
m_commands.append(runCommand);
m_commands.append(TerminalCommand("start", "Start the zigbee network"));
m_commands.append(TerminalCommand("reset", "Reset the zigbee controller"));
m_commands.append(TerminalCommand("scan", "Start scanning for zigbee networks"));
m_commands.append(TerminalCommand("version", "Print the version of the zigbee controll bridge firmware"));
m_commands.append(TerminalCommand("network-info", "Print all information of the zigbee network."));
m_commands.append(TerminalCommand("list-nodes", "List all nodes and information of the current network"));
m_commands.append(TerminalCommand("permit-join", "Permit nodes to join the network"));
m_commands.append(TerminalCommand("touch-link", "Initiate touch link pairing"));
m_commands.append(TerminalCommand("reset-touchlink", "Touch link factory reset"));
m_commands.append(TerminalCommand("whitelist", "Enable the white list joining"));
m_commands.append(TerminalCommand("address-request", "Request network address on host node"));
m_commands.append(TerminalCommand("matchdescriptor", "Request match descriptors"));
m_commands.append(TerminalCommand("init-node", "Request simple descriptors"));
m_commands.append(TerminalCommand("lqi", "Request link quality"));
m_commands.append(TerminalCommand("toggle", "Request to toggle"));
m_commands.append(TerminalCommand("authenticate", "Authenticate device with given IEEE address"));
// m_commands.append(runCommand);
// m_commands.append(TerminalCommand("start", "Start the zigbee network"));
// m_commands.append(TerminalCommand("reset", "Reset the zigbee controller"));
// m_commands.append(TerminalCommand("scan", "Start scanning for zigbee networks"));
// m_commands.append(TerminalCommand("version", "Print the version of the zigbee controll bridge firmware"));
// m_commands.append(TerminalCommand("network-info", "Print all information of the zigbee network."));
// m_commands.append(TerminalCommand("list-nodes", "List all nodes and information of the current network"));
// m_commands.append(TerminalCommand("permit-join", "Permit nodes to join the network"));
// m_commands.append(TerminalCommand("touch-link", "Initiate touch link pairing"));
// m_commands.append(TerminalCommand("reset-touchlink", "Touch link factory reset"));
// m_commands.append(TerminalCommand("whitelist", "Enable the white list joining"));
// m_commands.append(TerminalCommand("address-request", "Request network address on host node"));
// m_commands.append(TerminalCommand("matchdescriptor", "Request match descriptors"));
// m_commands.append(TerminalCommand("init-node", "Request simple descriptors"));
// m_commands.append(TerminalCommand("lqi", "Request link quality"));
// m_commands.append(TerminalCommand("toggle", "Request to toggle"));
// m_commands.append(TerminalCommand("authenticate", "Authenticate device with given IEEE address"));
TerminalCommander::instance()->setCommands(m_commands);
TerminalCommander::instance()->start();
// TerminalCommander::instance()->setCommands(m_commands);
// TerminalCommander::instance()->start();
connect(TerminalCommander::instance(), &TerminalCommander::commandReceived, this, &Core::onCommandReceived);
connect(TerminalCommander::instance(), &TerminalCommander::finished, QCoreApplication::instance(), &QCoreApplication::quit);
// connect(TerminalCommander::instance(), &TerminalCommander::commandReceived, this, &Core::onCommandReceived);
// connect(TerminalCommander::instance(), &TerminalCommander::finished, QCoreApplication::instance(), &QCoreApplication::quit);
}
ZigbeeNode *Core::findNode(const QString &shortAddressString)
{
foreach (ZigbeeNode *node, m_manager->nodeList()) {
if (ZigbeeUtils::convertUint16ToHexString(node->shortAddress()) == shortAddressString) {
return node;
}
}
//ZigbeeNode *Core::findNode(const QString &shortAddressString)
//{
// foreach (ZigbeeNode *node, m_manager->nodeList()) {
// if (ZigbeeUtils::convertUint16ToHexString(node->shortAddress()) == shortAddressString) {
// return node;
// }
// }
return nullptr;
}
// return nullptr;
//}
void Core::onCommandReceived(const QStringList &tokens)
{
TerminalCommand command;
foreach (const TerminalCommand &terminalCommand, m_commands) {
if (tokens.first() == terminalCommand.command()) {
command = terminalCommand;
break;
}
}
//void Core::onCommandReceived(const QStringList &tokens)
//{
// TerminalCommand command;
// foreach (const TerminalCommand &terminalCommand, m_commands) {
// if (tokens.first() == terminalCommand.command()) {
// command = terminalCommand;
// break;
// }
// }
if (!command.isValid()) {
qCWarning(dcZigbee()) << "Unknown command" << tokens;
return;
}
// if (!command.isValid()) {
// qCWarning(dcZigbee()) << "Unknown command" << tokens;
// return;
// }
// TODO: Process command
qCDebug(dcZigbee()) << "Executing" << tokens.join(" ");
// // TODO: Process command
// qCDebug(dcZigbee()) << "Executing" << tokens.join(" ");
if (command.command() == "run") {
// if (command.command() == "run") {
ZigbeeNetworkManager::NodeType nodeType = ZigbeeNetworkManager::NodeTypeCoordinator;
if (tokens.count() > 1) {
if (!command.optionalParameters().contains(tokens.at(1))) {
qCWarning(dcZigbee()) << "Unknown paramter" << tokens.at(1);
return;
}
// ZigbeeNetworkManager::NodeType nodeType = ZigbeeNetworkManager::NodeTypeCoordinator;
// if (tokens.count() > 1) {
// if (!command.optionalParameters().contains(tokens.at(1))) {
// qCWarning(dcZigbee()) << "Unknown paramter" << tokens.at(1);
// return;
// }
if (tokens.at(1) == "router") {
nodeType = ZigbeeNetworkManager::NodeTypeRouter;
}
}
// if (tokens.at(1) == "router") {
// nodeType = ZigbeeNetworkManager::NodeTypeRouter;
// }
// }
m_manager->erasePersistentData();
m_manager->getVersion();
m_manager->setExtendedPanId(m_manager->extendedPanId());
m_manager->setChannelMask(0x2108800);
m_manager->setDeviceType(nodeType);
// Note: this is the leaked philips ZLL master key
//m_manager->setInitialSecurity(3, 0, 1, "9F5595F10257C8A469CBF42BC93FEE31");
m_manager->setInitialSecurity(4, 0, 1, "5A6967426565416C6C69616E63653039");
// m_manager->erasePersistentData();
// m_manager->getVersion();
// m_manager->setExtendedPanId(m_manager->extendedPanId());
// m_manager->setChannelMask(0x2108800);
// m_manager->setDeviceType(nodeType);
// // Note: this is the leaked philips ZLL master key
// //m_manager->setInitialSecurity(3, 0, 1, "9F5595F10257C8A469CBF42BC93FEE31");
// m_manager->setInitialSecurity(4, 0, 1, "5A6967426565416C6C69616E63653039");
} else if (command.command() == "start") {
m_manager->startNetwork();
} else if (command.command() == "version") {
m_manager->getVersion();
} else if (command.command() == "network-info") {
qCDebug(dcZigbee()).nospace().noquote() << "Network controller: " << m_manager->serialPort() << ", Bridge version: " << m_manager->controllerVersion();
} else if (command.command() == "scan") {
m_manager->startScan();
} else if (command.command() == "reset") {
m_manager->resetController();
} else if (command.command() == "permit-join") {
m_manager->permitJoining(0x0000, 180, true);
} else if (command.command() == "touch-link") {
m_manager->initiateTouchLink();
} else if (command.command() == "reset-touchlink") {
m_manager->touchLinkFactoryReset();
} else if (command.command() == "whitelist") {
m_manager->enableWhitelist();
} else if (command.command() == "address-request") {
if (tokens.count() == 1) {
m_manager->networkAddressRequest(0, m_manager->extendedAddress().toUInt64());
return;
}
ZigbeeNode *node = findNode(tokens.at(1));
if (!node) {
qCWarning(dcZigbee()) << "Could not find node with short address tokens.at(1)";
return;
}
// } else if (command.command() == "start") {
// m_manager->startNetwork();
// } else if (command.command() == "version") {
// m_manager->getVersion();
// } else if (command.command() == "network-info") {
// qCDebug(dcZigbee()).nospace().noquote() << "Network controller: " << m_manager->serialPort() << ", Bridge version: " << m_manager->controllerVersion();
// } else if (command.command() == "scan") {
// m_manager->startScan();
// } else if (command.command() == "reset") {
// m_manager->resetController();
// } else if (command.command() == "permit-join") {
// m_manager->permitJoining(0x0000, 180, true);
// } else if (command.command() == "touch-link") {
// m_manager->initiateTouchLink();
// } else if (command.command() == "reset-touchlink") {
// m_manager->touchLinkFactoryReset();
// } else if (command.command() == "whitelist") {
// m_manager->enableWhitelist();
// } else if (command.command() == "address-request") {
// if (tokens.count() == 1) {
// m_manager->networkAddressRequest(0, m_manager->extendedAddress().toUInt64());
// return;
// }
// ZigbeeNode *node = findNode(tokens.at(1));
// if (!node) {
// qCWarning(dcZigbee()) << "Could not find node with short address tokens.at(1)";
// return;
// }
m_manager->networkAddressRequest(node->shortAddress(), node->extendedAddress().toUInt64());
// m_manager->networkAddressRequest(node->shortAddress(), node->extendedAddress().toUInt64());
} else if (command.command() == "toggle") {
if (tokens.count() < 3) {
qCWarning(dcZigbee()) << "Please specify also the node short address and adressMode";
return;
}
// } else if (command.command() == "toggle") {
// if (tokens.count() < 3) {
// qCWarning(dcZigbee()) << "Please specify also the node short address and adressMode";
// return;
// }
ZigbeeNode *node = findNode(tokens.at(1));
if (!node) {
qCWarning(dcZigbee()) << "Could not find node with short address tokens.at(1)";
return;
}
// ZigbeeNode *node = findNode(tokens.at(1));
// if (!node) {
// qCWarning(dcZigbee()) << "Could not find node with short address tokens.at(1)";
// return;
// }
int addressMode = QString(tokens.at(2)).toInt();
// int addressMode = QString(tokens.at(2)).toInt();
node->toggle(addressMode);
// node->toggle(addressMode);
} else if (command.command() == "lqi") {
m_manager->requestLinkQuality();
} else if (command.command() == "init-node") {
if (tokens.count() == 1) {
qCWarning(dcZigbee()) << "Please specify also the node short address";
return;
}
// } else if (command.command() == "lqi") {
// m_manager->requestLinkQuality();
// } else if (command.command() == "init-node") {
// if (tokens.count() == 1) {
// qCWarning(dcZigbee()) << "Please specify also the node short address";
// return;
// }
ZigbeeNode *node = findNode(tokens.at(1));
if (!node) {
qCWarning(dcZigbee()) << "Could not find node with short address tokens.at(1)";
return;
}
// ZigbeeNode *node = findNode(tokens.at(1));
// if (!node) {
// qCWarning(dcZigbee()) << "Could not find node with short address tokens.at(1)";
// return;
// }
node->init();
// node->init();
} else if (command.command() == "matchdescriptor") {
m_manager->requestMatchDescriptor(0x9004, Zigbee::ZigbeeProfileLightLink);
//m_manager->requestMatchDescriptor(0xFFFD, Zigbee::ZigbeeProfileLightLink);
// } else if (command.command() == "matchdescriptor") {
// m_manager->requestMatchDescriptor(0x9004, Zigbee::ZigbeeProfileLightLink);
// //m_manager->requestMatchDescriptor(0xFFFD, Zigbee::ZigbeeProfileLightLink);
} else if (command.command() == "authenticate") {
if (tokens.count() == 1) {
qCWarning(dcZigbee()) << "Please specify also the node short address";
return;
}
// } else if (command.command() == "authenticate") {
// if (tokens.count() == 1) {
// qCWarning(dcZigbee()) << "Please specify also the node short address";
// return;
// }
m_manager->authenticateDevice(ZigbeeAddress(tokens.at(1)));
// m_manager->authenticateDevice(ZigbeeAddress(tokens.at(1)));
} else if (command.command() == "list-nodes") {
qCDebug(dcZigbee()) << "--> Host:" << m_manager;
// } else if (command.command() == "list-nodes") {
// qCDebug(dcZigbee()) << "--> Host:" << m_manager;
foreach (ZigbeeNode *node, m_manager->nodeList()) {
qCDebug(dcZigbee()) << " -->" << node;
}
}
// foreach (ZigbeeNode *node, m_manager->nodeList()) {
// qCDebug(dcZigbee()) << " -->" << node;
// }
// }
}
//}

View File

@ -18,7 +18,7 @@ public:
explicit Core(const QString &serialPort, qint32 baudrate, const int &channel, QObject *parent = nullptr);
private:
ZigbeeNetworkManager *m_manager = nullptr;
ZigbeeNetwork *m_network = nullptr;
QList<TerminalCommand> m_commands;
QString m_serialPort;
qint32 m_baudRate;
@ -29,7 +29,7 @@ private:
signals:
private slots:
void onCommandReceived(const QStringList &tokens);
//void onCommandReceived(const QStringList &tokens);
};

View File

@ -1,111 +1,103 @@
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QDateTime>
#include <unistd.h>
#include <stdio.h>
#include <initializer_list>
#include <signal.h>
#include "zigbeenetworkmanager.h"
#include "core.h"
#include "loggingcategory.h"
#include "terminalcommander.h"
//static QHash<QString, bool> s_loggingFilters;
static QHash<QString, bool> s_loggingFilters;
//static bool s_aboutToShutdown = false;
static bool s_aboutToShutdown = false;
//static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vector<int>& ignoreSignals = std::vector<int>()) {
// auto handler = [](int sig) -> void {
// switch (sig) {
// case SIGQUIT:
// qDebug() << "Cought SIGQUIT quit signal...";
// break;
// case SIGINT:
// qDebug() << "Cought SIGINT quit signal...";
// break;
// case SIGTERM:
// qDebug() << "Cought SIGTERM quit signal...";
// break;
// case SIGHUP:
// qDebug() << "Cought SIGHUP quit signal...";
// break;
// case SIGSEGV: {
// qDebug() << "Cought SIGSEGV signal. Segmentation fault!";
// exit(1);
// }
// default:
// break;
// }
static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vector<int>& ignoreSignals = std::vector<int>()) {
auto handler = [](int sig) -> void {
switch (sig) {
case SIGQUIT:
qCDebug(dcZigbee()) << "Cought SIGQUIT quit signal...";
break;
case SIGINT:
qCDebug(dcZigbee()) << "Cought SIGINT quit signal...";
break;
case SIGTERM:
qCDebug(dcZigbee()) << "Cought SIGTERM quit signal...";
break;
case SIGHUP:
qCDebug(dcZigbee()) << "Cought SIGHUP quit signal...";
break;
case SIGSEGV: {
qCDebug(dcZigbee()) << "Cought SIGSEGV signal. Segmentation fault!";
exit(1);
}
default:
break;
}
// if (s_aboutToShutdown) {
// return;
// }
if (s_aboutToShutdown) {
return;
}
s_aboutToShutdown = true;
TerminalCommander::instance()->destroy();
TerminalCommander::instance()->quit();
};
// s_aboutToShutdown = true;
// TerminalCommander::instance()->destroy();
// TerminalCommander::instance()->quit();
// };
// all these signals will be ignored.
for (int sig : ignoreSignals)
signal(sig, SIG_IGN);
// // all these signals will be ignored.
// for (int sig : ignoreSignals)
// signal(sig, SIG_IGN);
for (int sig : quitSignals)
signal(sig, handler);
}
// for (int sig : quitSignals)
// signal(sig, handler);
//}
static void loggingCategoryFilter(QLoggingCategory *category)
{
// If this is a known category
if (s_loggingFilters.contains(category->categoryName())) {
category->setEnabled(QtDebugMsg, s_loggingFilters.value(category->categoryName()));
category->setEnabled(QtWarningMsg, true);
category->setEnabled(QtCriticalMsg, true);
category->setEnabled(QtFatalMsg, true);
} else {
//Disable default debug messages, print only >= warnings
category->setEnabled(QtDebugMsg, false);
category->setEnabled(QtWarningMsg, true);
category->setEnabled(QtCriticalMsg, true);
category->setEnabled(QtFatalMsg, true);
}
}
//static void loggingCategoryFilter(QLoggingCategory *category)
//{
// // If this is a known category
// if (s_loggingFilters.contains(category->categoryName())) {
// category->setEnabled(QtDebugMsg, s_loggingFilters.value(category->categoryName()));
// category->setEnabled(QtWarningMsg, true);
// category->setEnabled(QtCriticalMsg, true);
// category->setEnabled(QtFatalMsg, true);
// } else {
// //Disable default debug messages, print only >= warnings
// category->setEnabled(QtDebugMsg, false);
// category->setEnabled(QtWarningMsg, true);
// category->setEnabled(QtCriticalMsg, true);
// category->setEnabled(QtFatalMsg, true);
// }
//}
static void consoleLogHandler(QtMsgType type, const QMessageLogContext& context, const QString& message)
{
switch (type) {
case QtInfoMsg:
TerminalCommander::instance()->printToTerminal(QString("%1: %2\n").arg(context.category).arg(message.toUtf8().data()));
break;
case QtDebugMsg:
TerminalCommander::instance()->printToTerminal(QString("%1: %2\n").arg(context.category).arg(message.toUtf8().data()));
break;
case QtWarningMsg:
TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorYellow).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
break;
case QtCriticalMsg:
TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorRed).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
break;
case QtFatalMsg:
TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorRed).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
break;
}
}
//static void consoleLogHandler(QtMsgType type, const QMessageLogContext& context, const QString& message)
//{
// switch (type) {
// case QtInfoMsg:
// TerminalCommander::instance()->printToTerminal(QString("%1: %2\n").arg(context.category).arg(message.toUtf8().data()));
// break;
// case QtDebugMsg:
// TerminalCommander::instance()->printToTerminal(QString("%1: %2\n").arg(context.category).arg(message.toUtf8().data()));
// break;
// case QtWarningMsg:
// TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorYellow).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
// break;
// case QtCriticalMsg:
// TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorRed).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
// break;
// case QtFatalMsg:
// TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorRed).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
// break;
// }
//}
int main(int argc, char *argv[])
{
qInstallMessageHandler(consoleLogHandler);
//qInstallMessageHandler(consoleLogHandler);
QCoreApplication application(argc, argv);
catchUnixSignals({SIGQUIT, SIGINT, SIGTERM, SIGHUP, SIGSEGV});
//catchUnixSignals({SIGQUIT, SIGINT, SIGTERM, SIGHUP, SIGSEGV});
application.setOrganizationName("guh");
application.setApplicationName("qt-zigbee");
application.setOrganizationName("nymea");
application.setApplicationName("zigbee-cli");
// Command line parser
QCommandLineParser parser;
@ -146,13 +138,13 @@ int main(int argc, char *argv[])
debugLevel = 1;
}
s_loggingFilters.insert("Application", true);
s_loggingFilters.insert("Zigbee", true);
s_loggingFilters.insert("ZigbeeController", (debugLevel > 1));
s_loggingFilters.insert("ZigbeeInterface", (debugLevel > 2));
s_loggingFilters.insert("ZigbeeInterfaceTraffic", (debugLevel > 3));
// s_loggingFilters.insert("Application", true);
// s_loggingFilters.insert("Zigbee", true);
// s_loggingFilters.insert("ZigbeeController", (debugLevel > 1));
// s_loggingFilters.insert("ZigbeeInterface", (debugLevel > 2));
// s_loggingFilters.insert("ZigbeeInterfaceTraffic", (debugLevel > 3));
QLoggingCategory::installFilter(loggingCategoryFilter);
//QLoggingCategory::installFilter(loggingCategoryFilter);
// Check channel
bool channelValueOk = false;
@ -172,7 +164,13 @@ int main(int argc, char *argv[])
baudrate = 115200;
}
Core core(parser.value(serialOption), baudrate, channel);
ZigbeeNetwork *network = ZigbeeNetworkManager::createZigbeeNetwork(ZigbeeNetworkManager::BackendTypeNxp);
network->setSerialPortName(parser.value(serialOption));
network->setSerialBaudrate(baudrate);
network->setSettingsFileName("/tmp/zigbee.conf");
network->startNetwork();
//Core core(parser.value(serialOption), baudrate, channel);
return application.exec();
}

View File

@ -18,7 +18,7 @@ TerminalCommander *TerminalCommander::instance()
void TerminalCommander::destroy()
{
qCDebug(dcZigbee()) << "Shut down terminal commander. Have a nice day!";
qDebug() << "Shut down terminal commander. Have a nice day!";
stopProcess();
}
@ -62,9 +62,9 @@ void TerminalCommander::run()
{
m_abort = false;
qCDebug(dcZigbee()) << "Command list:";
qDebug() << "Command list:";
foreach (const TerminalCommand &command, m_commands) {
qCDebug(dcZigbee()) << " -->" << command;
qDebug() << " -->" << command;
}
rl_attempted_completion_function = commandCompletion;
@ -91,7 +91,7 @@ void TerminalCommander::run()
rl_on_new_line();
rl_replace_line("", 0);
rl_redisplay();
qCDebug(dcZigbee()) << "Terminal thread stopped";
qDebug() << "Terminal thread stopped";
free(buffer);
stopProcess();
return;
@ -114,7 +114,7 @@ void TerminalCommander::run()
//rl_on_new_line();
//rl_replace_line("", 0);
//rl_redisplay();
//qCDebug(dcZigbee()) << "Terminal thread stopped";
//qDebug() << "Terminal thread stopped";
return;
}
}
@ -155,7 +155,7 @@ void TerminalCommander::rl_printf(const char *fmt, ...)
void TerminalCommander::signalHandler(int status)
{
Q_UNUSED(status)
qCDebug(dcZigbee()) << "Terminal thread stopped";
qDebug() << "Terminal thread stopped";
TerminalCommander::instance()->stopProcess();
}
@ -182,7 +182,7 @@ char **commandCompletion(const char *text, int start, int end)
char *commandCompletionGenerator(const char *text, int state)
{
//qCDebug(dcZigbee()) << text << state;
//qDebug() << text << state;
static int list_index, len;
const char *name;
@ -193,7 +193,7 @@ char *commandCompletionGenerator(const char *text, int state)
}
while (list_index < TerminalCommander::instance()->commands().count() && (name = TerminalCommander::instance()->commands().at(list_index).command().toStdString().data())) {
//qCDebug(dcZigbee()) << " " << TerminalCommander::instance()->commands().at(list_index).command().toStdString().data();
//qDebug() << " " << TerminalCommander::instance()->commands().at(list_index).command().toStdString().data();
list_index++;
if (strncmp (name, text, len) == 0) return strdup (name);
}

View File

@ -5,7 +5,7 @@ CONFIG -= app_bundle
TARGET = zigbee-cli
LIBS += -L$$buildDir/libnymea-zigbee -lnymea-zigbee1 -lreadline
LIBS += -L$$buildDir/libnymea-zigbee -lnymea-zigbee1
INCLUDEPATH += ../libnymea-zigbee/
@ -13,11 +13,11 @@ target.path = /usr/bin
INSTALLS += target
SOURCES += main.cpp \
core.cpp \
terminalcommander.cpp \
terminalcommand.cpp
#core.cpp \
#terminalcommander.cpp \
#terminalcommand.cpp
HEADERS += \
core.h \
terminalcommander.h \
terminalcommand.h
#core.h \
#terminalcommander.h \
#terminalcommand.h