diff --git a/.gitignore b/.gitignore index b3ae506..2bb98e8 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ test/.deps *.lo .libs/ bin/libmbus.1 +bin/libmbus.1 bin/mbus-serial-request-data bin/mbus-serial-request-data-multi-reply bin/mbus-serial-scan @@ -57,3 +58,5 @@ bin/mbus-tcp-request-data-multi-reply bin/mbus-tcp-scan bin/mbus-tcp-scan-secondary bin/mbus-tcp-select-secondary +!*.c + diff --git a/bin/mbus-serial-request-data-multi-reply.c b/bin/mbus-serial-request-data-multi-reply.c index 7d9b04b..787a651 100755 --- a/bin/mbus-serial-request-data-multi-reply.c +++ b/bin/mbus-serial-request-data-multi-reply.c @@ -31,7 +31,7 @@ init_slaves(mbus_handle *handle) if (mbus_send_ping_frame(handle, MBUS_ADDRESS_NETWORK_LAYER, 1) == -1) { return 0; - } + } // // resend SND_NKE, maybe the first get lost diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index 57758eb..ec0f6f0 100755 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -1353,6 +1353,7 @@ mbus_context_serial(const char *device) handle->max_retry = 3; handle->is_serial = 1; + handle->purge_first_frame = MBUS_FRAME_PURGE_M2S; handle->auxdata = serial_data; handle->open = mbus_serial_connect; handle->close = mbus_serial_disconnect; @@ -1395,6 +1396,7 @@ mbus_context_tcp(const char *host, int port) handle->max_retry = 3; handle->is_serial = 0; + handle->purge_first_frame = MBUS_FRAME_PURGE_M2S; handle->auxdata = tcp_data; handle->open = mbus_tcp_connect; handle->close = mbus_tcp_disconnect; @@ -1467,6 +1469,18 @@ mbus_recv_frame(mbus_handle * handle, mbus_frame *frame) } result = handle->recv(handle, frame); + + switch (mbus_frame_direction(frame)) + { + case MBUS_CONTROL_MASK_DIR_M2S: + if (handle->purge_first_frame == MBUS_FRAME_PURGE_M2S) + result = handle->recv(handle, frame); // purge echo and retry + break; + case MBUS_CONTROL_MASK_DIR_S2M: + if (handle->purge_first_frame == MBUS_FRAME_PURGE_S2M) + result = handle->recv(handle, frame); // purge echo and retry + break; + } if (frame != NULL) { diff --git a/mbus/mbus-protocol-aux.h b/mbus/mbus-protocol-aux.h index 5b63188..02694d9 100755 --- a/mbus/mbus-protocol-aux.h +++ b/mbus/mbus-protocol-aux.h @@ -70,12 +70,17 @@ #define MBUS_PROBE_COLLISION 2 #define MBUS_PROBE_ERROR -1 +#define MBUS_FRAME_PURGE_S2M 2 +#define MBUS_FRAME_PURGE_M2S 1 +#define MBUS_FRAME_PURGE_NONE 0 + /** * Unified MBus handle type encapsulating either Serial or TCP gateway. */ struct _mbus_handle { int fd; int max_retry; + char purge_first_frame; char is_serial; /**< _handle type (non zero for serial) */ int (*open) (struct _mbus_handle *handle); int (*close) (struct _mbus_handle *handle); diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index 59736e9..e627091 100755 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -300,6 +300,26 @@ mbus_frame_type(mbus_frame *frame) return -1; } +//------------------------------------------------------------------------------ +/// Return the M-Bus frame direction +//------------------------------------------------------------------------------ +int +mbus_frame_direction(mbus_frame *frame) +{ + if (frame) + { + if (frame->type == MBUS_FRAME_TYPE_ACK) + { + return MBUS_CONTROL_MASK_DIR_S2M; + } + else + { + return (frame->control & MBUS_CONTROL_MASK_DIR); + } + } + return -1; +} + //------------------------------------------------------------------------------ /// Verify that parsed frame is a valid M-bus frame. // @@ -836,6 +856,15 @@ mbus_data_product_name(mbus_data_variable_header *header) break; } } + else if (manufacturer == MBUS_VARIABLE_DATA_MAN_RKE) + { + switch (header->version) + { + case 0x69: + strcpy(buff,"Ista sensonic II mbus"); + break; + } + } else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SVM) { switch (header->version) @@ -2713,7 +2742,23 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data) int mbus_frame_data_parse(mbus_frame *frame, mbus_frame_data *data) { - if (frame && data) + char direction; + + if (frame == NULL) + { + snprintf(error_str, sizeof(error_str), "Got null pointer to frame."); + return -1; + } + + if (data == NULL) + { + snprintf(error_str, sizeof(error_str), "Got null pointer to data."); + return -1; + } + + direction = (frame->control & MBUS_CONTROL_MASK_DIR); + + if (direction == MBUS_CONTROL_MASK_DIR_S2M) { if (frame->control_information == MBUS_CONTROL_INFO_ERROR_GENERAL) { @@ -2761,9 +2806,13 @@ mbus_frame_data_parse(mbus_frame *frame, mbus_frame_data *data) return -1; } } - - snprintf(error_str, sizeof(error_str), "Got null pointer to frame or data."); - + else + { + snprintf(error_str, sizeof(error_str), "Wrong direction in frame (master to slave)"); + + return -1; + } + return -1; } diff --git a/mbus/mbus-protocol.h b/mbus/mbus-protocol.h index 8ec0ce6..c1473a3 100755 --- a/mbus/mbus-protocol.h +++ b/mbus/mbus-protocol.h @@ -484,6 +484,7 @@ typedef struct _mbus_data_secondary_address { #define MBUS_VARIABLE_DATA_MAN_NZR 0x3B52 #define MBUS_VARIABLE_DATA_MAN_PAD 0x4024 #define MBUS_VARIABLE_DATA_MAN_QDS 0x4493 +#define MBUS_VARIABLE_DATA_MAN_RKE 0x4965 #define MBUS_VARIABLE_DATA_MAN_SEN 0x4CAE #define MBUS_VARIABLE_DATA_MAN_SLB 0x4D82 #define MBUS_VARIABLE_DATA_MAN_SON 0x4DEE @@ -555,6 +556,7 @@ const char *mbus_data_fixed_function(int status); // M-Bus frame data struct access/write functions // int mbus_frame_type(mbus_frame *frame); +int mbus_frame_direction(mbus_frame *frame); // // Slave status data register.