Add command line interface
This commit is contained in:
parent
83b888360a
commit
ef1837f105
8
config.pri
Normal file
8
config.pri
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
QT -= gui
|
||||||
|
QT += serialport
|
||||||
|
|
||||||
|
QMAKE_CXXFLAGS += -Werror -std=c++11
|
||||||
|
QMAKE_LFLAGS += -std=c++11
|
||||||
|
|
||||||
|
sourceDir = $$PWD
|
||||||
|
buildDir = $$shadowed($$PWD)
|
||||||
8
core.cpp
8
core.cpp
@ -1,8 +0,0 @@
|
|||||||
#include "core.h"
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
Core::Core(const int &channel, QObject *parent) :
|
|
||||||
QObject(parent)
|
|
||||||
{
|
|
||||||
m_manager = new ZigbeeNetworkManager(channel, "/dev/ttyS0", this);
|
|
||||||
}
|
|
||||||
2
debian/changelog
vendored
2
debian/changelog
vendored
@ -1,4 +1,4 @@
|
|||||||
qt-zigbee (0.0.1) xenial; urgency=medium
|
qtzigbee (0.0.1) xenial; urgency=medium
|
||||||
|
|
||||||
* Initial release.
|
* Initial release.
|
||||||
|
|
||||||
|
|||||||
52
debian/control
vendored
52
debian/control
vendored
@ -1,4 +1,4 @@
|
|||||||
Source: qt-zigbee
|
Source: qtzigbee
|
||||||
Section: utils
|
Section: utils
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Simon Stuerz <simon.stuerz@guh.io>
|
Maintainer: Simon Stuerz <simon.stuerz@guh.io>
|
||||||
@ -11,18 +11,50 @@ Build-Depends: debhelper (>= 9.0.0),
|
|||||||
qt5-qmake,
|
qt5-qmake,
|
||||||
qtbase5-dev,
|
qtbase5-dev,
|
||||||
qtbase5-dev-tools,
|
qtbase5-dev-tools,
|
||||||
libqt5serialport5-dev
|
libqt5serialport5-dev,
|
||||||
|
libncurses5-dev
|
||||||
|
|
||||||
Package: qt-zigbee
|
Package: zigbee-cli
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: net
|
Section: net
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Depends: libqt5network5,
|
Depends: ${shlibs:Depends},
|
||||||
libqt5gui5,
|
${misc:Depends},
|
||||||
libqt5serialport5,
|
libqtzigbee1 (= ${binary:Version}),
|
||||||
${shlibs:Depends},
|
libncurses5
|
||||||
${misc:Depends}
|
|
||||||
Description: Zigbee bridge controller Qt5 - tool
|
Description: Zigbee bridge controller Qt5 - tool
|
||||||
Tool written in Qt fro interacting with the NXP Zigbee controller.
|
Command line tool written in Qt for interacting with the NXP Zigbee controller.
|
||||||
.
|
.
|
||||||
This package will install the qt-zigbee tool.
|
This package will install the zigbee-cli tool.
|
||||||
|
|
||||||
|
Package: libqtzigbee1
|
||||||
|
Section: libs
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends},
|
||||||
|
${misc:Depends},
|
||||||
|
libqt5network5,
|
||||||
|
libqt5gui5,
|
||||||
|
libqt5serialport5
|
||||||
|
Description: Qt 5 based library for Zigbee
|
||||||
|
Qt 5 based library for Zigbee.
|
||||||
|
|
||||||
|
|
||||||
|
Package: libqtzigbee1-dev
|
||||||
|
Section: libdevel
|
||||||
|
Architecture: any
|
||||||
|
Depends: libqtzigbee1 (= ${binary:Version}),
|
||||||
|
${shlibs:Depends},
|
||||||
|
${misc:Depends}
|
||||||
|
Description: Qt 5 based library for Zigbee - development files
|
||||||
|
Development files for Qt 5 based Zigbee library.
|
||||||
|
|
||||||
|
|
||||||
|
Package: libqtzigbee1-dbg
|
||||||
|
Priority: extra
|
||||||
|
Architecture: any
|
||||||
|
Section: debug
|
||||||
|
Depends: libqtzigbee1 (= ${binary:Version}),
|
||||||
|
${shlibs:Depends},
|
||||||
|
${misc:Depends}
|
||||||
|
Description: Qt 5 based library for Zigbee - debug symbols
|
||||||
|
Debug Symbols for Qt 5 based Zigbee library.
|
||||||
|
|||||||
2
debian/libqtzigbee1-dev.install
vendored
Normal file
2
debian/libqtzigbee1-dev.install
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
usr/lib/libqtzigbee1.so
|
||||||
|
usr/include/qtzigbee/* usr/include/qtzigbee/
|
||||||
3
debian/libqtzigbee1.install
vendored
Normal file
3
debian/libqtzigbee1.install
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
usr/lib/libqtzigbee1.so.1
|
||||||
|
usr/lib/libqtzigbee1.so.1.0
|
||||||
|
usr/lib/libqtzigbee1.so.1.0.0
|
||||||
3
debian/rules
vendored
3
debian/rules
vendored
@ -16,6 +16,9 @@ include /usr/share/dpkg/buildflags.mk
|
|||||||
%:
|
%:
|
||||||
dh $@ --buildsystem=qmake --parallel
|
dh $@ --buildsystem=qmake --parallel
|
||||||
|
|
||||||
|
override_dh_strip:
|
||||||
|
dh_strip --dbg-package=libqtzigbee1-dbg
|
||||||
|
|
||||||
override_dh_auto_build:
|
override_dh_auto_build:
|
||||||
make -j$(DEB_PARALLEL_JOBS)
|
make -j$(DEB_PARALLEL_JOBS)
|
||||||
|
|
||||||
|
|||||||
1
debian/zigbee-cli.install
vendored
Normal file
1
debian/zigbee-cli.install
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
usr/bin/zigbee-cli
|
||||||
42
libqtzigbee/libqtzigbee.pro
Normal file
42
libqtzigbee/libqtzigbee.pro
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
include(../config.pri)
|
||||||
|
|
||||||
|
TARGET = qtzigbee1
|
||||||
|
TEMPLATE = lib
|
||||||
|
|
||||||
|
target.path = /usr/lib
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
interface/zigbeeinterface.cpp \
|
||||||
|
interface/zigbeeinterfacemessage.cpp \
|
||||||
|
interface/zigbeeinterfacerequest.cpp \
|
||||||
|
interface/zigbeeinterfacereply.cpp \
|
||||||
|
zigbeenetworkmanager.cpp \
|
||||||
|
zigbee.cpp \
|
||||||
|
loggingcategory.cpp \
|
||||||
|
zigbeebridgecontroller.cpp \
|
||||||
|
zigbeeutils.cpp \
|
||||||
|
zigbeenode.cpp \
|
||||||
|
zigbeeaddress.cpp \
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
interface/zigbeeinterface.h \
|
||||||
|
interface/zigbeeinterfacemessage.h \
|
||||||
|
interface/zigbeeinterfacerequest.h \
|
||||||
|
interface/zigbeeinterfacereply.h \
|
||||||
|
zigbeenetworkmanager.h \
|
||||||
|
zigbee.h \
|
||||||
|
loggingcategory.h \
|
||||||
|
zigbeebridgecontroller.h \
|
||||||
|
zigbeeutils.h \
|
||||||
|
zigbeenode.h \
|
||||||
|
zigbeeaddress.h \
|
||||||
|
|
||||||
|
INSTALLS += target
|
||||||
|
|
||||||
|
# install header file with relative subdirectory
|
||||||
|
for(header, HEADERS) {
|
||||||
|
path = /usr/include/qtzigbee/$${dirname(header)}
|
||||||
|
eval(headers_$${path}.files += $${header})
|
||||||
|
eval(headers_$${path}.path = $${path})
|
||||||
|
eval(INSTALLS *= headers_$${path})
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ ZigbeeNetworkManager::ZigbeeNetworkManager(const int &channel, const QString &se
|
|||||||
qCDebug(dcZigbee()) << "Bridge controller started successfully on" << serialPort;
|
qCDebug(dcZigbee()) << "Bridge controller started successfully on" << serialPort;
|
||||||
} else {
|
} else {
|
||||||
qCCritical(dcZigbee()) << "The zigbee controller is not available on" << serialPort;
|
qCCritical(dcZigbee()) << "The zigbee controller is not available on" << serialPort;
|
||||||
//return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
@ -55,6 +55,8 @@ ZigbeeNetworkManager::ZigbeeNetworkManager(const int &channel, const QString &se
|
|||||||
permitJoining();
|
permitJoining();
|
||||||
//getPermitJoiningStatus();
|
//getPermitJoiningStatus();
|
||||||
|
|
||||||
|
//startScan();
|
||||||
|
initiateTouchLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ZigbeeNetworkManager::controllerVersion() const
|
QString ZigbeeNetworkManager::controllerVersion() const
|
||||||
@ -249,6 +251,15 @@ void ZigbeeNetworkManager::enableWhitelist()
|
|||||||
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onEnableWhitelistFinished);
|
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onEnableWhitelistFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetworkManager::initiateTouchLink()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceRequest request(ZigbeeInterfaceMessage(Zigbee::MessageTypeInitiateTouchlink));
|
||||||
|
request.setDescription("Initiate touch link");
|
||||||
|
|
||||||
|
ZigbeeInterfaceReply *reply = controller()->sendRequest(request);
|
||||||
|
connect(reply, &ZigbeeInterfaceReply::finished, this, &ZigbeeNetworkManager::onInitiateTouchLinkFinished);
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkManager::requestMatchDescriptor(const quint16 &shortAddress, const Zigbee::ZigbeeProfile &profile)
|
void ZigbeeNetworkManager::requestMatchDescriptor(const quint16 &shortAddress, const Zigbee::ZigbeeProfile &profile)
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
@ -508,6 +519,19 @@ void ZigbeeNetworkManager::onEnableWhitelistFinished()
|
|||||||
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetworkManager::onInitiateTouchLinkFinished()
|
||||||
|
{
|
||||||
|
ZigbeeInterfaceReply *reply = static_cast<ZigbeeInterfaceReply *>(sender());
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
if (reply->status() != ZigbeeInterfaceReply::Success) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could not" << reply->request().description() << reply->status() << reply->statusErrorMessage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeController()) << reply->request().description() << "finished successfully";
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkManager::processLoggingMessage(const ZigbeeInterfaceMessage &message)
|
void ZigbeeNetworkManager::processLoggingMessage(const ZigbeeInterfaceMessage &message)
|
||||||
{
|
{
|
||||||
quint8 logLevel = static_cast<quint8>(message.data().at(0));
|
quint8 logLevel = static_cast<quint8>(message.data().at(0));
|
||||||
@ -746,7 +770,6 @@ void ZigbeeNetworkManager::processAttributeReport(const ZigbeeInterfaceMessage &
|
|||||||
|
|
||||||
void ZigbeeNetworkManager::processLeaveIndication(const ZigbeeInterfaceMessage &message)
|
void ZigbeeNetworkManager::processLeaveIndication(const ZigbeeInterfaceMessage &message)
|
||||||
{
|
{
|
||||||
|
|
||||||
quint16 shortAddress = message.data().at(0);
|
quint16 shortAddress = message.data().at(0);
|
||||||
shortAddress <<= 8;
|
shortAddress <<= 8;
|
||||||
shortAddress |= message.data().at(1);
|
shortAddress |= message.data().at(1);
|
||||||
@ -755,7 +778,7 @@ void ZigbeeNetworkManager::processLeaveIndication(const ZigbeeInterfaceMessage &
|
|||||||
|
|
||||||
qCDebug(dcZigbee()) << "Node leaving:" << ZigbeeUtils::convertUint16ToHexString(shortAddress) << rejoining;
|
qCDebug(dcZigbee()) << "Node leaving:" << ZigbeeUtils::convertUint16ToHexString(shortAddress) << rejoining;
|
||||||
|
|
||||||
// remove node
|
// TODO: remove node
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkManager::onMessageReceived(const ZigbeeInterfaceMessage &message)
|
void ZigbeeNetworkManager::onMessageReceived(const ZigbeeInterfaceMessage &message)
|
||||||
@ -43,6 +43,8 @@ private:
|
|||||||
void getPermitJoiningStatus();
|
void getPermitJoiningStatus();
|
||||||
void enableWhitelist();
|
void enableWhitelist();
|
||||||
|
|
||||||
|
void initiateTouchLink();
|
||||||
|
|
||||||
void requestMatchDescriptor(const quint16 &shortAddress, const Zigbee::ZigbeeProfile &profile);
|
void requestMatchDescriptor(const quint16 &shortAddress, const Zigbee::ZigbeeProfile &profile);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@ -66,6 +68,8 @@ private slots:
|
|||||||
void onPermitJoiningFinished();
|
void onPermitJoiningFinished();
|
||||||
void onEnableWhitelistFinished();
|
void onEnableWhitelistFinished();
|
||||||
|
|
||||||
|
void onInitiateTouchLinkFinished();
|
||||||
|
|
||||||
void onRequestMatchDescriptorFinished();
|
void onRequestMatchDescriptorFinished();
|
||||||
|
|
||||||
|
|
||||||
@ -1,38 +1,5 @@
|
|||||||
QT -= gui
|
TEMPLATE = subdirs
|
||||||
QT += serialport
|
CONFIG += ordered
|
||||||
|
|
||||||
CONFIG += c++11 console
|
SUBDIRS += libqtzigbee zigbee-cli
|
||||||
CONFIG -= app_bundle
|
|
||||||
|
|
||||||
TARGET = zigbee-cli
|
|
||||||
|
|
||||||
target.path = /usr/bin
|
|
||||||
INSTALLS += target
|
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
|
||||||
core.cpp \
|
|
||||||
interface/zigbeeinterface.cpp \
|
|
||||||
interface/zigbeeinterfacemessage.cpp \
|
|
||||||
interface/zigbeeinterfacerequest.cpp \
|
|
||||||
interface/zigbeeinterfacereply.cpp \
|
|
||||||
zigbeenetworkmanager.cpp \
|
|
||||||
zigbee.cpp \
|
|
||||||
loggingcategory.cpp \
|
|
||||||
zigbeebridgecontroller.cpp \
|
|
||||||
zigbeeutils.cpp \
|
|
||||||
zigbeenode.cpp \
|
|
||||||
zigbeeaddress.cpp
|
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
core.h \
|
|
||||||
interface/zigbeeinterface.h \
|
|
||||||
interface/zigbeeinterfacemessage.h \
|
|
||||||
interface/zigbeeinterfacerequest.h \
|
|
||||||
interface/zigbeeinterfacereply.h \
|
|
||||||
zigbeenetworkmanager.h \
|
|
||||||
zigbee.h \
|
|
||||||
loggingcategory.h \
|
|
||||||
zigbeebridgecontroller.h \
|
|
||||||
zigbeeutils.h \
|
|
||||||
zigbeenode.h \
|
|
||||||
zigbeeaddress.h
|
|
||||||
|
|||||||
35
zigbee-cli/core.cpp
Normal file
35
zigbee-cli/core.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "core.h"
|
||||||
|
#include "terminalcommander.h"
|
||||||
|
#include "loggingcategory.h"
|
||||||
|
|
||||||
|
Core::Core(const int &channel, QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
m_manager = new ZigbeeNetworkManager(channel, "/dev/ttyS0", this);
|
||||||
|
|
||||||
|
TerminalCommander::instance();
|
||||||
|
|
||||||
|
// Set commands
|
||||||
|
|
||||||
|
TerminalCommander::instance()->start();
|
||||||
|
|
||||||
|
m_testTimer = new QTimer(this);
|
||||||
|
m_testTimer->setInterval(5000);
|
||||||
|
m_testTimer->setSingleShot(false);
|
||||||
|
|
||||||
|
connect(m_testTimer, &QTimer::timeout, this, &Core::onTimeout);
|
||||||
|
m_testTimer->start();
|
||||||
|
|
||||||
|
connect(TerminalCommander::instance(), &TerminalCommander::commandReceived, this, &Core::onCommandReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::onTimeout()
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbee()) << "[+] This is a test message from the zigbee thread";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::onCommandReceived(const QStringList &tokens)
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbee()) << "Command received:" << tokens;
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,6 +2,11 @@
|
|||||||
#define CORE_H
|
#define CORE_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <readline/readline.h>
|
||||||
|
|
||||||
#include "zigbeenetworkmanager.h"
|
#include "zigbeenetworkmanager.h"
|
||||||
|
|
||||||
@ -13,11 +18,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeNetworkManager *m_manager;
|
ZigbeeNetworkManager *m_manager;
|
||||||
|
QTimer *m_testTimer;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
private slots:
|
||||||
|
void onTimeout();
|
||||||
|
void onCommandReceived(const QStringList &tokens);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CORE_H
|
#endif // CORE_H
|
||||||
@ -1,10 +1,14 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QCommandLineOption>
|
#include <QCommandLineOption>
|
||||||
|
#include <QDateTime>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "zigbeecommander.h"
|
||||||
#include "loggingcategory.h"
|
#include "loggingcategory.h"
|
||||||
|
#include "terminalcommander.h"
|
||||||
|
|
||||||
static const char *const normal = "\033[0m";
|
static const char *const normal = "\033[0m";
|
||||||
static const char *const warning = "\e[33m";
|
static const char *const warning = "\e[33m";
|
||||||
@ -33,25 +37,23 @@ static void consoleLogHandler(QtMsgType type, const QMessageLogContext& context,
|
|||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QtInfoMsg:
|
case QtInfoMsg:
|
||||||
fprintf(stdout, " I | %s: %s\n", context.category, message.toUtf8().data());
|
TerminalCommander::instance()->printToTerminal(QString("%1: %2\n").arg(context.category).arg(message.toUtf8().data()));
|
||||||
break;
|
break;
|
||||||
case QtDebugMsg:
|
case QtDebugMsg:
|
||||||
fprintf(stdout, " I | %s: %s\n", context.category, message.toUtf8().data());
|
TerminalCommander::instance()->printToTerminal(QString("%1: %2\n").arg(context.category).arg(message.toUtf8().data()));
|
||||||
break;
|
break;
|
||||||
case QtWarningMsg:
|
case QtWarningMsg:
|
||||||
fprintf(stdout, "%s W | %s: %s%s\n", warning, context.category, message.toUtf8().data(), normal);
|
TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorYellow).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
|
||||||
break;
|
break;
|
||||||
case QtCriticalMsg:
|
case QtCriticalMsg:
|
||||||
fprintf(stdout, "%s C | %s: %s%s\n", error, context.category, message.toUtf8().data(), normal);
|
TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorRed).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
|
||||||
break;
|
break;
|
||||||
case QtFatalMsg:
|
case QtFatalMsg:
|
||||||
fprintf(stdout, "%s F | %s: %s%s\n", error, context.category, message.toUtf8().data(), normal);
|
TerminalCommander::instance()->printToTerminal(QString("%1%2: %3%4\n").arg(terminalColorRed).arg(context.category).arg(message.toUtf8().data()).arg(terminalColorNormal));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
qInstallMessageHandler(consoleLogHandler);
|
qInstallMessageHandler(consoleLogHandler);
|
||||||
@ -105,8 +107,6 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Core core(channel);
|
Core core(channel);
|
||||||
|
|
||||||
return application.exec();
|
return application.exec();
|
||||||
6
zigbee-cli/terminalcommand.cpp
Normal file
6
zigbee-cli/terminalcommand.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "terminalcommand.h"
|
||||||
|
|
||||||
|
TerminalCommand::TerminalCommand(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
17
zigbee-cli/terminalcommand.h
Normal file
17
zigbee-cli/terminalcommand.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef TERMINALCOMMAND_H
|
||||||
|
#define TERMINALCOMMAND_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class TerminalCommand : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TerminalCommand(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TERMINALCOMMAND_H
|
||||||
145
zigbee-cli/terminalcommander.cpp
Normal file
145
zigbee-cli/terminalcommander.cpp
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList TerminalCommander::commands() const
|
||||||
|
{
|
||||||
|
return m_commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalCommander::TerminalCommander(QObject *parent) :
|
||||||
|
QThread(parent)
|
||||||
|
{
|
||||||
|
m_commands.append("start");
|
||||||
|
m_commands.append("stop");
|
||||||
|
m_commands.append("explode");
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalCommander::~TerminalCommander()
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
m_abort = true;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalCommander::printToTerminal(const QString &message)
|
||||||
|
{
|
||||||
|
rl_printf("%s", message.toStdString().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalCommander::stopProcess()
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
m_abort = true;
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalCommander::run()
|
||||||
|
{
|
||||||
|
m_abort = false;
|
||||||
|
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);
|
||||||
|
|
||||||
|
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(" ");
|
||||||
|
emit commandReceived(tokens);
|
||||||
|
add_history(buffer);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_abort)
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//qCDebug(dcZigbee) << text << state << TerminalCommander::instance()->commands();
|
||||||
|
|
||||||
|
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).toStdString().data())) {
|
||||||
|
list_index++;
|
||||||
|
if (strncmp (name, text, len) == 0) return strdup (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no names matched, then return NULL.
|
||||||
|
return ((char *) NULL);
|
||||||
|
}
|
||||||
54
zigbee-cli/terminalcommander.h
Normal file
54
zigbee-cli/terminalcommander.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#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>
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
QStringList commands() const;
|
||||||
|
void printToTerminal(const QString &message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit TerminalCommander(QObject *parent = nullptr);
|
||||||
|
~TerminalCommander();
|
||||||
|
|
||||||
|
bool m_abort = false;
|
||||||
|
QMutex mutex;
|
||||||
|
|
||||||
|
QStringList m_commands;
|
||||||
|
|
||||||
|
static void rl_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void commandReceived(const QStringList &tokens);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void stopProcess();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TERMINALCOMMANDER_H
|
||||||
23
zigbee-cli/zigbee-cli.pro
Normal file
23
zigbee-cli/zigbee-cli.pro
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
include(../config.pri)
|
||||||
|
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
TARGET = zigbee-cli
|
||||||
|
|
||||||
|
LIBS += -lncurses -L$$buildDir/libqtzigbee -lqtzigbee1 -lreadline
|
||||||
|
|
||||||
|
INCLUDEPATH += ../libqtzigbee/
|
||||||
|
|
||||||
|
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