Skip to content

Commit b50d174

Browse files
authored
Skip the MBus short frame at the beginning of the buffer (#18)
Fix #16
1 parent cc108a6 commit b50d174

4 files changed

Lines changed: 23 additions & 2 deletions

File tree

idf_component.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
version: "1.2.0"
21
description: "A C++20 library for parsing DLMS/COSEM push telegrams from electricity meters. It is designed for embedded and integration-heavy environments such as ESPHome"
32
url: "https://github.com/esphome-libs/dlms_parser"
43
files:

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dlms_parser",
3-
"version": "1.2.0",
3+
"version": "1.3.0",
44
"description": "A C++20 library for parsing DLMS/COSEM push telegrams from electricity meters. It is designed for embedded and integration-heavy environments such as ESPHome",
55
"keywords": [
66
"dlms",

src/dlms_parser/dlms_parser.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ static void log_span_as_hex(const LogLevel level, const std::span<const uint8_t>
2222
}
2323
}
2424

25+
static bool is_mbus_short_frame(const std::span<const uint8_t> data) {
26+
if (data.size() < 5 || data[0] != 0x10 || data[4] != 0x16) return false;
27+
return static_cast<uint8_t>(data[1] + data[2]) == data[3];
28+
}
29+
2530
DlmsParser::DlmsParser(Aes128GcmDecryptor* decryptor) : decryptor_(decryptor) {}
2631

2732
void DlmsParser::set_skip_crc_check(const bool skip) {
@@ -72,6 +77,12 @@ ParseResult DlmsParser::parse(std::span<uint8_t> buf, const DlmsDataCallback& co
7277
log_span_as_hex(LogLevel::VERY_VERBOSE, buf);
7378
Logger::log(LogLevel::VERY_VERBOSE, "============");
7479

80+
if (is_mbus_short_frame(buf)) {
81+
Logger::log(LogLevel::VERBOSE, "Skipping M-Bus short frame prefix");
82+
buf = buf.subspan(5);
83+
if (buf.empty()) return {};
84+
}
85+
7586
std::span<uint8_t> decoded;
7687

7788
// Step 1: Frame decode (auto-detect HDLC / MBus / RAW from first byte)

tests/test_meter_dumps.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,17 @@ TEST_CASE("Integration: HDLC") {
191191
);
192192
}
193193

194+
SUBCASE("Iskra 550 (3 segmented frames) with leading M-Bus short frame") {
195+
std::vector<uint8_t> frame{0x10, 0x40, 0x01, 0x41, 0x16};
196+
frame.insert(frame.end(), std::begin(dlms::test_data::iskra550_raw_frame), std::end(dlms::test_data::iskra550_raw_frame));
197+
run_meter_test(
198+
frame,
199+
dlms::test_data::iskra550_expected_count,
200+
dlms::test_data::iskra550_expected_strings,
201+
dlms::test_data::iskra550_expected_floats
202+
);
203+
}
204+
194205
SUBCASE("Iskra 550 (3 segmented frames) and the same data at the end. Should ignore the duplicated part") {
195206
std::vector<uint8_t> duplicated_frame(std::begin(dlms::test_data::iskra550_raw_frame), std::end(dlms::test_data::iskra550_raw_frame));
196207
duplicated_frame.insert(duplicated_frame.end(), std::begin(dlms::test_data::iskra550_raw_frame), std::end(dlms::test_data::iskra550_raw_frame));

0 commit comments

Comments
 (0)