code style
This commit is contained in:
@@ -308,7 +308,8 @@ bool GrabbedMessage::dump(bool unknown, MessageMap* messages, bool first, Output
|
||||
}
|
||||
for (const auto& it : *types) {
|
||||
const DataType* baseType = it.second;
|
||||
if ((baseType->getBitCount() % 8) != 0 || baseType->isIgnored() || baseType->hasFlag(DUP)) { // skip bit and ignored types
|
||||
if ((baseType->getBitCount() % 8) != 0 || baseType->isIgnored() || baseType->hasFlag(DUP)) {
|
||||
// skip bit and ignored types
|
||||
continue;
|
||||
}
|
||||
size_t maxLength = baseType->getBitCount()/8;
|
||||
|
||||
+14
-14
@@ -1046,7 +1046,8 @@ result_t loadScanConfigFile(MessageMap* messages, symbol_t address, bool verbose
|
||||
size_t offset = 0;
|
||||
size_t field = 0;
|
||||
bool fromLocal = s_configUriPrefix.empty();
|
||||
result_t result = (*identFields)[field]->read(data, offset, false, nullptr, -1, OF_NONE, -1, &out); // manufacturer name
|
||||
// manufacturer name
|
||||
result_t result = (*identFields)[field]->read(data, offset, false, nullptr, -1, OF_NONE, -1, &out);
|
||||
if (result == RESULT_ERR_NOTFOUND && fromLocal) {
|
||||
result = (*identFields)[field]->read(data, offset, false, nullptr, -1, OF_NUMERIC, -1, &out); // manufacturer name
|
||||
}
|
||||
@@ -1254,41 +1255,41 @@ int main(int argc, char* argv[]) {
|
||||
char* envopt = envname+2;
|
||||
for (char ** env = environ; *env; env++) {
|
||||
char* pos = strchr(*env, '=');
|
||||
if (!pos || strncmp(*env, "EBUSD_", sizeof("EBUSD_")-1)!=0) {
|
||||
if (!pos || strncmp(*env, "EBUSD_", sizeof("EBUSD_")-1) != 0) {
|
||||
continue;
|
||||
}
|
||||
char* start = *env+sizeof("EBUSD_")-1;
|
||||
size_t len = pos-start;
|
||||
if (len<=1 || len>sizeof(envname)-3) { // no single char long args
|
||||
if (len <= 1 || len > sizeof(envname)-3) { // no single char long args
|
||||
continue;
|
||||
}
|
||||
for (size_t i=0; i<len; i++) {
|
||||
envopt[i] = (char)tolower(start[i]);
|
||||
envopt[i] = static_cast<char>(tolower(start[i]));
|
||||
}
|
||||
envopt[len] = 0;
|
||||
if (strcmp(envopt, "version")==0 || strcmp(envopt, "image")==0 || strcmp(envopt, "arch")==0
|
||||
|| strcmp(envopt, "opts")==0 || strcmp(envopt, "inject")==0
|
||||
|| strcmp(envopt, "checkconfig")==0 || strcmp(envopt, "dumpconfig")==0
|
||||
if (strcmp(envopt, "version") == 0 || strcmp(envopt, "image") == 0 || strcmp(envopt, "arch") == 0
|
||||
|| strcmp(envopt, "opts") == 0 || strcmp(envopt, "inject") == 0
|
||||
|| strcmp(envopt, "checkconfig") == 0 || strcmp(envopt, "dumpconfig") == 0
|
||||
) {
|
||||
// ignore those defined in Dockerfile, EBUSD_OPTS, those with final args, and interactive ones
|
||||
continue;
|
||||
}
|
||||
char* envargv[] = {envname, pos+1};
|
||||
int cnt = pos[1] ? 2 : 1;
|
||||
if (pos[1] && strlen(*env)<sizeof(envname)-3
|
||||
&& (strcmp(envopt, "scanconfig")==0 || strcmp(envopt, "lograwdata")==0)) {
|
||||
if (pos[1] && strlen(*env) < sizeof(envname)-3
|
||||
&& (strcmp(envopt, "scanconfig") == 0 || strcmp(envopt, "lograwdata") == 0)) {
|
||||
// only really special case: OPTION_ARG_OPTIONAL with non-empty arg needs to use "=" syntax
|
||||
cnt = 1;
|
||||
strcat(envopt, pos);
|
||||
}
|
||||
int idx = -1;
|
||||
opt.injectMessages = true; // for skipping unknown values
|
||||
opt.injectMessages = true; // for skipping unknown values
|
||||
error_t err = argp_parse(&aargp, cnt, envargv, ARGP_PARSE_ARGV0|ARGP_SILENT|ARGP_IN_ORDER,
|
||||
&idx, &opt);
|
||||
if (err!=0 && idx==-1) { // ignore args for non-arg boolean options
|
||||
if (err!=0 && idx==-1) { // ignore args for non-arg boolean options
|
||||
logError(lf_main, "invalid/unknown argument in env: %s", envopt);
|
||||
}
|
||||
opt.injectMessages = false; // restore
|
||||
opt.injectMessages = false; // restore
|
||||
}
|
||||
|
||||
int arg_index = -1;
|
||||
@@ -1398,8 +1399,7 @@ int main(int argc, char* argv[]) {
|
||||
: opt.initialScan == BROADCAST ? " with broadcast scan" : opt.initialScan == SYN ? " with full scan"
|
||||
: " with single scan" : "",
|
||||
device->isEnhancedProto() ? " enhanced" : "",
|
||||
device->getName()
|
||||
);
|
||||
device->getName());
|
||||
|
||||
// load configuration files
|
||||
loadConfigFiles(s_messageMap);
|
||||
|
||||
@@ -2101,7 +2101,7 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
||||
}
|
||||
size_t comma = value.find(',');
|
||||
if (comma == string::npos || comma == 0
|
||||
|| value.find(circuit+","+name+",") != comma+1) { // ensure same circuit+name
|
||||
|| value.find(circuit+","+name+",") != comma+1) { // ensure same circuit+name
|
||||
ret = RESULT_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
|
||||
+89
-84
@@ -23,6 +23,8 @@
|
||||
#include "ebusd/mqtthandler.h"
|
||||
#include <csignal>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include "lib/utils/log.h"
|
||||
#include "lib/ebus/symbol.h"
|
||||
|
||||
@@ -55,38 +57,39 @@ using std::dec;
|
||||
|
||||
/** the definition of the MQTT arguments. */
|
||||
static const struct argp_option g_mqtt_argp_options[] = {
|
||||
{nullptr, 0, nullptr, 0, "MQTT options:", 1 },
|
||||
{"mqtthost", O_HOST, "HOST", 0, "Connect to MQTT broker on HOST [localhost]", 0 },
|
||||
{"mqttport", O_PORT, "PORT", 0, "Connect to MQTT broker on PORT (usually 1883), 0 to disable [0]", 0 },
|
||||
{"mqttclientid", O_CLID, "ID", 0, "Set client ID for connection to MQTT broker [" PACKAGE_NAME "_"
|
||||
{nullptr, 0, nullptr, 0, "MQTT options:", 1 },
|
||||
{"mqtthost", O_HOST, "HOST", 0, "Connect to MQTT broker on HOST [localhost]", 0 },
|
||||
{"mqttport", O_PORT, "PORT", 0, "Connect to MQTT broker on PORT (usually 1883), 0 to disable [0]", 0 },
|
||||
{"mqttclientid", O_CLID, "ID", 0, "Set client ID for connection to MQTT broker [" PACKAGE_NAME "_"
|
||||
PACKAGE_VERSION "_<pid>]", 0 },
|
||||
{"mqttuser", O_USER, "USER", 0, "Connect as USER to MQTT broker (no default)", 0 },
|
||||
{"mqttpass", O_PASS, "PASSWORD", 0, "Use PASSWORD when connecting to MQTT broker (no default)", 0 },
|
||||
{"mqtttopic", O_TOPI, "TOPIC", 0,
|
||||
{"mqttuser", O_USER, "USER", 0, "Connect as USER to MQTT broker (no default)", 0 },
|
||||
{"mqttpass", O_PASS, "PASSWORD", 0, "Use PASSWORD when connecting to MQTT broker (no default)", 0 },
|
||||
{"mqtttopic", O_TOPI, "TOPIC", 0,
|
||||
"Use MQTT TOPIC (prefix before /%circuit/%name or complete format) [ebusd]", 0 },
|
||||
{"mqttglobal", O_GTOP, "TOPIC", 0, "Use TOPIC for global data (default is \"global/\" suffix to mqtttopic prefix)", 0 },
|
||||
{"mqttretain", O_RETA, nullptr, 0, "Retain all topics instead of only selected global ones", 0 },
|
||||
{"mqttqos", O_PQOS, "QOS", 0, "Set the QoS value for all topics (0-2) [0]", 0 },
|
||||
{"mqttint", O_INTF, "FILE", 0, "Read MQTT integration settings from FILE (no default)", 0 },
|
||||
{"mqttglobal", O_GTOP, "TOPIC", 0,
|
||||
"Use TOPIC for global data (default is \"global/\" suffix to mqtttopic prefix)", 0 },
|
||||
{"mqttretain", O_RETA, nullptr, 0, "Retain all topics instead of only selected global ones", 0 },
|
||||
{"mqttqos", O_PQOS, "QOS", 0, "Set the QoS value for all topics (0-2) [0]", 0 },
|
||||
{"mqttint", O_INTF, "FILE", 0, "Read MQTT integration settings from FILE (no default)", 0 },
|
||||
{"mqttvar", O_IVAR, "NAME=VALUE[,...]", 0, "Add variable(s) to the read MQTT integration settings", 0 },
|
||||
{"mqttjson", O_JSON, nullptr, 0, "Publish in JSON format instead of strings", 0 },
|
||||
{"mqttverbose", O_VERB, nullptr, 0, "Publish all available attributes", 0 },
|
||||
{"mqttjson", O_JSON, nullptr, 0, "Publish in JSON format instead of strings", 0 },
|
||||
{"mqttverbose", O_VERB, nullptr, 0, "Publish all available attributes", 0 },
|
||||
#if (LIBMOSQUITTO_VERSION_NUMBER >= 1003001)
|
||||
{"mqttlog", O_LOGL, nullptr, 0, "Log library events", 0 },
|
||||
{"mqttlog", O_LOGL, nullptr, 0, "Log library events", 0 },
|
||||
#endif
|
||||
#if (LIBMOSQUITTO_VERSION_NUMBER >= 1004001)
|
||||
{"mqttversion", O_VERS, "VERSION", 0, "Use protocol VERSION [3.1]", 0 },
|
||||
{"mqttversion", O_VERS, "VERSION", 0, "Use protocol VERSION [3.1]", 0 },
|
||||
#endif
|
||||
{"mqttignoreinvalid", O_IGIN, nullptr, 0,
|
||||
"Ignore invalid parameters during init (e.g. for DNS not resolvable yet)", 0 },
|
||||
{"mqttchanges", O_CHGS, nullptr, 0, "Whether to only publish changed messages instead of all received", 0 },
|
||||
{"mqttchanges", O_CHGS, nullptr, 0, "Whether to only publish changed messages instead of all received", 0 },
|
||||
|
||||
#if (LIBMOSQUITTO_MAJOR >= 1)
|
||||
{"mqttca", O_CAFI, "CA", 0, "Use CA file or dir (ending with '/') for MQTT TLS (no default)", 0 },
|
||||
{"mqttcert", O_CERT, "CERTFILE", 0, "Use CERTFILE for MQTT TLS client certificate (no default)", 0 },
|
||||
{"mqttkey", O_KEYF, "KEYFILE", 0, "Use KEYFILE for MQTT TLS client certificate (no default)", 0 },
|
||||
{"mqttkeypass", O_KEPA, "PASSWORD", 0, "Use PASSWORD for the encrypted KEYFILE (no default)", 0 },
|
||||
{"mqttinsecure", O_INSE, nullptr, 0, "Allow insecure TLS connection (e.g. using a self signed certificate)", 0 },
|
||||
{"mqttca", O_CAFI, "CA", 0, "Use CA file or dir (ending with '/') for MQTT TLS (no default)", 0 },
|
||||
{"mqttcert", O_CERT, "CERTFILE", 0, "Use CERTFILE for MQTT TLS client certificate (no default)", 0 },
|
||||
{"mqttkey", O_KEYF, "KEYFILE", 0, "Use KEYFILE for MQTT TLS client certificate (no default)", 0 },
|
||||
{"mqttkeypass", O_KEPA, "PASSWORD", 0, "Use PASSWORD for the encrypted KEYFILE (no default)", 0 },
|
||||
{"mqttinsecure", O_INSE, nullptr, 0, "Allow insecure TLS connection (e.g. using a self signed certificate)", 0 },
|
||||
#endif
|
||||
|
||||
{nullptr, 0, nullptr, 0, nullptr, 0 },
|
||||
@@ -98,7 +101,7 @@ static const char* g_clientId = nullptr; //!< optional clientid override for MQ
|
||||
static const char* g_username = nullptr; //!< optional user name for MQTT broker (no default)
|
||||
static const char* g_password = nullptr; //!< optional password for MQTT broker (no default)
|
||||
static const char* g_topic = nullptr; //!< optional topic template
|
||||
static const char* g_globalTopic = nullptr; //!< optional global topic
|
||||
static const char* g_globalTopic = nullptr; //!< optional global topic
|
||||
static const char* g_integrationFile = nullptr; //!< the integration settings file
|
||||
static const char* g_integrationVars = nullptr; //!< the integration settings variables
|
||||
static bool g_retain = false; //!< whether to retail all topics
|
||||
@@ -381,8 +384,8 @@ std::pair<string, int> makeField(const string& name, bool isField) {
|
||||
if (!isField) {
|
||||
return {name, -1};
|
||||
}
|
||||
for (int idx = 0; idx < (int)knownFieldCount; idx++) {
|
||||
if (name==knownFieldNames[idx]) {
|
||||
for (int idx = 0; idx < static_cast<int>(knownFieldCount); idx++) {
|
||||
if (name == knownFieldNames[idx]) {
|
||||
return {name, idx};
|
||||
}
|
||||
}
|
||||
@@ -406,30 +409,30 @@ void addPart(ostringstream& stack, int inField, vector<std::pair<string, int>>&
|
||||
parts[parts.size()-1].first += str;
|
||||
return;
|
||||
}
|
||||
parts.push_back(makeField(str, inField>0));
|
||||
parts.push_back(makeField(str, inField > 0));
|
||||
}
|
||||
|
||||
bool MqttReplacer::parse(const string& templateStr, bool onlyKnown, bool noKnownDuplicates, bool emptyIfMissing) {
|
||||
m_parts.clear();
|
||||
int inField = 0; // 1 after '%', 2 after '%{'
|
||||
int inField = 0; // 1 after '%', 2 after '%{'
|
||||
ostringstream stack;
|
||||
for (auto ch : templateStr) {
|
||||
bool empty = stack.tellp()<=0;
|
||||
if (ch=='%') {
|
||||
if (inField==1 && empty) { // %% for plain %
|
||||
bool empty = stack.tellp() <= 0;
|
||||
if (ch == '%') {
|
||||
if (inField == 1 && empty) { // %% for plain %
|
||||
inField = 0;
|
||||
stack << ch;
|
||||
} else {
|
||||
addPart(stack, inField, m_parts);
|
||||
inField = 1;
|
||||
}
|
||||
} else if (ch=='{' && inField==1 && empty) {
|
||||
} else if (ch == '{' && inField == 1 && empty) {
|
||||
inField = 2;
|
||||
} else if (ch=='}' && inField==2) {
|
||||
} else if (ch == '}' && inField == 2) {
|
||||
addPart(stack, 1, m_parts);
|
||||
inField = 0;
|
||||
} else {
|
||||
if (inField>0 && !((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_')) {
|
||||
if (inField > 0 && !((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_')) {
|
||||
// invalid field character
|
||||
addPart(stack, inField, m_parts);
|
||||
inField = 0;
|
||||
@@ -449,7 +452,7 @@ bool MqttReplacer::parse(const string& templateStr, bool onlyKnown, bool noKnown
|
||||
return false;
|
||||
}
|
||||
if (noKnownDuplicates && it.second < knownCount) {
|
||||
int bit = 1<<it.second;
|
||||
int bit = 1 << it.second;
|
||||
if (foundMask & bit) {
|
||||
return false; // duplicate known field
|
||||
}
|
||||
@@ -469,7 +472,7 @@ void MqttReplacer::normalize(string& str) {
|
||||
|
||||
const string MqttReplacer::str() const {
|
||||
ostringstream ret;
|
||||
for (const auto &it: m_parts) {
|
||||
for (const auto &it : m_parts) {
|
||||
if (it.second >= 0) {
|
||||
ret << '%';
|
||||
}
|
||||
@@ -481,8 +484,8 @@ const string MqttReplacer::str() const {
|
||||
void MqttReplacer::ensureDefault() {
|
||||
if (m_parts.empty()) {
|
||||
m_parts.emplace_back(string(PACKAGE) + "/", -1);
|
||||
} else if (m_parts.size()==1 && m_parts[0].second<0 && m_parts[0].first.find('/')==string::npos) {
|
||||
m_parts[0] = {m_parts[0].first + "/", -1}; // ensure trailing slash
|
||||
} else if (m_parts.size() == 1 && m_parts[0].second < 0 && m_parts[0].first.find('/') == string::npos) {
|
||||
m_parts[0] = {m_parts[0].first + "/", -1}; // ensure trailing slash
|
||||
}
|
||||
if (!has("circuit")) {
|
||||
m_parts.emplace_back("circuit", 0); // index of circuit in knownFieldNames
|
||||
@@ -498,7 +501,7 @@ bool MqttReplacer::empty() const {
|
||||
}
|
||||
|
||||
bool MqttReplacer::has(const string& field) const {
|
||||
for (const auto &it: m_parts) {
|
||||
for (const auto &it : m_parts) {
|
||||
if (it.second >= 0 && it.first == field) {
|
||||
return true;
|
||||
}
|
||||
@@ -508,13 +511,13 @@ bool MqttReplacer::has(const string& field) const {
|
||||
|
||||
string MqttReplacer::get(const map<string, string>& values, bool untilFirstEmpty, bool onlyAlphanum) const {
|
||||
ostringstream ret;
|
||||
for (const auto &it: m_parts) {
|
||||
for (const auto &it : m_parts) {
|
||||
if (it.second < 0) {
|
||||
ret << it.first;
|
||||
continue;
|
||||
}
|
||||
const auto pos = values.find(it.first);
|
||||
if (pos==values.cend()) {
|
||||
if (pos == values.cend()) {
|
||||
if (untilFirstEmpty) {
|
||||
break;
|
||||
}
|
||||
@@ -561,12 +564,12 @@ string MqttReplacer::get(const Message* message, const string& fieldName) const
|
||||
}
|
||||
|
||||
bool MqttReplacer::isReducable(const map<string, string>& values) const {
|
||||
for (const auto &it: m_parts) {
|
||||
for (const auto &it : m_parts) {
|
||||
if (it.second < 0) {
|
||||
continue;
|
||||
}
|
||||
const auto pos = values.find(it.first);
|
||||
if (pos==values.cend()) {
|
||||
if (pos == values.cend()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -579,7 +582,7 @@ void MqttReplacer::compress(const map<string, string>& values) {
|
||||
bool isConstant = it->second < 0;
|
||||
if (!isConstant) {
|
||||
const auto pos = values.find(it->first);
|
||||
if (pos!=values.cend()) {
|
||||
if (pos != values.cend()) {
|
||||
it->second = -1;
|
||||
it->first = pos->second;
|
||||
isConstant = true;
|
||||
@@ -597,13 +600,13 @@ void MqttReplacer::compress(const map<string, string>& values) {
|
||||
|
||||
bool MqttReplacer::reduce(const map<string, string>& values, string& result, bool onlyAlphanum) const {
|
||||
ostringstream ret;
|
||||
for (const auto &it: m_parts) {
|
||||
for (const auto &it : m_parts) {
|
||||
if (it.second < 0) {
|
||||
ret << it.first;
|
||||
continue;
|
||||
}
|
||||
const auto pos = values.find(it.first);
|
||||
if (pos==values.cend()) {
|
||||
if (pos == values.cend()) {
|
||||
if (m_emptyIfMissing) {
|
||||
result = "";
|
||||
} else {
|
||||
@@ -670,7 +673,7 @@ ssize_t MqttReplacer::matchTopic(const string& topic, string* circuit, string* n
|
||||
case 0: *circuit = value; break;
|
||||
case 1: *name = value; break;
|
||||
case 2: *field = value; break;
|
||||
default: // unknown field
|
||||
default: // unknown field
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -681,7 +684,7 @@ static const string EMPTY = "";
|
||||
|
||||
const string& MqttReplacers::operator[](const string& key) const {
|
||||
auto itc = m_constants.find(key);
|
||||
if (itc==m_constants.end()) {
|
||||
if (itc == m_constants.end()) {
|
||||
return EMPTY;
|
||||
}
|
||||
return itc->second;
|
||||
@@ -719,20 +722,20 @@ MqttReplacer MqttReplacers::get(const string& key) const {
|
||||
|
||||
string MqttReplacers::get(const string& key, bool untilFirstEmpty, bool onlyAlphanum, const string& fallbackKey) const {
|
||||
auto itc = m_constants.find(key);
|
||||
if (itc!=m_constants.end()) {
|
||||
if (itc != m_constants.end()) {
|
||||
return itc->second;
|
||||
}
|
||||
auto itv = m_replacers.find(key);
|
||||
if (itv!=m_replacers.end()) {
|
||||
if (itv != m_replacers.end()) {
|
||||
return itv->second.get(m_constants, untilFirstEmpty, onlyAlphanum);
|
||||
}
|
||||
if (!fallbackKey.empty()) {
|
||||
itc = m_constants.find(fallbackKey);
|
||||
if (itc!=m_constants.end()) {
|
||||
if (itc != m_constants.end()) {
|
||||
return itc->second;
|
||||
}
|
||||
itv = m_replacers.find(fallbackKey);
|
||||
if (itv!=m_replacers.end()) {
|
||||
if (itv != m_replacers.end()) {
|
||||
return itv->second.get(m_constants, untilFirstEmpty, onlyAlphanum);
|
||||
}
|
||||
}
|
||||
@@ -744,12 +747,12 @@ bool MqttReplacers::set(const string& key, const string& value, bool removeRepla
|
||||
if (removeReplacer) {
|
||||
m_replacers.erase(key);
|
||||
}
|
||||
if (key.find_first_of("-_")!=string::npos) {
|
||||
if (key.find_first_of("-_") != string::npos) {
|
||||
return false;
|
||||
}
|
||||
string upper = key;
|
||||
transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
|
||||
if (upper==key) {
|
||||
if (upper == key) {
|
||||
return false;
|
||||
}
|
||||
string val = value;
|
||||
@@ -788,7 +791,7 @@ void MqttReplacers::reduce(bool compress) {
|
||||
if (restart) {
|
||||
string upper = it->first;
|
||||
transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
|
||||
if (m_replacers.erase(upper)>0) {
|
||||
if (m_replacers.erase(upper) > 0) {
|
||||
break; // restart as iterator is now invalid
|
||||
}
|
||||
}
|
||||
@@ -876,7 +879,7 @@ void MqttHandler::parseIntegration(const string& line) {
|
||||
return;
|
||||
}
|
||||
size_t pos = line.find('=');
|
||||
if (pos==string::npos || pos==0) {
|
||||
if (pos == string::npos || pos == 0) {
|
||||
return;
|
||||
}
|
||||
bool emptyIfMissing = false;
|
||||
@@ -890,7 +893,7 @@ void MqttHandler::parseIntegration(const string& line) {
|
||||
FileReader::trim(&key);
|
||||
string value = line.substr(pos+1);
|
||||
FileReader::trim(&value);
|
||||
if (value.find('%')==string::npos) {
|
||||
if (value.find('%') == string::npos) {
|
||||
m_replacers.set(key, value); // constant value
|
||||
} else {
|
||||
// simple variable
|
||||
@@ -914,7 +917,7 @@ static const char* directionNames[] = {
|
||||
|
||||
string removeTrailingNonTopicPart(const string& str) {
|
||||
size_t pos = str.find_last_not_of("/_");
|
||||
if (pos==string::npos) {
|
||||
if (pos == string::npos) {
|
||||
return str;
|
||||
}
|
||||
return str.substr(0, pos + 1);
|
||||
@@ -947,7 +950,7 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
||||
}
|
||||
if (last.empty()) {
|
||||
last = line;
|
||||
} else if (line[0] == '\t' || line[0] == ' ') { // continuation
|
||||
} else if (line[0] == '\t' || line[0] == ' ') { // continuation
|
||||
last += "\n" + line;
|
||||
} else {
|
||||
parseIntegration(last);
|
||||
@@ -962,7 +965,7 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
||||
splitFields(g_integrationVars, &strs);
|
||||
for (auto& str : strs) {
|
||||
size_t pos = str.find('=');
|
||||
if (pos==string::npos || pos==0) {
|
||||
if (pos == string::npos || pos == 0) {
|
||||
continue;
|
||||
}
|
||||
m_replacers.set(str.substr(0, pos), str.substr(pos+1));
|
||||
@@ -974,19 +977,19 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
||||
MqttReplacer& topic = m_replacers.get("topic");
|
||||
if (g_topic) {
|
||||
string str = g_topic;
|
||||
bool noDefault = str[str.size()-1]=='#';
|
||||
bool noDefault = str[str.size()-1] == '#';
|
||||
if (noDefault) {
|
||||
str.resize(str.size()-1);
|
||||
}
|
||||
bool parse = true;
|
||||
if (hasIntegration && !topic.empty()) {
|
||||
// topic defined in cmdline and integration file.
|
||||
if (str.find('%')==string::npos) {
|
||||
if (str.find('%') == string::npos) {
|
||||
// cmdline topic is only the prefix, use it
|
||||
m_replacers.set("prefix", str);
|
||||
m_replacers.set("prefixn", removeTrailingNonTopicPart(str));
|
||||
parse = false;
|
||||
} // else: cmdline topic is more than just a prefix => override integration topic completely
|
||||
} // else: cmdline topic is more than just a prefix => override integration topic completely
|
||||
}
|
||||
if (parse) {
|
||||
if (!topic.parse(str, true, true)) {
|
||||
@@ -1017,7 +1020,7 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
||||
for (int i=-1; i<static_cast<signed>(sizeof(directionNames)/sizeof(char*)); i++) {
|
||||
for (auto typeName : typeNames) {
|
||||
ostr.str("");
|
||||
if (i>=0) {
|
||||
if (i >= 0) {
|
||||
ostr << directionNames[i] << '-';
|
||||
}
|
||||
ostr << typeName;
|
||||
@@ -1026,7 +1029,7 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
||||
if (str.empty()) {
|
||||
continue;
|
||||
}
|
||||
str += '\n'; // add trailing newline to ease the split
|
||||
str += '\n'; // add trailing newline to ease the split
|
||||
size_t from = 0;
|
||||
do {
|
||||
size_t pos = str.find('\n', from);
|
||||
@@ -1172,7 +1175,7 @@ void MqttHandler::notifyConnected() {
|
||||
if (!m_staticTopic) {
|
||||
check(mosquitto_subscribe(m_mosquitto, nullptr, m_subscribeTopic.c_str(), 0), "subscribe");
|
||||
if (!m_subscribeConfigRestartTopic.empty()) {
|
||||
check(mosquitto_subscribe(m_mosquitto, nullptr, m_subscribeConfigRestartTopic.c_str(), 0), "subscribe definition");
|
||||
check(mosquitto_subscribe(m_mosquitto, nullptr, m_subscribeConfigRestartTopic.c_str(), 0), "subscribe def.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1209,7 +1212,7 @@ void MqttHandler::notifyTopic(const string& topic, const string& data) {
|
||||
logOtherDebug("mqtt", "received topic %s with data %s", topic.c_str(), data.c_str());
|
||||
string circuit, name, field;
|
||||
ssize_t match = m_replacers.get("topic").matchTopic(topic.substr(0, pos), &circuit, &name, &field);
|
||||
if (match<0 && !isList) {
|
||||
if (match < 0 && !isList) {
|
||||
logOtherError("mqtt", "received unmatchable topic %s", topic.c_str());
|
||||
}
|
||||
if (isList) {
|
||||
@@ -1311,7 +1314,7 @@ void MqttHandler::notifyScanStatus(const string& scanStatus) {
|
||||
}
|
||||
|
||||
bool parseBool(const string& str) {
|
||||
return !str.empty() && !(str=="0" || str=="no" || str=="false");
|
||||
return !str.empty() && !(str == "0" || str == "no" || str == "false");
|
||||
}
|
||||
|
||||
void splitFields(const string& str, vector<string>* row) {
|
||||
@@ -1388,7 +1391,8 @@ void MqttHandler::run() {
|
||||
}
|
||||
}
|
||||
if (m_connected && m_definitionsSince == 0) {
|
||||
publishDefinition(m_replacers, "def_global_running-", m_globalTopic.get("", "running"), "global", "running", "def_global-");
|
||||
publishDefinition(m_replacers, "def_global_running-", m_globalTopic.get("", "running"), "global", "running",
|
||||
"def_global-");
|
||||
if (globalHasName) {
|
||||
publishDefinition(m_replacers, "def_global_version-", m_globalTopic.get("", "version"), "global", "version",
|
||||
"def_global-");
|
||||
@@ -1408,7 +1412,7 @@ void MqttHandler::run() {
|
||||
for (const auto& message : messages) {
|
||||
bool checkPollAdjust = false;
|
||||
if (filterSeen > 0) {
|
||||
if (message->getLastUpdateTime()==0) {
|
||||
if (message->getLastUpdateTime() == 0) {
|
||||
if (message->isPassive()) {
|
||||
// only wait for data on passive messages
|
||||
continue; // no data ever
|
||||
@@ -1425,9 +1429,9 @@ void MqttHandler::run() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message->getDataHandlerState()==1) {
|
||||
if (message->getDataHandlerState() == 1) {
|
||||
// already seen in the past, check for poll prio update
|
||||
if (m_definitionsSince>1 && message->getCreateTime() <= m_definitionsSince) {
|
||||
if (m_definitionsSince > 1 && message->getCreateTime() <= m_definitionsSince) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1450,7 +1454,7 @@ void MqttHandler::run() {
|
||||
}
|
||||
m_messages->addPollMessage(false, message);
|
||||
}
|
||||
if (filterPriority>0 && (message->getPollPriority()==0 || message->getPollPriority()>filterPriority)) {
|
||||
if (filterPriority > 0 && (message->getPollPriority() == 0 || message->getPollPriority() > filterPriority)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1523,26 +1527,26 @@ void MqttHandler::run() {
|
||||
if (dt->getMinMax(false, OF_NONE, &ostr) == RESULT_OK) {
|
||||
values.set("min", ostr.str());
|
||||
ostr.str("");
|
||||
};
|
||||
}
|
||||
if (dt->getMinMax(true, OF_NONE, &ostr) == RESULT_OK) {
|
||||
values.set("max", ostr.str());
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!m_typeSwitches.empty()) {
|
||||
values.reduce(true);
|
||||
str = values.get("type_switch-by", false, false);
|
||||
string typeSwitch;
|
||||
for (int i=0; i<2; i++) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ostr.str("");
|
||||
if (i==0) {
|
||||
if (i == 0) {
|
||||
ostr << direction << '-';
|
||||
}
|
||||
ostr << typeStr;
|
||||
const string key = ostr.str();
|
||||
for (auto const &check: m_typeSwitches[key]) {
|
||||
for (auto const &check : m_typeSwitches[key]) {
|
||||
if (FileReader::matches(str, check.second, true, true)) {
|
||||
typeSwitch = check.first;
|
||||
i = 2; // early exit
|
||||
i = 2; // early exit
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1551,7 +1555,7 @@ void MqttHandler::run() {
|
||||
if (!typeSwitchNames.empty()) {
|
||||
vector<string> strs;
|
||||
splitFields(typeSwitch, &strs);
|
||||
for (size_t pos = 0; pos<strs.size() && pos<typeSwitchNames.size(); pos++) {
|
||||
for (size_t pos = 0; pos<strs.size() && pos < typeSwitchNames.size(); pos++) {
|
||||
values.set(typeSwitchNames[pos], strs[pos]);
|
||||
}
|
||||
}
|
||||
@@ -1567,7 +1571,7 @@ void MqttHandler::run() {
|
||||
if (m_hasDefinitionFieldsPayload) {
|
||||
string value = values["field_payload"];
|
||||
if (!value.empty()) {
|
||||
if (fields.tellp()>0) {
|
||||
if (fields.tellp() > 0) {
|
||||
fields << values["field-separator"];
|
||||
}
|
||||
fields << value;
|
||||
@@ -1576,17 +1580,17 @@ void MqttHandler::run() {
|
||||
}
|
||||
publishDefinition(values);
|
||||
}
|
||||
if (fields.tellp()>0) {
|
||||
if (fields.tellp() > 0) {
|
||||
msgValues.set("fields_payload", fields.str());
|
||||
publishDefinition(msgValues);
|
||||
}
|
||||
if (filterSeen && message->getLastUpdateTime()>message->getCreateTime()) {
|
||||
if (filterSeen && message->getLastUpdateTime() > message->getCreateTime()) {
|
||||
// ensure data is published as well
|
||||
m_updatedMessages[message->getKey()]++;
|
||||
} else if (filterSeen && direction=="w") {
|
||||
} else if (filterSeen && direction == "w") {
|
||||
// publish data for read pendant of write message
|
||||
Message* read = m_messages->find(message->getCircuit(), message->getName(), "", true);
|
||||
if (read && read->getLastUpdateTime()>0) {
|
||||
if (read && read->getLastUpdateTime() > 0) {
|
||||
m_updatedMessages[read->getKey()]++;
|
||||
}
|
||||
}
|
||||
@@ -1763,7 +1767,8 @@ void MqttHandler::publishMessage(const Message* message, ostringstream* updates,
|
||||
if (json) {
|
||||
*updates << "{";
|
||||
if (m_staticTopic) {
|
||||
*updates << "\"circuit\":\"" << message->getCircuit() << "\",\"name\":\"" << message->getName() << "\",\"fields\":{";
|
||||
*updates << "\"circuit\":\"" << message->getCircuit() << "\",\"name\":\"" << message->getName()
|
||||
<< "\",\"fields\":{";
|
||||
}
|
||||
} else {
|
||||
*updates << message->getCircuit() << UI_FIELD_SEPARATOR << message->getName() << UI_FIELD_SEPARATOR;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "ebusd/datahandler.h"
|
||||
#include "ebusd/bushandler.h"
|
||||
#include "lib/ebus/message.h"
|
||||
@@ -118,7 +119,7 @@ class MqttReplacer {
|
||||
* @param fieldName the field name for replacement.
|
||||
* @return the replaced template string.
|
||||
*/
|
||||
string get(const string& circuit, const string& name, const string& fieldName="") const;
|
||||
string get(const string& circuit, const string& name, const string& fieldName = "") const;
|
||||
|
||||
/**
|
||||
* Get the replaced template string.
|
||||
@@ -126,7 +127,7 @@ class MqttReplacer {
|
||||
* @param fieldName the field name for replacement.
|
||||
* @return the replaced template string.
|
||||
*/
|
||||
string get(const Message* message, const string& fieldName="") const;
|
||||
string get(const Message* message, const string& fieldName = "") const;
|
||||
|
||||
/**
|
||||
* Check if the fields can be reduced to a constant value.
|
||||
|
||||
@@ -130,8 +130,8 @@ void AttributedItem::mergeAttributes(map<string, string>* attributes) const {
|
||||
}
|
||||
}
|
||||
|
||||
void AttributedItem::dumpAttribute(bool prependFieldSeparator, OutputFormat outputFormat, const string& name, ostream* output)
|
||||
const {
|
||||
void AttributedItem::dumpAttribute(bool prependFieldSeparator, OutputFormat outputFormat, const string& name,
|
||||
ostream* output) const {
|
||||
if (outputFormat & OF_JSON) {
|
||||
appendJson(prependFieldSeparator, name, getAttribute(name), false, output);
|
||||
} else {
|
||||
|
||||
+2
-2
@@ -426,12 +426,12 @@ class SingleDataField : public DataField {
|
||||
size_t getCount(PartType partType = pt_any, const char* fieldName = nullptr) const override;
|
||||
|
||||
// @copydoc
|
||||
virtual string getName(ssize_t fieldIndex) const override {
|
||||
string getName(ssize_t fieldIndex) const override {
|
||||
return isIgnored() || fieldIndex > 0 ? "" : m_name;
|
||||
}
|
||||
|
||||
// @copydoc
|
||||
virtual const SingleDataField* getField(ssize_t fieldIndex) const override {
|
||||
const SingleDataField* getField(ssize_t fieldIndex) const override {
|
||||
if (isIgnored() || fieldIndex > 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -359,8 +359,8 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
||||
return RESULT_ERR_INVALID_POS;
|
||||
}
|
||||
// number of minutes since 01.01.2009
|
||||
minutes |= symbol*(1<<(8*i));
|
||||
if (i<3) {
|
||||
minutes |= symbol*(1 << (8*i));
|
||||
if (i < 3) {
|
||||
break;
|
||||
}
|
||||
int mjd = static_cast<int>(minutes/(24*60)) + 54832; // 01.01.2009
|
||||
@@ -424,7 +424,7 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
||||
if (length == 4 && i == 2 && !m_hasTime) {
|
||||
continue; // skip weekday in between
|
||||
}
|
||||
if (input->eof() || !getline(*input, token, m_hasTime && i==2 ? ' ' : '.')) {
|
||||
if (input->eof() || !getline(*input, token, m_hasTime && i == 2 ? ' ' : '.')) {
|
||||
return RESULT_ERR_EOF; // incomplete
|
||||
}
|
||||
if (!hasFlag(REQ) && token == NULL_VALUE) {
|
||||
@@ -464,7 +464,7 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
||||
index = start + incr;
|
||||
i = 1;
|
||||
type = 1;
|
||||
skip = true; // switch to second pass for parsing the time
|
||||
skip = true; // switch to second pass for parsing the time
|
||||
} else {
|
||||
// calculate local week day
|
||||
int daysSinceSunday = (mjd + 3) % 7; // Sun=0
|
||||
@@ -546,7 +546,7 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // date and time in store phase
|
||||
case 3: // date and time in store phase
|
||||
value = lastLast & 0xff;
|
||||
last = lastLast >> 8;
|
||||
break;
|
||||
@@ -677,7 +677,7 @@ result_t NumberDataType::derive(int divisor, size_t bitCount, const NumberDataTy
|
||||
|
||||
result_t NumberDataType::getMinMax(bool getMax, const OutputFormat outputFormat, ostream* output) const {
|
||||
size_t length;
|
||||
if (m_bitCount<8) {
|
||||
if (m_bitCount < 8) {
|
||||
length = 1;
|
||||
} else {
|
||||
length = m_bitCount/8;
|
||||
@@ -1135,7 +1135,7 @@ DataTypeList* DataTypeList::getInstance() {
|
||||
void DataTypeList::dump(OutputFormat outputFormat, bool appendDivisor, ostream* output) const {
|
||||
bool json = outputFormat & OF_JSON;
|
||||
string sep = "\n";
|
||||
for (const auto &it: m_typesById) {
|
||||
for (const auto &it : m_typesById) {
|
||||
const DataType *dataType = it.second;
|
||||
if (dataType->hasFlag(DUP)) {
|
||||
continue;
|
||||
|
||||
@@ -437,8 +437,8 @@ class NumberDataType : public DataType {
|
||||
NumberDataType(const string& id, size_t bitCount, uint16_t flags, unsigned int replacement,
|
||||
unsigned int minValue, unsigned int maxValue, int divisor,
|
||||
const NumberDataType* baseType = nullptr)
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(minValue), m_maxValue(maxValue), m_divisor(divisor==0 ? 1 : divisor),
|
||||
m_precision(calcPrecision(divisor)), m_firstBit(0), m_baseType(baseType) {}
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(minValue), m_maxValue(maxValue),
|
||||
m_divisor(divisor == 0 ? 1 : divisor), m_precision(calcPrecision(divisor)), m_firstBit(0), m_baseType(baseType) {}
|
||||
|
||||
/**
|
||||
* Constructs a new instance for less than 8 bits.
|
||||
@@ -452,8 +452,8 @@ class NumberDataType : public DataType {
|
||||
*/
|
||||
NumberDataType(const string& id, size_t bitCount, uint16_t flags, unsigned int replacement,
|
||||
int16_t firstBit, int divisor, const NumberDataType* baseType = nullptr)
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(0), m_maxValue((1 << bitCount)-1), m_divisor(divisor==0 ? 1 : divisor),
|
||||
m_precision(0), m_firstBit(firstBit), m_baseType(baseType) {}
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(0), m_maxValue((1 << bitCount)-1),
|
||||
m_divisor(divisor == 0 ? 1 : divisor), m_precision(0), m_firstBit(firstBit), m_baseType(baseType) {}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
|
||||
+12
-10
@@ -79,8 +79,8 @@ namespace ebusd {
|
||||
Device::Device(const char* name, bool checkDevice, unsigned int latency, bool readOnly, bool initialSend,
|
||||
bool enhancedProto)
|
||||
: m_name(name), m_checkDevice(checkDevice),
|
||||
m_latency(HOST_LATENCY_MS+(enhancedProto?ENHANCED_LATENCY_MS:0)+latency), m_readOnly(readOnly), m_initialSend(initialSend),
|
||||
m_enhancedProto(enhancedProto), m_fd(-1), m_listener(nullptr), m_arbitrationMaster(SYN),
|
||||
m_latency(HOST_LATENCY_MS+(enhancedProto?ENHANCED_LATENCY_MS:0)+latency), m_readOnly(readOnly),
|
||||
m_initialSend(initialSend), m_enhancedProto(enhancedProto), m_fd(-1), m_listener(nullptr), m_arbitrationMaster(SYN),
|
||||
m_arbitrationCheck(false), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0),
|
||||
m_extraFatures(0), m_infoId(0xff), m_infoLen(0), m_infoPos(0) {
|
||||
m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize));
|
||||
@@ -184,7 +184,7 @@ result_t Device::requestEnhancedInfo(symbol_t infoId) {
|
||||
if (!m_enhancedProto || m_extraFatures == 0 || infoId == 0xff) {
|
||||
return RESULT_ERR_INVALID_ARG;
|
||||
}
|
||||
for (unsigned int i=0; i<4; i++) {
|
||||
for (unsigned int i = 0; i < 4; i++) {
|
||||
if (m_infoId == 0xff) {
|
||||
break;
|
||||
}
|
||||
@@ -602,7 +602,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
|
||||
break;
|
||||
case ENH_RES_INFO:
|
||||
if (m_infoLen == 0) {
|
||||
if (data<=16) { // max length
|
||||
if (data <= 16) { // max length
|
||||
m_infoLen = data;
|
||||
m_infoPos = 0;
|
||||
}
|
||||
@@ -611,9 +611,10 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
|
||||
if (m_infoPos >= m_infoLen) {
|
||||
unsigned int val;
|
||||
ostringstream stream;
|
||||
switch ((m_infoLen<<8) | m_infoId) {
|
||||
switch ((m_infoLen << 8) | m_infoId) {
|
||||
case 0x0200:
|
||||
stream << "firmware " << static_cast<unsigned>(m_infoBuf[0]) << "." << std::hex << static_cast<unsigned>(m_infoBuf[1]);
|
||||
stream << "firmware " << static_cast<unsigned>(m_infoBuf[0]) << "." << std::hex
|
||||
<< static_cast<unsigned>(m_infoBuf[1]);
|
||||
break;
|
||||
case 0x0901:
|
||||
case 0x0802:
|
||||
@@ -624,12 +625,12 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
|
||||
}
|
||||
break;
|
||||
case 0x0203:
|
||||
val = (static_cast<unsigned>(m_infoBuf[0])<<8) | static_cast<unsigned>(m_infoBuf[1]);
|
||||
val = (static_cast<unsigned>(m_infoBuf[0]) << 8) | static_cast<unsigned>(m_infoBuf[1]);
|
||||
stream << "temperature " << static_cast<unsigned>(val) << " °C";
|
||||
m_enhInfoTemperature = stream.str();
|
||||
break;
|
||||
case 0x0204:
|
||||
val = (static_cast<unsigned>(m_infoBuf[0])<<8) | static_cast<unsigned>(m_infoBuf[1]);
|
||||
val = (static_cast<unsigned>(m_infoBuf[0]) << 8) | static_cast<unsigned>(m_infoBuf[1]);
|
||||
stream << "supply voltage " << static_cast<unsigned>(val) << " mV";
|
||||
m_enhInfoSupplyVoltage = stream.str();
|
||||
break;
|
||||
@@ -640,8 +641,9 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
|
||||
m_enhInfoBusVoltage = stream.str();
|
||||
break;
|
||||
default:
|
||||
stream << "unknown 0x" << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned>(m_infoId)
|
||||
<< ", len " << std::dec << std::setw(0) << static_cast<unsigned>(m_infoPos);
|
||||
stream << "unknown 0x" << std::hex << std::setfill('0') << std::setw(2)
|
||||
<< static_cast<unsigned>(m_infoId) << ", len " << std::dec << std::setw(0)
|
||||
<< static_cast<unsigned>(m_infoPos);
|
||||
break;
|
||||
}
|
||||
m_listener->notifyStatus(false, ("extra info: "+stream.str()).c_str());
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <netdb.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "lib/ebus/result.h"
|
||||
#include "lib/ebus/symbol.h"
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ bool FileReader::matches(const string& input, const string& search, bool ignoreC
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
if (from==to) {
|
||||
if (from == to) {
|
||||
return true; // empty pattern matches everything
|
||||
}
|
||||
size_t nextStart = to+1;
|
||||
@@ -150,11 +150,11 @@ bool FileReader::matches(const string& input, const string& search, bool ignoreC
|
||||
if (matchStart) {
|
||||
from++;
|
||||
}
|
||||
bool matchEnd = from<to && search[to-1] == '$';
|
||||
bool matchEnd = from < to && search[to-1] == '$';
|
||||
if (matchEnd) {
|
||||
to--;
|
||||
}
|
||||
if (matchEnd && matchStart && from==to) { // pattern is "^$"
|
||||
if (matchEnd && matchStart && from == to) { // pattern is "^$"
|
||||
if (input.empty()) {
|
||||
return true;
|
||||
}
|
||||
@@ -189,7 +189,7 @@ bool FileReader::matches(const string& input, const string& search, bool ignoreC
|
||||
}
|
||||
if (prefix.length() <= checkEnd) {
|
||||
if (matchStart) {
|
||||
if (input.substr(0, prefix.length()) == prefix && (!matchEnd || prefix.length()==checkEnd)) {
|
||||
if (input.substr(0, prefix.length()) == prefix && (!matchEnd || prefix.length() == checkEnd)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
||||
+15
-11
@@ -483,11 +483,11 @@ result_t Message::create(const string& filename, const DataFieldTemplates* templ
|
||||
}
|
||||
Message* message;
|
||||
if (chainIds.size() > 1) {
|
||||
message = new ChainedMessage(filename, useCircuit, level, name, isWrite, *row, srcAddress, dstAddress, id, chainIds,
|
||||
chainLengths, data, index == 0, pollPriority, condition);
|
||||
message = new ChainedMessage(filename, useCircuit, level, name, isWrite, *row, srcAddress, dstAddress, id,
|
||||
chainIds, chainLengths, data, index == 0, pollPriority, condition);
|
||||
} else {
|
||||
message = new Message(filename, useCircuit, level, name, isWrite, isPassive, *row, srcAddress, dstAddress, id, data,
|
||||
index == 0, pollPriority, condition);
|
||||
message = new Message(filename, useCircuit, level, name, isWrite, isPassive, *row, srcAddress, dstAddress, id,
|
||||
data, index == 0, pollPriority, condition);
|
||||
}
|
||||
messages->push_back(message);
|
||||
index++;
|
||||
@@ -853,7 +853,8 @@ void Message::dumpHeader(const vector<string>* fieldNames, ostream* output) {
|
||||
}
|
||||
}
|
||||
|
||||
void Message::dump(const vector<string>* fieldNames, bool withConditions, OutputFormat outputFormat, ostream* output) const {
|
||||
void Message::dump(const vector<string>* fieldNames, bool withConditions, OutputFormat outputFormat, ostream* output)
|
||||
const {
|
||||
// not to be used together with OF_JSON
|
||||
bool first = true;
|
||||
if (fieldNames == nullptr) {
|
||||
@@ -880,7 +881,8 @@ void Message::dump(const vector<string>* fieldNames, bool withConditions, Output
|
||||
}
|
||||
}
|
||||
|
||||
void Message::dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const {
|
||||
void Message::dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output)
|
||||
const {
|
||||
if (fieldName == "type") {
|
||||
if (withConditions && m_condition != nullptr) {
|
||||
m_condition->dump(false, output);
|
||||
@@ -969,7 +971,7 @@ void Message::decodeJson(bool leadingSeparator, bool appendDirectionCondition, b
|
||||
if (outputFormat & OF_ALL_ATTRS) {
|
||||
*output << ",\n \"filename\": \"" << m_filename << "\"";
|
||||
*output << ",\n \"level\": \"" << getLevel() << "\"";
|
||||
if (getPollPriority()>0) {
|
||||
if (getPollPriority() > 0) {
|
||||
*output << ",\n \"pollprio\": " << setw(0) << dec << getPollPriority();
|
||||
}
|
||||
if (isConditional()) {
|
||||
@@ -1278,7 +1280,8 @@ result_t ChainedMessage::combineLastParts() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void ChainedMessage::dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const {
|
||||
void ChainedMessage::dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output)
|
||||
const {
|
||||
if (fieldName != "id") {
|
||||
Message::dumpField(fieldName, withConditions, outputFormat, output);
|
||||
return;
|
||||
@@ -2164,10 +2167,11 @@ result_t MessageMap::readConditions(const string& filename, string* types, strin
|
||||
|
||||
bool MessageMap::extractDefaultsFromFilename(const string& filename, map<string, string>* defaults,
|
||||
symbol_t* destAddress, unsigned int* software, unsigned int* hardware) const {
|
||||
// check filename to match (glob style with optionals in brackets): ZZ.[ID.][*.][CIRCUIT.[?.]][*.][HW????.][*.][SW????.][*.]csv
|
||||
// check filename to match (glob style with optionals in brackets):
|
||||
// ZZ.[ID.][*.][CIRCUIT.[?.]][*.][HW????.][*.][SW????.][*.]csv
|
||||
// ZZ is the address, ID is the 5 char identifier (reduced by trailing 0 one by one for finding a match), CIRCUIT is
|
||||
// the optional circuit name, ? behind the circuit name is the circuit number suffix (when having more than one of these),
|
||||
// ???? behind HW is the hardware version, ???? behind SW is the software version
|
||||
// the optional circuit name, ? behind the circuit name is the circuit number suffix (when having more than one of
|
||||
// these), ???? behind HW is the hardware version, ???? behind SW is the software version
|
||||
string ident, circuit, suffix;
|
||||
unsigned int sw = UINT_MAX, hw = UINT_MAX;
|
||||
string remain = filename;
|
||||
|
||||
@@ -586,7 +586,8 @@ class Message : public AttributedItem {
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param output the @a ostream to append the formatted value to.
|
||||
*/
|
||||
virtual void dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const;
|
||||
virtual void dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output)
|
||||
const;
|
||||
|
||||
/**
|
||||
* Decode the message from the last stored data in JSON format.
|
||||
@@ -767,7 +768,8 @@ class ChainedMessage : public Message {
|
||||
|
||||
protected:
|
||||
// @copydoc
|
||||
void dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const override;
|
||||
void dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const
|
||||
override;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
*/
|
||||
|
||||
#include "lib/utils/httpclient.h"
|
||||
#include "lib/utils/log.h"
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <csignal>
|
||||
#include "lib/utils/log.h"
|
||||
|
||||
namespace ebusd {
|
||||
|
||||
@@ -59,7 +59,7 @@ bool isError(const char* call, long result, long expected) {
|
||||
if (checkError(call)) {
|
||||
return true;
|
||||
}
|
||||
if (result!=expected) {
|
||||
if (result != expected) {
|
||||
logError(lf_network, "HTTP %s: invalid result %d", call, result);
|
||||
return true;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ ssize_t SSLSocket::send(const char* data, size_t len) {
|
||||
do {
|
||||
size_t part = 0;
|
||||
int res = BIO_write_ex(m_bio, data, len, &part);
|
||||
if (res==1) {
|
||||
if (res == 1) {
|
||||
return static_cast<signed>(part);
|
||||
}
|
||||
if (!BIO_should_retry(m_bio)) {
|
||||
@@ -88,15 +88,15 @@ ssize_t SSLSocket::send(const char* data, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
usleep(SLEEP_NANOS);
|
||||
} while (time(nullptr)<m_until);
|
||||
return -1; // timeout
|
||||
} while (time(nullptr) < m_until);
|
||||
return -1; // timeout
|
||||
}
|
||||
|
||||
ssize_t SSLSocket::recv(char* data, size_t len) {
|
||||
do {
|
||||
size_t part = 0;
|
||||
int res = BIO_read_ex(m_bio, data, len, &part);
|
||||
if (res==1) {
|
||||
if (res == 1) {
|
||||
return static_cast<signed>(part);
|
||||
}
|
||||
if (!BIO_should_retry(m_bio)) {
|
||||
@@ -106,12 +106,12 @@ ssize_t SSLSocket::recv(char* data, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
usleep(SLEEP_NANOS);
|
||||
} while (time(nullptr)<m_until);
|
||||
return -1; // timeout
|
||||
} while (time(nullptr) < m_until);
|
||||
return -1; // timeout
|
||||
}
|
||||
|
||||
bool SSLSocket::isValid() {
|
||||
return time(nullptr)<m_until && !BIO_eof(m_bio);
|
||||
return time(nullptr) < m_until && !BIO_eof(m_bio);
|
||||
}
|
||||
|
||||
// general switch for future insecure option
|
||||
@@ -123,14 +123,14 @@ SSLSocket* SSLSocket::connect(const string& host, const uint16_t& port, bool htt
|
||||
ostringstream ostr;
|
||||
ostr << host << ':' << static_cast<unsigned>(port);
|
||||
const string hostPort = ostr.str();
|
||||
time_t until = time(nullptr) + (timeout<=2 ? 2 : timeout); // at least 2 seconds
|
||||
time_t until = time(nullptr) + (timeout <= 2 ? 2 : timeout); // at least 2 seconds
|
||||
if (!https) {
|
||||
do {
|
||||
bio = BIO_new_connect(hostPort.c_str());
|
||||
if (isError("connect", bio)) {
|
||||
break;
|
||||
}
|
||||
BIO_set_nbio(bio, 1); // set non-blocking
|
||||
BIO_set_nbio(bio, 1); // set non-blocking
|
||||
return new SSLSocket(nullptr, bio, until);
|
||||
} while (false);
|
||||
} else {
|
||||
@@ -157,7 +157,7 @@ SSLSocket* SSLSocket::connect(const string& host, const uint16_t& port, bool htt
|
||||
if (isError("conn_hostname", BIO_set_conn_hostname(bio, hostPort.c_str()), 1)) {
|
||||
break;
|
||||
}
|
||||
BIO_set_nbio(bio, 1); // set non-blocking
|
||||
BIO_set_nbio(bio, 1); // set non-blocking
|
||||
BIO_get_ssl(bio, &ssl);
|
||||
if (isError("get_ssl", ssl)) {
|
||||
break;
|
||||
@@ -217,13 +217,13 @@ void HttpClient::initialize() {
|
||||
s_initialized = true;
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
signal(SIGPIPE, SIG_IGN); // needed to avoid SIGPIPE when writing to a closed pipe
|
||||
signal(SIGPIPE, SIG_IGN); // needed to avoid SIGPIPE when writing to a closed pipe
|
||||
}
|
||||
#else // HAVE_SSL
|
||||
#else // HAVE_SSL
|
||||
void HttpClient::initialize() {
|
||||
// empty
|
||||
}
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_SSL
|
||||
|
||||
bool HttpClient::parseUrl(const string& url, string* proto, string* host, uint16_t* port, string* uri) {
|
||||
size_t hostPos = url.find("://");
|
||||
@@ -273,7 +273,8 @@ bool HttpClient::parseUrl(const string& url, string* proto, string* host, uint16
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpClient::connect(const string& host, const uint16_t port, const bool https, const string& userAgent, const int timeout) {
|
||||
bool HttpClient::connect(const string& host, const uint16_t port, bool https, const string& userAgent,
|
||||
const int timeout) {
|
||||
disconnect();
|
||||
#ifdef HAVE_SSL
|
||||
m_socket = SSLSocket::connect(host, port, https, timeout);
|
||||
@@ -445,7 +446,7 @@ bool HttpClient::request(const string& method, const string& uri, const string&
|
||||
|
||||
size_t HttpClient::readUntil(const string& delim, const size_t length, string* result) {
|
||||
if (!m_buffer) {
|
||||
m_buffer = reinterpret_cast<char*>(malloc(1024+1)); // 1 extra for final terminator
|
||||
m_buffer = reinterpret_cast<char*>(malloc(1024+1)); // 1 extra for final terminator
|
||||
if (!m_buffer) {
|
||||
return string::npos;
|
||||
}
|
||||
|
||||
@@ -106,11 +106,11 @@ class SSLSocket {
|
||||
|
||||
#define SocketClass SSLSocket
|
||||
|
||||
#else // HAVE_SSL
|
||||
#else // HAVE_SSL
|
||||
|
||||
#define SocketClass TCPSocket
|
||||
|
||||
#endif // HAVE_SSL
|
||||
#endif // HAVE_SSL
|
||||
|
||||
/**
|
||||
* Helper class for handling HTTP client requests.
|
||||
@@ -160,7 +160,7 @@ class HttpClient {
|
||||
* @param userAgent the optional user agent to send in the request header.
|
||||
* @return true on success, false on connect failure.
|
||||
*/
|
||||
bool connect(const string& host, uint16_t port, const bool https = false, const string& userAgent = "", int timeout = 5);
|
||||
bool connect(const string& host, uint16_t port, bool https = false, const string& userAgent = "", int timeout = 5);
|
||||
|
||||
/**
|
||||
* Re-connect to the last specified server.
|
||||
|
||||
Reference in New Issue
Block a user