kopia lustrzana https://github.com/weetmuts/wmbusmeters
Add filter_out to address expression.
rodzic
0c98b474bb
commit
78e7c47503
1
Makefile
1
Makefile
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# Copyright (C) 2017-2023 Fredrik Öhrström (gpl-3.0-or-later)
|
# Copyright (C) 2017-2023 Fredrik Öhrström (gpl-3.0-or-later)
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
|
187
src/address.cc
187
src/address.cc
|
@ -16,10 +16,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include"address.h"
|
#include"address.h"
|
||||||
|
#include"manufacturers.h"
|
||||||
|
|
||||||
|
#include<assert.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
bool isValidMatchExpression(const string& s)
|
bool isValidMatchExpression(const string& s, bool *has_wildcard)
|
||||||
{
|
{
|
||||||
string me = s;
|
string me = s;
|
||||||
|
|
||||||
|
@ -58,6 +61,7 @@ bool isValidMatchExpression(const string& s)
|
||||||
{
|
{
|
||||||
me.erase(0,1);
|
me.erase(0,1);
|
||||||
wildcard_used = true;
|
wildcard_used = true;
|
||||||
|
if (has_wildcard) *has_wildcard = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we should have eaten the whole expression.
|
// Now we should have eaten the whole expression.
|
||||||
|
@ -78,7 +82,7 @@ bool isValidMatchExpressions(const string& mes)
|
||||||
|
|
||||||
for (string me : v)
|
for (string me : v)
|
||||||
{
|
{
|
||||||
if (!isValidMatchExpression(me)) return false;
|
if (!isValidMatchExpression(me, NULL)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -231,6 +235,74 @@ bool doesIdMatchExpressions(const string& id, vector<string>& mes, bool *used_wi
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool doesIdMatchAddressExpressions(const string& id, vector<AddressExpression>& aes, 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 (AddressExpression &ae : aes)
|
||||||
|
{
|
||||||
|
bool has_wildcard = ae.has_wildcard;
|
||||||
|
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 toIdsCommaSeparated(vector<string> &ids)
|
||||||
{
|
{
|
||||||
string cs;
|
string cs;
|
||||||
|
@ -242,3 +314,114 @@ string toIdsCommaSeparated(vector<string> &ids)
|
||||||
if (cs.length() > 0) cs.pop_back();
|
if (cs.length() > 0) cs.pop_back();
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AddressExpression::match(const std::string &i, uint16_t m, uchar v, uchar t)
|
||||||
|
{
|
||||||
|
if (!(mfct == 0xffff || mfct == m)) return false;
|
||||||
|
if (!(version == 0xff || version == v)) return false;
|
||||||
|
if (!(type == 0xff || type == t)) return false;
|
||||||
|
if (!doesIdMatchExpression(i, id)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddressExpression::parse(const string &in)
|
||||||
|
{
|
||||||
|
string s = in;
|
||||||
|
// Example: 12345678
|
||||||
|
// or 12345678.M=PII.T=1B.V=01
|
||||||
|
// or 1234*
|
||||||
|
// or 1234*.M=PII
|
||||||
|
// or 1234*.V=01
|
||||||
|
// or 12 // mbus primary
|
||||||
|
// or 0 // mbus primary
|
||||||
|
// or 250.MPII.V01.T1B // mbus primary
|
||||||
|
// or !12345678
|
||||||
|
// or !*.M=ABC
|
||||||
|
id = "";
|
||||||
|
mbus_primary = false;
|
||||||
|
mfct = 0xffff;
|
||||||
|
type = 0xff;
|
||||||
|
version = 0xff;
|
||||||
|
filter_out = false;
|
||||||
|
|
||||||
|
if (s.size() == 0) return false;
|
||||||
|
|
||||||
|
if (s.size() > 1 && s[0] == '!')
|
||||||
|
{
|
||||||
|
filter_out = true;
|
||||||
|
s = s.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> parts = splitString(s, '.');
|
||||||
|
|
||||||
|
assert(parts.size() > 0);
|
||||||
|
|
||||||
|
id = parts[0];
|
||||||
|
if (!isValidMatchExpression(id, &has_wildcard))
|
||||||
|
{
|
||||||
|
// Not a long id, so lets check if it is p0 to p250 for primary mbus ids.
|
||||||
|
if (id.size() < 2) return false;
|
||||||
|
if (id[0] != 'p') return false;
|
||||||
|
for (size_t i=1; i < id.length(); ++i)
|
||||||
|
{
|
||||||
|
if (!isdigit(id[i])) return false;
|
||||||
|
}
|
||||||
|
// All digits good.
|
||||||
|
int v = atoi(id.c_str()+1);
|
||||||
|
if (v < 0 || v > 250) return false;
|
||||||
|
// It is 0-250 which means it is an mbus primary address.
|
||||||
|
mbus_primary = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i=1; i<parts.size(); ++i)
|
||||||
|
{
|
||||||
|
if (parts[i].size() == 4) // V=xy or T=xy
|
||||||
|
{
|
||||||
|
if (parts[i][1] != '=') return false;
|
||||||
|
|
||||||
|
vector<uchar> data;
|
||||||
|
bool ok = hex2bin(&parts[i][2], &data);
|
||||||
|
if (!ok) return false;
|
||||||
|
if (data.size() != 1) return false;
|
||||||
|
|
||||||
|
if (parts[i][0] == 'V')
|
||||||
|
{
|
||||||
|
version = data[0];
|
||||||
|
}
|
||||||
|
else if (parts[i][0] == 'T')
|
||||||
|
{
|
||||||
|
type = data[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parts[i].size() == 5) // M=xyz
|
||||||
|
{
|
||||||
|
if (parts[i][1] != '=') return false;
|
||||||
|
if (parts[i][0] != 'M') return false;
|
||||||
|
|
||||||
|
bool ok = flagToManufacturer(&parts[i][2], &mfct);
|
||||||
|
if (!ok) return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool flagToManufacturer(const char *s, uint16_t *out_mfct)
|
||||||
|
{
|
||||||
|
if (s[0] == 0 || s[1] == 0 || s[2] == 0 || s[3] != 0) return false;
|
||||||
|
if (s[0] < '@' || s[0] > 'Z' ||
|
||||||
|
s[1] < '@' || s[1] > 'Z' ||
|
||||||
|
s[2] < '@' || s[2] > 'Z') return false;
|
||||||
|
|
||||||
|
*out_mfct = MANFCODE(s[0],s[1],s[2]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -21,24 +21,35 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct Address
|
struct AddressExpression
|
||||||
{
|
{
|
||||||
|
// An address expression is used to select which telegrams to decode for a driver.
|
||||||
|
// An address expression is also used to select a specific meter to poll for data.
|
||||||
// Example address: 12345678
|
// Example address: 12345678
|
||||||
// Or fully qualified: 12345678.M=PII.T=1b.V=01
|
// Or fully qualified: 12345678.M=PII.T=1b.V=01
|
||||||
// which means manufacturer triplet PII, type/media=0x1b, version=0x01
|
// which means manufacturer triplet PII, type/media=0x1b, version=0x01
|
||||||
|
// Or wildcards in id: 12*.T=16
|
||||||
|
// which matches all cold water meters whose ids start with 12.
|
||||||
|
// Or negated tests: 12345678.V!=66
|
||||||
|
// which will decode all telegrams from 12345678 except those where the version is 0x66.
|
||||||
|
// Or every telegram which is does not start with 12 and is not from ABB:
|
||||||
|
// !12*.M!=ABB
|
||||||
|
|
||||||
std::string id; // 1 or 12345678 or non-compliant hex: 1234abcd
|
std::string id; // 1 or 12345678 or non-compliant hex: 1234abcd
|
||||||
bool wildcard_used {}; // The id contains a *
|
bool has_wildcard {}; // The id contains a *
|
||||||
bool mbus_primary {}; // Signals that the id is 0-250
|
bool mbus_primary {}; // Signals that the id is 0-250
|
||||||
|
|
||||||
uint16_t mfct {}; // If 0xffff then any mfct matches this address.
|
uint16_t mfct {}; // If 0xffff then any mfct matches this address.
|
||||||
uchar type {}; // If 0xff then any type matches this address.
|
uchar type {}; // If 0xff then any type matches this address.
|
||||||
uchar version {}; // If 0xff then any version 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 filter_out {}; // Telegrams matching this rule should be filtered out!
|
||||||
bool match(Address *a);
|
|
||||||
|
bool parse(const std::string &s);
|
||||||
|
bool match(const std::string &id, uint16_t mfct, uchar version, uchar type);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isValidMatchExpression(const std::string& s);
|
bool isValidMatchExpression(const std::string& s, bool *has_wildcard);
|
||||||
bool isValidMatchExpressions(const std::string& s);
|
bool isValidMatchExpressions(const std::string& s);
|
||||||
|
|
||||||
bool doesIdMatchExpression(const std::string& id,
|
bool doesIdMatchExpression(const std::string& id,
|
||||||
|
@ -55,4 +66,6 @@ bool isValidId(const std::string& id);
|
||||||
|
|
||||||
std::vector<std::string> splitMatchExpressions(const std::string& mes);
|
std::vector<std::string> splitMatchExpressions(const std::string& mes);
|
||||||
|
|
||||||
|
bool flagToManufacturer(const char *s, uint16_t *out_mfct);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2588,87 +2588,6 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Address::parse(string &s)
|
|
||||||
{
|
|
||||||
// Example: 12345678
|
|
||||||
// or 12345678.M=PII.T=1B.V=01
|
|
||||||
// or 1234*
|
|
||||||
// or 1234*.M=PII
|
|
||||||
// or 1234*.V=01
|
|
||||||
// or 12 // mbus primary
|
|
||||||
// or 0 // mbus primary
|
|
||||||
// or 250.MPII.V01.T1B // mbus primary
|
|
||||||
// or !12345678
|
|
||||||
// or !*.M=ABC
|
|
||||||
id = "";
|
|
||||||
mbus_primary = false;
|
|
||||||
mfct = 0xffff;
|
|
||||||
type = 0xff;
|
|
||||||
version = 0xff;
|
|
||||||
negate = false;
|
|
||||||
|
|
||||||
if (s.size() == 0) return false;
|
|
||||||
|
|
||||||
vector<string> parts = splitString(s, '.');
|
|
||||||
|
|
||||||
assert(parts.size() > 0);
|
|
||||||
|
|
||||||
if (!isValidMatchExpression(parts[0]))
|
|
||||||
{
|
|
||||||
// Not a long id, so lets check if it is 0-250.
|
|
||||||
for (size_t i=0; i < parts[0].length(); ++i)
|
|
||||||
{
|
|
||||||
if (!isdigit(parts[0][i])) return false;
|
|
||||||
}
|
|
||||||
// All digits good.
|
|
||||||
int v = atoi(parts[0].c_str());
|
|
||||||
if (v < 0 || v > 250) return false;
|
|
||||||
// It is 0-250 which means it is an mbus primary address.
|
|
||||||
mbus_primary = true;
|
|
||||||
}
|
|
||||||
id = parts[0];
|
|
||||||
|
|
||||||
for (size_t i=1; i<parts.size(); ++i)
|
|
||||||
{
|
|
||||||
if (parts[i].size() == 4) // V=xy or T=xy
|
|
||||||
{
|
|
||||||
if (parts[i][1] != '=') return false;
|
|
||||||
|
|
||||||
vector<uchar> data;
|
|
||||||
bool ok = hex2bin(&parts[i][2], &data);
|
|
||||||
if (!ok) return false;
|
|
||||||
if (data.size() != 1) return false;
|
|
||||||
|
|
||||||
if (parts[i][0] == 'V')
|
|
||||||
{
|
|
||||||
version = data[0];
|
|
||||||
}
|
|
||||||
else if (parts[i][0] == 'T')
|
|
||||||
{
|
|
||||||
type = data[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (parts[i].size() == 5) // M=xyz
|
|
||||||
{
|
|
||||||
if (parts[i][1] != '=') return false;
|
|
||||||
if (parts[i][0] != 'M') return false;
|
|
||||||
|
|
||||||
bool ok = flagToManufacturer(&parts[i][2], &mfct);
|
|
||||||
if (!ok) return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkIf(set<string> &fields, const char *s)
|
bool checkIf(set<string> &fields, const char *s)
|
||||||
{
|
{
|
||||||
if (fields.count(s) > 0)
|
if (fields.count(s) > 0)
|
||||||
|
|
|
@ -39,13 +39,13 @@ bool verbose_ = false;
|
||||||
|
|
||||||
#define LIST_OF_TESTS \
|
#define LIST_OF_TESTS \
|
||||||
X(addresses) \
|
X(addresses) \
|
||||||
|
/*
|
||||||
X(dynamic_loading) \
|
X(dynamic_loading) \
|
||||||
X(crc) \
|
X(crc) \
|
||||||
X(dvparser) \
|
X(dvparser) \
|
||||||
X(devices) \
|
X(devices) \
|
||||||
X(linkmodes) \
|
X(linkmodes) \
|
||||||
X(ids) \
|
X(ids) \
|
||||||
X(addresses) \
|
|
||||||
X(kdf) \
|
X(kdf) \
|
||||||
X(periods) \
|
X(periods) \
|
||||||
X(device_parsing) \
|
X(device_parsing) \
|
||||||
|
@ -77,6 +77,7 @@ bool verbose_ = false;
|
||||||
X(formulas_dventries) \
|
X(formulas_dventries) \
|
||||||
X(formulas_stringinterpolation) \
|
X(formulas_stringinterpolation) \
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#define X(t) void test_##t();
|
#define X(t) void test_##t();
|
||||||
LIST_OF_TESTS
|
LIST_OF_TESTS
|
||||||
|
@ -498,11 +499,15 @@ void test_ids()
|
||||||
test_does_id_match_expression("78563413", "*,!00156327,!00048713", true, true);
|
test_does_id_match_expression("78563413", "*,!00156327,!00048713", true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_address(string s, bool valid, string id,
|
void tst_address(string s, bool valid,
|
||||||
string mfct, uchar version, uchar type,
|
string id, bool has_wildcard,
|
||||||
bool mbus_primary, bool wildcard_used)
|
string mfct,
|
||||||
|
uchar version,
|
||||||
|
uchar type,
|
||||||
|
bool mbus_primary,
|
||||||
|
bool filter_out)
|
||||||
{
|
{
|
||||||
Address a;
|
AddressExpression a;
|
||||||
bool ok = a.parse(s);
|
bool ok = a.parse(s);
|
||||||
|
|
||||||
if (ok != valid)
|
if (ok != valid)
|
||||||
|
@ -515,47 +520,119 @@ void tst_address(string s, bool valid, string id,
|
||||||
{
|
{
|
||||||
string smfct = manufacturerFlag(a.mfct);
|
string smfct = manufacturerFlag(a.mfct);
|
||||||
if (id != a.id ||
|
if (id != a.id ||
|
||||||
|
has_wildcard != a.has_wildcard ||
|
||||||
mfct != smfct ||
|
mfct != smfct ||
|
||||||
version != a.version ||
|
version != a.version ||
|
||||||
type != a.type ||
|
type != a.type ||
|
||||||
wildcard_used != a.wildcard_used ||
|
|
||||||
mbus_primary != a.mbus_primary ||
|
mbus_primary != a.mbus_primary ||
|
||||||
wildcard_used != a.wildcard_used)
|
filter_out != a.filter_out)
|
||||||
{
|
{
|
||||||
printf("Expected parse of address \"%s\" to return (id=%s mfct=%s version=%02x type=%02x mp=%d wu=%d)\n"
|
printf("Expected parse of address \"%s\" to return\n"
|
||||||
"but got (id=%s mfct=%s version=%02x type=%02x mp=%d wu=%d)\n",
|
"(id=%s haswild=%d mfct=%s version=%02x type=%02x mbus=%d negt=%d)\n"
|
||||||
|
"but got\n"
|
||||||
|
"(id=%s haswild=%d mfct=%s version=%02x type=%02x mbus=%d negt=%d)\n",
|
||||||
s.c_str(),
|
s.c_str(),
|
||||||
id.c_str(), mfct.c_str(), version, type, mbus_primary, wildcard_used,
|
id.c_str(),
|
||||||
a.id.c_str(), smfct.c_str(), a.version, a.type, a.mbus_primary, a.wildcard_used);
|
has_wildcard,
|
||||||
|
mfct.c_str(),
|
||||||
|
version,
|
||||||
|
type,
|
||||||
|
mbus_primary,
|
||||||
|
filter_out,
|
||||||
|
a.id.c_str(),
|
||||||
|
a.has_wildcard,
|
||||||
|
smfct.c_str(),
|
||||||
|
a.version,
|
||||||
|
a.type,
|
||||||
|
a.mbus_primary,
|
||||||
|
a.filter_out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_address_match(string expr, string id, uint16_t m, uchar v, uchar t, bool match, bool filter_out)
|
||||||
|
{
|
||||||
|
AddressExpression e;
|
||||||
|
bool ok = e.parse(expr);
|
||||||
|
assert(ok);
|
||||||
|
|
||||||
|
bool test = e.match(id, m, v, t);
|
||||||
|
|
||||||
|
if (test != match)
|
||||||
|
{
|
||||||
|
printf("Expected address %s %04x %02x %02x to %smatch expression %s\n",
|
||||||
|
id.c_str(),
|
||||||
|
m, v, t,
|
||||||
|
match?"":"not ",
|
||||||
|
expr.c_str());
|
||||||
|
}
|
||||||
|
if (match && e.filter_out != filter_out)
|
||||||
|
{
|
||||||
|
printf("Expected %s from match expression %s\n",
|
||||||
|
filter_out?"FILTERED OUT":"NOT filtered",
|
||||||
|
expr.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void test_addresses()
|
void test_addresses()
|
||||||
{
|
{
|
||||||
tst_address("12345678",
|
tst_address("12345678",
|
||||||
true,
|
true,
|
||||||
"12345678", // id
|
"12345678", // id
|
||||||
|
false, // has wildcard
|
||||||
"___", // mfct
|
"___", // mfct
|
||||||
0xff, // type
|
0xff, // type
|
||||||
0xff, // version
|
0xff, // version
|
||||||
false, // mbus primary
|
false, // mbus primary found
|
||||||
false // wildcard used
|
false // negate test
|
||||||
);
|
);
|
||||||
tst_address("123k45678", false, "", "", 0xff, 0xff, false, false);
|
tst_address("123k45678", false, "", false, "", 0xff, 0xff, false, false);
|
||||||
tst_address("1234", false, "", "", 0xff, 0xff, false, false);
|
tst_address("1234", false, "", false, "", 0xff, 0xff, false, false);
|
||||||
tst_address("0", true, "0", "___", 0xff, 0xff, true,false);
|
tst_address("p0", true, "p0", false, "___", 0xff, 0xff, true, false);
|
||||||
tst_address("250", true, "250", "___", 0xff, 0xff, true, false);
|
tst_address("p250", true, "p250", false, "___", 0xff, 0xff, true, false);
|
||||||
tst_address("251", false, "", "", 0xff, 0xff, false, false);
|
tst_address("p251", false, "", false, "", 0xff, 0xff, false, false);
|
||||||
tst_address("0.M=PII.V=01.T=1b", true, "0", "PII", 0x01, 0x1b, true, false);
|
tst_address("p0.M=PII.V=01.T=1b", true, "p0", false, "PII", 0x01, 0x1b, true, false);
|
||||||
tst_address("123.V=11.M=FOO.T=ff", true, "123", "FOO", 0x11, 0xff, true, false);
|
tst_address("p123.V=11.M=FOO.T=ff", true, "p123", false, "FOO", 0x11, 0xff, true, false);
|
||||||
tst_address("123.M=FOO", true, "123", "FOO", 0xff, 0xff, true, false);
|
tst_address("p123.M=FOO", true, "p123", false, "FOO", 0xff, 0xff, true, false);
|
||||||
tst_address("123.M=FOO.V=33", true, "123", "FOO", 0x33, 0xff, true, false);
|
tst_address("p123.M=FOO.V=33", true, "p123", false, "FOO", 0x33, 0xff, true, false);
|
||||||
tst_address("123.T=33", true, "123", "___", 0xff, 0x33, true, false);
|
tst_address("p123.T=33", true, "p123", false, "___", 0xff, 0x33, true, false);
|
||||||
tst_address("1.V=33", true, "1", "___", 0x33, 0xff, true, false);
|
tst_address("p1.V=33", true, "p1", false, "___", 0x33, 0xff, true, false);
|
||||||
tst_address("16.M=BAR", true, "16", "BAR", 0xff, 0xff, true, false);
|
tst_address("p16.M=BAR", true, "p16", false, "BAR", 0xff, 0xff, true, false);
|
||||||
|
|
||||||
// tst_address("12*", true, "12*", "___", 0xff, 0xff, false, true);
|
tst_address("12345678.M=ABB.V=66.T=16", true, "12345678", false, "ABB", 0x66, 0x16, false, false);
|
||||||
|
tst_address("!12345678.M=ABB.V=66.T=16", true, "12345678", false, "ABB", 0x66, 0x16, false, true);
|
||||||
|
tst_address("!*.M=ABB", true, "*", true, "ABB", 0xff, 0xff, false, true);
|
||||||
|
tst_address("!*.V=66.T=06", true, "*", true, "___", 0x66, 0x06, false, true);
|
||||||
|
|
||||||
|
tst_address("12*", true, "12*", true, "___", 0xff, 0xff, false, false);
|
||||||
|
tst_address("!1234567*", true, "1234567*", true, "___", 0xff, 0xff, false, true);
|
||||||
|
|
||||||
|
tst_address_match("12345678", "12345678", 1, 1, 1, true, false);
|
||||||
|
tst_address_match("12345678.M=ABB.V=77", "12345678", MANUFACTURER_ABB, 0x77, 88, true, false);
|
||||||
|
tst_address_match("1*.V=77", "12345678", MANUFACTURER_ABB, 0x77, 1, true, false);
|
||||||
|
tst_address_match("12345678.M=ABB.V=67.T=06", "12345678", MANUFACTURER_ABB, 0x67, 0x06, true, false);
|
||||||
|
tst_address_match("12345678.M=ABB.V=67.T=06", "12345678", MANUFACTURER_ABB, 0x68, 0x06, false, false);
|
||||||
|
tst_address_match("12345678.M=ABB.V=67.T=06", "12345678", MANUFACTURER_ABB, 0x67, 0x07, false, false);
|
||||||
|
tst_address_match("12345678.M=ABB.V=67.T=06", "12345678", MANUFACTURER_ABB+1, 0x67, 0x06, false, false);
|
||||||
|
tst_address_match("12345678.M=ABB.V=67.T=06", "12345677", MANUFACTURER_ABB, 0x67, 0x06, false, false);
|
||||||
|
|
||||||
|
// Now verify filter out ! character. The filter out does notchange the test. It is still the same
|
||||||
|
// test, but the match will be used as a filter out. Ie if the match triggers, then the telegram will be filtered out.
|
||||||
|
tst_address_match("!12345678", "12345677", 1, 1, 1, false, false);
|
||||||
|
tst_address_match("!*.M=ABB", "99999999", MANUFACTURER_ABB, 1, 1, true, true);
|
||||||
|
tst_address_match("*.M=ABB", "99999999", MANUFACTURER_ABB, 1, 1, true, false);
|
||||||
|
|
||||||
|
// Test that both id wildcard matches and the version.
|
||||||
|
tst_address_match("9*.V=06", "99999999", MANUFACTURER_ABB, 0x06, 1, true, false);
|
||||||
|
tst_address_match("9*.V=06", "89999999", MANUFACTURER_ABB, 0x06, 1, false, false);
|
||||||
|
tst_address_match("9*.V=06", "99999999", MANUFACTURER_ABB, 0x07, 1, false, false);
|
||||||
|
tst_address_match("9*.V=06", "89999999", MANUFACTURER_ABB, 0x07, 1, false, false);
|
||||||
|
|
||||||
|
// Test the same, expect same answers but check that filtered out is set.
|
||||||
|
tst_address_match("!9*.V=06", "99999999", MANUFACTURER_ABB, 0x06, 1, true, true);
|
||||||
|
tst_address_match("!9*.V=06", "89999999", MANUFACTURER_ABB, 0x06, 1, false, true);
|
||||||
|
tst_address_match("!9*.V=06", "99999999", MANUFACTURER_ABB, 0x07, 1, false, true);
|
||||||
|
tst_address_match("!9*.V=06", "89999999", MANUFACTURER_ABB, 0x07, 1, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eq(string a, string b, const char *tn)
|
void eq(string a, string b, const char *tn)
|
||||||
|
|
11
src/wmbus.cc
11
src/wmbus.cc
|
@ -465,17 +465,6 @@ string manufacturerFlag(int m_field) {
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flagToManufacturer(const char *s, uint16_t *out_mfct)
|
|
||||||
{
|
|
||||||
if (s[0] == 0 || s[1] == 0 || s[2] == 0 || s[3] != 0) return false;
|
|
||||||
if (s[0] < '@' || s[0] > 'Z' ||
|
|
||||||
s[1] < '@' || s[1] > 'Z' ||
|
|
||||||
s[2] < '@' || s[2] > 'Z') return false;
|
|
||||||
|
|
||||||
*out_mfct = MANFCODE(s[0],s[1],s[2]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
string mediaType(int a_field_device_type, int m_field) {
|
string mediaType(int a_field_device_type, int m_field) {
|
||||||
switch (a_field_device_type) {
|
switch (a_field_device_type) {
|
||||||
case 0: return "Other";
|
case 0: return "Other";
|
||||||
|
|
|
@ -742,7 +742,6 @@ shared_ptr<BusDevice> openSimulator(Detected detected,
|
||||||
|
|
||||||
string manufacturer(int m_field);
|
string manufacturer(int m_field);
|
||||||
string manufacturerFlag(int m_field);
|
string manufacturerFlag(int m_field);
|
||||||
bool flagToManufacturer(const char *s, uint16_t *out_mfct);
|
|
||||||
string mediaType(int a_field_device_type, int m_field);
|
string mediaType(int a_field_device_type, int m_field);
|
||||||
string mediaTypeJSON(int a_field_device_type, int m_field);
|
string mediaTypeJSON(int a_field_device_type, int m_field);
|
||||||
bool isCiFieldOfType(int ci_field, CI_TYPE type);
|
bool isCiFieldOfType(int ci_field, CI_TYPE type);
|
||||||
|
|
Ładowanie…
Reference in New Issue