kopia lustrzana https://github.com/weetmuts/wmbusmeters
Simulation file and hex on command line now auto-removes any valid dll-crcs found.
rodzic
02e84048f0
commit
f7cb6ce2ee
8
CHANGES
8
CHANGES
|
@ -1,4 +1,12 @@
|
|||
|
||||
Now any DLL crcs (frame A or B) are removed automatically
|
||||
when telegrams are read from a simulation_... file or
|
||||
passed as hex on the command line. If the DLL crc do not
|
||||
check out (usually because they are not there), then the
|
||||
telegram is kept as is. If the crcs are broken because
|
||||
of a bad data, then the telegram will be passed on as is,
|
||||
probably causing a bad parse later on.
|
||||
|
||||
Added multical602 heat meter.
|
||||
|
||||
Version 1.5.0: 2021-11-06
|
||||
|
|
|
@ -303,6 +303,7 @@ These telegrams are expected to have the data link layer crc bytes removed alrea
|
|||
|
||||
`simulation_abc.txt`, to read telegrams from the file (the file must have a name beginning with simulation_....)
|
||||
expecting the same format that is the output from `--logtelegrams`. This format also supports replay with timing.
|
||||
The telegrams are allowed to have valid dll crcs, which will be automatically stripped.
|
||||
|
||||
As meter quadruples you specify:
|
||||
|
||||
|
@ -604,8 +605,11 @@ echo 234433300602010014007a8e0000002f2f0efd3a1147000000008e40fd3a341200000000 |
|
|||
|
||||
or read hex data from a a file, `wmbusmeters myfile.txt:hex`
|
||||
|
||||
Any non-hex characters are ignored when using the suffix `:hex`. The hex string must be proper
|
||||
with no spaces nor bad characters, when supplied on the command line.
|
||||
Any non-hex characters are ignored when using the suffix `:hex`. However when the hex string is
|
||||
supplied on the command line it must be a proper hex string with no spaces.
|
||||
|
||||
When a telegram is supplied on the command line, then any valid dll crcs will be automatically removed,
|
||||
like when the telegram is suppled in a simulation file.
|
||||
|
||||
# Additional tools
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# This telegram is not really broken, but the current dvparser fails, in particular the end triggers a varlen with
|
||||
# not enough bytes in the telegram. When the protocol/dvparser is improved, a replacement telegram should be placed here.
|
||||
telegram=|3444EE4D813929271608|811D|7A51000000|046D1912A62B036E000000|5170426CE1F1436E00000002FF2C00000259D6D0D4090265FC0902FD66A00044C4|
|
||||
# The last byte C4 has been removed. This means that the dll crcs will not check out.
|
||||
# Since the simulation will not remove the crcs unless they all check out, this will result in a broken telegram.
|
||||
telegram=|3444EE4D813929271608|811D|7A51000000|046D1912A62B036E000000|5170426CE1F1436E00000002FF2C00000259D6D0D4090265FC0902FD66A00044|
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# These telegrams have their dll crc:s still inside.
|
||||
telegram=|734414867CC30B0003030D58A00EDF0700DC41343CEA390306FF0A0D44EADF07000DDF07000DDF07000DDF07000E44F9DF07000EDF07000EDF07000EDF07000E931EDF07000DDF07000DDF07000DDF0700035A4500000000374F0B20000000000000243412B31C07050C12280000000000002C002302062F19080F2F000000000000DCF5|
|
||||
telegram=|3444EE4D813929271608|811D|7A51000000|046D1912A62B036E000000|5170426CE1F1436E00000002FF2C00000259D6D0D4090265FC0902FD66A00044C4|
|
109
src/wmbus.cc
109
src/wmbus.cc
|
@ -4060,14 +4060,20 @@ LIST_OF_AFL_AUTH_TYPES
|
|||
return AFLAuthenticationType::Reserved1;
|
||||
}
|
||||
|
||||
bool trimCRCsFrameFormatA(std::vector<uchar> &payload)
|
||||
bool trimCRCsFrameFormatAInternal(std::vector<uchar> &payload, bool fail_is_ok)
|
||||
{
|
||||
if (payload.size() < 12) {
|
||||
debug("(wmbus) not enough bytes! expected at least 12 but got (%zu)!\n", payload.size());
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) not enough bytes! expected at least 12 but got (%zu)!\n", payload.size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
size_t len = payload.size();
|
||||
debugPayload("(wmbus) trimming frame A", payload);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debugPayload("(wmbus) trimming frame A", payload);
|
||||
}
|
||||
|
||||
vector<uchar> out;
|
||||
|
||||
|
@ -4080,7 +4086,10 @@ bool trimCRCsFrameFormatA(std::vector<uchar> &payload)
|
|||
return false;
|
||||
}
|
||||
out.insert(out.end(), payload.begin(), payload.begin()+10);
|
||||
debug("(wmbus) ff a dll crc 0-%zu %04x ok\n", 10-1, calc_crc);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff a dll crc 0-%zu %04x ok\n", 10-1, calc_crc);
|
||||
}
|
||||
|
||||
size_t pos = 12;
|
||||
for (pos = 12; pos+18 <= len; pos += 18)
|
||||
|
@ -4090,12 +4099,18 @@ bool trimCRCsFrameFormatA(std::vector<uchar> &payload)
|
|||
check_crc = payload[to] << 8 | payload[to+1];
|
||||
if (calc_crc != check_crc && !FUZZING)
|
||||
{
|
||||
debug("(wmbus) ff a dll crc mid (calculated %04x) did not match (expected %04x) for bytes %zu-%zu!\n",
|
||||
calc_crc, check_crc, pos, to-1);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff a dll crc mid (calculated %04x) did not match (expected %04x) for bytes %zu-%zu!\n",
|
||||
calc_crc, check_crc, pos, to-1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
out.insert(out.end(), payload.begin()+pos, payload.begin()+pos+16);
|
||||
debug("(wmbus) ff a dll crc mid %zu-%zu %04x ok\n", pos, to-1, calc_crc);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff a dll crc mid %zu-%zu %04x ok\n", pos, to-1, calc_crc);
|
||||
}
|
||||
}
|
||||
|
||||
if (pos < len-2)
|
||||
|
@ -4106,12 +4121,23 @@ bool trimCRCsFrameFormatA(std::vector<uchar> &payload)
|
|||
check_crc = payload[tto] << 8 | payload[tto+1];
|
||||
if (calc_crc != check_crc && !FUZZING)
|
||||
{
|
||||
debug("(wmbus) ff a dll crc final (calculated %04x) did not match (expected %04x) for bytes %zu-%zu!\n",
|
||||
calc_crc, check_crc, pos, tto-1);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff a dll crc final (calculated %04x) did not match (expected %04x) for bytes %zu-%zu!\n",
|
||||
calc_crc, check_crc, pos, tto-1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
out.insert(out.end(), payload.begin()+pos, payload.begin()+tto);
|
||||
debug("(wmbus) ff a dll crc final %zu-%zu %04x ok\n", pos, tto-1, calc_crc);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff a dll crc final %zu-%zu %04x ok\n", pos, tto-1, calc_crc);
|
||||
}
|
||||
}
|
||||
|
||||
if (fail_is_ok)
|
||||
{
|
||||
debugPayload("(wmbus) trimming frame A", payload);
|
||||
}
|
||||
|
||||
out[0] = out.size()-1;
|
||||
|
@ -4120,20 +4146,26 @@ bool trimCRCsFrameFormatA(std::vector<uchar> &payload)
|
|||
payload = out;
|
||||
size_t new_size = payload.size();
|
||||
|
||||
debug("(wmbus) trimmed %zu crc bytes from frame a and ignored %zu suffix bytes.\n", (len-new_len), (old_size-new_size)-(len-new_len));
|
||||
debugPayload("(wmbus) trimmed frame A", payload);
|
||||
debug("(wmbus) trimmed %zu dll crc bytes from frame a and ignored %zu suffix bytes.\n", (len-new_len), (old_size-new_size)-(len-new_len));
|
||||
debugPayload("(wmbus) trimmed frame A", payload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trimCRCsFrameFormatB(std::vector<uchar> &payload)
|
||||
bool trimCRCsFrameFormatBInternal(std::vector<uchar> &payload, bool fail_is_ok)
|
||||
{
|
||||
if (payload.size() < 12) {
|
||||
debug("(wmbus) not enough bytes! expected at least 12 but got (%zu)!\n", payload.size());
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) not enough bytes! expected at least 12 but got (%zu)!\n", payload.size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
size_t len = payload.size();
|
||||
debugPayload("(wmbus) trimming frame B", payload);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debugPayload("(wmbus) trimming frame B", payload);
|
||||
}
|
||||
|
||||
vector<uchar> out;
|
||||
size_t crc1_pos, crc2_pos;
|
||||
|
@ -4153,12 +4185,18 @@ bool trimCRCsFrameFormatB(std::vector<uchar> &payload)
|
|||
|
||||
if (calc_crc != check_crc && !FUZZING)
|
||||
{
|
||||
debug("(wmbus) ff b dll crc (calculated %04x) did not match (expected %04x) for bytes 0-%zu!\n", calc_crc, check_crc, crc1_pos);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff b dll crc (calculated %04x) did not match (expected %04x) for bytes 0-%zu!\n", calc_crc, check_crc, crc1_pos);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
out.insert(out.end(), payload.begin(), payload.begin()+crc1_pos);
|
||||
debug("(wmbus) ff b dll crc first 0-%zu %04x ok\n", crc1_pos, calc_crc);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff b dll crc first 0-%zu %04x ok\n", crc1_pos, calc_crc);
|
||||
}
|
||||
|
||||
if (crc2_pos > 0)
|
||||
{
|
||||
|
@ -4167,13 +4205,24 @@ bool trimCRCsFrameFormatB(std::vector<uchar> &payload)
|
|||
|
||||
if (calc_crc != check_crc && !FUZZING)
|
||||
{
|
||||
debug("(wmbus) ff b dll crc (calculated %04x) did not match (expected %04x) for bytes %zu-%zu!\n",
|
||||
calc_crc, check_crc, crc1_pos+2, crc2_pos);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff b dll crc (calculated %04x) did not match (expected %04x) for bytes %zu-%zu!\n",
|
||||
calc_crc, check_crc, crc1_pos+2, crc2_pos);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
out.insert(out.end(), payload.begin()+crc1_pos+2, payload.begin()+crc2_pos);
|
||||
debug("(wmbus) ff b dll crc final %zu-%zu %04x ok\n", crc1_pos+2, crc2_pos, calc_crc);
|
||||
if (!fail_is_ok)
|
||||
{
|
||||
debug("(wmbus) ff b dll crc final %zu-%zu %04x ok\n", crc1_pos+2, crc2_pos, calc_crc);
|
||||
}
|
||||
}
|
||||
|
||||
if (fail_is_ok)
|
||||
{
|
||||
debugPayload("(wmbus) trimming frame B", payload);
|
||||
}
|
||||
|
||||
out[0] = out.size()-1;
|
||||
|
@ -4182,12 +4231,28 @@ bool trimCRCsFrameFormatB(std::vector<uchar> &payload)
|
|||
payload = out;
|
||||
size_t new_size = payload.size();
|
||||
|
||||
debug("(wmbus) trimmed %zu crc bytes from frame b and ignored %zu suffix bytes.\n", (len-new_len), (old_size-new_size)-(len-new_len));
|
||||
debugPayload("(wmbus) trimmed frame B", payload);
|
||||
debug("(wmbus) trimmed %zu dll crc bytes from frame b and ignored %zu suffix bytes.\n", (len-new_len), (old_size-new_size)-(len-new_len));
|
||||
debugPayload("(wmbus) trimmed frame B", payload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void removeAnyDLLCRCs(std::vector<uchar> &payload)
|
||||
{
|
||||
bool trimmed = trimCRCsFrameFormatAInternal(payload, true);
|
||||
if (!trimmed) trimCRCsFrameFormatBInternal(payload, true);
|
||||
}
|
||||
|
||||
bool trimCRCsFrameFormatA(std::vector<uchar> &payload)
|
||||
{
|
||||
return trimCRCsFrameFormatAInternal(payload, false);
|
||||
}
|
||||
|
||||
bool trimCRCsFrameFormatB(std::vector<uchar> &payload)
|
||||
{
|
||||
return trimCRCsFrameFormatBInternal(payload, false);
|
||||
}
|
||||
|
||||
FrameStatus checkWMBusFrame(vector<uchar> &data,
|
||||
size_t *frame_length,
|
||||
int *payload_len_out,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
// Check and remove the data link layer CRCs from a wmbus telegram.
|
||||
// If the CRCs do not pass the test, return false.
|
||||
void removeAnyDLLCRCs(std::vector<uchar> &payload);
|
||||
bool trimCRCsFrameFormatA(std::vector<uchar> &payload);
|
||||
bool trimCRCsFrameFormatB(std::vector<uchar> &payload);
|
||||
|
||||
|
|
|
@ -175,6 +175,13 @@ void WMBusSimulator::simulate()
|
|||
error("Not a valid string of hex bytes! \"%s\"\n", l.c_str());
|
||||
}
|
||||
AboutTelegram about("", 0, FrameType::WMBUS);
|
||||
// Since this is a simulation, try to remove any frame format A or B
|
||||
// data link layer crcs. These might remain if we have received the telegram
|
||||
// to be simulated, from a CUL device or some other devices that does not remove the crcs.
|
||||
// Normally the dongle (im871a/amb8465/rc1180/rtlwmbus/rtl443) removes the dll-crcs.
|
||||
// Removing dll-crcs are also done explicitly in the wmbus_cul.cc driver.
|
||||
removeAnyDLLCRCs(payload);
|
||||
|
||||
handleTelegram(about, payload);
|
||||
}
|
||||
manager_->stop();
|
||||
|
|
3
test.sh
3
test.sh
|
@ -114,6 +114,9 @@ if [ "$?" != "0" ]; then RC="1"; fi
|
|||
./tests/test_hex_cmdline.sh $PROG
|
||||
if [ "$?" != "0" ]; then RC="1"; fi
|
||||
|
||||
./tests/test_removing_dll_crcs.sh $PROG
|
||||
if [ "$?" != "0" ]; then RC="1"; fi
|
||||
|
||||
./tests/test_broken.sh $PROG
|
||||
if [ "$?" != "0" ]; then RC="1"; fi
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROG="$1"
|
||||
TEST=testoutput
|
||||
mkdir -p $TEST
|
||||
|
||||
TESTNAME="Test auto removal of dll crcs in simulated telegrams"
|
||||
TESTRESULT="ERROR"
|
||||
|
||||
cat > $TEST/test_expected.txt <<EOF
|
||||
No meters configured. Printing id:s of all telegrams heard!
|
||||
Received telegram from: 000bc37c
|
||||
manufacturer: (APT) Unknown (0x8614)
|
||||
type: Gas meter (0x03)
|
||||
ver: 0x03
|
||||
driver: apator08
|
||||
Received telegram from: 27293981
|
||||
manufacturer: (SON) Sontex, Switzerland (0x4dee)
|
||||
type: Heat Cost Allocator (0x08)
|
||||
ver: 0x16
|
||||
driver: sontex868
|
||||
EOF
|
||||
|
||||
$PROG simulations/simulation_dll_crcs.txt > $TEST/test_output.txt 2>&1
|
||||
|
||||
if [ "$?" = "0" ]
|
||||
then
|
||||
diff $TEST/test_expected.txt $TEST/test_output.txt
|
||||
if [ "$?" = "0" ]
|
||||
then
|
||||
echo OK: $TESTNAME
|
||||
TESTRESULT="OK"
|
||||
fi
|
||||
else
|
||||
echo "wmbusmeters returned error code: $?"
|
||||
cat $TEST/test_output.txt
|
||||
fi
|
Ładowanie…
Reference in New Issue