diff --git a/simulations/simulation_log_test.txt b/simulations/simulation_log_test.txt new file mode 100644 index 0000000..d2d31f0 --- /dev/null +++ b/simulations/simulation_log_test.txt @@ -0,0 +1,19 @@ +telegram=|A244EE4D785634123C067A8F000000_0C1348550000426CE1F14C130000000082046C21298C0413330000008D04931E3A3CFE3300000033000000330000003300000033000000330000003300000033000000330000003300000033000000330000004300000034180000046D0D0B5C2B03FD6C5E150082206C5C290BFD0F0200018C4079678885238310FD3100000082106C01018110FD610002FD66020002FD170000| +{"media":"warm water","meter":"supercom587","name":"MyWarmWater","id":"12345678","total_m3":5.548,"software_version":"010002","status":"OK","timestamp":"1111-11-11T11:11:11Z"} +|MyWarmWater;12345678;5.548;1111-11-11 11:11.11 + +telegram=|A244EE4D111111113C077AAC000000_0C1389490000426CE1F14C130000000082046C21298C0413010000008D04931E3A3CFE0100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000001600000031130000046D0A0C5C2B03FD6C60150082206C5C290BFD0F0200018C4079629885238310FD3100000082106C01018110FD610002FD66020002FD170000| +{"media":"water","meter":"supercom587","name":"MyColdWater","id":"11111111","total_m3":4.989,"software_version":"010002","status":"OK","timestamp":"1111-11-11T11:11:11Z"} +|MyColdWater;11111111;4.989;1111-11-11 11:11.11 + +telegram=|1E44AE4C9956341268077A36001000_2F2F0413181E0000023B00002F2F2F2F| +{"media":"water","meter":"iperl","name":"MoreWater","id":"12345699","total_m3":7.704,"max_flow_m3h":0,"timestamp":"1111-11-11T11:11:11Z"} +|MoreWater;12345699;7.704;0;1111-11-11 11:11.11 + +telegram=|1844AE4C4455223368077A55000000_041389E20100023B0000| +{"media":"water","meter":"iperl","name":"WaterWater","id":"33225544","total_m3":123.529,"max_flow_m3h":0,"timestamp":"1111-11-11T11:11:11Z"} +|WaterWater;33225544;123.529;0;1111-11-11 11:11.11 + +telegram=|31446850226677116980A0119F27020480048300C408F709143C003D341A2B0B2A0707000000000000062D114457563D71A1850000| +{"media":"heat cost allocator","meter":"fhkvdataiii","name":"Room","id":"11776622","current_hca":131,"current_date":"2020-02-08T02:00:00Z","previous_hca":1026,"previous_date":"2019-12-31T02:00:00Z","temp_room_c":22.44,"temp_radiator_c":25.51,"timestamp":"1111-11-11T11:11:11Z"} +|Room;11776622;131;2020-02-08T02:00:00Z;1026;2019-12-31T02:00:00Z;22.44;25.51;1111-11-11 11:11.11 diff --git a/simulations/simulation_t1.txt b/simulations/simulation_t1.txt index 25bc83e..6e3cd66 100644 --- a/simulations/simulation_t1.txt +++ b/simulations/simulation_t1.txt @@ -60,7 +60,7 @@ telegram=|374468506549235827C3A2_129F25383300A8622600008200800A2AF86211517555287 # Test FHKV data II/III # There is a problem in the decoding here, the data stored inside the telegram does not seem to properly encode/decode the year.... # We should not report a current_date with a full year, if the year is actually not part of the telegram. -telegram=|31446850226677116980A0119F27020480048300C408F709143C003D341A2B0B2A0707000000000000062D114457563D71A1850000| +telegram=|34446850226677116980A0119F27020480048300C408F709143C003D341A2B0B2A0707000000000000062D114457563D71A1850000| {"media":"heat cost allocator","meter":"fhkvdataiii","name":"Room","id":"11776622","current_hca":131,"current_date":"2020-02-08T02:00:00Z","previous_hca":1026,"previous_date":"2019-12-31T02:00:00Z","temp_room_c":22.44,"temp_radiator_c":25.51,"timestamp":"1111-11-11T11:11:11Z"} |Room;11776622;131;2020-02-08T02:00:00Z;1026;2019-12-31T02:00:00Z;22.44;25.51;1111-11-11 11:11.11 diff --git a/src/address.cc b/src/address.cc index c4bd6fb..e2e6658 100644 --- a/src/address.cc +++ b/src/address.cc @@ -19,7 +19,7 @@ using namespace std; -bool isValidMatchExpression(const string& s, bool non_compliant) +bool isValidMatchExpression(const string& s) { string me = s; @@ -41,27 +41,15 @@ bool isValidMatchExpression(const string& s, bool non_compliant) 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... + // We accept hex anyway. + while (me.length() > 0 && + ((me.front() >= '0' && me.front() <= '9') || + (me.front() >= 'a' && me.front() <= 'f'))) { - // 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++; - } + me.erase(0,1); + count++; } bool wildcard_used = false; @@ -84,28 +72,26 @@ bool isValidMatchExpression(const string& s, bool non_compliant) return count <= 7; } -bool isValidMatchExpressions(const string& mes, bool non_compliant) +bool isValidMatchExpressions(const string& mes) { vector v = splitMatchExpressions(mes); for (string me : v) { - if (!isValidMatchExpression(me, non_compliant)) return false; + if (!isValidMatchExpression(me)) return false; } return true; } -bool isValidId(const string& id, bool accept_non_compliant) +bool isValidId(const string& id) { for (size_t i=0; 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; - } + // Some non-compliant meters have hex in their id. + if (id[i] >= 'a' && id[i] <= 'f') continue; + if (id[i] >= 'A' && id[i] <= 'F') continue; return false; } return true; diff --git a/src/address.h b/src/address.h index 3f13306..0964c5f 100644 --- a/src/address.h +++ b/src/address.h @@ -26,7 +26,7 @@ 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; + std::string id; // 1 or 12345678 or non-compliant hex: 1234abcd 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. @@ -38,14 +38,20 @@ struct Address 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& match_rules, bool *used_wildcard); -bool doesIdsMatchExpressions(std::vector &ids, std::vector& match_rules, bool *used_wildcard); +bool isValidMatchExpression(const std::string& s); +bool isValidMatchExpressions(const std::string& s); + +bool doesIdMatchExpression(const std::string& id, + std::string match_rule); +bool doesIdMatchExpressions(const std::string& id, + std::vector& match_rules, + bool *used_wildcard); +bool doesIdsMatchExpressions(std::vector &ids, + std::vector& match_rules, + bool *used_wildcard); std::string toIdsCommaSeparated(std::vector &ids); -bool isValidId(const std::string& id, bool accept_non_compliant); +bool isValidId(const std::string& id); std::vector splitMatchExpressions(const std::string& mes); diff --git a/src/config.cc b/src/config.cc index db5af87..e63c48d 100644 --- a/src/config.cc +++ b/src/config.cc @@ -193,7 +193,7 @@ void parseMeterConfig(Configuration *c, vector &buf, string file) debug("(cmdline) setting link modes to %s for meter %s\n", mi.link_modes.hr().c_str(), name.c_str()); */ - if (!isValidMatchExpressions(id, true)) { + if (!isValidMatchExpressions(id)) { warning("Not a valid meter id nor a valid meter match expression \"%s\"\n", id.c_str()); use = false; } diff --git a/src/driver_dynamic.cc b/src/driver_dynamic.cc index c158091..1f5539f 100644 --- a/src/driver_dynamic.cc +++ b/src/driver_dynamic.cc @@ -104,6 +104,7 @@ bool DriverDynamic::load(DriverInfo *di, const string &file_name, const char *co } catch (...) { + xmqFreeDoc(doc); return false; } } @@ -111,9 +112,10 @@ bool DriverDynamic::load(DriverInfo *di, const string &file_name, const char *co DriverDynamic::DriverDynamic(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di), file_name_(di.getDynamicFileName()) { + XMQDoc *doc = NULL; try { - XMQDoc *doc = di.getDynamicDriver(); + doc = di.getDynamicDriver(); assert(doc); verbose("(driver) constructing driver %s from already loaded file %s\n", @@ -125,6 +127,7 @@ DriverDynamic::DriverDynamic(MeterInfo &mi, DriverInfo &di) : } catch(...) { + xmqFreeDoc(doc); } } diff --git a/src/meters.cc b/src/meters.cc index 385d40c..15f6253 100644 --- a/src/meters.cc +++ b/src/meters.cc @@ -2613,7 +2613,7 @@ bool Address::parse(string &s) assert(parts.size() > 0); - if (!isValidMatchExpression(parts[0], true)) + 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) diff --git a/src/testinternals.cc b/src/testinternals.cc index c0c64f3..a41ee28 100644 --- a/src/testinternals.cc +++ b/src/testinternals.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2018-2022 Fredrik Öhrström (gpl-3.0-or-later) + Copyright (C) 2018-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 @@ -15,6 +15,7 @@ along with this program. If not, see . */ +#include"address.h" #include"aes.h" #include"aescmac.h" #include"cmdline.h" @@ -425,7 +426,7 @@ void test_linkmodes() void test_valid_match_expression(string s, bool expected) { - bool b = isValidMatchExpressions(s, false); + bool b = isValidMatchExpressions(s); if (b == expected) return; if (expected == true) { diff --git a/tests/config2/etc/wmbusmeters.conf b/tests/config2/etc/wmbusmeters.conf index a4a1080..93a6f3f 100644 --- a/tests/config2/etc/wmbusmeters.conf +++ b/tests/config2/etc/wmbusmeters.conf @@ -1,5 +1,5 @@ loglevel=normal -device=simulations/simulation_t1.txt +device=simulations/simulation_log_test.txt logtelegrams=true format=json meterfiles=testoutput/meter_readings2 diff --git a/tests/test_listen_to_all.sh b/tests/test_listen_to_all.sh index 8b385c0..3b1d3c2 100755 --- a/tests/test_listen_to_all.sh +++ b/tests/test_listen_to_all.sh @@ -70,7 +70,6 @@ Received telegram from: 58234965 type: Heat meter (0xc3) ver: 0x27 driver: vario451 -(wmbus) telegram length byte (the first) 0x31 (49) is probably wrong. Expected 0x34 (52) based on the length of the telegram. Received telegram from: 11776622 manufacturer: (TCH) Techem Service (0x5068) type: Heat Cost Allocator (0x80)