Merge remote-tracking branch 'origin/master' into enhanced_device
This commit is contained in:
+3
-1
@@ -1,4 +1,4 @@
|
|||||||
# 3.4 (2019-10-?)
|
# 3.4 (2019-10-27)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
* fix for always enabled "--mqttchanges" option
|
* fix for always enabled "--mqttchanges" option
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
* fix for compilation and running on FreeBSD and MacOS with low latency setting for FTDI device (thanks to samm-git)
|
* fix for compilation and running on FreeBSD and MacOS with low latency setting for FTDI device (thanks to samm-git)
|
||||||
* fix for switching to daemon mode when log file was not opened
|
* fix for switching to daemon mode when log file was not opened
|
||||||
* fix for checking required arguments of "write" command with "-h"
|
* fix for checking required arguments of "write" command with "-h"
|
||||||
|
* fix for potential MQTT reconnect issue after lost connection
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* added option to set poll priority with MQTT get topic
|
* added option to set poll priority with MQTT get topic
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
* added MQTT /list topic for retrieval of all known messages
|
* added MQTT /list topic for retrieval of all known messages
|
||||||
* added support for init scripts on non-LSB distributions (thanks to andr2000)
|
* added support for init scripts on non-LSB distributions (thanks to andr2000)
|
||||||
* added support for logging to syslog instead of file (thanks to samm-git)
|
* added support for logging to syslog instead of file (thanks to samm-git)
|
||||||
|
* added adjustable verbosity and option to include unknown messages to "listen" command
|
||||||
|
|
||||||
|
|
||||||
# 3.3 (2018-12-26)
|
# 3.3 (2018-12-26)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Contributor: Milan Knizek <knizek volny cz>
|
# Contributor: Milan Knizek <knizek volny cz>
|
||||||
# Usage: makepkg
|
# Usage: makepkg
|
||||||
pkgname=ebusd
|
pkgname=ebusd
|
||||||
pkgver=3.3
|
pkgver=3.4
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="ebusd, the daemon for communication with eBUS heating systems."
|
pkgdesc="ebusd, the daemon for communication with eBUS heating systems."
|
||||||
arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
|
arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
|
||||||
@@ -37,4 +37,4 @@ package() {
|
|||||||
install -m 0644 contrib/archlinux/conf.d/ebusd "${pkgdir}/etc/conf.d/ebusd"
|
install -m 0644 contrib/archlinux/conf.d/ebusd "${pkgdir}/etc/conf.d/ebusd"
|
||||||
}
|
}
|
||||||
# update md5sums: updpkgsums
|
# update md5sums: updpkgsums
|
||||||
md5sums=('f65252d59ccce4c244d3c4c5597a6b8e')
|
md5sums=('0ce4e4646445612373d5114bb2f99fa8')
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Usage: makepkg -p PKGBUILD.git
|
# Usage: makepkg -p PKGBUILD.git
|
||||||
pkgname=ebusd-git
|
pkgname=ebusd-git
|
||||||
_gitname=ebusd
|
_gitname=ebusd
|
||||||
pkgver=3.3
|
pkgver=3.4
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="ebusd, the daemon for communication with eBUS heating systems."
|
pkgdesc="ebusd, the daemon for communication with eBUS heating systems."
|
||||||
arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
|
arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ RUN apt-get update && apt-get install -y \
|
|||||||
|
|
||||||
LABEL maintainer "ebusd@ebusd.eu"
|
LABEL maintainer "ebusd@ebusd.eu"
|
||||||
|
|
||||||
ENV EBUSD_VERSION 3.3
|
ENV EBUSD_VERSION 3.4
|
||||||
ENV EBUSD_ARCH amd64
|
ENV EBUSD_ARCH amd64
|
||||||
|
|
||||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}-devel"
|
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}-devel"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ RUN apt-get update && apt-get install -y \
|
|||||||
|
|
||||||
LABEL maintainer "ebusd@ebusd.eu"
|
LABEL maintainer "ebusd@ebusd.eu"
|
||||||
|
|
||||||
ENV EBUSD_VERSION 3.3
|
ENV EBUSD_VERSION 3.4
|
||||||
ENV EBUSD_ARCH amd64
|
ENV EBUSD_ARCH amd64
|
||||||
|
|
||||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
||||||
|
|||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
FROM balenalib/raspberrypi3
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
LABEL maintainer "ebusd@ebusd.eu"
|
||||||
|
|
||||||
|
ENV EBUSD_VERSION 3.4
|
||||||
|
ENV EBUSD_ARCH armhf
|
||||||
|
|
||||||
|
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
||||||
|
|
||||||
|
RUN curl -SL https://github.com/john30/ebusd/releases/download/v${EBUSD_VERSION}/ebusd-${EBUSD_VERSION}_${EBUSD_ARCH}-stretch_mqtt1.deb > ebusd.deb
|
||||||
|
|
||||||
|
RUN dpkg -i ebusd.deb
|
||||||
|
|
||||||
|
RUN rm ebusd.deb
|
||||||
|
|
||||||
|
EXPOSE 8888
|
||||||
|
|
||||||
|
COPY docker-entrypoint.sh /
|
||||||
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
|
CMD ["-f", "--scanconfig"]
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "${1#-}" != "$1" ]; then
|
||||||
|
set -- ebusd "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
Executable → Regular
+1
-1
@@ -2,5 +2,5 @@
|
|||||||
set -e
|
set -e
|
||||||
export EBUSD_VERSION=`cat ../../VERSION`
|
export EBUSD_VERSION=`cat ../../VERSION`
|
||||||
export EBUSD_ARCH=`docker version|grep -i "Arch[^:]*:"|tail -n 1|sed -e 's#^.*/##'`
|
export EBUSD_ARCH=`docker version|grep -i "Arch[^:]*:"|tail -n 1|sed -e 's#^.*/##'`
|
||||||
sed -i -e "s#^ENV EBUSD_VERSION .*\$#ENV EBUSD_VERSION ${EBUSD_VERSION}#" -e "s#^ENV EBUSD_ARCH .*\$#ENV EBUSD_ARCH ${EBUSD_ARCH}#" Dockerfile release/Dockerfile runtime/Dockerfile
|
sed -i -e "s#^ENV EBUSD_VERSION .*\$#ENV EBUSD_VERSION ${EBUSD_VERSION}#" -e "s#^ENV EBUSD_ARCH .*\$#ENV EBUSD_ARCH ${EBUSD_ARCH}#" Dockerfile release/Dockerfile rpirelease/Dockerfile
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
$agent = $_SERVER['HTTP_USER_AGENT'];
|
$agent = $_SERVER['HTTP_USER_AGENT'];
|
||||||
|
require_once('prepend.inc');
|
||||||
if (substr($agent, 0, 5)==='ebusd') {
|
if (substr($agent, 0, 5)==='ebusd') {
|
||||||
require_once('prepend.inc');
|
|
||||||
$r = @file_get_contents('php://input');
|
$r = @file_get_contents('php://input');
|
||||||
header('Content-Type: text/plain');
|
header('Content-Type: text/plain');
|
||||||
$r = @json_decode($r, true);
|
$r = @json_decode($r, true);
|
||||||
echo checkUpdate(@$r['v'], @$r['r'], @$r['a'], @$r['l']);
|
echo checkUpdate(@$r['v'], @$r['r'], @$r['a'], @$r['l']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
header('HTTP/1.1 404 Not Found');
|
readVersions();
|
||||||
?>
|
?>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ebusd update check service</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>latest ebusd version: <?=$versions['ebusd'][0]?></p>
|
||||||
|
<p>last update: <?=date('c', @filemtime('versions.txt'))?></p>
|
||||||
|
</body>
|
||||||
|
|||||||
Executable → Regular
+25
-11
@@ -223,11 +223,12 @@ static const struct argp_option argpoptions[] = {
|
|||||||
{"updatecheck", O_UPDCHK, "MODE", 0, "Set automatic update check to MODE (on|off) [on]", 0 },
|
{"updatecheck", O_UPDCHK, "MODE", 0, "Set automatic update check to MODE (on|off) [on]", 0 },
|
||||||
|
|
||||||
{nullptr, 0, nullptr, 0, "Log options:", 5 },
|
{nullptr, 0, nullptr, 0, "Log options:", 5 },
|
||||||
{"logfile", 'l', "FILE", 0, "Write log to FILE (only for daemon, empty string for using syslog) [" PACKAGE_LOGFILE "]", 0 },
|
{"logfile", 'l', "FILE", 0, "Write log to FILE (only for daemon, empty string for using syslog) ["
|
||||||
|
PACKAGE_LOGFILE "]", 0 },
|
||||||
{"log", O_LOG, "AREAS LEVEL", 0, "Only write log for matching AREA(S) below or equal to LEVEL"
|
{"log", O_LOG, "AREAS LEVEL", 0, "Only write log for matching AREA(S) below or equal to LEVEL"
|
||||||
" (alternative to --logareas/--logevel, may be used multiple times) [all notice]", 0 },
|
" (alternative to --logareas/--logevel, may be used multiple times) [all notice]", 0 },
|
||||||
{"logareas", O_LOGARE, "AREAS", 0, "Only write log for matching AREA(S): main|network|bus|update|all"
|
{"logareas", O_LOGARE, "AREAS", 0, "Only write log for matching AREA(S): main|network|bus|update|other"
|
||||||
" [all]", 0 },
|
"|all [all]", 0 },
|
||||||
{"loglevel", O_LOGLEV, "LEVEL", 0, "Only write log below or equal to LEVEL: error|notice|info|debug"
|
{"loglevel", O_LOGLEV, "LEVEL", 0, "Only write log below or equal to LEVEL: error|notice|info|debug"
|
||||||
" [notice]", 0 },
|
" [notice]", 0 },
|
||||||
|
|
||||||
@@ -661,7 +662,7 @@ void closePidFile() {
|
|||||||
/**
|
/**
|
||||||
* Helper method performing shutdown.
|
* Helper method performing shutdown.
|
||||||
*/
|
*/
|
||||||
void shutdown() {
|
void shutdown(bool error = false) {
|
||||||
// stop main loop and all dependent components
|
// stop main loop and all dependent components
|
||||||
if (s_mainLoop) {
|
if (s_mainLoop) {
|
||||||
delete s_mainLoop;
|
delete s_mainLoop;
|
||||||
@@ -690,7 +691,7 @@ void shutdown() {
|
|||||||
logNotice(lf_main, "ebusd stopped");
|
logNotice(lf_main, "ebusd stopped");
|
||||||
closeLogFile();
|
closeLogFile();
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(error ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -701,7 +702,7 @@ void signalHandler(int sig) {
|
|||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
logNotice(lf_main, "SIGHUP received");
|
logNotice(lf_main, "SIGHUP received");
|
||||||
if (!opt.foreground && opt.logFile && opt.logFile[0] != 0) { // for log file rotation
|
if (!opt.foreground && opt.logFile && opt.logFile[0] != 0) { // for log file rotation
|
||||||
closeLogFile();
|
closeLogFile();
|
||||||
setLogFile(opt.logFile);
|
setLogFile(opt.logFile);
|
||||||
}
|
}
|
||||||
@@ -928,7 +929,7 @@ void readMessage(Message* message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void executeInstructions(MessageMap* messages, bool verbose) {
|
result_t executeInstructions(MessageMap* messages, bool verbose) {
|
||||||
string errorDescription;
|
string errorDescription;
|
||||||
result_t result = messages->resolveConditions(verbose, &errorDescription);
|
result_t result = messages->resolveConditions(verbose, &errorDescription);
|
||||||
if (result != RESULT_OK) {
|
if (result != RESULT_OK) {
|
||||||
@@ -945,6 +946,7 @@ void executeInstructions(MessageMap* messages, bool verbose) {
|
|||||||
}
|
}
|
||||||
logNotice(lf_main, "found messages: %d (%d conditional on %d conditions, %d poll, %d update)", messages->size(),
|
logNotice(lf_main, "found messages: %d (%d conditional on %d conditions, %d poll, %d update)", messages->size(),
|
||||||
messages->sizeConditional(), messages->sizeConditions(), messages->sizePoll(), messages->sizePassive());
|
messages->sizeConditional(), messages->sizeConditions(), messages->sizePoll(), messages->sizePassive());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t loadDefinitionsFromConfigPath(FileReader* reader, const string& filename, bool verbose,
|
result_t loadDefinitionsFromConfigPath(FileReader* reader, const string& filename, bool verbose,
|
||||||
@@ -992,7 +994,7 @@ result_t loadConfigFiles(MessageMap* messages, bool verbose, bool denyRecursive)
|
|||||||
getResultCode(result), errorDescription.c_str());
|
getResultCode(result), errorDescription.c_str());
|
||||||
}
|
}
|
||||||
messages->unlock();
|
messages->unlock();
|
||||||
return RESULT_OK;
|
return opt.checkConfig ? result : RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t loadScanConfigFile(MessageMap* messages, symbol_t address, bool verbose, string* relativeFile) {
|
result_t loadScanConfigFile(MessageMap* messages, symbol_t address, bool verbose, string* relativeFile) {
|
||||||
@@ -1255,7 +1257,7 @@ int main(int argc, char* argv[]) {
|
|||||||
logNotice(lf_main, PACKAGE_STRING "." REVISION " performing configuration check...");
|
logNotice(lf_main, PACKAGE_STRING "." REVISION " performing configuration check...");
|
||||||
|
|
||||||
result_t result = loadConfigFiles(s_messageMap, true, opt.scanConfig && arg_index < argc);
|
result_t result = loadConfigFiles(s_messageMap, true, opt.scanConfig && arg_index < argc);
|
||||||
executeInstructions(s_messageMap, true);
|
result_t overallResult = executeInstructions(s_messageMap, true);
|
||||||
MasterSymbolString master;
|
MasterSymbolString master;
|
||||||
SlaveSymbolString slave;
|
SlaveSymbolString slave;
|
||||||
while (result == RESULT_OK && opt.scanConfig && arg_index < argc) {
|
while (result == RESULT_OK && opt.scanConfig && arg_index < argc) {
|
||||||
@@ -1267,21 +1269,33 @@ int main(int argc, char* argv[]) {
|
|||||||
Message* message = s_messageMap->getScanMessage(address);
|
Message* message = s_messageMap->getScanMessage(address);
|
||||||
if (!message) {
|
if (!message) {
|
||||||
logError(lf_main, "invalid scan address %2.2x", address);
|
logError(lf_main, "invalid scan address %2.2x", address);
|
||||||
|
if (overallResult == RESULT_OK) {
|
||||||
|
overallResult = RESULT_ERR_INVALID_ADDR;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
message->storeLastData(master, slave);
|
message->storeLastData(master, slave);
|
||||||
string file;
|
string file;
|
||||||
result_t res = loadScanConfigFile(s_messageMap, address, true, &file);
|
result_t res = loadScanConfigFile(s_messageMap, address, true, &file);
|
||||||
executeInstructions(s_messageMap, true);
|
result_t instrRes = executeInstructions(s_messageMap, true);
|
||||||
if (res == RESULT_OK) {
|
if (res == RESULT_OK) {
|
||||||
logInfo(lf_main, "scan config %2.2x: file %s loaded", address, file.c_str());
|
logInfo(lf_main, "scan config %2.2x: file %s loaded", address, file.c_str());
|
||||||
|
} else if (overallResult == RESULT_OK) {
|
||||||
|
overallResult = res;
|
||||||
|
}
|
||||||
|
if (overallResult == RESULT_OK && instrRes != RESULT_OK) {
|
||||||
|
overallResult = instrRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result != RESULT_OK) {
|
||||||
|
overallResult = result;
|
||||||
|
}
|
||||||
if (result == RESULT_OK && opt.dumpConfig) {
|
if (result == RESULT_OK && opt.dumpConfig) {
|
||||||
logNotice(lf_main, "configuration dump:");
|
logNotice(lf_main, "configuration dump:");
|
||||||
s_messageMap->dump(true, &cout);
|
s_messageMap->dump(true, &cout);
|
||||||
}
|
}
|
||||||
shutdown();
|
|
||||||
|
shutdown(overallResult != RESULT_OK);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable → Regular
+2
-1
@@ -120,8 +120,9 @@ result_t loadScanConfigFile(MessageMap* messages, symbol_t address, bool verbose
|
|||||||
* Helper method for executing all loaded and resolvable instructions.
|
* Helper method for executing all loaded and resolvable instructions.
|
||||||
* @param messages the @a MessageMap instance.
|
* @param messages the @a MessageMap instance.
|
||||||
* @param verbose whether to verbosely log all problems.
|
* @param verbose whether to verbosely log all problems.
|
||||||
|
* @return the result code.
|
||||||
*/
|
*/
|
||||||
void executeInstructions(MessageMap* messages, bool verbose = false);
|
result_t executeInstructions(MessageMap* messages, bool verbose = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for loading definitions from a relative file from the config path/URL.
|
* Helper method for loading definitions from a relative file from the config path/URL.
|
||||||
|
|||||||
Executable → Regular
+100
-45
@@ -371,12 +371,12 @@ void MainLoop::run() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_shutdown) {
|
if (m_shutdown) {
|
||||||
netMessage->setResult("ERR: shutdown", "", cm_normal, now, true);
|
netMessage->setResult("ERR: shutdown", "", nullptr, now, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
string request = netMessage->getRequest();
|
string request = netMessage->getRequest();
|
||||||
string user = netMessage->getUser();
|
string user = netMessage->getUser();
|
||||||
ClientMode mode = netMessage->getMode(&since);
|
ClientSettings settings = netMessage->getSettings(&since);
|
||||||
if (!netMessage->isListeningMode()) {
|
if (!netMessage->isListeningMode()) {
|
||||||
since = now;
|
since = now;
|
||||||
}
|
}
|
||||||
@@ -384,9 +384,9 @@ void MainLoop::run() {
|
|||||||
bool connected = true;
|
bool connected = true;
|
||||||
if (request.length() > 0) {
|
if (request.length() > 0) {
|
||||||
logDebug(lf_main, ">>> %s", request.c_str());
|
logDebug(lf_main, ">>> %s", request.c_str());
|
||||||
result_t result = decodeMessage(request, netMessage->isHttp(), &connected, &mode, &user, &reload, &ostream);
|
result_t result = decodeMessage(request, netMessage->isHttp(), &connected, &settings, &user, &reload, &ostream);
|
||||||
if (!netMessage->isHttp() && (ostream.tellp() == 0 || result != RESULT_OK)) {
|
if (!netMessage->isHttp() && (ostream.tellp() == 0 || result != RESULT_OK)) {
|
||||||
if (mode != cm_direct) {
|
if (settings.mode != cm_direct) {
|
||||||
ostream.str("");
|
ostream.str("");
|
||||||
}
|
}
|
||||||
ostream << getResultCode(result);
|
ostream << getResultCode(result);
|
||||||
@@ -399,25 +399,34 @@ void MainLoop::run() {
|
|||||||
if (ostream.tellp() == 0) {
|
if (ostream.tellp() == 0) {
|
||||||
ostream << "\n"; // only for HTTP
|
ostream << "\n"; // only for HTTP
|
||||||
} else if (!netMessage->isHttp()) {
|
} else if (!netMessage->isHttp()) {
|
||||||
ostream << (mode == cm_direct ? "\n" : "\n\n");
|
ostream << (settings.mode == cm_direct ? "\n" : "\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode == cm_listen) {
|
if (settings.mode == cm_listen) {
|
||||||
string levels = getUserLevels(user);
|
if (!settings.listenOnlyUnknown) {
|
||||||
messages.clear();
|
string levels = getUserLevels(user);
|
||||||
m_messages->findAll("", "", levels, false, true, true, true, true, true, since, now, true, &messages);
|
messages.clear();
|
||||||
for (const auto message : messages) {
|
m_messages->findAll("", "", levels, false, true, true, true, true, true, since, now, true, &messages);
|
||||||
ostream << message->getCircuit() << " " << message->getName() << " = " << dec;
|
for (const auto message : messages) {
|
||||||
message->decodeLastData(false, nullptr, -1, 0, &ostream);
|
ostream << message->getCircuit() << " " << message->getName() << " = " << dec;
|
||||||
ostream << endl;
|
message->decodeLastData(false, nullptr, -1, settings.format, &ostream);
|
||||||
|
ostream << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (mode == cm_direct) {
|
if (settings.listenWithUnknown || settings.listenOnlyUnknown) {
|
||||||
|
if (m_busHandler->isGrabEnabled()) {
|
||||||
|
m_busHandler->formatGrabResult(true, false, &ostream, true, since, now);
|
||||||
|
} else {
|
||||||
|
m_busHandler->enableGrab(true); // needed for listening to all messages
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (settings.mode == cm_direct) {
|
||||||
if (m_busHandler->isGrabEnabled()) {
|
if (m_busHandler->isGrabEnabled()) {
|
||||||
m_busHandler->formatGrabResult(false, false, &ostream, true, since, now);
|
m_busHandler->formatGrabResult(false, false, &ostream, true, since, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// send result to client
|
// send result to client
|
||||||
netMessage->setResult(ostream.str(), user, mode, now, !connected);
|
netMessage->setResult(ostream.str(), user, &settings, now, !connected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +471,7 @@ void MainLoop::notifyDeviceData(symbol_t symbol, bool received) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connected, ClientMode* mode,
|
result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connected, ClientSettings* settings,
|
||||||
string* user, bool* reload, ostringstream* ostream) {
|
string* user, bool* reload, ostringstream* ostream) {
|
||||||
string token, previous;
|
string token, previous;
|
||||||
istringstream stream(data);
|
istringstream stream(data);
|
||||||
@@ -520,8 +529,8 @@ result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connecte
|
|||||||
transform(cmd.begin(), cmd.end(), cmd.begin(), ::toupper);
|
transform(cmd.begin(), cmd.end(), cmd.begin(), ::toupper);
|
||||||
args.clear(); // empty args is used as command help indicator
|
args.clear(); // empty args is used as command help indicator
|
||||||
}
|
}
|
||||||
if (*mode == cm_direct) {
|
if (settings->mode == cm_direct) {
|
||||||
return executeDirect(args, mode, ostream);
|
return executeDirect(args, &settings->mode, ostream);
|
||||||
}
|
}
|
||||||
if (cmd.empty() && args.size() == 0) {
|
if (cmd.empty() && args.size() == 0) {
|
||||||
return executeHelp(ostream);
|
return executeHelp(ostream);
|
||||||
@@ -553,10 +562,10 @@ result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connecte
|
|||||||
return executeFind(args, getUserLevels(*user), ostream);
|
return executeFind(args, getUserLevels(*user), ostream);
|
||||||
}
|
}
|
||||||
if (cmd == "L" || cmd == "LISTEN") {
|
if (cmd == "L" || cmd == "LISTEN") {
|
||||||
return executeListen(args, mode, ostream);
|
return executeListen(args, settings, ostream);
|
||||||
}
|
}
|
||||||
if (cmd == "DIRECT") {
|
if (cmd == "DIRECT") {
|
||||||
return executeDirect(args, mode, ostream);
|
return executeDirect(args, &settings->mode, ostream);
|
||||||
}
|
}
|
||||||
if (cmd == "S" || cmd == "STATE") {
|
if (cmd == "S" || cmd == "STATE") {
|
||||||
return executeState(args, ostream);
|
return executeState(args, ostream);
|
||||||
@@ -652,7 +661,7 @@ result_t MainLoop::executeAuth(const vector<string>& args, string* user, ostring
|
|||||||
|
|
||||||
result_t MainLoop::executeRead(const vector<string>& args, const string& levels, ostringstream* ostream) {
|
result_t MainLoop::executeRead(const vector<string>& args, const string& levels, ostringstream* ostream) {
|
||||||
size_t argPos = 1;
|
size_t argPos = 1;
|
||||||
bool hex = false, newDefinition = false, numeric = false, valueName = false;
|
bool hex = false, newDefinition = false;
|
||||||
OutputFormat verbosity = 0;
|
OutputFormat verbosity = 0;
|
||||||
time_t maxAge = 5*60;
|
time_t maxAge = 5*60;
|
||||||
string circuit, params;
|
string circuit, params;
|
||||||
@@ -699,10 +708,9 @@ result_t MainLoop::executeRead(const vector<string>& args, const string& levels,
|
|||||||
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
||||||
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
||||||
} else if (args[argPos] == "-n") {
|
} else if (args[argPos] == "-n") {
|
||||||
numeric = true;
|
verbosity = (verbosity & ~OF_VALUENAME) | OF_NUMERIC;
|
||||||
} else if (args[argPos] == "-N") {
|
} else if (args[argPos] == "-N") {
|
||||||
numeric = true;
|
verbosity = (verbosity & ~OF_NUMERIC) | OF_VALUENAME;
|
||||||
valueName = true;
|
|
||||||
} else if (args[argPos] == "-c") {
|
} else if (args[argPos] == "-c") {
|
||||||
argPos++;
|
argPos++;
|
||||||
if (argPos >= args.size()) {
|
if (argPos >= args.size()) {
|
||||||
@@ -751,7 +759,7 @@ result_t MainLoop::executeRead(const vector<string>& args, const string& levels,
|
|||||||
}
|
}
|
||||||
argPos++;
|
argPos++;
|
||||||
}
|
}
|
||||||
if ((hex && (newDefinition || numeric || verbosity != 0 || !circuit.empty() || !params.empty() || dstAddress != SYN
|
if ((hex && (newDefinition || verbosity != 0 || !circuit.empty() || !params.empty() || dstAddress != SYN
|
||||||
|| pollPriority > 0 || args.size() < argPos + 1))
|
|| pollPriority > 0 || args.size() < argPos + 1))
|
||||||
|| (newDefinition && (hex || !circuit.empty() || pollPriority > 0 || args.size() != argPos + 1))) {
|
|| (newDefinition && (hex || !circuit.empty() || pollPriority > 0 || args.size() != argPos + 1))) {
|
||||||
argPos = 0; // print usage
|
argPos = 0; // print usage
|
||||||
@@ -895,7 +903,6 @@ result_t MainLoop::executeRead(const vector<string>& args, const string& levels,
|
|||||||
if (!newDefinition && message != nullptr && pollPriority > 0 && message->setPollPriority(pollPriority)) {
|
if (!newDefinition && message != nullptr && pollPriority > 0 && message->setPollPriority(pollPriority)) {
|
||||||
m_messages->addPollMessage(false, message);
|
m_messages->addPollMessage(false, message);
|
||||||
}
|
}
|
||||||
verbosity |= valueName ? OF_VALUENAME : numeric ? OF_NUMERIC : 0;
|
|
||||||
bool allowCache = !newDefinition && srcAddress == SYN && dstAddress == SYN && maxAge > 0 && params.length() == 0;
|
bool allowCache = !newDefinition && srcAddress == SYN && dstAddress == SYN && maxAge > 0 && params.length() == 0;
|
||||||
Message* cacheMessage = allowCache ? m_messages->find(circuit, name, levels, false, true) : nullptr;
|
Message* cacheMessage = allowCache ? m_messages->find(circuit, name, levels, false, true) : nullptr;
|
||||||
bool hasCache = cacheMessage != nullptr;
|
bool hasCache = cacheMessage != nullptr;
|
||||||
@@ -1479,23 +1486,71 @@ result_t MainLoop::executeFind(const vector<string>& args, const string& levels,
|
|||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t MainLoop::executeListen(const vector<string>& args, ClientMode* mode, ostringstream* ostream) {
|
result_t MainLoop::executeListen(const vector<string>& args, ClientSettings* settings, ostringstream* ostream) {
|
||||||
if (args.size() == 1) {
|
size_t argPos = 1;
|
||||||
if (*mode == cm_listen) {
|
OutputFormat verbosity = 0;
|
||||||
|
bool listenWithUnknown = false;
|
||||||
|
bool listenOnlyUnknown = false;
|
||||||
|
while (args.size() > argPos && args[argPos][0] == '-') {
|
||||||
|
if (args[argPos] == "-v") {
|
||||||
|
switch (verbosity) {
|
||||||
|
case 0:
|
||||||
|
verbosity = OF_NAMES;
|
||||||
|
break;
|
||||||
|
case OF_NAMES:
|
||||||
|
verbosity |= OF_UNITS;
|
||||||
|
break;
|
||||||
|
case OF_NAMES|OF_UNITS:
|
||||||
|
verbosity |= OF_COMMENTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (args[argPos] == "-vv") {
|
||||||
|
verbosity |= OF_NAMES|OF_UNITS;
|
||||||
|
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
||||||
|
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
||||||
|
} else if (args[argPos] == "-n") {
|
||||||
|
verbosity = (verbosity & ~OF_VALUENAME) | OF_NUMERIC;
|
||||||
|
} else if (args[argPos] == "-N") {
|
||||||
|
verbosity = (verbosity & ~OF_NUMERIC) | OF_VALUENAME;
|
||||||
|
} else if (args[argPos] == "-u") {
|
||||||
|
listenWithUnknown = true;
|
||||||
|
listenOnlyUnknown = false;
|
||||||
|
} else if (args[argPos] == "-U") {
|
||||||
|
listenOnlyUnknown = true;
|
||||||
|
} else {
|
||||||
|
argPos = 0; // print usage
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
argPos++;
|
||||||
|
}
|
||||||
|
if (argPos > 0 && args.size() == argPos) {
|
||||||
|
settings->format = verbosity;
|
||||||
|
settings->listenWithUnknown = listenWithUnknown;
|
||||||
|
settings->listenOnlyUnknown = listenOnlyUnknown;
|
||||||
|
if (listenWithUnknown || listenOnlyUnknown) {
|
||||||
|
m_busHandler->enableGrab(true); // needed for listening to all messages
|
||||||
|
}
|
||||||
|
if (settings->mode == cm_listen) {
|
||||||
*ostream << "listen continued";
|
*ostream << "listen continued";
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
*mode = cm_listen;
|
settings->mode = cm_listen;
|
||||||
*ostream << "listen started";
|
*ostream << "listen started";
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.size() != 2 || args[1] != "stop") {
|
if (argPos == 0 || args.size() != argPos + 1 || args[argPos] != "stop") {
|
||||||
*ostream << "usage: listen [stop]\n"
|
*ostream << "usage: listen [-v|-V] [-n|-N] [-u|-U] [stop]\n"
|
||||||
" Listen for updates or stop it.";
|
" Listen for updates or stop it.\n"
|
||||||
|
" -v increase verbosity (include names/units/comments)\n"
|
||||||
|
" -V be very verbose (include names, units, and comments)\n"
|
||||||
|
" -n use numeric value of value=name pairs\n"
|
||||||
|
" -N use numeric and named value of value=name pairs\n"
|
||||||
|
" -u include unknown messages\n"
|
||||||
|
" -U only show unknown messages";
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
*mode = cm_normal;
|
settings->mode = cm_normal;
|
||||||
*ostream << "listen stopped";
|
*ostream << "listen stopped";
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
@@ -1573,7 +1628,6 @@ result_t MainLoop::executeDefine(const vector<string>& args, ostringstream* ostr
|
|||||||
|
|
||||||
result_t MainLoop::executeDecode(const vector<string>& args, ostringstream* ostream) {
|
result_t MainLoop::executeDecode(const vector<string>& args, ostringstream* ostream) {
|
||||||
size_t argPos = 1;
|
size_t argPos = 1;
|
||||||
bool numeric = false, valueName = false;
|
|
||||||
OutputFormat verbosity = 0;
|
OutputFormat verbosity = 0;
|
||||||
while (args.size() > argPos && args[argPos][0] == '-') {
|
while (args.size() > argPos && args[argPos][0] == '-') {
|
||||||
if (args[argPos] == "-v") {
|
if (args[argPos] == "-v") {
|
||||||
@@ -1593,10 +1647,9 @@ result_t MainLoop::executeDecode(const vector<string>& args, ostringstream* ostr
|
|||||||
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
||||||
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
||||||
} else if (args[argPos] == "-n") {
|
} else if (args[argPos] == "-n") {
|
||||||
numeric = true;
|
verbosity = (verbosity & ~OF_VALUENAME) | OF_NUMERIC;
|
||||||
} else if (args[argPos] == "-N") {
|
} else if (args[argPos] == "-N") {
|
||||||
numeric = true;
|
verbosity = (verbosity & ~OF_NUMERIC) | OF_VALUENAME;
|
||||||
valueName = true;
|
|
||||||
} else {
|
} else {
|
||||||
argPos = 0; // print usage
|
argPos = 0; // print usage
|
||||||
break;
|
break;
|
||||||
@@ -1622,7 +1675,6 @@ result_t MainLoop::executeDecode(const vector<string>& args, ostringstream* ostr
|
|||||||
|
|
||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
verbosity |= valueName ? OF_VALUENAME : numeric ? OF_NUMERIC : 0;
|
|
||||||
istringstream defstr("#\n" + args[argPos]); // ensure first line is not used for determining col names
|
istringstream defstr("#\n" + args[argPos]); // ensure first line is not used for determining col names
|
||||||
string errorDescription;
|
string errorDescription;
|
||||||
DataFieldTemplates* templates = getTemplates("*");
|
DataFieldTemplates* templates = getTemplates("*");
|
||||||
@@ -1865,7 +1917,7 @@ result_t MainLoop::executeHelp(ostringstream* ostream) {
|
|||||||
" hex Send hex data: hex [-s QQ] ZZPBSBNN[DD]* (if enabled)\n"
|
" hex Send hex data: hex [-s QQ] ZZPBSBNN[DD]* (if enabled)\n"
|
||||||
" find|f Find message(s): find [-v|-V] [-r] [-w] [-p] [-a] [-d] [-h] [-i ID] [-f] [-F COL[,COL]*] [-e]"
|
" find|f Find message(s): find [-v|-V] [-r] [-w] [-p] [-a] [-d] [-h] [-i ID] [-f] [-F COL[,COL]*] [-e]"
|
||||||
" [-c CIRCUIT] [-l LEVEL] [NAME]\n"
|
" [-c CIRCUIT] [-l LEVEL] [NAME]\n"
|
||||||
" listen|l Listen for updates: listen [stop]\n"
|
" listen|l Listen for updates: listen [-v|-V] [-n|-N] [-u|-U] [stop]\n"
|
||||||
" direct Enter direct mode\n"
|
" direct Enter direct mode\n"
|
||||||
" state|s Report bus state\n"
|
" state|s Report bus state\n"
|
||||||
" info|i Report information about the daemon, the configuration, and seen devices.\n"
|
" info|i Report information about the daemon, the configuration, and seen devices.\n"
|
||||||
@@ -1895,7 +1947,7 @@ bool parseBoolQuery(const string& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostringstream* ostream) {
|
result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostringstream* ostream) {
|
||||||
bool numeric = false, valueName = false, required = false, full = false, withWrite = false, raw = false;
|
bool required = false, full = false, withWrite = false, raw = false;
|
||||||
bool withDefinition = false;
|
bool withDefinition = false;
|
||||||
OutputFormat verbosity = OF_NAMES;
|
OutputFormat verbosity = OF_NAMES;
|
||||||
time_t maxAge = -1;
|
time_t maxAge = -1;
|
||||||
@@ -1945,9 +1997,13 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
|||||||
verbosity &= ~OF_NAMES;
|
verbosity &= ~OF_NAMES;
|
||||||
}
|
}
|
||||||
} else if (qname == "numeric") {
|
} else if (qname == "numeric") {
|
||||||
numeric = parseBoolQuery(value);
|
if (parseBoolQuery(value)) {
|
||||||
|
verbosity = (verbosity & ~OF_VALUENAME) | OF_NUMERIC;
|
||||||
|
}
|
||||||
} else if (qname == "valuename") {
|
} else if (qname == "valuename") {
|
||||||
valueName = parseBoolQuery(value);
|
if (parseBoolQuery(value)) {
|
||||||
|
verbosity = (verbosity & ~OF_NUMERIC) | OF_VALUENAME;
|
||||||
|
}
|
||||||
} else if (qname == "full") {
|
} else if (qname == "full") {
|
||||||
full = parseBoolQuery(value);
|
full = parseBoolQuery(value);
|
||||||
} else if (qname == "required") {
|
} else if (qname == "required") {
|
||||||
@@ -1982,8 +2038,7 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
|||||||
time_t maxLastUp = 0;
|
time_t maxLastUp = 0;
|
||||||
if (ret == RESULT_OK) {
|
if (ret == RESULT_OK) {
|
||||||
bool first = true;
|
bool first = true;
|
||||||
verbosity |= (valueName ? OF_VALUENAME : numeric ? OF_NUMERIC : 0) | OF_JSON | (full ? OF_ALL_ATTRS : 0)
|
verbosity |= OF_JSON | (full ? OF_ALL_ATTRS : 0) | (withDefinition ? OF_DEFINTION : 0);
|
||||||
| (withDefinition ? OF_DEFINTION : 0);
|
|
||||||
deque<Message*> messages;
|
deque<Message*> messages;
|
||||||
m_messages->findAll(circuit, name, getUserLevels(user), exact, true, withWrite, true, true, true, 0, 0, false,
|
m_messages->findAll(circuit, name, getUserLevels(user), exact, true, withWrite, true, true, true, 0, 0, false,
|
||||||
&messages);
|
&messages);
|
||||||
|
|||||||
Executable → Regular
+4
-4
@@ -144,13 +144,13 @@ class MainLoop : public Thread, DeviceListener {
|
|||||||
* @param data the data string to decode (may be empty).
|
* @param data the data string to decode (may be empty).
|
||||||
* @param connected set to false when the client connection shall be closed.
|
* @param connected set to false when the client connection shall be closed.
|
||||||
* @param isHttp true for HTTP message.
|
* @param isHttp true for HTTP message.
|
||||||
* @param mode set to the new client mode.
|
* @param settings set to the new client settings.
|
||||||
* @param user set to the new user name when changed by authentication.
|
* @param user set to the new user name when changed by authentication.
|
||||||
* @param reload set to true when the configuration files were reloaded.
|
* @param reload set to true when the configuration files were reloaded.
|
||||||
* @param ostream the @a ostringstream to format the result string to.
|
* @param ostream the @a ostringstream to format the result string to.
|
||||||
* @return the result code.
|
* @return the result code.
|
||||||
*/
|
*/
|
||||||
result_t decodeMessage(const string& data, bool isHttp, bool* connected, ClientMode* mode,
|
result_t decodeMessage(const string& data, bool isHttp, bool* connected, ClientSettings* settings,
|
||||||
string* user, bool* reload, ostringstream* ostream);
|
string* user, bool* reload, ostringstream* ostream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -238,11 +238,11 @@ class MainLoop : public Thread, DeviceListener {
|
|||||||
/**
|
/**
|
||||||
* Execute the listen command.
|
* Execute the listen command.
|
||||||
* @param args the arguments passed to the command (starting with the command itself), or empty for help.
|
* @param args the arguments passed to the command (starting with the command itself), or empty for help.
|
||||||
* @param mode set to the new client mode.
|
* @param settings set to the new client settings.
|
||||||
* @param ostream the @a ostringstream to format the result string to.
|
* @param ostream the @a ostringstream to format the result string to.
|
||||||
* @return the result code.
|
* @return the result code.
|
||||||
*/
|
*/
|
||||||
result_t executeListen(const vector<string>& args, ClientMode* mode, ostringstream* ostream);
|
result_t executeListen(const vector<string>& args, ClientSettings* settings, ostringstream* ostream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the state command.
|
* Execute the state command.
|
||||||
|
|||||||
@@ -109,6 +109,15 @@ static const char* g_keypass = nullptr; //!< client key file password for TLS
|
|||||||
|
|
||||||
bool parseTopic(const string& topic, vector<string>* strs, vector<string>* fields);
|
bool parseTopic(const string& topic, vector<string>* strs, vector<string>* fields);
|
||||||
|
|
||||||
|
static char* replaceSecret(char *arg) {
|
||||||
|
char* ret = strdup(arg);
|
||||||
|
int cnt = 0;
|
||||||
|
while (*arg && cnt++ < 256) {
|
||||||
|
*arg++ = ' ';
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MQTT argument parsing function.
|
* The MQTT argument parsing function.
|
||||||
* @param key the key from @a g_mqtt_argp_options.
|
* @param key the key from @a g_mqtt_argp_options.
|
||||||
@@ -156,7 +165,7 @@ static error_t mqtt_parse_opt(int key, char *arg, struct argp_state *state) {
|
|||||||
argp_error(state, "invalid mqttpass");
|
argp_error(state, "invalid mqttpass");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
g_password = arg;
|
g_password = replaceSecret(arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_TOPI: // --mqtttopic=ebusd
|
case O_TOPI: // --mqtttopic=ebusd
|
||||||
@@ -237,7 +246,7 @@ static error_t mqtt_parse_opt(int key, char *arg, struct argp_state *state) {
|
|||||||
argp_error(state, "invalid mqttkeypass");
|
argp_error(state, "invalid mqttkeypass");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
g_keypass = arg;
|
g_keypass = replaceSecret(arg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -743,12 +752,12 @@ void MqttHandler::run() {
|
|||||||
for (auto it = m_updatedMessages.begin(); it != m_updatedMessages.end(); ) {
|
for (auto it = m_updatedMessages.begin(); it != m_updatedMessages.end(); ) {
|
||||||
const vector<Message*>* messages = m_messages->getByKey(it->first);
|
const vector<Message*>* messages = m_messages->getByKey(it->first);
|
||||||
if (messages) {
|
if (messages) {
|
||||||
updates.str("");
|
|
||||||
updates.clear();
|
|
||||||
updates << dec;
|
|
||||||
for (auto message : *messages) {
|
for (auto message : *messages) {
|
||||||
if (message->getLastChangeTime() > 0 && message->isAvailable()
|
if (message->getLastChangeTime() > 0 && message->isAvailable()
|
||||||
&& (!g_onlyChanges || message->getLastChangeTime() > lastUpdates)) {
|
&& (!g_onlyChanges || message->getLastChangeTime() > lastUpdates)) {
|
||||||
|
updates.str("");
|
||||||
|
updates.clear();
|
||||||
|
updates << dec;
|
||||||
publishMessage(message, &updates);
|
publishMessage(message, &updates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -778,7 +787,7 @@ bool MqttHandler::handleTraffic(bool allowReconnect) {
|
|||||||
#else
|
#else
|
||||||
ret = mosquitto_loop(m_mosquitto, -1); // waits up to 1 second for network traffic
|
ret = mosquitto_loop(m_mosquitto, -1); // waits up to 1 second for network traffic
|
||||||
#endif
|
#endif
|
||||||
if (!m_connected && ret == MOSQ_ERR_NO_CONN && allowReconnect) {
|
if (!m_connected && (ret == MOSQ_ERR_NO_CONN || ret == MOSQ_ERR_CONN_LOST) && allowReconnect) {
|
||||||
if (m_initialConnectFailed) {
|
if (m_initialConnectFailed) {
|
||||||
#if (LIBMOSQUITTO_MAJOR >= 1)
|
#if (LIBMOSQUITTO_MAJOR >= 1)
|
||||||
ret = mosquitto_connect(m_mosquitto, g_host, g_port, 60);
|
ret = mosquitto_connect(m_mosquitto, g_host, g_port, 60);
|
||||||
|
|||||||
Executable → Regular
+1
-1
@@ -208,7 +208,7 @@ Network::~Network() {
|
|||||||
stop();
|
stop();
|
||||||
NetMessage* netMsg;
|
NetMessage* netMsg;
|
||||||
while ((netMsg = m_netQueue->pop()) != nullptr) {
|
while ((netMsg = m_netQueue->pop()) != nullptr) {
|
||||||
netMsg->setResult("ERR: shutdown", "", cm_normal, 0, true);
|
netMsg->setResult("ERR: shutdown", "", nullptr, 0, true);
|
||||||
}
|
}
|
||||||
while (!m_connections.empty()) {
|
while (!m_connections.empty()) {
|
||||||
Connection* connection = m_connections.back();
|
Connection* connection = m_connections.back();
|
||||||
|
|||||||
Executable → Regular
+29
-11
@@ -23,6 +23,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include "lib/ebus/datatype.h"
|
||||||
#include "lib/utils/tcpsocket.h"
|
#include "lib/utils/tcpsocket.h"
|
||||||
#include "lib/utils/queue.h"
|
#include "lib/utils/queue.h"
|
||||||
#include "lib/utils/notify.h"
|
#include "lib/utils/notify.h"
|
||||||
@@ -44,6 +45,16 @@ enum ClientMode {
|
|||||||
cm_direct, //!< direct mode
|
cm_direct, //!< direct mode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combination of client settings.
|
||||||
|
*/
|
||||||
|
struct ClientSettings {
|
||||||
|
ClientMode mode; //!< the current client mode
|
||||||
|
OutputFormat format; //!< the output format settings for listen mode
|
||||||
|
bool listenWithUnknown; //!< include unknown messages in listen mode
|
||||||
|
bool listenOnlyUnknown; //!< only print unknown messages in listen mode
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for data/message transfer between @a Connection and @a MainLoop.
|
* Class for data/message transfer between @a Connection and @a MainLoop.
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +65,11 @@ class NetMessage {
|
|||||||
* @param isHttp whether this is a HTTP message.
|
* @param isHttp whether this is a HTTP message.
|
||||||
*/
|
*/
|
||||||
explicit NetMessage(bool isHttp)
|
explicit NetMessage(bool isHttp)
|
||||||
: m_isHttp(isHttp), m_resultSet(false), m_disconnect(false), m_mode(cm_normal), m_listenSince(0) {
|
: m_isHttp(isHttp), m_resultSet(false), m_disconnect(false), m_listenSince(0) {
|
||||||
|
m_settings.mode = cm_normal;
|
||||||
|
m_settings.format = 0;
|
||||||
|
m_settings.listenWithUnknown = false;
|
||||||
|
m_settings.listenOnlyUnknown = false;
|
||||||
pthread_mutex_init(&m_mutex, nullptr);
|
pthread_mutex_init(&m_mutex, nullptr);
|
||||||
pthread_cond_init(&m_cond, nullptr);
|
pthread_cond_init(&m_cond, nullptr);
|
||||||
}
|
}
|
||||||
@@ -124,16 +139,19 @@ class NetMessage {
|
|||||||
* Set the result string and notify the waiting thread.
|
* Set the result string and notify the waiting thread.
|
||||||
* @param result the result string.
|
* @param result the result string.
|
||||||
* @param user the new user name.
|
* @param user the new user name.
|
||||||
* @param mode the new client mode.
|
* @param settings the new client settings.
|
||||||
* @param listenUntil the end time to which to updates were added (exclusive).
|
* @param listenUntil the end time to which to updates were added (exclusive).
|
||||||
* @param disconnect true when the client shall be disconnected.
|
* @param disconnect true when the client shall be disconnected.
|
||||||
*/
|
*/
|
||||||
void setResult(const string& result, const string& user, ClientMode mode, time_t listenUntil, bool disconnect) {
|
void setResult(const string& result, const string& user, ClientSettings* settings, time_t listenUntil,
|
||||||
|
bool disconnect) {
|
||||||
pthread_mutex_lock(&m_mutex);
|
pthread_mutex_lock(&m_mutex);
|
||||||
m_result = result;
|
m_result = result;
|
||||||
m_user = user;
|
m_user = user;
|
||||||
m_disconnect = disconnect;
|
m_disconnect = disconnect;
|
||||||
m_mode = mode;
|
if (settings) {
|
||||||
|
m_settings = *settings;
|
||||||
|
}
|
||||||
m_listenSince = listenUntil;
|
m_listenSince = listenUntil;
|
||||||
m_resultSet = true;
|
m_resultSet = true;
|
||||||
pthread_cond_signal(&m_cond);
|
pthread_cond_signal(&m_cond);
|
||||||
@@ -141,22 +159,22 @@ class NetMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the client mode.
|
* Return the client settings.
|
||||||
* @param listenSince set listening to the specified start time from which to add updates (inclusive).
|
* @param listenSince set listening to the specified start time from which to add updates (inclusive).
|
||||||
* @return the client mode.
|
* @return the client settings.
|
||||||
*/
|
*/
|
||||||
ClientMode getMode(time_t* listenSince = nullptr) {
|
ClientSettings getSettings(time_t* listenSince = nullptr) {
|
||||||
if (listenSince) {
|
if (listenSince) {
|
||||||
*listenSince = m_listenSince;
|
*listenSince = m_listenSince;
|
||||||
}
|
}
|
||||||
return m_mode;
|
return m_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether this instance is in one of the listening modes.
|
* Return whether this instance is in one of the listening modes.
|
||||||
* @return whether this instance is in one of the listening modes.
|
* @return whether this instance is in one of the listening modes.
|
||||||
*/
|
*/
|
||||||
bool isListeningMode() { return m_mode == cm_listen || m_mode == cm_direct; }
|
bool isListeningMode() { return m_settings.mode == cm_listen || m_settings.mode == cm_direct; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the client shall be disconnected.
|
* Return whether the client shall be disconnected.
|
||||||
@@ -190,8 +208,8 @@ class NetMessage {
|
|||||||
/** condition variable for exclusive lock. */
|
/** condition variable for exclusive lock. */
|
||||||
pthread_cond_t m_cond;
|
pthread_cond_t m_cond;
|
||||||
|
|
||||||
/** the client mode. */
|
/** the client settings. */
|
||||||
ClientMode m_mode;
|
ClientSettings m_settings;
|
||||||
|
|
||||||
/** start timestamp of listening update. */
|
/** start timestamp of listening update. */
|
||||||
time_t m_listenSince;
|
time_t m_listenSince;
|
||||||
|
|||||||
@@ -227,6 +227,9 @@ string fetchData(ebusd::TCPSocket* socket, bool listening) {
|
|||||||
}
|
}
|
||||||
} else if (newInput) {
|
} else if (newInput) {
|
||||||
getline(cin, message);
|
getline(cin, message);
|
||||||
|
if (message.length()==0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
sendmessage = message+'\n';
|
sendmessage = message+'\n';
|
||||||
socket->send(sendmessage.c_str(), sendmessage.size());
|
socket->send(sendmessage.c_str(), sendmessage.size());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user