diff --git a/bin/mbus-serial-request-data-multi-reply.c b/bin/mbus-serial-request-data-multi-reply.c index 787a651..91a2642 100755 --- a/bin/mbus-serial-request-data-multi-reply.c +++ b/bin/mbus-serial-request-data-multi-reply.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-serial-request-data.c b/bin/mbus-serial-request-data.c index c65e54f..f1eaaf0 100755 --- a/bin/mbus-serial-request-data.c +++ b/bin/mbus-serial-request-data.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-serial-scan-secondary.c b/bin/mbus-serial-scan-secondary.c index a5b6ed2..e85355e 100755 --- a/bin/mbus-serial-scan-secondary.c +++ b/bin/mbus-serial-scan-secondary.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include @@ -90,7 +86,7 @@ main(int argc, char **argv) device = argv[3]; addr_mask = strdup("FFFFFFFFFFFFFFFF"); } - else if (argc == 5 && strcmp(argv[1], "-d") == 0) + else if (argc == 5 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-b") == 0) { baudrate = atoi(argv[3]); device = argv[4]; diff --git a/bin/mbus-serial-scan.c b/bin/mbus-serial-scan.c index 2509e89..f4bae6b 100755 --- a/bin/mbus-serial-scan.c +++ b/bin/mbus-serial-scan.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-serial-select-secondary.c b/bin/mbus-serial-select-secondary.c index ccb16b9..628d45b 100755 --- a/bin/mbus-serial-select-secondary.c +++ b/bin/mbus-serial-select-secondary.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-serial-switch-baudrate.c b/bin/mbus-serial-switch-baudrate.c index 49cc969..b9186c4 100755 --- a/bin/mbus-serial-switch-baudrate.c +++ b/bin/mbus-serial-switch-baudrate.c @@ -11,10 +11,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-tcp-raw-send.c b/bin/mbus-tcp-raw-send.c index 526145e..8cc84f7 100644 --- a/bin/mbus-tcp-raw-send.c +++ b/bin/mbus-tcp-raw-send.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include @@ -30,8 +26,10 @@ main(int argc, char **argv) mbus_handle *handle = NULL; char *host, *addr_str, matching_addr[16], *file = NULL; - int port, address, fd, len, i, result; - u_char raw_buff[4096], buff[4096], *ptr, *endptr; + int port, address, result; + FILE *fp = NULL; + size_t buff_len, len; + u_char raw_buff[4096], buff[4096]; memset((void *)&reply, 0, sizeof(mbus_frame)); memset((void *)&reply_data, 0, sizeof(mbus_frame_data)); @@ -88,7 +86,7 @@ main(int argc, char **argv) if (mbus_connect(handle) == -1) { - fprintf(stderr, "Failed to setup connection to M-bus gateway\n"); + fprintf(stderr, "Failed to setup connection to M-bus gateway\n%s\n", mbus_error_str()); return 1; } @@ -127,41 +125,35 @@ main(int argc, char **argv) // if (file != NULL) { - if ((fd = open(file, O_RDONLY, 0)) == -1) + if ((fp = fopen(file, "r")) == NULL) { - fprintf(stderr, "%s: failed to open '%s'\n", __PRETTY_FUNCTION__, file); + fprintf(stderr, "%s: failed to open '%s'\n", __PRETTY_FUNCTION__, file); return 1; } } else { - fd = 0; // stdin + fp = stdin; } - memset(raw_buff, 0, sizeof(raw_buff)); - len = read(fd, raw_buff, sizeof(raw_buff)); - close(fd); + memset(raw_buff, 0, sizeof(raw_buff)); + len = fread(raw_buff, 1, sizeof(raw_buff), fp); - ptr = 0; - endptr = raw_buff; - for (i = 0; i < sizeof(buff)-1; i++) + if (fp != stdin) { - ptr = endptr; - buff[i] = (u_char)strtol(ptr, (char **)&endptr, 16); - - // abort at non hex value - if (ptr == endptr) - break; + fclose(fp); } + buff_len = mbus_hex2bin(buff,sizeof(buff),raw_buff,sizeof(raw_buff)); + // // attempt to parse the input data // - result = mbus_parse(&request, buff, i); + result = mbus_parse(&request, buff, buff_len); - if (result < 0) - { - fprintf(stderr, "mbus_parse: %s\n", mbus_error_str()); + if (result < 0) + { + fprintf(stderr, "mbus_parse: %s\n", mbus_error_str()); return 1; } else if (result > 0) diff --git a/bin/mbus-tcp-request-data-multi-reply.c b/bin/mbus-tcp-request-data-multi-reply.c index c9e227e..4d932eb 100755 --- a/bin/mbus-tcp-request-data-multi-reply.c +++ b/bin/mbus-tcp-request-data-multi-reply.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-tcp-request-data.c b/bin/mbus-tcp-request-data.c index 2e23c5d..08fbca8 100755 --- a/bin/mbus-tcp-request-data.c +++ b/bin/mbus-tcp-request-data.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-tcp-scan-secondary.c b/bin/mbus-tcp-scan-secondary.c index 55b731f..761d86d 100755 --- a/bin/mbus-tcp-scan-secondary.c +++ b/bin/mbus-tcp-scan-secondary.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-tcp-scan.c b/bin/mbus-tcp-scan.c index 4e72bf5..44c7959 100755 --- a/bin/mbus-tcp-scan.c +++ b/bin/mbus-tcp-scan.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/bin/mbus-tcp-select-secondary.c b/bin/mbus-tcp-select-secondary.c index e295b5b..2970f98 100755 --- a/bin/mbus-tcp-select-secondary.c +++ b/bin/mbus-tcp-select-secondary.c @@ -8,10 +8,6 @@ // //------------------------------------------------------------------------------ -#include -#include -#include -#include #include #include diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index f91d246..0d2645e 100755 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -17,6 +17,7 @@ #include #include +#include #include #define MBUS_ERROR(...) fprintf (stderr, __VA_ARGS__) @@ -1484,6 +1485,38 @@ mbus_disconnect(mbus_handle * handle) return handle->close(handle); } +int +mbus_context_set_option(mbus_handle * handle, mbus_context_option option, long value) +{ + if (handle == NULL) + { + MBUS_ERROR("%s: Invalid M-Bus handle to set option.\n", __PRETTY_FUNCTION__); + return -1; + } + + switch (option) + { + case MBUS_OPTION_MAX_RETRY: + if ((value >= 0) && (value <= 9)) + { + handle->max_retry = value; + return 0; + } + break; + case MBUS_OPTION_PURGE_FIRST_FRAME: + if ((value == MBUS_FRAME_PURGE_NONE) || + (value == MBUS_FRAME_PURGE_M2S) || + (value == MBUS_FRAME_PURGE_S2M)) + { + handle->purge_first_frame = value; + return 0; + } + break; + } + + return -1; // unable to set option +} + int mbus_recv_frame(mbus_handle * handle, mbus_frame *frame) { @@ -2152,3 +2185,50 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask) free(mask); return 0; } + +//------------------------------------------------------------------------------ +// Convert a buffer with hex values into a buffer with binary values. +// - invalid character stops convertion +// - whitespaces will be ignored +//------------------------------------------------------------------------------ +size_t +mbus_hex2bin(u_char * dst, size_t dst_len, const u_char * src, size_t src_len) +{ + size_t i, result = 0; + unsigned long val; + u_char *ptr, *end, buf[3]; + + if (!src || !dst) + { + return 0; + } + + memset(buf, 0, sizeof(buf)); + memset(dst, 0, dst_len); + + for (i = 0; i+1 < src_len; i++) + { + // ignore whitespace + if (isspace(src[i])) + continue; + + buf[0] = src[i]; + buf[1] = src[++i]; + + end = buf; + ptr = end; + val = strtoul(ptr, (char **)&end, 16); + + // abort at non hex value + if (ptr == end) + break; + + // abort at end of buffer + if (result >= dst_len) + break; + + dst[result++] = (u_char) val; + } + + return result; +} diff --git a/mbus/mbus-protocol-aux.h b/mbus/mbus-protocol-aux.h index 2f18b98..c219ab2 100755 --- a/mbus/mbus-protocol-aux.h +++ b/mbus/mbus-protocol-aux.h @@ -24,6 +24,8 @@ * or * mbus_handle = mbus_context_tcp(host, port); * + * mbus_context_set_option(mbus_handle,option,value); // optional + * * mbus_connect(mbus_handle); * * ... @@ -140,6 +142,15 @@ typedef struct _mbus_record { char *quantity; /**< Quantity type (e.g. Energy) */ } mbus_record; +/** + * MBus handle option type + */ +enum _mbus_context_option { + MBUS_OPTION_MAX_RETRY, + MBUS_OPTION_PURGE_FIRST_FRAME +}; + +typedef enum _mbus_context_option mbus_context_option; /** * Event callback functions @@ -198,6 +209,17 @@ int mbus_connect(mbus_handle * handle); */ int mbus_disconnect(mbus_handle * handle); +/** + * Set option of a M-Bus context. + * + * @param handle Initialized handle + * @param option option to set + * @param value value to set + * + * @return Zero when successful. + */ +int mbus_context_set_option(mbus_handle * handle, mbus_context_option option, long value); + /** * Receives a frame using "unified" handle * @@ -437,6 +459,18 @@ char * mbus_frame_data_xml_normalized(mbus_frame_data *data); */ int mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask); +/** + * Convert a buffer with hex values into a buffer with binary values. + * + * @param dst destination buffer with binary values + * @param dst_len byte count of destination buffer + * @param src source buffer with hex values + * @param src_len byte count of source buffer + * + * @return byte count of successful converted values + */ +size_t mbus_hex2bin(u_char * dst, size_t dst_len, const u_char * src, size_t src_len); + #ifdef __cplusplus } #endif diff --git a/mbus/mbus-protocol.h b/mbus/mbus-protocol.h index 3a9c99a..bd6192f 100755 --- a/mbus/mbus-protocol.h +++ b/mbus/mbus-protocol.h @@ -19,7 +19,6 @@ #define _MBUS_PROTOCOL_H_ #include -#include #include #ifdef __cplusplus diff --git a/test/mbus_parse.c b/test/mbus_parse.c index f55eb5e..886cc28 100644 --- a/test/mbus_parse.c +++ b/test/mbus_parse.c @@ -8,23 +8,17 @@ // //------------------------------------------------------------------------------ -#include - #include -#include #include -#include -#include #include -#include -#include #include int main(int argc, char *argv[]) { - int fd, len; + FILE *fp = NULL; + size_t buff_len, len; u_char buf[1024]; mbus_frame reply; mbus_frame_data frame_data; @@ -36,16 +30,15 @@ main(int argc, char *argv[]) return 1; } - if ((fd = open(argv[1], O_RDONLY, 0)) == -1) + if ((fp = fopen(argv[1], "r")) == NULL) { - fprintf(stderr, "%s: failed to open '%s'", argv[0], argv[1]); + fprintf(stderr, "%s: failed to open '%s'\n", argv[0], argv[1]); return 1; } memset(buf, 0, sizeof(buf)); - len = read(fd, buf, sizeof(buf)); - - close(fd); + len = fread(buf, 1, sizeof(buf), fp); + fclose(fp); memset(&reply, 0, sizeof(reply)); memset(&frame_data, 0, sizeof(frame_data)); diff --git a/test/mbus_parse_hex.c b/test/mbus_parse_hex.c index 75f819d..fefdd15 100644 --- a/test/mbus_parse_hex.c +++ b/test/mbus_parse_hex.c @@ -8,24 +8,19 @@ // //------------------------------------------------------------------------------ -#include - #include -#include #include -#include -#include #include -#include -#include #include int main(int argc, char *argv[]) { - int fd, len, i, result; - u_char raw_buff[4096], buff[4096], *ptr, *endptr; + FILE *fp = NULL; + size_t buff_len, len; + int result; + u_char raw_buff[4096], buff[4096]; mbus_frame reply; mbus_frame_data frame_data; char *xml_result = NULL; @@ -35,38 +30,25 @@ main(int argc, char *argv[]) fprintf(stderr, "usage: %s hex-file\n", argv[0]); return 1; } - - if ((fd = open(argv[1], O_RDONLY, 0)) == -1) + + if ((fp = fopen(argv[1], "r")) == NULL) { - fprintf(stderr, "%s: failed to open '%s'", argv[0], argv[1]); + fprintf(stderr, "%s: failed to open '%s'\n", argv[0], argv[1]); return 1; } - - memset(raw_buff, 0, sizeof(raw_buff)); - len = read(fd, raw_buff, sizeof(raw_buff)); - close(fd); - - i = 0; - ptr = 0; - endptr = raw_buff; - while (i < sizeof(buff)-1) - { - ptr = endptr; - buff[i] = (u_char)strtol(ptr, (char **)&endptr, 16); - - // abort at non hex value - if (ptr == endptr) - break; - - i++; - } + + memset(raw_buff, 0, sizeof(raw_buff)); + len = fread(raw_buff, 1, sizeof(raw_buff), fp); + fclose(fp); + + buff_len = mbus_hex2bin(buff,sizeof(buff),raw_buff,sizeof(raw_buff)); memset(&reply, 0, sizeof(reply)); memset(&frame_data, 0, sizeof(frame_data)); //mbus_parse_set_debug(1); - result = mbus_parse(&reply, buff, i); + result = mbus_parse(&reply, buff, buff_len); if (result < 0) {