From 166b93a1b1036c7fc16a62e08d9e7d1c96473e58 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Wed, 25 Jul 2012 00:09:11 +0200 Subject: [PATCH 1/4] Added product name mapping for Kamstrup 382 --- mbus/mbus-protocol.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index ffbb059..31b67ab 100755 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -897,6 +897,9 @@ mbus_data_product_name(mbus_data_variable_header *header) { switch (header->version) { + case 0x01: + strcpy(buff,"Kamstrup 382 (6850-005)"); + break; case 0x08: strcpy(buff,"Kamstrup Multical 601"); break; From d2608d5de76aaf47f3f661ca2e9a5940b0305099 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 1 Sep 2012 22:14:21 +0200 Subject: [PATCH 2/4] add allocation error handling --- bin/mbus-serial-scan-secondary.c | 13 ++++++++++++- bin/mbus-serial-select-secondary.c | 8 +++++++- bin/mbus-tcp-scan-secondary.c | 11 ++++++++--- bin/mbus-tcp-select-secondary.c | 11 ++++++++--- mbus/mbus-protocol-aux.c | 30 +++++++++++++++++++++++++----- 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/bin/mbus-serial-scan-secondary.c b/bin/mbus-serial-scan-secondary.c index c382406..0fcc544 100755 --- a/bin/mbus-serial-scan-secondary.c +++ b/bin/mbus-serial-scan-secondary.c @@ -25,7 +25,7 @@ static int debug = 0; int main(int argc, char **argv) { - char *device, *addr_mask; + char *device, *addr_mask = NULL; int baudrate = 9600; mbus_handle *handle = NULL; mbus_frame *frame = NULL, reply; @@ -95,28 +95,38 @@ main(int argc, char **argv) mbus_register_send_event(&mbus_dump_send_event); mbus_register_recv_event(&mbus_dump_recv_event); } + + if (addr_mask == NULL) + { + fprintf(stderr, "Failed to allocate address mask.\n"); + return 1; + } if (strlen(addr_mask) != 16) { fprintf(stderr, "Misformatted secondary address mask. Must be 16 character HEX number.\n"); + free(addr_mask); return 1; } if ((handle = mbus_context_serial(device)) == NULL) { fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); + free(addr_mask); return 1; } if (mbus_connect(handle) == -1) { printf("Failed to setup connection to M-bus gateway\n"); + free(addr_mask); return 1; } if (mbus_serial_set_baudrate(handle, baudrate) == -1) { fprintf(stderr, "Failed to set baud rate.\n"); + free(addr_mask); return 1; } @@ -126,6 +136,7 @@ main(int argc, char **argv) if (frame == NULL) { fprintf(stderr, "Failed to allocate mbus frame.\n"); + free(addr_mask); return 1; } diff --git a/bin/mbus-serial-select-secondary.c b/bin/mbus-serial-select-secondary.c index 66b4d4b..ccb16b9 100755 --- a/bin/mbus-serial-select-secondary.c +++ b/bin/mbus-serial-select-secondary.c @@ -26,7 +26,7 @@ main(int argc, char **argv) { mbus_handle *handle; mbus_frame reply; - char *device, *addr; + char *device, *addr = NULL; int ret, baudrate = 9600; if (argc == 3) @@ -46,6 +46,12 @@ main(int argc, char **argv) fprintf(stderr, " optional flag -b for selecting baudrate\n"); return 0; } + + if (addr == NULL) + { + fprintf(stderr, "Failed to allocate address.\n"); + return 1; + } if (strlen(addr) != 16) { diff --git a/bin/mbus-tcp-scan-secondary.c b/bin/mbus-tcp-scan-secondary.c index 570a617..71f532b 100755 --- a/bin/mbus-tcp-scan-secondary.c +++ b/bin/mbus-tcp-scan-secondary.c @@ -25,7 +25,7 @@ static int debug = 0; int main(int argc, char **argv) { - char *host, *addr_mask; + char *host, *addr_mask = NULL; int port; mbus_handle *handle = NULL; mbus_frame *frame = NULL, reply; @@ -50,6 +50,12 @@ main(int argc, char **argv) { addr_mask = strdup("FFFFFFFFFFFFFFFF"); } + + if (addr_mask == NULL) + { + fprintf(stderr, "Failed to allocate address mask.\n"); + return 1; + } if (strlen(addr_mask) != 16) { @@ -97,8 +103,7 @@ main(int argc, char **argv) if (mbus_send_frame(handle, frame) == -1) { - fprintf(stderr, "Failed to send SND_NKE #2.\n"); - mbus_frame_free(frame); + free(addr_mask); return 1; } diff --git a/bin/mbus-tcp-select-secondary.c b/bin/mbus-tcp-select-secondary.c index 5795d83..e295b5b 100755 --- a/bin/mbus-tcp-select-secondary.c +++ b/bin/mbus-tcp-select-secondary.c @@ -26,7 +26,7 @@ main(int argc, char **argv) { mbus_handle *handle; mbus_frame reply; - char *host, *addr; + char *host, *addr = NULL; int port, ret; if (argc != 4) @@ -37,9 +37,14 @@ main(int argc, char **argv) host = argv[1]; port = atoi(argv[2]); - addr = strdup(argv[3]); + + if ((addr = strdup(argv[3])) == NULL) + { + fprintf(stderr, "Failed to allocate address.\n"); + return 1; + } - if (strlen(argv[3]) != 16) + if (strlen(addr) != 16) { printf("Misformatted secondary address. Must be 16 character HEX number.\n"); return 1; diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index ef607ae..f6c3bf2 100755 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -791,7 +791,11 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real, switch (record->drh.dib.dif & 0x0F) { case 0x00: /* no data */ - *value_out_str = (char*) malloc(1); + if ((*value_out_str = (char*) malloc(1)) == NULL) + { + MBUS_ERROR("Unable to allocate memory"); + return -1; + } *value_out_str_size = 0; result = 0; break; @@ -806,7 +810,11 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real, if (vif == 0x6C) { mbus_data_tm_decode(&time, record->data, 2); - *value_out_str = (char*) malloc(11); + if ((*value_out_str = (char*) malloc(11)) == NULL) + { + MBUS_ERROR("Unable to allocate memory"); + return -1; + } *value_out_str_size = snprintf(*value_out_str, 11, "%04d-%02d-%02d", (time.tm_year + 2000), (time.tm_mon + 1), @@ -834,7 +842,11 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real, ((record->drh.vib.vif == 0xFD) && (vife == 0x70))) { mbus_data_tm_decode(&time, record->data, 4); - *value_out_str = (char*) malloc(20); + if ((*value_out_str = (char*) malloc(20)) == NULL) + { + MBUS_ERROR("Unable to allocate memory"); + return -1; + } *value_out_str_size = snprintf(*value_out_str, 20, "%04d-%02d-%02dT%02d:%02d:%02d", (time.tm_year + 2000), (time.tm_mon + 1), @@ -888,7 +900,11 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real, case 0x0D: /* variable length */ { if (record->data_len <= 0xBF) { - *value_out_str = (char*) malloc(record->data_len + 1); + if ((*value_out_str = (char*) malloc(record->data_len + 1)) == NULL) + { + MBUS_ERROR("Unable to allocate memory"); + return -1; + } *value_out_str_size = record->data_len; mbus_data_str_decode((u_char*)(*value_out_str), record->data, record->data_len); result = 0; @@ -905,7 +921,11 @@ int mbus_variable_value_decode(mbus_data_record *record, double *value_out_real, break; case 0x0F: /* Special functions */ - *value_out_str = (char*) malloc(3 * record->data_len + 1); + if ((*value_out_str = (char*) malloc(3 * record->data_len + 1)) == NULL) + { + MBUS_ERROR("Unable to allocate memory"); + return -1; + } *value_out_str_size = 3 * record->data_len; mbus_data_bin_decode((u_char*)(*value_out_str), record->data, record->data_len, (3 * record->data_len + 1)); result = 0; From 1a538e73aae15ed308dc39663ec40a64bd2714ce Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 1 Sep 2012 22:51:44 +0200 Subject: [PATCH 3/4] New parameter for mbus_send_ping_frame to purge response --- bin/mbus-serial-scan.c | 2 +- bin/mbus-tcp-scan.c | 2 +- mbus/mbus-protocol-aux.c | 14 ++++++++++---- mbus/mbus-protocol-aux.h | 7 ++++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/bin/mbus-serial-scan.c b/bin/mbus-serial-scan.c index a2c14c9..2509e89 100755 --- a/bin/mbus-serial-scan.c +++ b/bin/mbus-serial-scan.c @@ -95,7 +95,7 @@ main(int argc, char **argv) fflush(stdout); } - if (mbus_send_ping_frame(handle, address) == -1) + if (mbus_send_ping_frame(handle, address, 0) == -1) { printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str()); return 1; diff --git a/bin/mbus-tcp-scan.c b/bin/mbus-tcp-scan.c index 10d4165..4e72bf5 100755 --- a/bin/mbus-tcp-scan.c +++ b/bin/mbus-tcp-scan.c @@ -78,7 +78,7 @@ main(int argc, char **argv) fflush(stdout); } - if (mbus_send_ping_frame(handle, address) == -1) + if (mbus_send_ping_frame(handle, address, 0) == -1) { printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str()); return 1; diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index f6c3bf2..41fd3b0 100755 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -1786,10 +1786,10 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m //------------------------------------------------------------------------------ -// send a data request packet to from master to slave +// send a data request packet to from master to slave and optional purge response //------------------------------------------------------------------------------ int -mbus_send_ping_frame(mbus_handle *handle, int address) +mbus_send_ping_frame(mbus_handle *handle, int address, char purge_response) { int retval = 0; mbus_frame *frame; @@ -1808,8 +1808,14 @@ mbus_send_ping_frame(mbus_handle *handle, int address) if (mbus_send_frame(handle, frame) == -1) { MBUS_ERROR("%s: failed to send mbus frame.\n", __PRETTY_FUNCTION__); - retval = -1; - } + mbus_frame_free(frame); + return -1; + } + + if (purge_response) + { + mbus_purge_frames(handle); + } mbus_frame_free(frame); return retval; diff --git a/mbus/mbus-protocol-aux.h b/mbus/mbus-protocol-aux.h index f5bf56b..5b63188 100755 --- a/mbus/mbus-protocol-aux.h +++ b/mbus/mbus-protocol-aux.h @@ -265,12 +265,13 @@ int mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, i /** * Sends ping frame to given slave using "unified" handle * - * @param handle Initialized handle - * @param address Address (0-255) + * @param handle Initialized handle + * @param address Address (0-255) + * @param purge_response Response flag (=0 don't receive response, >0 purge response) * * @return Zero when successful. */ -int mbus_send_ping_frame(mbus_handle *handle, int address); +int mbus_send_ping_frame(mbus_handle *handle, int address, char purge_response); /** * Select slave by secondary address using "unified" handle From 501b105d01079a76adf3e93a6d55f152d337f43e Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 1 Sep 2012 22:52:55 +0200 Subject: [PATCH 4/4] unify m-bus slave init --- bin/mbus-serial-request-data-multi-reply.c | 72 +++++++++------------- bin/mbus-serial-scan-secondary.c | 55 ++++++++++------- bin/mbus-tcp-request-data-multi-reply.c | 20 +----- bin/mbus-tcp-scan-secondary.c | 40 +++++------- 4 files changed, 79 insertions(+), 108 deletions(-) diff --git a/bin/mbus-serial-request-data-multi-reply.c b/bin/mbus-serial-request-data-multi-reply.c index dcdf390..7d9b04b 100755 --- a/bin/mbus-serial-request-data-multi-reply.c +++ b/bin/mbus-serial-request-data-multi-reply.c @@ -19,6 +19,35 @@ static int debug = 0; +// +// init slave to get really the beginning of the records +// +int +init_slaves(mbus_handle *handle) +{ + if (debug) + printf("%s: debug: sending init frame #1\n", __PRETTY_FUNCTION__); + + if (mbus_send_ping_frame(handle, MBUS_ADDRESS_NETWORK_LAYER, 1) == -1) + { + return 0; + } + + // + // resend SND_NKE, maybe the first get lost + // + + if (debug) + printf("%s: debug: sending init frame #2\n", __PRETTY_FUNCTION__); + + if (mbus_send_ping_frame(handle, MBUS_ADDRESS_NETWORK_LAYER, 1) == -1) + { + return 0; + } + + return 1; +} + //------------------------------------------------------------------------------ // Scan for devices using secondary addressing. //------------------------------------------------------------------------------ @@ -91,51 +120,10 @@ main(int argc, char **argv) return 1; } - // - // init slave to get really the beginning of the records - // - - frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT); - - if (frame == NULL) + if (init_slaves(handle) == 0) { - fprintf(stderr, "Failed to allocate mbus frame.\n"); return 1; } - - frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; - frame->address = MBUS_ADDRESS_NETWORK_LAYER; - - if (debug) - printf("%s: debug: sending init frame #1\n", __PRETTY_FUNCTION__); - - if (mbus_send_frame(handle, frame) == -1) - { - fprintf(stderr, "Failed to send mbus frame.\n"); - mbus_frame_free(frame); - return 1; - } - - mbus_purge_frames(handle); - - // - // resend SND_NKE, maybe the first get lost - // - - frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; - frame->address = MBUS_ADDRESS_NETWORK_LAYER; - - if (debug) - printf("%s: debug: sending init frame #2\n", __PRETTY_FUNCTION__); - - if (mbus_send_frame(handle, frame) == -1) - { - fprintf(stderr, "Failed to send mbus frame.\n"); - mbus_frame_free(frame); - return 1; - } - - mbus_purge_frames(handle); if (strlen(addr_str) == 16) { diff --git a/bin/mbus-serial-scan-secondary.c b/bin/mbus-serial-scan-secondary.c index 0fcc544..a5b6ed2 100755 --- a/bin/mbus-serial-scan-secondary.c +++ b/bin/mbus-serial-scan-secondary.c @@ -19,6 +19,36 @@ static int debug = 0; +// +// init slave to get really the beginning of the records +// +int +init_slaves(mbus_handle *handle) +{ + if (debug) + printf("%s: debug: sending init frame #1\n", __PRETTY_FUNCTION__); + + if (mbus_send_ping_frame(handle, MBUS_ADDRESS_NETWORK_LAYER, 1) == -1) + { + return 0; + } + + // + // resend SND_NKE, maybe the first get lost + // + + if (debug) + printf("%s: debug: sending init frame #2\n", __PRETTY_FUNCTION__); + + if (mbus_send_ping_frame(handle, MBUS_ADDRESS_BROADCAST_NOREPLY, 1) == -1) + { + return 0; + } + + return 1; +} + + //------------------------------------------------------------------------------ // Scan for devices using secondary addressing. //------------------------------------------------------------------------------ @@ -140,33 +170,12 @@ main(int argc, char **argv) return 1; } - // - // init slaves - // - frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; - frame->address = MBUS_ADDRESS_NETWORK_LAYER; - - if (mbus_send_frame(handle, frame) == -1) + if (init_slaves(handle) == 0) { - fprintf(stderr, "Failed to send SND_NKE #1.\n"); - mbus_frame_free(frame); + free(addr_mask); return 1; } - (void) mbus_recv_frame(handle, &reply); - - frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; - frame->address = MBUS_ADDRESS_BROADCAST_NOREPLY; - - if (mbus_send_frame(handle, frame) == -1) - { - fprintf(stderr, "Failed to send SND_NKE #2.\n"); - mbus_frame_free(frame); - return 1; - } - - (void) mbus_recv_frame(handle, &reply); - mbus_scan_2nd_address_range(handle, 0, addr_mask); mbus_disconnect(handle); diff --git a/bin/mbus-tcp-request-data-multi-reply.c b/bin/mbus-tcp-request-data-multi-reply.c index 7d421f0..c9e227e 100755 --- a/bin/mbus-tcp-request-data-multi-reply.c +++ b/bin/mbus-tcp-request-data-multi-reply.c @@ -77,29 +77,13 @@ main(int argc, char **argv) // // init slave to get really the beginning of the records // - - frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT); - - if (frame == NULL) - { - fprintf(stderr, "Failed to allocate mbus frame.\n"); - return 1; - } - - frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; - frame->address = MBUS_ADDRESS_BROADCAST_NOREPLY; - if (debug) printf("%s: debug: sending init frame\n", __PRETTY_FUNCTION__); - - if (mbus_send_frame(handle, frame) == -1) + + if (mbus_send_ping_frame(handle, MBUS_ADDRESS_BROADCAST_NOREPLY, 1) == -1) { - fprintf(stderr, "Failed to send mbus frame.\n"); - mbus_frame_free(frame); return 1; } - - mbus_recv_frame(handle, &reply); if (strlen(addr_str) == 16) { diff --git a/bin/mbus-tcp-scan-secondary.c b/bin/mbus-tcp-scan-secondary.c index 71f532b..55b731f 100755 --- a/bin/mbus-tcp-scan-secondary.c +++ b/bin/mbus-tcp-scan-secondary.c @@ -74,40 +74,30 @@ main(int argc, char **argv) fprintf(stderr, "Failed to setup connection to M-bus gateway\n"); return 1; } - - frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT); - - if (frame == NULL) - { - fprintf(stderr, "Failed to allocate mbus frame.\n"); - return 1; - } // // init slaves // - frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; - frame->address = MBUS_ADDRESS_NETWORK_LAYER; - - if (mbus_send_frame(handle, frame) == -1) - { - fprintf(stderr, "Failed to send SND_NKE #1.\n"); - mbus_frame_free(frame); - return 1; - } - - (void) mbus_recv_frame(handle, &reply); - - frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; - frame->address = MBUS_ADDRESS_BROADCAST_NOREPLY; - - if (mbus_send_frame(handle, frame) == -1) + if (debug) + printf("%s: debug: sending init frame #1\n", __PRETTY_FUNCTION__); + + if (mbus_send_ping_frame(handle, MBUS_ADDRESS_NETWORK_LAYER, 1) == -1) { free(addr_mask); return 1; } - (void) mbus_recv_frame(handle, &reply); + // + // resend SND_NKE, maybe the first get lost + // + if (debug) + printf("%s: debug: sending init frame #2\n", __PRETTY_FUNCTION__); + + if (mbus_send_ping_frame(handle, MBUS_ADDRESS_BROADCAST_NOREPLY, 1) == -1) + { + free(addr_mask); + return 1; + } mbus_scan_2nd_address_range(handle, 0, addr_mask);