Drop unfinished and unneeded zigbe-cli
This commit is contained in:
parent
804e416b1b
commit
2735223d19
@ -1,4 +1,2 @@
|
||||
TEMPLATE = subdirs
|
||||
CONFIG += ordered
|
||||
|
||||
SUBDIRS += libnymea-zigbee #zigbee-cli
|
||||
SUBDIRS += libnymea-zigbee
|
||||
|
||||
@ -1,194 +0,0 @@
|
||||
#include "core.h"
|
||||
#include "loggingcategory.h"
|
||||
#include "zigbeeutils.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
Core::Core(const QString &serialPort, qint32 baudrate, const int &channel, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_serialPort(serialPort),
|
||||
m_baudRate(baudrate)
|
||||
{
|
||||
m_channelMask = 0;
|
||||
m_channelMask |= 1 << (channel);
|
||||
|
||||
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);
|
||||
|
||||
// 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();
|
||||
|
||||
// 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;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return nullptr;
|
||||
//}
|
||||
|
||||
//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;
|
||||
// }
|
||||
|
||||
// // TODO: Process command
|
||||
// qCDebug(dcZigbee()) << "Executing" << tokens.join(" ");
|
||||
|
||||
// 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;
|
||||
// }
|
||||
|
||||
// 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");
|
||||
|
||||
// } 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());
|
||||
|
||||
// } 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;
|
||||
// }
|
||||
|
||||
// int addressMode = QString(tokens.at(2)).toInt();
|
||||
|
||||
// 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;
|
||||
// }
|
||||
|
||||
// ZigbeeNode *node = findNode(tokens.at(1));
|
||||
// if (!node) {
|
||||
// qCWarning(dcZigbee()) << "Could not find node with short address tokens.at(1)";
|
||||
// return;
|
||||
// }
|
||||
|
||||
// node->init();
|
||||
|
||||
// } 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;
|
||||
// }
|
||||
|
||||
// m_manager->authenticateDevice(ZigbeeAddress(tokens.at(1)));
|
||||
|
||||
// } else if (command.command() == "list-nodes") {
|
||||
// qCDebug(dcZigbee()) << "--> Host:" << m_manager;
|
||||
|
||||
// foreach (ZigbeeNode *node, m_manager->nodeList()) {
|
||||
// qCDebug(dcZigbee()) << " -->" << node;
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
@ -1,36 +0,0 @@
|
||||
#ifndef CORE_H
|
||||
#define CORE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <readline/readline.h>
|
||||
|
||||
#include "terminalcommander.h"
|
||||
#include "zigbeenetworkmanager.h"
|
||||
|
||||
class Core : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Core(const QString &serialPort, qint32 baudrate, const int &channel, QObject *parent = nullptr);
|
||||
|
||||
private:
|
||||
ZigbeeNetwork *m_network = nullptr;
|
||||
QList<TerminalCommand> m_commands;
|
||||
QString m_serialPort;
|
||||
qint32 m_baudRate;
|
||||
quint32 m_channelMask = 0;
|
||||
|
||||
ZigbeeNode *findNode(const QString &shortAddressString);
|
||||
|
||||
signals:
|
||||
|
||||
private slots:
|
||||
//void onCommandReceived(const QStringList &tokens);
|
||||
|
||||
};
|
||||
|
||||
#endif // CORE_H
|
||||
@ -1,191 +0,0 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
#include <QLoggingCategory>
|
||||
#include "zigbeenetworkkey.h"
|
||||
#include "zigbeenetworkmanager.h"
|
||||
|
||||
//static QHash<QString, bool> s_loggingFilters;
|
||||
|
||||
//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;
|
||||
// }
|
||||
|
||||
// if (s_aboutToShutdown) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// s_aboutToShutdown = true;
|
||||
// TerminalCommander::instance()->destroy();
|
||||
// TerminalCommander::instance()->quit();
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// // all these signals will be ignored.
|
||||
// for (int sig : ignoreSignals)
|
||||
// signal(sig, SIG_IGN);
|
||||
|
||||
// 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 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);
|
||||
|
||||
QCoreApplication application(argc, argv);
|
||||
|
||||
//catchUnixSignals({SIGQUIT, SIGINT, SIGTERM, SIGHUP, SIGSEGV});
|
||||
|
||||
application.setOrganizationName("nymea");
|
||||
application.setApplicationName("zigbee-cli");
|
||||
|
||||
// Command line parser
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
parser.setApplicationDescription(QString("\nCommand line tool for the zigbee NXP uart control bridge.\n\nCopyright %1 2018 Simon Stürz <simon.stuerz@guh.io>\nAll rights reserved.").arg(QChar(0xA9)));
|
||||
|
||||
// Debug level
|
||||
QCommandLineOption debugLevelOption(QStringList() << "d" << "debug-level", "Set debug level [1-4]. Default 1.");
|
||||
debugLevelOption.setDefaultValue("1");
|
||||
debugLevelOption.setValueName("level");
|
||||
parser.addOption(debugLevelOption);
|
||||
|
||||
// Debug level
|
||||
QCommandLineOption serialOption(QStringList() << "s" << "serial-port", "Set the serial port for the NXP controller. Default '/dev/ttyUSB0'.");
|
||||
serialOption.setDefaultValue("/dev/ttyUSB0");
|
||||
serialOption.setValueName("port");
|
||||
parser.addOption(serialOption);
|
||||
|
||||
QCommandLineOption baudOption(QStringList() << "b" << "baudrate", "Set the serial port baud rate for the NXP controller. Default '115200'.");
|
||||
baudOption.setDefaultValue("115200");
|
||||
baudOption.setValueName("baudrate");
|
||||
parser.addOption(baudOption);
|
||||
|
||||
// Channel
|
||||
QCommandLineOption channelOption(QStringList() << "c" << "channel", "Set channel for the zigbee network. Channel between [11-26] are allowed. If not specified, the quitest channel will be choosen automatically.");
|
||||
channelOption.setDefaultValue("0");
|
||||
channelOption.setValueName("channel");
|
||||
parser.addOption(channelOption);
|
||||
|
||||
parser.process(application);
|
||||
|
||||
// Check debug level
|
||||
bool debugLevelValueOk = false;
|
||||
int debugLevel = parser.value(debugLevelOption).toInt(&debugLevelValueOk);
|
||||
if (debugLevel < 1 || debugLevel > 4 || !debugLevelValueOk) {
|
||||
qCritical() << "Invalid debug level passed:" << parser.value(debugLevelOption) << "Reset to default debug level 1.";
|
||||
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));
|
||||
|
||||
//QLoggingCategory::installFilter(loggingCategoryFilter);
|
||||
|
||||
QLoggingCategory::setFilterRules("*.debug=false\n"
|
||||
"Zigbee.debug=true\n"
|
||||
"ZigbeeController.debug=true\n"
|
||||
"ZigbeeInterface.debug=false\n"
|
||||
"ZigbeeInterfaceTraffic.debug=false\n"
|
||||
);
|
||||
|
||||
// Check channel
|
||||
bool channelValueOk = false;
|
||||
int channel = parser.value(channelOption).toInt(&channelValueOk);
|
||||
if (channel != 0) {
|
||||
if (channel < 11 || channel > 26 || !channelValueOk) {
|
||||
qCritical() << "Invalid channel value passed:" << parser.value(channelOption) << "Selecting automatically quitest channel.";
|
||||
channel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Check baud rate value
|
||||
bool baudrateValueOk = false;
|
||||
int baudrate = parser.value(baudOption).toInt(&baudrateValueOk);
|
||||
if (!debugLevelValueOk) {
|
||||
qCritical() << "Invalid baud rate passed:" << parser.value(baudOption) << "Reset to default baudrate 115200.";
|
||||
baudrate = 115200;
|
||||
}
|
||||
|
||||
ZigbeeNetwork *network = ZigbeeNetworkManager::createZigbeeNetwork(ZigbeeNetworkManager::BackendTypeNxp);
|
||||
network->setSerialPortName(parser.value(serialOption));
|
||||
network->setSerialBaudrate(baudrate);
|
||||
network->setSettingsFileName("/tmp/zigbee.conf");
|
||||
network->setExtendedPanId(5);
|
||||
ZigbeeChannelMask mask;
|
||||
mask.setChannel(Zigbee::ZigbeeChannel13);
|
||||
network->setChannelMask(mask);
|
||||
|
||||
ZigbeeSecurityConfiguration securityConfiguration;
|
||||
securityConfiguration.setNetworkKey(ZigbeeNetworkKey(QString("2a:59:f4:11:75:bb:64:48:55:c5:23:62:b0:33:ea:33")));
|
||||
network->setSecurityConfiguration(securityConfiguration);
|
||||
|
||||
network->startNetwork();
|
||||
|
||||
return application.exec();
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
#include "terminalcommand.h"
|
||||
|
||||
TerminalCommand::TerminalCommand()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TerminalCommand::TerminalCommand(const QString &command, const QString &description) :
|
||||
m_command(command),
|
||||
m_description(description)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString TerminalCommand::command() const
|
||||
{
|
||||
return m_command;
|
||||
}
|
||||
|
||||
void TerminalCommand::setCommand(const QString &command)
|
||||
{
|
||||
m_command = command;
|
||||
}
|
||||
|
||||
QString TerminalCommand::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void TerminalCommand::setDescription(const QString &description)
|
||||
{
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
QStringList TerminalCommand::mandatoryParameters() const
|
||||
{
|
||||
return m_mandatorysParameters;
|
||||
}
|
||||
|
||||
void TerminalCommand::setMandatoryParameters(const QStringList ¶meters)
|
||||
{
|
||||
m_mandatorysParameters = parameters;
|
||||
}
|
||||
|
||||
QStringList TerminalCommand::optionalParameters() const
|
||||
{
|
||||
return m_optionalParameters;
|
||||
}
|
||||
|
||||
void TerminalCommand::setOptionalParameters(const QStringList ¶meters)
|
||||
{
|
||||
m_optionalParameters = parameters;
|
||||
}
|
||||
|
||||
QString TerminalCommand::defaultParameter() const
|
||||
{
|
||||
return m_defaultParamter;
|
||||
}
|
||||
|
||||
void TerminalCommand::setDefaultParameters(const QString ¶meter)
|
||||
{
|
||||
m_defaultParamter = parameter;
|
||||
}
|
||||
|
||||
bool TerminalCommand::isValid()
|
||||
{
|
||||
return !m_command.isEmpty() && !m_description.isEmpty();
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const TerminalCommand &command)
|
||||
{
|
||||
debug << command.command() << command.description();
|
||||
return debug;
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
#ifndef TERMINALCOMMAND_H
|
||||
#define TERMINALCOMMAND_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
class TerminalCommand
|
||||
{
|
||||
public:
|
||||
explicit TerminalCommand();
|
||||
explicit TerminalCommand(const QString &command, const QString &description);
|
||||
|
||||
QString command() const;
|
||||
void setCommand(const QString &command);
|
||||
|
||||
QString description() const;
|
||||
void setDescription(const QString &description);
|
||||
|
||||
QStringList mandatoryParameters() const;
|
||||
void setMandatoryParameters(const QStringList ¶meters);
|
||||
|
||||
QStringList optionalParameters() const;
|
||||
void setOptionalParameters(const QStringList ¶meters);
|
||||
|
||||
QString defaultParameter() const;
|
||||
void setDefaultParameters(const QString ¶meter);
|
||||
|
||||
bool isValid();
|
||||
|
||||
private:
|
||||
QString m_command;
|
||||
QString m_description;
|
||||
QString m_defaultParamter;
|
||||
QStringList m_mandatorysParameters;
|
||||
QStringList m_optionalParameters;
|
||||
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, const TerminalCommand &command);
|
||||
|
||||
|
||||
#endif // TERMINALCOMMAND_H
|
||||
@ -1,203 +0,0 @@
|
||||
#include "terminalcommander.h"
|
||||
#include "loggingcategory.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
static char **commandCompletion(const char* text, int start, int end);
|
||||
static char *commandCompletionGenerator(const char *text, int state);
|
||||
|
||||
static TerminalCommander *s_instance = nullptr;
|
||||
|
||||
TerminalCommander *TerminalCommander::instance()
|
||||
{
|
||||
if (!s_instance)
|
||||
s_instance = new TerminalCommander();
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void TerminalCommander::destroy()
|
||||
{
|
||||
qDebug() << "Shut down terminal commander. Have a nice day!";
|
||||
stopProcess();
|
||||
}
|
||||
|
||||
QList<TerminalCommand> TerminalCommander::commands() const
|
||||
{
|
||||
return m_commands;
|
||||
}
|
||||
|
||||
void TerminalCommander::setCommands(QList<TerminalCommand> commands)
|
||||
{
|
||||
m_commands.append(commands);
|
||||
}
|
||||
|
||||
TerminalCommander::TerminalCommander(QObject *parent) :
|
||||
QThread(parent)
|
||||
{
|
||||
// Native terminal commands
|
||||
m_commands.append(TerminalCommand("exit", "Exit this application"));
|
||||
m_commands.append(TerminalCommand("quit", "Quit this application"));
|
||||
m_commands.append(TerminalCommand("help", "Print this help message"));
|
||||
}
|
||||
|
||||
TerminalCommander::~TerminalCommander()
|
||||
{
|
||||
destroy();
|
||||
wait();
|
||||
}
|
||||
|
||||
void TerminalCommander::printToTerminal(const QString &message)
|
||||
{
|
||||
rl_printf("%s", message.toStdString().data());
|
||||
}
|
||||
|
||||
void TerminalCommander::stopProcess()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_abort = true;
|
||||
}
|
||||
|
||||
void TerminalCommander::run()
|
||||
{
|
||||
m_abort = false;
|
||||
|
||||
qDebug() << "Command list:";
|
||||
foreach (const TerminalCommand &command, m_commands) {
|
||||
qDebug() << " -->" << command;
|
||||
}
|
||||
|
||||
rl_attempted_completion_function = commandCompletion;
|
||||
|
||||
rl_set_prompt(QString("%1[zigbee]%2 ").arg(terminalColorBoldGray).arg(terminalColorNormal).toStdString().data());
|
||||
rl_redisplay();
|
||||
rl_bind_key('\t',rl_complete);
|
||||
|
||||
rl_set_signals();
|
||||
|
||||
//rl_clear_signals();
|
||||
rl_catch_signals = 1;
|
||||
|
||||
while (true) {
|
||||
char *buffer = readline(QString("%1[zigbee]%2 ").arg(terminalColorBoldGray).arg(terminalColorNormal).toStdString().data());
|
||||
rl_bind_key('\t',rl_complete);
|
||||
if (buffer) {
|
||||
if (!QString(buffer).isEmpty()) {
|
||||
QStringList tokens = QString(buffer).split(" ");
|
||||
|
||||
// Check quit
|
||||
if (tokens.count() == 1 && (tokens.first() == "quit" || tokens.first() == "exit")) {
|
||||
qDebug() << "";
|
||||
rl_on_new_line();
|
||||
rl_replace_line("", 0);
|
||||
rl_redisplay();
|
||||
qDebug() << "Terminal thread stopped";
|
||||
free(buffer);
|
||||
stopProcess();
|
||||
return;
|
||||
|
||||
} else if (tokens.count() == 1 && (tokens.first() == "?" || tokens.first() == "help")) {
|
||||
printHelpMessage();
|
||||
add_history(buffer);
|
||||
free(buffer);
|
||||
} else {
|
||||
emit commandReceived(tokens);
|
||||
add_history(buffer);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (m_abort) {
|
||||
//qDebug() << "";
|
||||
//rl_on_new_line();
|
||||
//rl_replace_line("", 0);
|
||||
//rl_redisplay();
|
||||
//qDebug() << "Terminal thread stopped";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
void TerminalCommander::rl_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
bool save_input;
|
||||
char *saved_line;
|
||||
int saved_point;
|
||||
|
||||
save_input = !RL_ISSTATE(RL_STATE_DONE);
|
||||
|
||||
if (save_input) {
|
||||
saved_point = rl_point;
|
||||
saved_line = rl_copy_text(0, rl_end);
|
||||
rl_save_prompt();
|
||||
rl_replace_line("", 0);
|
||||
rl_redisplay();
|
||||
}
|
||||
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (save_input) {
|
||||
rl_restore_prompt();
|
||||
rl_replace_line(saved_line, 0);
|
||||
rl_point = saved_point;
|
||||
rl_redisplay();
|
||||
free(saved_line);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalCommander::signalHandler(int status)
|
||||
{
|
||||
Q_UNUSED(status)
|
||||
qDebug() << "Terminal thread stopped";
|
||||
TerminalCommander::instance()->stopProcess();
|
||||
}
|
||||
|
||||
void TerminalCommander::printHelpMessage()
|
||||
{
|
||||
for (int i = 0; i < m_commands.count(); i++) {
|
||||
QString command = QString("\t%1 %2").arg(m_commands.at(i).command(), -20).arg(m_commands.at(i).description());
|
||||
rl_printf("%s\n",command.toStdString().data());
|
||||
}
|
||||
}
|
||||
|
||||
char **commandCompletion(const char *text, int start, int end)
|
||||
{
|
||||
Q_UNUSED(end)
|
||||
rl_completion_append_character = '\0';
|
||||
|
||||
char **matches = (char **) NULL;
|
||||
if (start == 0) {
|
||||
matches = rl_completion_matches ((char *) text, &commandCompletionGenerator);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
char *commandCompletionGenerator(const char *text, int state)
|
||||
{
|
||||
//qDebug() << text << state;
|
||||
|
||||
static int list_index, len;
|
||||
const char *name;
|
||||
|
||||
if (!state) {
|
||||
list_index = 0;
|
||||
len = strlen(text);
|
||||
}
|
||||
|
||||
while (list_index < TerminalCommander::instance()->commands().count() && (name = 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);
|
||||
}
|
||||
|
||||
// If no names matched, then return NULL.
|
||||
return ((char *) NULL);
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
#ifndef TERMINALCOMMANDER_H
|
||||
#define TERMINALCOMMANDER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#include "terminalcommand.h"
|
||||
|
||||
static const char *const terminalColorNormal = "\033[0m";
|
||||
static const char *const terminalColorYellow = "\x1B[0;93m";
|
||||
static const char *const terminalColorRed = "\x1B[0;91m";
|
||||
static const char *const terminalColorBlue = "\x1B[0;94m";
|
||||
static const char *const terminalColorGreen = "\e[31m";
|
||||
static const char *const terminalColorBoldGray = "\x1B[1;30m";
|
||||
static const char *const terminalColorBoldNormal = "\x1B[1;37m";
|
||||
|
||||
class TerminalCommander : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static TerminalCommander* instance();
|
||||
void destroy();
|
||||
|
||||
QList<TerminalCommand> commands() const;
|
||||
void setCommands(QList<TerminalCommand> commands);
|
||||
|
||||
void printToTerminal(const QString &message);
|
||||
|
||||
private:
|
||||
explicit TerminalCommander(QObject *parent = nullptr);
|
||||
~TerminalCommander();
|
||||
|
||||
QList<TerminalCommand> m_commands;
|
||||
|
||||
QMutex m_mutex;
|
||||
bool m_abort = false;
|
||||
|
||||
static void rl_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
static void signalHandler(int status);
|
||||
|
||||
void printHelpMessage();
|
||||
|
||||
signals:
|
||||
void commandReceived(const QStringList &tokens);
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
|
||||
public slots:
|
||||
void stopProcess();
|
||||
|
||||
};
|
||||
|
||||
#endif // TERMINALCOMMANDER_H
|
||||
@ -1,26 +0,0 @@
|
||||
include(../config.pri)
|
||||
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
|
||||
TARGET = zigbee-cli
|
||||
|
||||
LIBS += -L$$buildDir/libnymea-zigbee -lnymea-zigbee1
|
||||
|
||||
win32:LIBS += -L$$buildDir/libnymea-zigbee/debug -lnymea-zigbee1
|
||||
|
||||
|
||||
INCLUDEPATH += ../libnymea-zigbee/
|
||||
|
||||
target.path = /usr/bin
|
||||
INSTALLS += target
|
||||
|
||||
SOURCES += main.cpp \
|
||||
#core.cpp \
|
||||
#terminalcommander.cpp \
|
||||
#terminalcommand.cpp
|
||||
|
||||
HEADERS += \
|
||||
#core.h \
|
||||
#terminalcommander.h \
|
||||
#terminalcommand.h
|
||||
Reference in New Issue
Block a user