From 9ef73e407b37ddb3d0085935ab586d49511c6845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 25 Sep 2020 13:42:55 +0200 Subject: [PATCH] Test get version command for initial communication tests --- .../deconz/zigbeebridgecontrollerdeconz.cpp | 2 + .../nxp/interface/zigbeeinterfacenxp.cpp | 16 +- .../nxp/interface/zigbeeinterfacenxpreply.cpp | 76 +++++ .../nxp/interface/zigbeeinterfacenxpreply.h | 62 ++++ .../nxp/zigbeebridgecontrollernxp.cpp | 56 ++++ .../backends/nxp/zigbeebridgecontrollernxp.h | 10 + .../backends/nxp/zigbeenetworknxp.cpp | 14 +- .../backends/nxp/zigbeenetworknxp.h | 6 +- libnymea-zigbee/libnymea-zigbee.pro | 2 + libnymea-zigbee/zigbeenetworkmanager.cpp | 7 +- libnymea-zigbee/zigbeenetworkmanager.h | 8 +- nymea-zigbee.pro | 2 +- zigbee-cli/core.cpp | 288 +++++++++--------- zigbee-cli/core.h | 4 +- zigbee-cli/main.cpp | 184 ++++++----- zigbee-cli/terminalcommander.cpp | 16 +- zigbee-cli/zigbee-cli.pro | 14 +- 17 files changed, 496 insertions(+), 271 deletions(-) create mode 100644 libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.cpp create mode 100644 libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.h diff --git a/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp b/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp index d990501..45772f9 100644 --- a/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp +++ b/libnymea-zigbee/backends/deconz/zigbeebridgecontrollerdeconz.cpp @@ -36,6 +36,8 @@ ZigbeeBridgeControllerDeconz::ZigbeeBridgeControllerDeconz(QObject *parent) : ZigbeeBridgeController(parent) { + qRegisterMetaType(); + m_interface = new ZigbeeInterfaceDeconz(this); connect(m_interface, &ZigbeeInterfaceDeconz::availableChanged, this, &ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged); connect(m_interface, &ZigbeeInterfaceDeconz::packageReceived, this, &ZigbeeBridgeControllerDeconz::onInterfacePackageReceived); diff --git a/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxp.cpp b/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxp.cpp index 574acb0..bf319cf 100644 --- a/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxp.cpp +++ b/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxp.cpp @@ -36,6 +36,8 @@ ZigbeeInterfaceNxp::ZigbeeInterfaceNxp(QObject *parent) : QObject(parent) { + qRegisterMetaType(); + 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(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(ProtocolByteEnd); // Start with SLIP END character + //stream << static_cast(ProtocolByteEnd); // Start with SLIP END character for (int i = 0; i < serializedData.length(); i++) stream << static_cast(serializedData.at(i)); diff --git a/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.cpp b/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.cpp new file mode 100644 index 0000000..dcd443e --- /dev/null +++ b/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.cpp @@ -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(); +} diff --git a/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.h b/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.h new file mode 100644 index 0000000..2140d4b --- /dev/null +++ b/libnymea-zigbee/backends/nxp/interface/zigbeeinterfacenxpreply.h @@ -0,0 +1,62 @@ +#ifndef ZIGBEEINTERFACENXPREPLY_H +#define ZIGBEEINTERFACENXPREPLY_H + +#include +#include + +#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 diff --git a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp index b778f1e..7437638 100644 --- a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp +++ b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.cpp @@ -1,9 +1,65 @@ #include "zigbeebridgecontrollernxp.h" +#include "loggingcategory.h" + +#include 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(Nxp::CommandGetVersion); + stream << static_cast(m_sequenceNumber); + stream << static_cast(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) diff --git a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h index 4ae462c..c198818 100644 --- a/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h +++ b/libnymea-zigbee/backends/nxp/zigbeebridgecontrollernxp.h @@ -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(); diff --git a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp index 17f63bc..89410cc 100644 --- a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp +++ b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.cpp @@ -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() diff --git a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h index a5e260e..6dbcfa9 100644 --- a/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h +++ b/libnymea-zigbee/backends/nxp/zigbeenetworknxp.h @@ -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: diff --git a/libnymea-zigbee/libnymea-zigbee.pro b/libnymea-zigbee/libnymea-zigbee.pro index 74df3a3..403df96 100644 --- a/libnymea-zigbee/libnymea-zigbee.pro +++ b/libnymea-zigbee/libnymea-zigbee.pro @@ -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 \ diff --git a/libnymea-zigbee/zigbeenetworkmanager.cpp b/libnymea-zigbee/zigbeenetworkmanager.cpp index 4702612..46483cf 100644 --- a/libnymea-zigbee/zigbeenetworkmanager.cpp +++ b/libnymea-zigbee/zigbeenetworkmanager.cpp @@ -28,13 +28,14 @@ #include "zigbeenetworkmanager.h" #include "loggingcategory.h" +#include "backends/nxp/zigbeenetworknxp.h" #include "backends/deconz/zigbeenetworkdeconz.h" #include 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(QDateTime::currentMSecsSinceEpoch() / 1000)); switch (backend) { -// case BackendTypeNxp: -// return qobject_cast(new ZigbeeNetworkNxp(parent)); + case BackendTypeNxp: + return qobject_cast(new ZigbeeNetworkNxp(parent)); case BackendTypeDeconz: return qobject_cast(new ZigbeeNetworkDeconz(parent)); } diff --git a/libnymea-zigbee/zigbeenetworkmanager.h b/libnymea-zigbee/zigbeenetworkmanager.h index a78e058..2e86a22 100644 --- a/libnymea-zigbee/zigbeenetworkmanager.h +++ b/libnymea-zigbee/zigbeenetworkmanager.h @@ -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); diff --git a/nymea-zigbee.pro b/nymea-zigbee.pro index f2af4eb..dbc7bcb 100644 --- a/nymea-zigbee.pro +++ b/nymea-zigbee.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs CONFIG += ordered -SUBDIRS += libnymea-zigbee #zigbee-cli +SUBDIRS += libnymea-zigbee zigbee-cli diff --git a/zigbee-cli/core.cpp b/zigbee-cli/core.cpp index 387a5e3..2da46ea 100644 --- a/zigbee-cli/core.cpp +++ b/zigbee-cli/core.cpp @@ -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; +// } +// } -} +//} diff --git a/zigbee-cli/core.h b/zigbee-cli/core.h index 695f9be..062636d 100644 --- a/zigbee-cli/core.h +++ b/zigbee-cli/core.h @@ -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 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); }; diff --git a/zigbee-cli/main.cpp b/zigbee-cli/main.cpp index 5705a30..0f889f1 100644 --- a/zigbee-cli/main.cpp +++ b/zigbee-cli/main.cpp @@ -1,111 +1,103 @@ #include #include #include -#include -#include -#include -#include -#include +#include "zigbeenetworkmanager.h" -#include "core.h" -#include "loggingcategory.h" -#include "terminalcommander.h" +//static QHash s_loggingFilters; -static QHash s_loggingFilters; +//static bool s_aboutToShutdown = false; -static bool s_aboutToShutdown = false; +//static void catchUnixSignals(const std::vector& quitSignals, const std::vector& ignoreSignals = std::vector()) { +// 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& quitSignals, const std::vector& ignoreSignals = std::vector()) { - 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(); } diff --git a/zigbee-cli/terminalcommander.cpp b/zigbee-cli/terminalcommander.cpp index 66b34a8..7bdd18a 100644 --- a/zigbee-cli/terminalcommander.cpp +++ b/zigbee-cli/terminalcommander.cpp @@ -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); } diff --git a/zigbee-cli/zigbee-cli.pro b/zigbee-cli/zigbee-cli.pro index a0bbe74..b2f4237 100644 --- a/zigbee-cli/zigbee-cli.pro +++ b/zigbee-cli/zigbee-cli.pro @@ -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