From 0f74dba6e9ff16b99e775526065960a125d23a4b Mon Sep 17 00:00:00 2001 From: weetmuts Date: Thu, 6 Feb 2020 19:01:48 +0100 Subject: [PATCH] Added more debug information. --- README.md | 14 ++++++++----- src/meters.cc | 6 ++++++ src/wmbus.cc | 1 - src/wmbus_amb8465.cc | 22 +++++++++++++++++---- src/wmbus_cul.cc | 12 +++++++++-- src/wmbus_d1tc.cc | 11 +++++++++-- src/wmbus_im871a.cc | 1 + src/wmbus_rawtty.cc | 12 +++++++++-- src/wmbus_rtlwmbus.cc | 46 +++++++++++++++++++++++++++++++++++-------- 9 files changed, 101 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 8a184a3..fd4e953 100644 --- a/README.md +++ b/README.md @@ -365,13 +365,17 @@ the computer boots, if the dongle is already inserted. If you do not want the daemon to start automatically, simply edit /dev/udev/rules.d/99-wmbus-usb-serial.rules and remove -`,TAG+="systemd",ENV{SYSTEMD_WANTS}="wmbusmeters.service"` from each +`,TAG+="systemd",ENV{SYSTEMD_WANTS}="wmbusmeters.@/dev/im871a_%n.service"` from each line. -You can also start/stop the daemon with `sudo systemctl restart wmbusmeters@im871a_0` -and trigger the daemon to reload the config files with `sudo killall -HUP wmbusmetersd` -If you add more dongles, then more daemons gets started. Each daemon gets a unique name -like `wmbusmeters@im871a_0 wmbusmeters@im871a_1`. +You can start/stop the daemon with `sudo systemctl stop wmbusmeters@-dev-im871a_0.service` +or `sudo systemctl stop wmbusmeters@-dev-amb8465_1.service` etc. Alas +rtl_sdr does not play nice right now with wmbusmeters daemon. If you first do `sudo systemctl stop wmbusmeters@-dev-rtlsdr_3.service` +it will hang, in a separate window do `sudo killall -9 rtl_sdr` to get rid of the spinning rtl_sdr process. + +You can trigger a reload of the config files with `sudo killall -HUP wmbusmetersd` + +If you add more dongles, then more daemons gets started, each with a unique name/nr. # Source code diff --git a/src/meters.cc b/src/meters.cc index 032d517..fb8470a 100644 --- a/src/meters.cc +++ b/src/meters.cc @@ -291,6 +291,12 @@ bool MeterCommonImplementation::handleTelegram(vector input_frame) return false; } + if (isDebugEnabled()) + { + string msg = bin2hex(input_frame); + debug("(meter) %s %s \"%s\"\n", name().c_str(), t.id.c_str(), msg.c_str()); + } + ok = t.parse(input_frame, &meter_keys_); if (!ok) { diff --git a/src/wmbus.cc b/src/wmbus.cc index abd9a66..659fe74 100644 --- a/src/wmbus.cc +++ b/src/wmbus.cc @@ -1664,7 +1664,6 @@ bool Telegram::parse(vector &input_frame, MeterKeys *mk) if (!ok) return false; verboseFields(); - debugPayload("(wmbus) frame", frame); return true; } diff --git a/src/wmbus_amb8465.cc b/src/wmbus_amb8465.cc index b5e6f75..c659339 100644 --- a/src/wmbus_amb8465.cc +++ b/src/wmbus_amb8465.cc @@ -300,22 +300,31 @@ FrameStatus WMBusAmber::checkAMB8465Frame(vector &data, int *payload_offset, uchar *rssi) { - // telegram=|2A442D2C998734761B168D2021D0871921|58387802FF2071000413F81800004413F8180000615B|+96 if (data.size() == 0) return PartialFrame; + debugPayload("(amb8465) checkIM871AFrame", data); int payload_len = 0; if (data[0] == 0xff) { - if (data.size() < 3) return PartialFrame; + if (data.size() < 3) + { + debug("(amb8465) not enough bytes yet for command.\n"); + return PartialFrame; + } // A command response begins with 0xff *msgid_out = data[1]; payload_len = data[2]; *payload_len_out = payload_len; *payload_offset = 3; *frame_length = 3+payload_len + (int)rssi_expected_; - if (data.size() < *frame_length) return PartialFrame; + if (data.size() < *frame_length) + { + debug("(amb8465) not enough bytes yet, partial command response %d %d.\n", data.size(), *frame_length); + return PartialFrame; + } if (rssi_expected_) { *rssi = data[*frame_length-1]; } + debug("(amb8465) received full command frame\n"); return FullFrame; } // If it is not a 0xff we assume it is a message beginning with a length. @@ -326,8 +335,13 @@ FrameStatus WMBusAmber::checkAMB8465Frame(vector &data, *payload_len_out = payload_len; *payload_offset = 1; *frame_length = payload_len+1; - if (data.size() < *frame_length) return PartialFrame; + if (data.size() < *frame_length) + { + debug("(amb8465) not enough bytes yet, partial frame %d %d.\n", data.size(), *frame_length); + return PartialFrame; + } + debug("(amb8465) received full frame\n"); return FullFrame; } diff --git a/src/wmbus_cul.cc b/src/wmbus_cul.cc index 0e5a3fd..e48e92b 100644 --- a/src/wmbus_cul.cc +++ b/src/wmbus_cul.cc @@ -289,16 +289,24 @@ FrameStatus WMBusCUL::checkCULFrame(vector &data, int *hex_payload_offset) { if (data.size() == 0) return PartialFrame; + + debugPayload("(cul) checkCULFrame", data); + size_t eolp = 0; // Look for end of line for (; eolp < data.size(); ++eolp) { if (data[eolp] == '\n') break; } - if (eolp >= data.size()) return PartialFrame; + if (eolp >= data.size()) + { + debug("(cul) no eol found yet, partial frame\n"); + return PartialFrame; + } if (data[0] != 'b') { // C1 and T1 telegrams should start with a 'b' + debug("(cul) text and no frame\n"); return TextAndNotFrame; } @@ -320,7 +328,7 @@ FrameStatus WMBusCUL::checkCULFrame(vector &data, *hex_payload_len_out = data.size()-8+fix; *hex_payload_offset = 2+fix; - debug("(cul) got full frame\n"); + debug("(cul) received full frame\n"); return FullFrame; } diff --git a/src/wmbus_d1tc.cc b/src/wmbus_d1tc.cc index 2b1a829..b74c703 100644 --- a/src/wmbus_d1tc.cc +++ b/src/wmbus_d1tc.cc @@ -125,7 +125,11 @@ FrameStatus WMBusD1TC::checkD1TCFrame(vector &data, // Ugly: 00615B2A442D2C998734761B168D2021D0871921|58387802FF2071000413F81800004413F8180000615B // Here the frame is prefixed with some random data. - if (data.size() < 11) { + debugPayload("(d1tc) checkD1TCFrame", data); + + if (data.size() < 11) + { + debug("(d1tc) less than 11 bytes, partial frame"); return PartialFrame; } int payload_len = data[0]; @@ -166,9 +170,12 @@ FrameStatus WMBusD1TC::checkD1TCFrame(vector &data, *payload_len_out = payload_len; *payload_offset = offset; *frame_length = payload_len+offset; - if (data.size() < *frame_length) { + if (data.size() < *frame_length) + { + debug("(rawtty) not enough bytes, partial frame %d %d", data.size(), *frame_length); return PartialFrame; } + debug("(d1tc) received full frame\n"); return FullFrame; } diff --git a/src/wmbus_im871a.cc b/src/wmbus_im871a.cc index 0e27dd1..18c0b8b 100644 --- a/src/wmbus_im871a.cc +++ b/src/wmbus_im871a.cc @@ -507,6 +507,7 @@ FrameStatus WMBusIM871A::checkIM871AFrame(vector &data, } } + debug("(im871a) received full frame\n"); return FullFrame; } diff --git a/src/wmbus_rawtty.cc b/src/wmbus_rawtty.cc index 812e893..6fcb2ff 100644 --- a/src/wmbus_rawtty.cc +++ b/src/wmbus_rawtty.cc @@ -125,7 +125,11 @@ FrameStatus WMBusRawTTY::checkRawTTYFrame(vector &data, // Ugly: 00615B2A442D2C998734761B168D2021D0871921|58387802FF2071000413F81800004413F8180000615B // Here the frame is prefixed with some random data. - if (data.size() < 11) { + debugPayload("(rawtty) checkRAWTTYFrame", data); + + if (data.size() < 11) + { + debug("(rawtty) less than 11 bytes, partial frame"); return PartialFrame; } int payload_len = data[0]; @@ -166,9 +170,13 @@ FrameStatus WMBusRawTTY::checkRawTTYFrame(vector &data, *payload_len_out = payload_len; *payload_offset = offset; *frame_length = payload_len+offset; - if (data.size() < *frame_length) { + if (data.size() < *frame_length) + { + debug("(rawtty) not enough bytes, partial frame %d %d", data.size(), *frame_length); return PartialFrame; } + + debug("(rawtty) received full frame\n"); return FullFrame; } diff --git a/src/wmbus_rtlwmbus.cc b/src/wmbus_rtlwmbus.cc index f7d26c9..84c5c47 100644 --- a/src/wmbus_rtlwmbus.cc +++ b/src/wmbus_rtlwmbus.cc @@ -205,26 +205,49 @@ FrameStatus WMBusRTLWMBUS::checkRTLWMBUSFrame(vector &data, // C1;1;1;2019-02-09 07:14:18.000;117;102;94740459;0x49449344590474943508780dff5f3500827f0000f10007b06effff530100005f2c620100007f2118010000008000800080008000000000000000000e003f005500d4ff2f046d10086922 // There might be a second telegram on the same line ;0x4944....... if (data.size() == 0) return PartialFrame; + + if (isDebugEnabled()) + { + string msg = safeString(data); + debug("(rtlwmbus) checkRTLWMBusFrame \"%s\"\n", msg.c_str()); + } + int payload_len = 0; size_t eolp = 0; // Look for end of line for (; eolp < data.size(); ++eolp) { if (data[eolp] == '\n') break; } - if (eolp >= data.size()) return PartialFrame; + if (eolp >= data.size()) + { + debug("(rtlwmbus) no eol found, partial frame\n"); + return PartialFrame; + } // We got a full line, but if it is too short, then // there is something wrong. Discard the data. - if (data.size() < 10) return ErrorInFrame; + if (data.size() < 10) + { - if (data[0] != '0' || data[1] != 'x') { + debug("(rtlwmbus) too short line\n"); + return ErrorInFrame; + } + + if (data[0] != '0' || data[1] != 'x') + { // Discard lines that do not begin with T1 or C1, these lines are probably // stderr output from rtl_sdr/rtl_wmbus. if (!(data[0] == 'T' && data[1] == '1') && - !(data[0] == 'C' && data[1] == '1')) return TextAndNotFrame; + !(data[0] == 'C' && data[1] == '1')) + { + + debug("(rtlwmbus) only text\n"); + return TextAndNotFrame; + } // And the checksums should match. - if (strncmp((const char*)&data[1], "1;1", 3)) { + if (strncmp((const char*)&data[1], "1;1", 3)) + { // Packages that begin with C1;1 or with T1;1 are good. The full format is: // MODE;CRC_OK;3OUTOF6OK;TIMESTAMP;PACKET_RSSI;CURRENT_RSSI;LINK_LAYER_IDENT_NO;DATAGRAM_WITHOUT_CRC_BYTES. // 3OUTOF6OK makes sense only with mode T1 and no sense with mode C1 (always set to 1). @@ -239,7 +262,10 @@ FrameStatus WMBusRTLWMBUS::checkRTLWMBUSFrame(vector &data, for (; i+1 < data.size(); ++i) { if (data[i] == '0' && data[i+1] == 'x') break; } - if (i+1 >= data.size()) return ErrorInFrame; // No 0x found, then discard the frame. + if (i+1 >= data.size()) + { + return ErrorInFrame; // No 0x found, then discard the frame. + } i+=2; // Skip 0x // Look for end of line or semicolon. @@ -247,14 +273,18 @@ FrameStatus WMBusRTLWMBUS::checkRTLWMBUSFrame(vector &data, if (data[eolp] == '\n') break; if (data[eolp] == ';' && data[eolp+1] == '0' && data[eolp+2] == 'x') break; } - if (eolp >= data.size()) return PartialFrame; + if (eolp >= data.size()) + { + debug("(rtlwmbus) no eol or semicolon, partial frame\n"); + return PartialFrame; + } payload_len = eolp-i; *hex_payload_len_out = payload_len; *hex_payload_offset = i; *hex_frame_length = eolp+1; - debug("(rtlwmbus) got full frame\n"); + debug("(rtlwmbus) received full frame\n"); return FullFrame; }