diff --git a/bin/Makefile.am b/bin/Makefile.am index 82b8446..e3cb10b 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -17,7 +17,7 @@ bin_PROGRAMS = mbus-tcp-scan mbus-tcp-request-data mbus-tcp-request-data-multi mbus-tcp-select-secondary mbus-tcp-scan-secondary \ mbus-serial-scan mbus-serial-request-data mbus-serial-request-data-multi-reply \ mbus-serial-select-secondary mbus-serial-scan-secondary \ - mbus-serial-switch-baudrate mbus-tcp-raw-send + mbus-serial-switch-baudrate mbus-tcp-raw-send mbus-tcp-application-reset # tcp mbus_tcp_scan_LDFLAGS = -L$(top_builddir)/mbus @@ -44,6 +44,9 @@ mbus_tcp_raw_send_LDFLAGS = -L$(top_builddir)/mbus mbus_tcp_raw_send_LDADD = -lmbus -lm mbus_tcp_raw_send_SOURCES = mbus-tcp-raw-send.c +mbus_tcp_application_reset_LDFLAGS = -L$(top_builddir)/mbus +mbus_tcp_application_reset_LDADD = -lmbus -lm +mbus_tcp_application_reset_SOURCES = mbus-tcp-application-reset.c # serial mbus_serial_scan_LDFLAGS = -L$(top_builddir)/mbus diff --git a/bin/libmbus.pod b/bin/libmbus.pod index 634e4ea..c35c344 100644 --- a/bin/libmbus.pod +++ b/bin/libmbus.pod @@ -10,9 +10,9 @@ the communication with M-Bus devices. B [-b BAUDRATE] device address target-baudrate -B [-d] [-b BAUDRATE] device +B [-d] [-b BAUDRATE] [-r RETRIES] device -B [-d] host port +B [-d] [-r RETRIES] host port B [-d] [-b BAUDRATE] device [address-mask] @@ -72,6 +72,13 @@ Note that your MBus gateway and/or MBus device will most likely support only a subset of these. The most commonlu used/supported rates are probably 9600, 2400 and 300. +=item B<-r> I + +Maximum retransmissions. In case a MBus device doesn't reply to a request or +the response is erroneous, the MBus master can send a retransmissions. + +libmbus supports the following range of retransmission: 0 until 9 + =item B<-d> Enable debugging messages. diff --git a/bin/mbus-serial-request-data-multi-reply.c b/bin/mbus-serial-request-data-multi-reply.c index d0c06d1..e9c74a8 100755 --- a/bin/mbus-serial-request-data-multi-reply.c +++ b/bin/mbus-serial-request-data-multi-reply.c @@ -106,13 +106,13 @@ main(int argc, char **argv) if (mbus_connect(handle) == -1) { - printf("Failed to setup connection to M-bus gateway\n"); + fprintf(stderr,"Failed to setup connection to M-bus gateway\n"); return 1; } if (mbus_serial_set_baudrate(handle, baudrate) == -1) { - printf("Failed to set baud rate.\n"); + fprintf(stderr,"Failed to set baud rate.\n"); return 1; } diff --git a/bin/mbus-serial-request-data.c b/bin/mbus-serial-request-data.c index 74dacf3..a250781 100755 --- a/bin/mbus-serial-request-data.c +++ b/bin/mbus-serial-request-data.c @@ -77,13 +77,13 @@ main(int argc, char **argv) if (mbus_connect(handle) == -1) { - printf("Failed to setup connection to M-bus gateway\n"); + fprintf(stderr,"Failed to setup connection to M-bus gateway\n"); return 1; } if (mbus_serial_set_baudrate(handle, baudrate) == -1) { - printf("Failed to set baud rate.\n"); + fprintf(stderr,"Failed to set baud rate.\n"); return 1; } diff --git a/bin/mbus-serial-scan-secondary.c b/bin/mbus-serial-scan-secondary.c index b382f4a..e4ae295 100755 --- a/bin/mbus-serial-scan-secondary.c +++ b/bin/mbus-serial-scan-secondary.c @@ -144,7 +144,7 @@ main(int argc, char **argv) if (mbus_connect(handle) == -1) { - printf("Failed to setup connection to M-bus gateway\n"); + fprintf(stderr,"Failed to setup connection to M-bus gateway\n"); free(addr_mask); return 1; } diff --git a/bin/mbus-serial-scan.c b/bin/mbus-serial-scan.c index 29eaa2b..ad06cdd 100755 --- a/bin/mbus-serial-scan.c +++ b/bin/mbus-serial-scan.c @@ -15,6 +15,37 @@ static int debug = 0; +int ping_address(mbus_handle *handle, mbus_frame *reply, int address) +{ + int i, ret = MBUS_RECV_RESULT_ERROR; + + memset((void *)reply, 0, sizeof(mbus_frame)); + + for (i = 0; i <= handle->max_retry; i++) + { + if (debug) + { + printf("%d ", address); + fflush(stdout); + } + + if (mbus_send_ping_frame(handle, address, 0) == -1) + { + fprintf(stderr,"Scan failed. Could not send ping frame: %s\n", mbus_error_str()); + return MBUS_RECV_RESULT_ERROR; + } + + ret = mbus_recv_frame(handle, reply); + + if (ret != MBUS_RECV_RESULT_TIMEOUT) + { + return ret; + } + } + + return ret; +} + //------------------------------------------------------------------------------ // Primary addressing scanning of mbus devices. //------------------------------------------------------------------------------ @@ -23,7 +54,7 @@ main(int argc, char **argv) { mbus_handle *handle; char *device; - int address, baudrate = 9600; + int address, baudrate = 9600, retries = 0; int ret; if (argc == 2) @@ -40,15 +71,39 @@ main(int argc, char **argv) baudrate = atoi(argv[2]); device = argv[3]; } + else if (argc == 4 && strcmp(argv[1], "-r") == 0) + { + retries = 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 if (argc == 5 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-r") == 0) + { + debug = 1; + retries = atoi(argv[3]); + device = argv[4]; + } + else if (argc == 6 && strcmp(argv[1], "-b") == 0 && strcmp(argv[3], "-r") == 0) + { + baudrate = atoi(argv[2]); + retries = atoi(argv[4]); + device = argv[5]; + } + else if (argc == 7 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-b") == 0 && strcmp(argv[4], "-r") == 0) + { + debug = 1; + baudrate = atoi(argv[3]); + retries = atoi(argv[5]); + device = argv[6]; + } else { - fprintf(stderr, "usage: %s [-d] [-b BAUDRATE] device\n", argv[0]); + fprintf(stderr,"usage: %s [-d] [-b BAUDRATE] [-r RETRIES] device\n", argv[0]); return 0; } @@ -60,19 +115,25 @@ main(int argc, char **argv) if ((handle = mbus_context_serial(device)) == NULL) { - fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); + fprintf(stderr,"Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } if (mbus_connect(handle) == -1) { - printf("Failed to setup connection to M-bus gateway\n"); + fprintf(stderr,"Scan failed: Could not setup connection to M-bus gateway: %s\n", mbus_error_str()); + return 1; + } + + if (mbus_context_set_option(handle, MBUS_OPTION_MAX_RETRY, retries) == -1) + { + fprintf(stderr,"Failed to set retry count\n"); return 1; } if (mbus_serial_set_baudrate(handle, baudrate) == -1) { - printf("Failed to set baud rate.\n"); + fprintf(stderr,"Failed to set baud rate.\n"); return 1; } @@ -83,30 +144,13 @@ main(int argc, char **argv) { mbus_frame reply; - memset((void *)&reply, 0, sizeof(mbus_frame)); - - if (debug) - { - printf("%d ", address); - fflush(stdout); - } - - if (mbus_send_ping_frame(handle, address, 0) == -1) - { - printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str()); - return 1; - } + ret = ping_address(handle, &reply, address); - ret = mbus_recv_frame(handle, &reply); - if (ret == MBUS_RECV_RESULT_TIMEOUT) { continue; } - if (debug) - printf("\n"); - if (ret == MBUS_RECV_RESULT_INVALID) { /* check for more data (collision) */ @@ -121,10 +165,9 @@ main(int argc, char **argv) if (mbus_purge_frames(handle)) { printf("Collision at address %d\n", address); - continue; } - + printf("Found a M-Bus device at address %d\n", address); } } diff --git a/bin/mbus-serial-select-secondary.c b/bin/mbus-serial-select-secondary.c index 87f5b80..343a22a 100755 --- a/bin/mbus-serial-select-secondary.c +++ b/bin/mbus-serial-select-secondary.c @@ -51,7 +51,7 @@ main(int argc, char **argv) if (mbus_is_secondary_address(addr) == 0) { - printf("Misformatted secondary address. Must be 16 character HEX number.\n"); + fprintf(stderr,"Misformatted secondary address. Must be 16 character HEX number.\n"); return 1; } @@ -63,19 +63,19 @@ main(int argc, char **argv) if (mbus_connect(handle) == -1) { - printf("Failed to setup connection to M-bus gateway\n"); + fprintf(stderr,"Failed to setup connection to M-bus gateway\n"); return 1; } if (mbus_serial_set_baudrate(handle, baudrate) == -1) { - printf("Failed to set baud rate.\n"); + fprintf(stderr,"Failed to set baud rate.\n"); return 1; } if (mbus_send_select_frame(handle, addr) == -1) { - printf("Failed to send selection frame: %s\n", mbus_error_str()); + fprintf(stderr,"Failed to send selection frame: %s\n", mbus_error_str()); return 1; } @@ -83,13 +83,13 @@ main(int argc, char **argv) if (ret == MBUS_RECV_RESULT_TIMEOUT) { - printf("No reply from device with secondary address %s: %s\n", argv[2], mbus_error_str()); + fprintf(stderr,"No reply from device with secondary address %s: %s\n", argv[2], mbus_error_str()); return 1; } if (ret == MBUS_RECV_RESULT_INVALID) { - printf("Invalid reply from %s: The address address probably match more than one device: %s\n", argv[2], mbus_error_str()); + fprintf(stderr,"Invalid reply from %s: The address address probably match more than one device: %s\n", argv[2], mbus_error_str()); return 1; } @@ -97,13 +97,13 @@ main(int argc, char **argv) { if (mbus_send_request_frame(handle, MBUS_ADDRESS_NETWORK_LAYER) == -1) { - printf("Failed to send request to selected secondary device: %s\n", mbus_error_str()); + fprintf(stderr,"Failed to send request to selected secondary device: %s\n", mbus_error_str()); return 1; } if (mbus_recv_frame(handle, &reply) != MBUS_RECV_RESULT_OK) { - printf("Failed to recieve reply from selected secondary device: %s\n", mbus_error_str()); + fprintf(stderr,"Failed to recieve reply from selected secondary device: %s\n", mbus_error_str()); return 1; } @@ -115,7 +115,7 @@ main(int argc, char **argv) } else { - printf("Unknown reply:\n"); + fprintf(stderr,"Unknown reply:\n"); mbus_frame_print(&reply); } diff --git a/bin/mbus-serial-switch-baudrate.c b/bin/mbus-serial-switch-baudrate.c index b9186c4..c5c4849 100755 --- a/bin/mbus-serial-switch-baudrate.c +++ b/bin/mbus-serial-switch-baudrate.c @@ -56,19 +56,19 @@ main(int argc, char **argv) if (mbus_connect(handle) == -1) { - printf("Failed to setup connection to M-bus gateway\n"); + fprintf(stderr,"Failed to setup connection to M-bus gateway\n"); return 1; } if (mbus_serial_set_baudrate(handle, source_baudrate) == -1) { - printf("Failed to set baud rate.\n"); + fprintf(stderr,"Failed to set baud rate.\n"); return 1; } if (mbus_send_switch_baudrate_frame(handle, address, target_baudrate) == -1) { - printf("Failed to send switch baudrate frame: %s\n", mbus_error_str()); + fprintf(stderr,"Failed to send switch baudrate frame: %s\n", mbus_error_str()); return 1; } @@ -76,12 +76,12 @@ main(int argc, char **argv) if (ret == MBUS_RECV_RESULT_TIMEOUT) { - printf("No reply from device\n"); + fprintf(stderr,"No reply from device\n"); return 1; } else if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK) { - printf("Unknown reply:\n"); + fprintf(stderr,"Unknown reply:\n"); mbus_frame_print(&reply); } else diff --git a/bin/mbus-tcp-scan.c b/bin/mbus-tcp-scan.c index 31d4341..38ecb75 100755 --- a/bin/mbus-tcp-scan.c +++ b/bin/mbus-tcp-scan.c @@ -13,15 +13,48 @@ #include #include +static int debug = 0; + +int ping_address(mbus_handle *handle, mbus_frame *reply, int address) +{ + int i, ret = MBUS_RECV_RESULT_ERROR; + + memset((void *)reply, 0, sizeof(mbus_frame)); + + for (i = 0; i <= handle->max_retry; i++) + { + if (debug) + { + printf("%d ", address); + fflush(stdout); + } + + if (mbus_send_ping_frame(handle, address, 0) == -1) + { + fprintf(stderr,"Scan failed. Could not send ping frame: %s\n", mbus_error_str()); + return MBUS_RECV_RESULT_ERROR; + } + + ret = mbus_recv_frame(handle, reply); + + if (ret != MBUS_RECV_RESULT_TIMEOUT) + { + return ret; + } + } + + return ret; +} + //------------------------------------------------------------------------------ -// Execution starts here: +// Primary addressing scanning of mbus devices. //------------------------------------------------------------------------------ int main(int argc, char **argv) { mbus_handle *handle; char *host; - int port, address, debug = 0; + int port, address, retries = 0; int ret; if (argc == 3) @@ -35,9 +68,22 @@ main(int argc, char **argv) host = argv[2]; port = atoi(argv[3]); } + else if (argc == 5 && strcmp(argv[1], "-r") == 0) + { + retries = atoi(argv[2]); + host = argv[3]; + port = atoi(argv[4]); + } + else if (argc == 6 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-r") == 0) + { + debug = 1; + retries = atoi(argv[3]); + host = argv[4]; + port = atoi(argv[5]); + } else { - printf("usage: %s [-d] host port\n", argv[0]); + fprintf(stderr,"usage: %s [-d] [-r RETRIES] host port\n", argv[0]); return 0; } @@ -49,13 +95,19 @@ main(int argc, char **argv) if ((handle = mbus_context_tcp(host, port)) == NULL) { - printf("Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str()); + fprintf(stderr,"Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } if (mbus_connect(handle) == -1) { - printf("Scan failed: Could not setup connection to M-bus gateway: %s\n", mbus_error_str()); + fprintf(stderr,"Scan failed: Could not setup connection to M-bus gateway: %s\n", mbus_error_str()); + return 1; + } + + if (mbus_context_set_option(handle, MBUS_OPTION_MAX_RETRY, retries) == -1) + { + fprintf(stderr,"Failed to set retry count\n"); return 1; } @@ -66,30 +118,13 @@ main(int argc, char **argv) { mbus_frame reply; - memset((void *)&reply, 0, sizeof(mbus_frame)); - - if (debug) - { - printf("%d ", address); - fflush(stdout); - } - - if (mbus_send_ping_frame(handle, address, 0) == -1) - { - printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str()); - return 1; - } + ret = ping_address(handle, &reply, address); - ret = mbus_recv_frame(handle, &reply); - if (ret == MBUS_RECV_RESULT_TIMEOUT) { continue; } - if (debug) - printf("\n"); - if (ret == MBUS_RECV_RESULT_INVALID) { /* check for more data (collision) */ diff --git a/bin/mbus-tcp-select-secondary.c b/bin/mbus-tcp-select-secondary.c index 904bd27..5966ff5 100755 --- a/bin/mbus-tcp-select-secondary.c +++ b/bin/mbus-tcp-select-secondary.c @@ -27,7 +27,7 @@ main(int argc, char **argv) if (argc != 4) { - printf("usage: %s host port secondary-mbus-address\n", argv[0]); + fprintf(stderr,"usage: %s host port secondary-mbus-address\n", argv[0]); return 0; } @@ -42,7 +42,7 @@ main(int argc, char **argv) if (mbus_is_secondary_address(addr) == 0) { - printf("Misformatted secondary address. Must be 16 character HEX number.\n"); + fprintf(stderr,"Misformatted secondary address. Must be 16 character HEX number.\n"); return 1; } @@ -60,7 +60,7 @@ main(int argc, char **argv) if (mbus_send_select_frame(handle, addr) == -1) { - printf("Failed to send selection frame: %s\n", mbus_error_str()); + fprintf(stderr,"Failed to send selection frame: %s\n", mbus_error_str()); return 1; } @@ -68,13 +68,13 @@ main(int argc, char **argv) if (ret == MBUS_RECV_RESULT_TIMEOUT) { - printf("No reply from device with secondary address %s: %s\n", argv[3], mbus_error_str()); + fprintf(stderr,"No reply from device with secondary address %s: %s\n", argv[3], mbus_error_str()); return 1; } if (ret == MBUS_RECV_RESULT_INVALID) { - printf("Invalid reply from %s: The address address probably match more than one device: %s\n", argv[3], mbus_error_str()); + fprintf(stderr,"Invalid reply from %s: The address address probably match more than one device: %s\n", argv[3], mbus_error_str()); return 1; } @@ -82,13 +82,13 @@ main(int argc, char **argv) { if (mbus_send_request_frame(handle, MBUS_ADDRESS_NETWORK_LAYER) == -1) { - printf("Failed to send request to selected secondary device: %s\n", mbus_error_str()); + fprintf(stderr,"Failed to send request to selected secondary device: %s\n", mbus_error_str()); return 1; } if (mbus_recv_frame(handle, &reply) != MBUS_RECV_RESULT_OK) { - printf("Failed to recieve reply from selected secondary device: %s\n", mbus_error_str()); + fprintf(stderr,"Failed to recieve reply from selected secondary device: %s\n", mbus_error_str()); return 1; } @@ -100,7 +100,7 @@ main(int argc, char **argv) } else { - printf("Unknown reply:\n"); + fprintf(stderr,"Unknown reply:\n"); mbus_frame_print(&reply); } diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index b09a643..08e5d8c 100755 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -1711,6 +1711,61 @@ mbus_send_switch_baudrate_frame(mbus_handle * handle, int address, int baudrate) return retval; } +//------------------------------------------------------------------------------ +// send a user data packet from master to slave: the packet resets +// the application layer in the slave +//------------------------------------------------------------------------------ +int +mbus_send_application_reset_frame(mbus_handle * handle, int address, int subcode) +{ + int retval = 0; + mbus_frame *frame; + + if (mbus_is_primary_address(address) == 0) + { + MBUS_ERROR("%s: invalid address %d\n", __PRETTY_FUNCTION__, address); + return -1; + } + + if (subcode > 0xFF) + { + MBUS_ERROR("%s: invalid subcode %d\n", __PRETTY_FUNCTION__, subcode); + return -1; + } + + frame = mbus_frame_new(MBUS_FRAME_TYPE_LONG); + + if (frame == NULL) + { + MBUS_ERROR("%s: failed to allocate mbus frame.\n", __PRETTY_FUNCTION__); + return -1; + } + + frame->control = MBUS_CONTROL_MASK_SND_UD | MBUS_CONTROL_MASK_DIR_M2S; + frame->address = address; + frame->control_information = MBUS_CONTROL_INFO_APPLICATION_RESET; + + if (subcode >= 0) + { + frame->data_size = 1; + frame->data[0] = (subcode & 0xFF); + } + else + { + frame->data_size = 0; + } + + 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 retval; +} + + //------------------------------------------------------------------------------ // send a request packet to from master to slave //------------------------------------------------------------------------------ diff --git a/mbus/mbus-protocol-aux.h b/mbus/mbus-protocol-aux.h index 7d996a1..dc655d3 100755 --- a/mbus/mbus-protocol-aux.h +++ b/mbus/mbus-protocol-aux.h @@ -246,7 +246,7 @@ int mbus_purge_frames(mbus_handle * handle); int mbus_send_frame(mbus_handle * handle, mbus_frame *frame); /** - * Sends secodary address selection frame using "unified" handle + * Sends secondary address selection frame using "unified" handle * * @param handle Initialized handle * @param secondary_addr_str Secondary address @@ -255,6 +255,17 @@ int mbus_send_frame(mbus_handle * handle, mbus_frame *frame); */ int mbus_send_select_frame(mbus_handle * handle, const char *secondary_addr_str); +/** + * Sends application reset to given slave using "unified" handle + * + * @param handle Initialized handle + * @param address Address (0-255) + * @param subcode Subcode (0-255) or no subcode (-1) + * + * @return Zero when successful. + */ +int mbus_send_application_reset_frame(mbus_handle * handle, int address, int subcode); + /** * Sends switch baudrate frame using "unified" handle *