From f14b3beb84101c90c8eea0cc024f6ce658dea4ab Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Tue, 15 May 2012 23:30:55 +0200 Subject: [PATCH] Fixed bugs in wildcard search - init slaves before search - corrected return codes - handle collisions (possibly more bytes than expected) - sync recv frame (tcp vs serial) - add tracing --- bin/mbus-serial-scan-secondary.c | 37 ++++++++++++++++++++++++++++++++ mbus/mbus-protocol-aux.c | 23 +++++++++++++++++++- mbus/mbus-serial.c | 30 ++++++++++++++------------ mbus/mbus-tcp.c | 26 +++++++++++----------- 4 files changed, 89 insertions(+), 27 deletions(-) diff --git a/bin/mbus-serial-scan-secondary.c b/bin/mbus-serial-scan-secondary.c index 3909c49..c6e282e 100644 --- a/bin/mbus-serial-scan-secondary.c +++ b/bin/mbus-serial-scan-secondary.c @@ -28,6 +28,7 @@ main(int argc, char **argv) char *device, *addr_mask; int baudrate = 9600; mbus_handle *handle = NULL; + mbus_frame *frame = NULL, *reply = NULL; if (argc == 2) { @@ -111,6 +112,42 @@ main(int argc, char **argv) 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 = 0xFD; + + 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 = 0xFF; + + 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/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index 52e336f..84ea5a5 100644 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -1711,11 +1711,25 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match if (ret == -2) { + /* check for more data (collision) */ + while (mbus_recv_frame(handle, &reply) != -1); + return MBUS_PROBE_COLLISION; } if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) { + /* check for more data (collision) */ + while (mbus_recv_frame(handle, &reply) != -1) + { + ret = -2; + } + + if (ret == -2) + { + return MBUS_PROBE_COLLISION; + } + /* send a data request command to find out the full address */ if (mbus_send_request_frame(handle, 253) == -1) { @@ -1726,11 +1740,18 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match return MBUS_PROBE_ERROR; } - if (mbus_recv_frame(handle, &reply) == -1) + ret = mbus_recv_frame(handle, &reply); + + if (ret == -1) { return MBUS_PROBE_NOTHING; } + if (ret == -2) + { + return MBUS_PROBE_COLLISION; + } + if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK) { snprintf(matching_addr, 17, "%s", mbus_frame_get_secondary_address(&reply)); diff --git a/mbus/mbus-serial.c b/mbus/mbus-serial.c index 08c4d7d..784bfa0 100644 --- a/mbus/mbus-serial.c +++ b/mbus/mbus-serial.c @@ -205,7 +205,7 @@ mbus_serial_send_frame(mbus_serial_handle *handle, mbus_frame *frame) // call the send event function, if the callback function is registered // if (_mbus_send_event) - _mbus_send_event(MBUS_HANDLE_TYPE_SERIAL); + _mbus_send_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); } else { @@ -236,17 +236,7 @@ mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame) do { //printf("%s: Attempt to read %d bytes [len = %d]\n", __PRETTY_FUNCTION__, remaining, len); - nread = read(handle->fd, &buff[len], remaining); - - if (nread > 0) - { - // - // call the receive event function, if the callback function is registered - // - if (_mbus_recv_event) - _mbus_recv_event(MBUS_HANDLE_TYPE_SERIAL); - } - else if (nread == -1) + if ((nread = read(handle->fd, &buff[len], remaining)) == -1) { // fprintf(stderr, "%s: aborting recv frame (remaining = %d, len = %d, nread = %d)\n", // __PRETTY_FUNCTION__, remaining, len, nread); @@ -258,12 +248,24 @@ mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame) len += nread; } while ((remaining = mbus_parse(frame, buff, len)) > 0); + + if (len == 0) + { + // No data received + return -1; + } + + // + // call the receive event function, if the callback function is registered + // + if (_mbus_recv_event) + _mbus_recv_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); - if(remaining < 0) + if (remaining < 0) { // Would be OK when e.g. scanning the bus, otherwise it is a failure. // printf("%s: M-Bus layer failed to receive complete data.\n", __PRETTY_FUNCTION__); - return -1; + return -2; } if (len == -1) diff --git a/mbus/mbus-tcp.c b/mbus/mbus-tcp.c index 62d21e2..2911e89 100644 --- a/mbus/mbus-tcp.c +++ b/mbus/mbus-tcp.c @@ -144,7 +144,7 @@ mbus_tcp_send_frame(mbus_tcp_handle *handle, mbus_frame *frame) // call the send event function, if the callback function is registered // if (_mbus_send_event) - _mbus_send_event(MBUS_HANDLE_TYPE_TCP); + _mbus_send_event(MBUS_HANDLE_TYPE_TCP, buff, len); } else { @@ -176,17 +176,7 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame) do { - nread = read(handle->sock, &buff[len], remaining); - - if (nread > 0) - { - // - // call the receive event function, if the callback function is registered - // - if (_mbus_recv_event) - _mbus_recv_event(MBUS_HANDLE_TYPE_TCP); - } - else if (nread == -1) + if ((nread = read(handle->sock, &buff[len], remaining)) == -1) { mbus_error_str_set("M-Bus tcp transport layer failed to read data."); return -1; @@ -195,6 +185,18 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame) len += nread; } while ((remaining = mbus_parse(frame, buff, len)) > 0); + + if (len == 0) + { + // No data received + return -1; + } + + // + // call the receive event function, if the callback function is registered + // + if (_mbus_recv_event) + _mbus_recv_event(MBUS_HANDLE_TYPE_TCP, buff, len); if (remaining < 0) {