diff --git a/simulations/simulation_broken.txt b/simulations/simulation_broken.txt new file mode 100644 index 0000000..3e53fc8 --- /dev/null +++ b/simulations/simulation_broken.txt @@ -0,0 +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| diff --git a/src/dvparser.cc b/src/dvparser.cc index 5c21872..239ba90 100644 --- a/src/dvparser.cc +++ b/src/dvparser.cc @@ -253,11 +253,7 @@ bool parseDV(Telegram *t, int remaining = std::distance(data, data_end); if (variable_length) { DEBUG_PARSER("(dvparser debug) varlen %02x\n", *(data+0)); - if (remaining > 2) { - datalen = *(data); - } else { - datalen = remaining; - } + datalen = *(data); } DEBUG_PARSER("(dvparser debug) remaining data %d len=%d\n", remaining, datalen); if (remaining < datalen) { @@ -267,7 +263,7 @@ bool parseDV(Telegram *t, // Skip the length byte in the variable length data. if (variable_length) { - t->addExplanationAndIncrementPos(data, 1, "%02X varlen=%d", datalen, datalen); + t->addExplanationAndIncrementPos(data, 1, "%02X varlen=%d", *(data+0), datalen); } string value = bin2hex(data, data_end, datalen); int offset = start_parse_here+data-data_start; diff --git a/src/wmbus.cc b/src/wmbus.cc index 94382d7..e828bd8 100644 --- a/src/wmbus.cc +++ b/src/wmbus.cc @@ -595,6 +595,7 @@ string mediaTypeJSON(int a_field_device_type, int m_field) X(0x78, TPL_78, "TPL: no header APL follows", 0, CI_TYPE::TPL, "") \ X(0x79, TPL_79, "TPL: compact APL follows", 0, CI_TYPE::TPL, "") \ X(0x7A, TPL_7A, "TPL: short header APL follows", 0, CI_TYPE::TPL, "") \ + X(0x81, NWL_81, "NWL: TPL or APL follows?", 0, CI_TYPE::NWL, "") \ X(0x8C, ELL_I, "ELL: I", 2, CI_TYPE::ELL, "CC, ACC") \ X(0x8D, ELL_II, "ELL: II", 8, CI_TYPE::ELL, "CC, ACC, SN, Payload CRC") \ X(0x8E, ELL_III, "ELL: III", 10, CI_TYPE::ELL, "CC, ACC, M2, A2") \ @@ -1030,6 +1031,23 @@ bool Telegram::parseELL(vector::iterator &pos) bool Telegram::parseNWL(vector::iterator &pos) { + int remaining = distance(pos, frame.end()); + if (remaining == 0) return false; + + debug("(wmbus) parseNWL @%d %d\n", distance(frame.begin(), pos), remaining); + int ci_field = *pos; + if (!isCiFieldOfType(ci_field, CI_TYPE::NWL)) return true; + addExplanationAndIncrementPos(pos, 1, "%02x nwl-ci-field (%s)", + ci_field, ciType(ci_field).c_str()); + nwl_ci = ci_field; + // We have only seen 0x81 0x1d so far. + int len = 1; // ciFieldLength(nwl_ci); + + if (remaining < len+1) return expectedMore(__LINE__); + + uchar nwl = *pos; + addExplanationAndIncrementPos(pos, 1, "%02x nwl?", nwl); + return true; } diff --git a/test.sh b/test.sh index b2bdc40..f8fbc79 100755 --- a/test.sh +++ b/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_broken.sh $PROG +if [ "$?" != "0" ]; then RC="1"; fi + if [ -x ../additional_tests.sh ] then (cd ..; ./additional_tests.sh $PROG) diff --git a/tests/test_broken.sh b/tests/test_broken.sh new file mode 100755 index 0000000..8bb594f --- /dev/null +++ b/tests/test_broken.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +PROG="$1" +TEST=testoutput +mkdir -p $TEST + +TESTNAME="Test broken telegrams" +TESTRESULT="ERROR" + +cat > $TEST/test_expected.txt <&1 | grep dvparser > $TEST/test_output.txt + +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