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)
|
||||
#
|
||||
# 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"manufacturers.h"
|
||||
|
||||
#include<assert.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool isValidMatchExpression(const string& s)
|
||||
bool isValidMatchExpression(const string& s, bool *has_wildcard)
|
||||
{
|
||||
string me = s;
|
||||
|
||||
|
@ -58,6 +61,7 @@ bool isValidMatchExpression(const string& s)
|
|||
{
|
||||
me.erase(0,1);
|
||||
wildcard_used = true;
|
||||
if (has_wildcard) *has_wildcard = true;
|
||||
}
|
||||
|
||||
// Now we should have eaten the whole expression.
|
||||
|
@ -78,7 +82,7 @@ bool isValidMatchExpressions(const string& mes)
|
|||
|
||||
for (string me : v)
|
||||
{
|
||||
if (!isValidMatchExpression(me)) return false;
|
||||
if (!isValidMatchExpression(me, NULL)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -231,6 +235,74 @@ bool doesIdMatchExpressions(const string& id, vector<string>& mes, bool *used_wi
|
|||
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 cs;
|
||||
|
@ -242,3 +314,114 @@ string toIdsCommaSeparated(vector<string> &ids)
|
|||
if (cs.length() > 0) cs.pop_back();
|
||||
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 <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
|
||||
// Or fully qualified: 12345678.M=PII.T=1b.V=01
|
||||
// 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
|
||||
bool wildcard_used {}; // The id contains a *
|
||||
bool has_wildcard {}; // 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 filter_out {}; // Telegrams matching this rule should be filtered out!
|
||||
|
||||
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 doesIdMatchExpression(const std::string& id,
|
||||
|
@ -55,4 +66,6 @@ bool isValidId(const std::string& id);
|
|||
|
||||
std::vector<std::string> splitMatchExpressions(const std::string& mes);
|
||||
|
||||
bool flagToManufacturer(const char *s, uint16_t *out_mfct);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2588,87 +2588,6 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve)
|
|||
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)
|
||||
{
|
||||
if (fields.count(s) > 0)
|
||||
|
|
|
@ -39,13 +39,13 @@ bool verbose_ = false;
|
|||
|
||||
#define LIST_OF_TESTS \
|
||||
X(addresses) \
|
||||
/*
|
||||
X(dynamic_loading) \
|
||||
X(crc) \
|
||||
X(dvparser) \
|
||||
X(devices) \
|
||||
X(linkmodes) \
|
||||
X(ids) \
|
||||
X(addresses) \
|
||||
X(kdf) \
|
||||
X(periods) \
|
||||
X(device_parsing) \
|
||||
|
@ -77,6 +77,7 @@ bool verbose_ = false;
|
|||
X(formulas_dventries) \
|
||||
X(formulas_stringinterpolation) \
|
||||
|
||||
*/
|
||||
|
||||
#define X(t) void test_##t();
|
||||
LIST_OF_TESTS
|
||||
|
@ -498,11 +499,15 @@ 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 version, uchar type,
|
||||
bool mbus_primary, bool wildcard_used)
|
||||
void tst_address(string s, bool valid,
|
||||
string id, bool has_wildcard,
|
||||
string mfct,
|
||||
uchar version,
|
||||
uchar type,
|
||||
bool mbus_primary,
|
||||
bool filter_out)
|
||||
{
|
||||
Address a;
|
||||
AddressExpression a;
|
||||
bool ok = a.parse(s);
|
||||
|
||||
if (ok != valid)
|
||||
|
@ -515,47 +520,119 @@ void tst_address(string s, bool valid, string id,
|
|||
{
|
||||
string smfct = manufacturerFlag(a.mfct);
|
||||
if (id != a.id ||
|
||||
has_wildcard != a.has_wildcard ||
|
||||
mfct != smfct ||
|
||||
version != a.version ||
|
||||
type != a.type ||
|
||||
wildcard_used != a.wildcard_used ||
|
||||
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"
|
||||
"but got (id=%s mfct=%s version=%02x type=%02x mp=%d wu=%d)\n",
|
||||
printf("Expected parse of address \"%s\" to return\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(),
|
||||
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);
|
||||
id.c_str(),
|
||||
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()
|
||||
{
|
||||
tst_address("12345678",
|
||||
true,
|
||||
"12345678", // id
|
||||
false, // has wildcard
|
||||
"___", // mfct
|
||||
0xff, // type
|
||||
0xff, // version
|
||||
false, // mbus primary
|
||||
false // wildcard used
|
||||
false, // mbus primary found
|
||||
false // negate test
|
||||
);
|
||||
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, "", false, "", 0xff, 0xff, false, false);
|
||||
tst_address("1234", false, "", false, "", 0xff, 0xff, false, false);
|
||||
tst_address("p0", true, "p0", false, "___", 0xff, 0xff, true, false);
|
||||
tst_address("p250", true, "p250", false, "___", 0xff, 0xff, true, false);
|
||||
tst_address("p251", false, "", false, "", 0xff, 0xff, false, false);
|
||||
tst_address("p0.M=PII.V=01.T=1b", true, "p0", false, "PII", 0x01, 0x1b, true, false);
|
||||
tst_address("p123.V=11.M=FOO.T=ff", true, "p123", false, "FOO", 0x11, 0xff, true, false);
|
||||
tst_address("p123.M=FOO", true, "p123", false, "FOO", 0xff, 0xff, true, false);
|
||||
tst_address("p123.M=FOO.V=33", true, "p123", false, "FOO", 0x33, 0xff, true, false);
|
||||
tst_address("p123.T=33", true, "p123", false, "___", 0xff, 0x33, true, false);
|
||||
tst_address("p1.V=33", true, "p1", false, "___", 0x33, 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)
|
||||
|
|
11
src/wmbus.cc
11
src/wmbus.cc
|
@ -465,17 +465,6 @@ string manufacturerFlag(int m_field) {
|
|||
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) {
|
||||
switch (a_field_device_type) {
|
||||
case 0: return "Other";
|
||||
|
|
|
@ -742,7 +742,6 @@ shared_ptr<BusDevice> openSimulator(Detected detected,
|
|||
|
||||
string manufacturer(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 mediaTypeJSON(int a_field_device_type, int m_field);
|
||||
bool isCiFieldOfType(int ci_field, CI_TYPE type);
|
||||
|
|
Ładowanie…
Reference in New Issue