Merge branch 'master' of github.com:rscada/libmbus

This commit is contained in:
Robert Johansson
2012-07-25 00:04:16 +09:00
74 changed files with 2175 additions and 74535 deletions

View File

@ -12,7 +12,9 @@ VERSION = @VERSION@
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
pkginclude_HEADERS = mbus.h mbus-protocol.h mbus-tcp.h mbus-serial.h mbus-protocol-aux.h
includedir = $(prefix)/include/mbus
include_HEADERS = mbus.h mbus-protocol.h mbus-tcp.h mbus-serial.h mbus-protocol-aux.h
lib_LTLIBRARIES = libmbus.la
libmbus_la_SOURCES = mbus.c mbus-protocol.c mbus-tcp.c mbus-serial.c mbus-protocol-aux.c

View File

@ -1330,6 +1330,7 @@ mbus_context_serial(const char *device)
return NULL;
}
handle->max_retry = 3;
handle->is_serial = 1;
handle->auxdata = serial_data;
handle->open = mbus_serial_connect;
@ -1371,6 +1372,7 @@ mbus_context_tcp(const char *host, int port)
return NULL;
}
handle->max_retry = 3;
handle->is_serial = 0;
handle->auxdata = tcp_data;
handle->open = mbus_tcp_connect;
@ -1434,13 +1436,13 @@ mbus_recv_frame(mbus_handle * handle, mbus_frame *frame)
if (handle == NULL)
{
MBUS_ERROR("%s: Invalid M-Bus handle for receive.\n", __PRETTY_FUNCTION__);
return -1;
return MBUS_RECV_RESULT_ERROR;
}
if (frame == NULL)
{
MBUS_ERROR("%s: Invalid frame.\n", __PRETTY_FUNCTION__);
return -1;
return MBUS_RECV_RESULT_ERROR;
}
result = handle->recv(handle, frame);
@ -1463,7 +1465,8 @@ int mbus_purge_frames(mbus_handle *handle)
while (1)
{
err = mbus_recv_frame(handle, &reply);
if (err != -2 && err != 0)
if (err != MBUS_RECV_RESULT_OK &&
err != MBUS_RECV_RESULT_INVALID)
break;
received = 1;
@ -1615,10 +1618,10 @@ mbus_send_request_frame(mbus_handle * handle, int address)
int
mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int max_frames)
{
int retval = 0, more_frames = 1;
int retval = 0, more_frames = 1, retry = 0;
mbus_frame_data reply_data;
mbus_frame *frame, *next_frame;
int frame_count = 0;
int frame_count = 0, result;
frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT);
@ -1634,16 +1637,6 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m
MBUS_CONTROL_MASK_FCB;
frame->address = address;
if (debug)
printf("%s: debug: sending request frame\n", __PRETTY_FUNCTION__);
if (mbus_send_frame(handle, frame) == -1)
{
MBUS_ERROR("%s: failed to send mbus frame.\n", __PRETTY_FUNCTION__);
mbus_frame_free(frame);
return -1;
}
//
// continue to read until no more records are available (usually only one
@ -1655,18 +1648,55 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m
while (more_frames)
{
frame_count++;
if (retry > handle->max_retry)
{
// Give up
retval = 1;
break;
}
if (debug)
printf("%s: debug: sending request frame\n", __PRETTY_FUNCTION__);
if (mbus_send_frame(handle, frame) == -1)
{
MBUS_ERROR("%s: failed to send mbus frame.\n", __PRETTY_FUNCTION__);
retval = -1;
break;
}
if (debug)
printf("%s: debug: receiving response frame #%d\n", __PRETTY_FUNCTION__, frame_count);
if (mbus_recv_frame(handle, next_frame) != 0)
result = mbus_recv_frame(handle, next_frame);
if (result == MBUS_RECV_RESULT_OK)
{
retry = 0;
mbus_purge_frames(handle);
}
else if (result == MBUS_RECV_RESULT_TIMEOUT)
{
MBUS_ERROR("%s: No M-Bus response frame received.\n", __PRETTY_FUNCTION__);
retry++;
continue;
}
else if (result == MBUS_RECV_RESULT_INVALID)
{
MBUS_ERROR("%s: Received invalid M-Bus response frame.\n", __PRETTY_FUNCTION__);
retry++;
mbus_purge_frames(handle);
continue;
}
else
{
MBUS_ERROR("%s: Failed to receive M-Bus response frame.\n", __PRETTY_FUNCTION__);
retval = 1;
break;
}
frame_count++;
//
// We need to parse the data in the received frame to be able to tell
// if more records are available or not.
@ -1712,20 +1742,9 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m
}
next_frame = next_frame->next;
// need to send a new request and receive another reply
if (debug)
printf("%s: debug: resending request frame\n", __PRETTY_FUNCTION__);
// toogle FCB bit before
// toogle FCB bit
frame->control ^= MBUS_CONTROL_MASK_FCB;
if (mbus_send_frame(handle, frame) == -1)
{
MBUS_ERROR("%s: failed to send mbus frame.\n", __PRETTY_FUNCTION__);
retval = -1;
more_frames = 0;
}
}
else
{
@ -1802,12 +1821,12 @@ mbus_select_secondary_address(mbus_handle * handle, const char *mask)
ret = mbus_recv_frame(handle, &reply);
if (ret == -3)
if (ret == MBUS_RECV_RESULT_TIMEOUT)
{
return MBUS_PROBE_NOTHING;
}
if (ret == -2)
if (ret == MBUS_RECV_RESULT_INVALID)
{
/* check for more data (collision) */
mbus_purge_frames(handle);
@ -1862,12 +1881,12 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match
ret = mbus_recv_frame(handle, &reply);
if (ret == -3)
if (ret == MBUS_RECV_RESULT_TIMEOUT)
{
return MBUS_PROBE_NOTHING;
}
if (ret == -2)
if (ret == MBUS_RECV_RESULT_INVALID)
{
return MBUS_PROBE_COLLISION;
}

View File

@ -75,6 +75,7 @@
*/
struct _mbus_handle {
int fd;
int max_retry;
char is_serial; /**< _handle type (non zero for serial) */
int (*open) (struct _mbus_handle *handle);
int (*close) (struct _mbus_handle *handle);

View File

@ -106,6 +106,15 @@ typedef struct _mbus_slave_data {
#define MBUS_HANDLE_TYPE_TCP 0
#define MBUS_HANDLE_TYPE_SERIAL 1
//
// Resultcodes for mbus_recv_frame
//
#define MBUS_RECV_RESULT_OK 0
#define MBUS_RECV_RESULT_ERROR -1
#define MBUS_RECV_RESULT_INVALID -2
#define MBUS_RECV_RESULT_TIMEOUT -3
#define MBUS_RECV_RESULT_RESET -4
//------------------------------------------------------------------------------
// MBUS FRAME DATA FORMATS
//

View File

@ -111,6 +111,11 @@ mbus_serial_set_baudrate(mbus_handle *handle, int baudrate)
serial_data->t.c_cc[VTIME] = 12; // Timeout in 1/10 sec
break;
case 600:
speed = B600;
serial_data->t.c_cc[VTIME] = 6; // Timeout in 1/10 sec
break;
case 1200:
speed = B1200;
serial_data->t.c_cc[VTIME] = 4; // Timeout in 1/10 sec
@ -121,11 +126,26 @@ mbus_serial_set_baudrate(mbus_handle *handle, int baudrate)
serial_data->t.c_cc[VTIME] = 2; // Timeout in 1/10 sec
break;
case 4800:
speed = B4800;
serial_data->t.c_cc[VTIME] = 2; // Timeout in 1/10 sec
break;
case 9600:
speed = B9600;
serial_data->t.c_cc[VTIME] = 1; // Timeout in 1/10 sec
break;
case 19200:
speed = B19200;
serial_data->t.c_cc[VTIME] = 1; // Timeout in 1/10 sec
break;
case 38400:
speed = B38400;
serial_data->t.c_cc[VTIME] = 1; // Timeout in 1/10 sec
break;
default:
return -1; // unsupported baudrate
}
@ -245,7 +265,7 @@ mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame)
if (handle == NULL || frame == NULL)
{
fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1;
return MBUS_RECV_RESULT_ERROR;
}
memset((void *)buff, 0, sizeof(buff));
@ -264,7 +284,7 @@ mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame)
{
// fprintf(stderr, "%s: aborting recv frame (remaining = %d, len = %d, nread = %d)\n",
// __PRETTY_FUNCTION__, remaining, len, nread);
return -1;
return MBUS_RECV_RESULT_ERROR;
}
// printf("%s: Got %d byte [remaining %d, len %d]\n", __PRETTY_FUNCTION__, nread, remaining, len);
@ -288,7 +308,7 @@ mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame)
if (len == 0)
{
// No data received
return -1;
return MBUS_RECV_RESULT_TIMEOUT;
}
//
@ -301,16 +321,16 @@ mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame)
{
// 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 -2;
return MBUS_RECV_RESULT_INVALID;
}
if (len == -1)
{
fprintf(stderr, "%s: M-Bus layer failed to parse data.\n", __PRETTY_FUNCTION__);
return -1;
return MBUS_RECV_RESULT_ERROR;
}
return 0;
return MBUS_RECV_RESULT_OK;
}

View File

@ -169,7 +169,7 @@ int mbus_tcp_recv_frame(mbus_handle *handle, mbus_frame *frame)
if (handle == NULL || frame == NULL) {
fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1;
return MBUS_RECV_RESULT_ERROR;
}
memset((void *) buff, 0, sizeof(buff));
@ -190,14 +190,14 @@ retry:
if (errno == EAGAIN || errno == EWOULDBLOCK) {
mbus_error_str_set("M-Bus tcp transport layer response timeout has been reached.");
return -3;
return MBUS_RECV_RESULT_TIMEOUT;
}
mbus_error_str_set("M-Bus tcp transport layer failed to read data.");
return -1;
return MBUS_RECV_RESULT_ERROR;
case 0:
mbus_error_str_set("M-Bus tcp transport layer connection closed by remote host.");
return -4;
return MBUS_RECV_RESULT_RESET;
default:
len += nread;
}
@ -211,10 +211,10 @@ retry:
if (remaining < 0) {
mbus_error_str_set("M-Bus layer failed to parse data.");
return -2;
return MBUS_RECV_RESULT_INVALID;
}
return 0;
return MBUS_RECV_RESULT_OK;
}