From 6f76632728f88ec1706c1d7b0f6b5376d66e0687 Mon Sep 17 00:00:00 2001 From: Robert Johansson Date: Sun, 13 May 2012 16:32:17 +0900 Subject: [PATCH 1/6] fix bug in breakout of loop due to max_frames condition --- mbus/mbus-protocol-aux.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index df836e4..52e336f 100644 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -24,7 +24,7 @@ #define MBUS_DEBUG(...) #endif -static int debug = 1; +static int debug = 0; typedef struct _mbus_variable_vif { unsigned vif; @@ -1557,14 +1557,7 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m while (more_frames) { frame_count++; - - if ((max_frames > 0) && - (frame_count > max_frames)) - { - // only readout max_frames - break; - } - + if (debug) printf("%s: debug: receiving response frame #%d\n", __PRETTY_FUNCTION__, frame_count); @@ -1601,7 +1594,8 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m { more_frames = 0; - if (reply_data.data_var.more_records_follow) + if (reply_data.data_var.more_records_follow && + ((max_frames > 0) && (frame_count < max_frames))) // only readout max_frames { if (debug) printf("%s: debug: expecting more frames\n", __PRETTY_FUNCTION__); From 59fca0a709ae3c69b0b635a182903bb01d3c1e55 Mon Sep 17 00:00:00 2001 From: Robert Johansson Date: Sun, 13 May 2012 16:32:55 +0900 Subject: [PATCH 2/6] added option to dump frame in HEX to stdout before writing it to the serial port --- mbus/mbus-serial.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mbus/mbus-serial.c b/mbus/mbus-serial.c index 8534bb5..80a7b06 100644 --- a/mbus/mbus-serial.c +++ b/mbus/mbus-serial.c @@ -167,6 +167,16 @@ mbus_serial_send_frame(mbus_serial_handle *handle, mbus_frame *frame) return -1; } +#ifdef MBUS_SERIAL_DEBUG + // if debug, dump in HEX form to stdout what we write to the serial port + printf("%s: Dumping M-Bus frame [%d bytes]: ", __PRETTY_FUNCTION__, len); + for (i = 0; i < len; i++) + { + printf("%.2X ", buff[i]); + } + printf("\n"); +#endif + if ((ret = write(handle->fd, buff, len)) != len) { fprintf(stderr, "%s: Failed to write frame to socket (ret = %d: %s)\n", __PRETTY_FUNCTION__, ret, strerror(errno)); From 29201258e791e1f8dc74a5748d2e267a7dde5af3 Mon Sep 17 00:00:00 2001 From: Robert Johansson Date: Sun, 13 May 2012 16:33:53 +0900 Subject: [PATCH 3/6] in mbus_frame_print for dumping frame in HEX format to stdout, now looping over all frames in a multi-telegram frame list --- mbus/mbus-protocol.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index 0e97e30..4da4b45 100644 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -2744,27 +2744,29 @@ mbus_parse_set_debug(int debug) int mbus_frame_print(mbus_frame *frame) { + mbus_frame *iter; u_char data_buff[256]; int len, i; - - if (frame) + + if (frame == NULL) + return -1; + + for (iter = frame; iter; iter = iter->next) { - if ((len = mbus_frame_pack(frame, data_buff, sizeof(data_buff))) == -1) + if ((len = mbus_frame_pack(iter, data_buff, sizeof(data_buff))) == -1) { return -2; } - - printf("%s: Dumping M-Bus frame [type %d, %d bytes]: ", __PRETTY_FUNCTION__, frame->type, len); + + printf("%s: Dumping M-Bus frame [type %d, %d bytes]: ", __PRETTY_FUNCTION__, iter->type, len); for (i = 0; i < len; i++) { printf("%.2X ", data_buff[i]); } printf("\n"); - - return 0; } - - return -1; + + return 0; } //------------------------------------------------------------------------------ From 726f837d2dd88bda87e425fa33c97e48b08878ab Mon Sep 17 00:00:00 2001 From: Robert Johansson Date: Sun, 13 May 2012 16:34:12 +0900 Subject: [PATCH 4/6] improved error handling --- bin/mbus-serial-request-data-multi-reply.c | 9 +++++++-- bin/mbus-tcp-request-data-multi-reply.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/bin/mbus-serial-request-data-multi-reply.c b/bin/mbus-serial-request-data-multi-reply.c index fb90ad0..c6082f5 100644 --- a/bin/mbus-serial-request-data-multi-reply.c +++ b/bin/mbus-serial-request-data-multi-reply.c @@ -29,7 +29,7 @@ main(int argc, char **argv) mbus_frame_data reply_data; mbus_handle *handle = NULL; - char *device, *addr_str, matching_addr[16]; + char *device, *addr_str, matching_addr[16], *xml_result; int address, baudrate = 9600; memset((void *)&reply, 0, sizeof(mbus_frame)); @@ -132,7 +132,12 @@ main(int argc, char **argv) // // generate XML and print to standard output // - printf("%s", mbus_frame_xml(&reply)); + if ((xml_result = mbus_frame_xml(&reply)) == NULL) + { + fprintf(stderr, "Failed to generate XML representation of MBUS frames: %s\n", mbus_error_str()); + return 1; + } + printf("%s", xml_result); mbus_disconnect(handle); return 0; diff --git a/bin/mbus-tcp-request-data-multi-reply.c b/bin/mbus-tcp-request-data-multi-reply.c index fee2d2a..91ea0c1 100644 --- a/bin/mbus-tcp-request-data-multi-reply.c +++ b/bin/mbus-tcp-request-data-multi-reply.c @@ -29,7 +29,7 @@ main(int argc, char **argv) mbus_frame_data reply_data; mbus_handle *handle = NULL; - char *host, *addr_str, matching_addr[16]; + char *host, *addr_str, matching_addr[16], *xml_result; int port, address; memset((void *)&reply, 0, sizeof(mbus_frame)); @@ -114,7 +114,12 @@ main(int argc, char **argv) // // generate XML and print to standard output // - printf("%s", mbus_frame_xml(&reply)); + if ((xml_result = mbus_frame_xml(&reply)) == NULL) + { + fprintf(stderr, "Failed to generate XML representation of MBUS frames: %s\n", mbus_error_str()); + return 1; + } + printf("%s", xml_result); mbus_disconnect(handle); return 0; From dadf3b48235e059893442e5fa1cb04874dc20b1d Mon Sep 17 00:00:00 2001 From: Robert Johansson Date: Sun, 13 May 2012 16:34:34 +0900 Subject: [PATCH 5/6] added a debug/verbose flag to the primary address scan utils --- bin/mbus-serial-scan.c | 26 ++++++++++++++++++++++++-- bin/mbus-tcp-scan.c | 34 +++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/bin/mbus-serial-scan.c b/bin/mbus-serial-scan.c index 42f09f7..178cbbe 100644 --- a/bin/mbus-serial-scan.c +++ b/bin/mbus-serial-scan.c @@ -25,20 +25,31 @@ main(int argc, char **argv) { mbus_handle *handle; char *device; - int address, baudrate = 9600; + int address, baudrate = 9600, debug = 0; if (argc == 2) { device = argv[1]; } + else if (argc == 3 && strcmp(argv[1], "-d") == 0) + { + debug = 1; + device = argv[2]; + } else if (argc == 4 && strcmp(argv[1], "-b") == 0) { baudrate = atoi(argv[2]); device = argv[3]; } + else if (argc == 5 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-b") == 0) + { + debug = 1; + baudrate = atoi(argv[3]); + device = argv[4]; + } else { - fprintf(stderr, "usage: %s [-b BAUDRATE] device\n", argv[0]); + fprintf(stderr, "usage: %s [-d] [-b BAUDRATE] device\n", argv[0]); return 0; } @@ -54,6 +65,8 @@ main(int argc, char **argv) return 1; } + if (debug) + printf("Scanning primary addresses:\n"); for (address = 0; address < 254; address++) { @@ -61,6 +74,12 @@ main(int argc, char **argv) memset((void *)&reply, 0, sizeof(mbus_frame)); + if (debug) + { + printf("%d ", address); + fflush(stdout); + } + if (mbus_send_ping_frame(handle, address) == -1) { printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str()); @@ -74,6 +93,9 @@ main(int argc, char **argv) if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) { + if (debug) + printf("\n"); + printf("Found a M-Bus device at address %d\n", address); } } diff --git a/bin/mbus-tcp-scan.c b/bin/mbus-tcp-scan.c index 9ae5b34..7633b00 100644 --- a/bin/mbus-tcp-scan.c +++ b/bin/mbus-tcp-scan.c @@ -26,27 +26,44 @@ main(int argc, char **argv) { mbus_handle *handle; char *host; - int port, address; + int port, address, debug = 0; - if (argc != 3) + if (argc == 3) { - printf("usage: %s host port\n", argv[0]); + host = argv[1]; + port = atoi(argv[2]); + } + else if (argc == 4 && strcmp(argv[1], "-d") == 0) + { + debug = 1; + host = argv[2]; + port = atoi(argv[3]); + } + else + { + printf("usage: %s [-d] host port\n", argv[0]); return 0; } - - host = argv[1]; - port = atoi(argv[2]); - + if ((handle = mbus_connect_tcp(host, port)) == NULL) { printf("Scan failed: Could not setup connection to M-bus gateway: %s\n", mbus_error_str()); return 1; } + if (debug) + printf("Scanning primary addresses:\n"); + for (address = 0; address < 254; address++) { mbus_frame reply; + if (debug) + { + printf("%d ", address); + fflush(stdout); + } + if (mbus_send_ping_frame(handle, address) == -1) { printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str()); @@ -60,6 +77,9 @@ main(int argc, char **argv) if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) { + if (debug) + printf("\n"); + printf("Found a M-Bus device at address %d\n", address); } } From 7d482e47f72c9c92389de47a0f0e3d56caecf13c Mon Sep 17 00:00:00 2001 From: Robert Johansson Date: Sun, 13 May 2012 16:39:48 +0900 Subject: [PATCH 6/6] use the max frame limit 16 also for serial multi-telegram transfers (some devices does not seems to stop reporting 'more data follows', so unless we set a hard limit it will loop forever. so this limit should probably be made a cmd line argument) --- bin/mbus-serial-request-data-multi-reply.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/mbus-serial-request-data-multi-reply.c b/bin/mbus-serial-request-data-multi-reply.c index c6082f5..46bcbe5 100644 --- a/bin/mbus-serial-request-data-multi-reply.c +++ b/bin/mbus-serial-request-data-multi-reply.c @@ -114,8 +114,8 @@ main(int argc, char **argv) } // instead of the send and recv, use this sendrecv function that - // takes care of the possibility of multi-telegram replies - if (mbus_sendrecv_request(handle, address, &reply, -1) == -1) + // takes care of the possibility of multi-telegram replies (limit = 16 frames) + if (mbus_sendrecv_request(handle, address, &reply, 16) == -1) { fprintf(stderr, "Failed to send/receive M-Bus request.\n"); return 1;