kopia lustrzana https://github.com/weetmuts/wmbusmeters
New source file address.cc for mbus addressing.
rodzic
c21efd1d69
commit
9d27ab3fb3
1
Makefile
1
Makefile
|
@ -153,6 +153,7 @@ $(BUILD)/%.o: src/%.c $(wildcard src/%.h)
|
|||
$(CXX) -I/usr/include/libxml2 -fpermissive $(CXXFLAGS) $< -MMD -c -o $@
|
||||
|
||||
PROG_OBJS:=\
|
||||
$(BUILD)/address.o \
|
||||
$(BUILD)/aes.o \
|
||||
$(BUILD)/aescmac.o \
|
||||
$(BUILD)/bus.o \
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
Copyright (C) 2017-2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include"address.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool isValidMatchExpression(const string& s, bool non_compliant)
|
||||
{
|
||||
string me = s;
|
||||
|
||||
// Examples of valid match expressions:
|
||||
// 12345678
|
||||
// *
|
||||
// 123*
|
||||
// !12345677
|
||||
// 2222222*
|
||||
// !22222222
|
||||
|
||||
// A match expression cannot be empty.
|
||||
if (me.length() == 0) return false;
|
||||
|
||||
// An me can be negated with an exclamation mark first.
|
||||
if (me.front() == '!') me.erase(0, 1);
|
||||
|
||||
// A match expression cannot be only a negation mark.
|
||||
if (me.length() == 0) return false;
|
||||
|
||||
int count = 0;
|
||||
if (non_compliant)
|
||||
{
|
||||
// Some non-compliant meters have full hex in the id,
|
||||
// but according to the standard there should only be bcd here...
|
||||
while (me.length() > 0 &&
|
||||
((me.front() >= '0' && me.front() <= '9') ||
|
||||
(me.front() >= 'a' && me.front() <= 'f')))
|
||||
{
|
||||
me.erase(0,1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// But compliant meters use only a bcd subset.
|
||||
while (me.length() > 0 &&
|
||||
(me.front() >= '0' && me.front() <= '9'))
|
||||
{
|
||||
me.erase(0,1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
bool wildcard_used = false;
|
||||
// An expression can end with a *
|
||||
if (me.length() > 0 && me.front() == '*')
|
||||
{
|
||||
me.erase(0,1);
|
||||
wildcard_used = true;
|
||||
}
|
||||
|
||||
// Now we should have eaten the whole expression.
|
||||
if (me.length() > 0) return false;
|
||||
|
||||
// Check the length of the matching bcd/hex
|
||||
// If no wildcard is used, then the match expression must be exactly 8 digits.
|
||||
if (!wildcard_used) return count == 8;
|
||||
|
||||
// If wildcard is used, then the match expressions must be 7 or less digits,
|
||||
// even zero is allowed which means a single *, which matches any bcd/hex id.
|
||||
return count <= 7;
|
||||
}
|
||||
|
||||
bool isValidMatchExpressions(const string& mes, bool non_compliant)
|
||||
{
|
||||
vector<string> v = splitMatchExpressions(mes);
|
||||
|
||||
for (string me : v)
|
||||
{
|
||||
if (!isValidMatchExpression(me, non_compliant)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidId(const string& id, bool accept_non_compliant)
|
||||
{
|
||||
|
||||
for (size_t i=0; i<id.length(); ++i)
|
||||
{
|
||||
if (id[i] >= '0' && id[i] <= '9') continue;
|
||||
if (accept_non_compliant)
|
||||
{
|
||||
if (id[i] >= 'a' && id[i] <= 'f') continue;
|
||||
if (id[i] >= 'A' && id[i] <= 'F') continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool doesIdMatchExpression(const string& s, string match)
|
||||
{
|
||||
string id = s;
|
||||
if (id.length() == 0) return false;
|
||||
|
||||
// Here we assume that the match expression has been
|
||||
// verified to be valid.
|
||||
bool can_match = true;
|
||||
|
||||
// Now match bcd/hex until end of id, or '*' in match.
|
||||
while (id.length() > 0 && match.length() > 0 && match.front() != '*')
|
||||
{
|
||||
if (id.front() != match.front())
|
||||
{
|
||||
// We hit a difference, it cannot match.
|
||||
can_match = false;
|
||||
break;
|
||||
}
|
||||
id.erase(0,1);
|
||||
match.erase(0,1);
|
||||
}
|
||||
|
||||
bool wildcard_used = false;
|
||||
if (match.length() && match.front() == '*')
|
||||
{
|
||||
wildcard_used = true;
|
||||
match.erase(0,1);
|
||||
}
|
||||
|
||||
if (can_match)
|
||||
{
|
||||
// Ok, now the match expression should be empty.
|
||||
// If wildcard is true, then the id can still have digits,
|
||||
// otherwise it must also be empty.
|
||||
if (wildcard_used)
|
||||
{
|
||||
can_match = match.length() == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
can_match = match.length() == 0 && id.length() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
return can_match;
|
||||
}
|
||||
|
||||
bool hasWildCard(const string& mes)
|
||||
{
|
||||
return mes.find('*') != string::npos;
|
||||
}
|
||||
|
||||
bool doesIdsMatchExpressions(vector<string> &ids, vector<string>& mes, bool *used_wildcard)
|
||||
{
|
||||
bool match = false;
|
||||
for (string &id : ids)
|
||||
{
|
||||
if (doesIdMatchExpressions(id, mes, used_wildcard))
|
||||
{
|
||||
match = true;
|
||||
}
|
||||
// Go through all ids even though there is an early match.
|
||||
// This way we can see if theres an exact match later.
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
bool doesIdMatchExpressions(const string& id, vector<string>& mes, bool *used_wildcard)
|
||||
{
|
||||
bool found_match = false;
|
||||
bool found_negative_match = false;
|
||||
bool exact_match = false;
|
||||
*used_wildcard = false;
|
||||
|
||||
// Goes through all possible match expressions.
|
||||
// If no expression matches, neither positive nor negative,
|
||||
// then the result is false. (ie no match)
|
||||
|
||||
// If more than one positive match is found, and no negative,
|
||||
// then the result is true.
|
||||
|
||||
// If more than one negative match is found, irrespective
|
||||
// if there is any positive matches or not, then the result is false.
|
||||
|
||||
// If a positive match is found, using a wildcard not any exact match,
|
||||
// then *used_wildcard is set to true.
|
||||
|
||||
for (string me : mes)
|
||||
{
|
||||
bool has_wildcard = hasWildCard(me);
|
||||
bool is_negative_rule = (me.length() > 0 && me.front() == '!');
|
||||
if (is_negative_rule)
|
||||
{
|
||||
me.erase(0, 1);
|
||||
}
|
||||
|
||||
bool m = doesIdMatchExpression(id, me);
|
||||
|
||||
if (is_negative_rule)
|
||||
{
|
||||
if (m) found_negative_match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m)
|
||||
{
|
||||
found_match = true;
|
||||
if (!has_wildcard)
|
||||
{
|
||||
exact_match = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_negative_match)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (found_match)
|
||||
{
|
||||
if (exact_match)
|
||||
{
|
||||
*used_wildcard = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*used_wildcard = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string toIdsCommaSeparated(vector<string> &ids)
|
||||
{
|
||||
string cs;
|
||||
for (string& s: ids)
|
||||
{
|
||||
cs += s;
|
||||
cs += ",";
|
||||
}
|
||||
if (cs.length() > 0) cs.pop_back();
|
||||
return cs;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright (C) 2017-2022 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ADDRESS_H_
|
||||
#define ADDRESS_H_
|
||||
|
||||
#include "util.h"
|
||||
#include <string>
|
||||
|
||||
struct Address
|
||||
{
|
||||
// Example address: 12345678
|
||||
// Or fully qualified: 12345678.M=PII.T=1b.V=01
|
||||
// which means manufacturer triplet PII, type/media=0x1b, version=0x01
|
||||
std::string id;
|
||||
bool wildcard_used {}; // The id contains a *
|
||||
bool mbus_primary {}; // Signals that the id is 0-250
|
||||
uint16_t mfct {}; // If 0xffff then any mfct matches this address.
|
||||
uchar type {}; // If 0xff then any type matches this address.
|
||||
uchar version {}; // If 0xff then any version matches this address.
|
||||
bool negate {}; // When used for testing this address was negated. !12345678
|
||||
|
||||
bool parse(std::string &s);
|
||||
bool match(Address *a);
|
||||
};
|
||||
|
||||
bool isValidMatchExpression(const std::string& s, bool non_compliant);
|
||||
bool isValidMatchExpressions(const std::string& s, bool non_compliant);
|
||||
bool doesIdMatchExpression(const std::string& id, std::string match_rule);
|
||||
bool doesIdMatchExpressions(const std::string& id, std::vector<std::string>& match_rules, bool *used_wildcard);
|
||||
bool doesIdsMatchExpressions(std::vector<std::string> &ids, std::vector<std::string>& match_rules, bool *used_wildcard);
|
||||
std::string toIdsCommaSeparated(std::vector<std::string> &ids);
|
||||
|
||||
bool isValidId(const std::string& id, bool accept_non_compliant);
|
||||
|
||||
std::vector<std::string> splitMatchExpressions(const std::string& mes);
|
||||
|
||||
#endif
|
|
@ -2593,17 +2593,19 @@ bool Address::parse(string &s)
|
|||
// Example: 12345678
|
||||
// or 12345678.M=PII.T=1B.V=01
|
||||
// or 1234*
|
||||
// or 1234*.PII
|
||||
// or 1234*.V01
|
||||
// or 1234*.M=PII
|
||||
// or 1234*.V=01
|
||||
// or 12 // mbus primary
|
||||
// or 0 // mbus primary
|
||||
// or 250.MPII.T1B.V01 // mbus primary
|
||||
|
||||
// or 250.MPII.V01.T1B // mbus primary
|
||||
// or !12345678
|
||||
// or !*.M=ABC
|
||||
id = "";
|
||||
mbus_primary = false;
|
||||
mfct = 0;
|
||||
type = 0;
|
||||
version = 0;
|
||||
mfct = 0xffff;
|
||||
type = 0xff;
|
||||
version = 0xff;
|
||||
negate = false;
|
||||
|
||||
if (s.size() == 0) return false;
|
||||
|
||||
|
@ -2626,7 +2628,7 @@ bool Address::parse(string &s)
|
|||
}
|
||||
id = parts[0];
|
||||
|
||||
for (size_t i=1; i<parts[i].size(); ++i)
|
||||
for (size_t i=1; i<parts.size(); ++i)
|
||||
{
|
||||
if (parts[i].size() == 4) // V=xy or T=xy
|
||||
{
|
||||
|
|
17
src/meters.h
17
src/meters.h
|
@ -18,6 +18,7 @@
|
|||
#ifndef METER_H_
|
||||
#define METER_H_
|
||||
|
||||
#include"address.h"
|
||||
#include"dvparser.h"
|
||||
#include"formula.h"
|
||||
#include"util.h"
|
||||
|
@ -80,22 +81,6 @@ bool isValidKey(const string& key, MeterInfo &mt);
|
|||
|
||||
using namespace std;
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
struct Address
|
||||
{
|
||||
// Example address: 12345678
|
||||
// Or fully qualified: 12345678.M=PII.T=1b.V=01
|
||||
// which means manufacturer triplet PII, type/media=0x1b, version=0x01
|
||||
string id;
|
||||
bool wildcard_used {}; // The id contains a *
|
||||
bool mbus_primary {}; // Signals that the id is 0-250
|
||||
uint16_t mfct {};
|
||||
uchar type {};
|
||||
uchar version {};
|
||||
|
||||
bool parse(string &s);
|
||||
};
|
||||
|
||||
struct MeterInfo
|
||||
{
|
||||
|
|
|
@ -37,7 +37,8 @@ using namespace std;
|
|||
bool verbose_ = false;
|
||||
|
||||
#define LIST_OF_TESTS \
|
||||
X(dynamic_loading)\
|
||||
X(addresses) \
|
||||
X(dynamic_loading) \
|
||||
X(crc) \
|
||||
X(dvparser) \
|
||||
X(devices) \
|
||||
|
@ -75,6 +76,7 @@ bool verbose_ = false;
|
|||
X(formulas_dventries) \
|
||||
X(formulas_stringinterpolation) \
|
||||
|
||||
|
||||
#define X(t) void test_##t();
|
||||
LIST_OF_TESTS
|
||||
#undef X
|
||||
|
@ -495,7 +497,9 @@ void test_ids()
|
|||
test_does_id_match_expression("78563413", "*,!00156327,!00048713", true, true);
|
||||
}
|
||||
|
||||
void tst_address(string s, bool valid, string id, string mfct, uchar type, uchar version)
|
||||
void tst_address(string s, bool valid, string id,
|
||||
string mfct, uchar version, uchar type,
|
||||
bool mbus_primary, bool wildcard_used)
|
||||
{
|
||||
Address a;
|
||||
bool ok = a.parse(s);
|
||||
|
@ -511,38 +515,46 @@ void tst_address(string s, bool valid, string id, string mfct, uchar type, uchar
|
|||
string smfct = manufacturerFlag(a.mfct);
|
||||
if (id != a.id ||
|
||||
mfct != smfct ||
|
||||
version != a.version ||
|
||||
type != a.type ||
|
||||
version != a.version)
|
||||
wildcard_used != a.wildcard_used ||
|
||||
mbus_primary != a.mbus_primary ||
|
||||
wildcard_used != a.wildcard_used)
|
||||
{
|
||||
printf("Expected parse of address \"%s\" to return (id=%s mfct=%s type=%02x version=%02x) "
|
||||
"but got (id=%s mfct=%s type=%02x version=%02x)\n",
|
||||
printf("Expected parse of address \"%s\" to return (id=%s mfct=%s version=%02x type=%02x mp=%d wu=%d)\n"
|
||||
"but got (id=%s mfct=%s version=%02x type=%02x mp=%d wu=%d)\n",
|
||||
s.c_str(),
|
||||
id.c_str(), mfct.c_str(), type, version,
|
||||
a.id.c_str(), smfct.c_str(), a.type, a.version);
|
||||
id.c_str(), mfct.c_str(), version, type, mbus_primary, wildcard_used,
|
||||
a.id.c_str(), smfct.c_str(), a.version, a.type, a.mbus_primary, a.wildcard_used);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_addresses()
|
||||
{
|
||||
/*
|
||||
tst_address("12345678",
|
||||
true,
|
||||
"12345678", // id
|
||||
"@@@", // mfct
|
||||
0, // type
|
||||
0 // version
|
||||
"___", // mfct
|
||||
0xff, // type
|
||||
0xff, // version
|
||||
false, // mbus primary
|
||||
false // wildcard used
|
||||
);
|
||||
tst_address("123k45678", false, "", "", 0xff, 0xff, false, false);
|
||||
tst_address("1234", false, "", "", 0xff, 0xff, false, false);
|
||||
tst_address("0", true, "0", "___", 0xff, 0xff, true,false);
|
||||
tst_address("250", true, "250", "___", 0xff, 0xff, true, false);
|
||||
tst_address("251", false, "", "", 0xff, 0xff, false, false);
|
||||
tst_address("0.M=PII.V=01.T=1b", true, "0", "PII", 0x01, 0x1b, true, false);
|
||||
tst_address("123.V=11.M=FOO.T=ff", true, "123", "FOO", 0x11, 0xff, true, false);
|
||||
tst_address("123.M=FOO", true, "123", "FOO", 0xff, 0xff, true, false);
|
||||
tst_address("123.M=FOO.V=33", true, "123", "FOO", 0x33, 0xff, true, false);
|
||||
tst_address("123.T=33", true, "123", "___", 0xff, 0x33, true, false);
|
||||
tst_address("1.V=33", true, "1", "___", 0x33, 0xff, true, false);
|
||||
tst_address("16.M=BAR", true, "16", "BAR", 0xff, 0xff, true, false);
|
||||
|
||||
tst_address("123k45678", false, "", "", 0, 0);
|
||||
tst_address("1234", false, "", "", 0, 0);
|
||||
tst_address("0", true, "0", "@@@", 0, 0);
|
||||
tst_address("250", true, "250", "@@@", 0, 0);
|
||||
tst_address("251", false, "", "", 0, 0);
|
||||
tst_address("0.M=PII.T=1b.V=01", true, "0", "PII", 0x1b, 0x01);
|
||||
tst_address("123.V=11.M=FOO.T=ff", true, "123", "FOO", 0xff, 0x11);
|
||||
tst_address("16.M=BAR", true, "16", "BAR", 0, 0);
|
||||
*/
|
||||
// tst_address("12*", true, "12*", "___", 0xff, 0xff, false, true);
|
||||
}
|
||||
|
||||
void eq(string a, string b, const char *tn)
|
||||
|
|
238
src/util.cc
238
src/util.cc
|
@ -654,244 +654,6 @@ bool isValidAlias(const string& alias)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool isValidMatchExpression(const string& s, bool non_compliant)
|
||||
{
|
||||
string me = s;
|
||||
|
||||
// Examples of valid match expressions:
|
||||
// 12345678
|
||||
// *
|
||||
// 123*
|
||||
// !12345677
|
||||
// 2222222*
|
||||
// !22222222
|
||||
|
||||
// A match expression cannot be empty.
|
||||
if (me.length() == 0) return false;
|
||||
|
||||
// An me can be negated with an exclamation mark first.
|
||||
if (me.front() == '!') me.erase(0, 1);
|
||||
|
||||
// A match expression cannot be only a negation mark.
|
||||
if (me.length() == 0) return false;
|
||||
|
||||
int count = 0;
|
||||
if (non_compliant)
|
||||
{
|
||||
// Some non-compliant meters have full hex in the id,
|
||||
// but according to the standard there should only be bcd here...
|
||||
while (me.length() > 0 &&
|
||||
((me.front() >= '0' && me.front() <= '9') ||
|
||||
(me.front() >= 'a' && me.front() <= 'f')))
|
||||
{
|
||||
me.erase(0,1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// But compliant meters use only a bcd subset.
|
||||
while (me.length() > 0 &&
|
||||
(me.front() >= '0' && me.front() <= '9'))
|
||||
{
|
||||
me.erase(0,1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
bool wildcard_used = false;
|
||||
// An expression can end with a *
|
||||
if (me.length() > 0 && me.front() == '*')
|
||||
{
|
||||
me.erase(0,1);
|
||||
wildcard_used = true;
|
||||
}
|
||||
|
||||
// Now we should have eaten the whole expression.
|
||||
if (me.length() > 0) return false;
|
||||
|
||||
// Check the length of the matching bcd/hex
|
||||
// If no wildcard is used, then the match expression must be exactly 8 digits.
|
||||
if (!wildcard_used) return count == 8;
|
||||
|
||||
// If wildcard is used, then the match expressions must be 7 or less digits,
|
||||
// even zero is allowed which means a single *, which matches any bcd/hex id.
|
||||
return count <= 7;
|
||||
}
|
||||
|
||||
bool isValidMatchExpressions(const string& mes, bool non_compliant)
|
||||
{
|
||||
vector<string> v = splitMatchExpressions(mes);
|
||||
|
||||
for (string me : v)
|
||||
{
|
||||
if (!isValidMatchExpression(me, non_compliant)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidId(const string& id, bool accept_non_compliant)
|
||||
{
|
||||
|
||||
for (size_t i=0; i<id.length(); ++i)
|
||||
{
|
||||
if (id[i] >= '0' && id[i] <= '9') continue;
|
||||
if (accept_non_compliant)
|
||||
{
|
||||
if (id[i] >= 'a' && id[i] <= 'f') continue;
|
||||
if (id[i] >= 'A' && id[i] <= 'F') continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool doesIdMatchExpression(const string& s, string match)
|
||||
{
|
||||
string id = s;
|
||||
if (id.length() == 0) return false;
|
||||
|
||||
// Here we assume that the match expression has been
|
||||
// verified to be valid.
|
||||
bool can_match = true;
|
||||
|
||||
// Now match bcd/hex until end of id, or '*' in match.
|
||||
while (id.length() > 0 && match.length() > 0 && match.front() != '*')
|
||||
{
|
||||
if (id.front() != match.front())
|
||||
{
|
||||
// We hit a difference, it cannot match.
|
||||
can_match = false;
|
||||
break;
|
||||
}
|
||||
id.erase(0,1);
|
||||
match.erase(0,1);
|
||||
}
|
||||
|
||||
bool wildcard_used = false;
|
||||
if (match.length() && match.front() == '*')
|
||||
{
|
||||
wildcard_used = true;
|
||||
match.erase(0,1);
|
||||
}
|
||||
|
||||
if (can_match)
|
||||
{
|
||||
// Ok, now the match expression should be empty.
|
||||
// If wildcard is true, then the id can still have digits,
|
||||
// otherwise it must also be empty.
|
||||
if (wildcard_used)
|
||||
{
|
||||
can_match = match.length() == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
can_match = match.length() == 0 && id.length() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
return can_match;
|
||||
}
|
||||
|
||||
bool hasWildCard(const string& mes)
|
||||
{
|
||||
return mes.find('*') != string::npos;
|
||||
}
|
||||
|
||||
bool doesIdsMatchExpressions(vector<string> &ids, vector<string>& mes, bool *used_wildcard)
|
||||
{
|
||||
bool match = false;
|
||||
for (string &id : ids)
|
||||
{
|
||||
if (doesIdMatchExpressions(id, mes, used_wildcard))
|
||||
{
|
||||
match = true;
|
||||
}
|
||||
// Go through all ids even though there is an early match.
|
||||
// This way we can see if theres an exact match later.
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
bool doesIdMatchExpressions(const string& id, vector<string>& mes, bool *used_wildcard)
|
||||
{
|
||||
bool found_match = false;
|
||||
bool found_negative_match = false;
|
||||
bool exact_match = false;
|
||||
*used_wildcard = false;
|
||||
|
||||
// Goes through all possible match expressions.
|
||||
// If no expression matches, neither positive nor negative,
|
||||
// then the result is false. (ie no match)
|
||||
|
||||
// If more than one positive match is found, and no negative,
|
||||
// then the result is true.
|
||||
|
||||
// If more than one negative match is found, irrespective
|
||||
// if there is any positive matches or not, then the result is false.
|
||||
|
||||
// If a positive match is found, using a wildcard not any exact match,
|
||||
// then *used_wildcard is set to true.
|
||||
|
||||
for (string me : mes)
|
||||
{
|
||||
bool has_wildcard = hasWildCard(me);
|
||||
bool is_negative_rule = (me.length() > 0 && me.front() == '!');
|
||||
if (is_negative_rule)
|
||||
{
|
||||
me.erase(0, 1);
|
||||
}
|
||||
|
||||
bool m = doesIdMatchExpression(id, me);
|
||||
|
||||
if (is_negative_rule)
|
||||
{
|
||||
if (m) found_negative_match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m)
|
||||
{
|
||||
found_match = true;
|
||||
if (!has_wildcard)
|
||||
{
|
||||
exact_match = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_negative_match)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (found_match)
|
||||
{
|
||||
if (exact_match)
|
||||
{
|
||||
*used_wildcard = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*used_wildcard = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string toIdsCommaSeparated(vector<string> &ids)
|
||||
{
|
||||
string cs;
|
||||
for (string& s: ids)
|
||||
{
|
||||
cs += s;
|
||||
cs += ",";
|
||||
}
|
||||
if (cs.length() > 0) cs.pop_back();
|
||||
return cs;
|
||||
}
|
||||
|
||||
bool isFrequency(const string& fq)
|
||||
{
|
||||
int len = fq.length();
|
||||
|
|
|
@ -155,19 +155,10 @@ void setAlarmShells(std::vector<std::string> &alarm_shells);
|
|||
|
||||
bool isValidAlias(const std::string& alias);
|
||||
bool isValidBps(const std::string& b);
|
||||
bool isValidMatchExpression(const std::string& s, bool non_compliant);
|
||||
bool isValidMatchExpressions(const std::string& s, bool non_compliant);
|
||||
bool doesIdMatchExpression(const std::string& id, std::string match_rule);
|
||||
bool doesIdMatchExpressions(const std::string& id, std::vector<std::string>& match_rules, bool *used_wildcard);
|
||||
bool doesIdsMatchExpressions(std::vector<std::string> &ids, std::vector<std::string>& match_rules, bool *used_wildcard);
|
||||
std::string toIdsCommaSeparated(std::vector<std::string> &ids);
|
||||
|
||||
bool isValidId(const std::string& id, bool accept_non_compliant);
|
||||
|
||||
bool isFrequency(const std::string& fq);
|
||||
bool isNumber(const std::string& fq);
|
||||
|
||||
std::vector<std::string> splitMatchExpressions(const std::string& mes);
|
||||
// Split s into strings separated by c.
|
||||
std::vector<std::string> splitString(const std::string &s, char c);
|
||||
// Split s into strings separated by c and store inte set.
|
||||
|
|
|
@ -231,6 +231,7 @@ LIST_OF_MANUFACTURERS
|
|||
|
||||
void Telegram::addId(const vector<uchar>::iterator &pos)
|
||||
{
|
||||
// string id = tostrprintf("%02x%02x%02x%02x_%02x_%02x", *(pos+3), *(pos+2), *(pos+1), *(pos+0), *(pos+4), *(pos+5));
|
||||
string id = tostrprintf("%02x%02x%02x%02x", *(pos+3), *(pos+2), *(pos+1), *(pos+0));
|
||||
ids.push_back(id);
|
||||
if (idsc.empty()) {
|
||||
|
|
Ładowanie…
Reference in New Issue