parse all by default, check topic for match-ability
This commit is contained in:
@@ -197,7 +197,7 @@ static error_t mqtt_parse_opt(int key, char *arg, struct argp_state *state) {
|
||||
return EINVAL;
|
||||
} else {
|
||||
MqttReplacer replacer;
|
||||
if (!replacer.parse(arg)) {
|
||||
if (!replacer.parse(arg, true)) {
|
||||
argp_error(state, "malformed mqtttopic");
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -624,6 +624,18 @@ bool MqttReplacer::reduce(const map<string, string>& values, string& result, boo
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MqttReplacer::checkMatch() const {
|
||||
bool lastField = false;
|
||||
for (const auto& part : m_parts) {
|
||||
bool field = part.second >= 0;
|
||||
if (field && lastField) {
|
||||
return false;
|
||||
}
|
||||
lastField = field;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t MqttReplacer::matchTopic(const string& topic, string* circuit, string* name, string* field) const {
|
||||
size_t last = 0;
|
||||
size_t count = m_parts.size();
|
||||
@@ -967,18 +979,23 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
||||
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) {
|
||||
// cmdline topic is more than just a prefix => override integration topic completely
|
||||
topic.parse(str);
|
||||
} else {
|
||||
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
|
||||
}
|
||||
if (parse) {
|
||||
if (!topic.parse(str, true, true)) {
|
||||
logOtherNotice("mqtt", "unknown or duplicate topic parts potentially prevent matching incoming topics");
|
||||
topic.parse(str, true);
|
||||
} else if (!topic.checkMatch()) {
|
||||
logOtherNotice("mqtt", "missing separators between topic parts potentially prevent matching incoming topics");
|
||||
}
|
||||
} else {
|
||||
topic.parse(str);
|
||||
}
|
||||
if (!noDefault) {
|
||||
topic.ensureDefault();
|
||||
@@ -1038,9 +1055,9 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
||||
m_subscribeConfigRestartTopic = m_replacers.get("config_restart-topic", false, false);
|
||||
m_subscribeConfigRestartPayload = m_replacers.get("config_restart-payload", false, false);
|
||||
if (g_globalTopic) {
|
||||
m_globalTopic.parse(g_globalTopic, true);
|
||||
m_globalTopic.parse(g_globalTopic);
|
||||
} else {
|
||||
m_globalTopic.parse(getTopic(nullptr, "%circuit/%name"), true);
|
||||
m_globalTopic.parse(getTopic(nullptr, "%circuit/%name"));
|
||||
}
|
||||
if (m_globalTopic.has("circuit")) {
|
||||
map<string, string> values;
|
||||
|
||||
@@ -82,7 +82,7 @@ class MqttReplacer {
|
||||
* is empty or not defined.
|
||||
* @return true on success, false on malformed template string.
|
||||
*/
|
||||
bool parse(const string& templateStr, bool onlyKnown = true, bool noKnownDuplicates = true, bool emptyIfMissing = false);
|
||||
bool parse(const string& templateStr, bool onlyKnown = false, bool noKnownDuplicates = false, bool emptyIfMissing = false);
|
||||
|
||||
/**
|
||||
* Ensure the default topic parts are present (circuit and message).
|
||||
@@ -150,6 +150,12 @@ class MqttReplacer {
|
||||
*/
|
||||
bool reduce(const map<string, string>& values, string& result, bool onlyAlphanum = false) const;
|
||||
|
||||
/**
|
||||
* Check match-ability against topics.
|
||||
* @return true on success, false on bad match-ability.
|
||||
*/
|
||||
bool checkMatch() const;
|
||||
|
||||
/**
|
||||
* Match a topic string against the constant and variables parts.
|
||||
* @param topic the topic string to match.
|
||||
|
||||
Reference in New Issue
Block a user