3 Commits

Author SHA1 Message Date
d4aa9520f9 mbus-serial-scan: Make timeout adjustable 2018-05-15 21:17:09 +02:00
af5a843e6a Revert "mbus-serial: Increase serial timeouts"
This reverts commit a572c0f742.
2018-05-15 20:47:25 +02:00
13e6811630 mbus-serial-scan: Refactor cmdline parsing 2018-05-15 20:20:34 +02:00
8 changed files with 76 additions and 107 deletions

View File

@ -11,6 +11,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <mbus/mbus.h>
static int debug = 0;
@ -54,60 +55,43 @@ main(int argc, char **argv)
{
mbus_handle *handle;
char *device;
int address, retries = 0;
int address, retries = 0, timeout = 0;
long baudrate = 9600;
int ret;
int opt, ret;
if (argc == 2)
while ((opt = getopt(argc, argv, "db:r:t:")) != -1)
{
device = argv[1];
switch (opt)
{
case 'd':
debug = 1;
break;
case 'b':
baudrate = atol(optarg);
break;
case 'r':
retries = atoi(optarg);
break;
case 't':
timeout = atoi(optarg);
break;
default:
fprintf(stderr,"usage: %s [-d] [-b BAUDRATE] [-r RETRIES] [-t TIMEOUT] device\n",
argv[0]);
return 0;
}
}
else if (argc == 3 && strcmp(argv[1], "-d") == 0)
{
debug = 1;
device = argv[2];
}
else if (argc == 4 && strcmp(argv[1], "-b") == 0)
{
baudrate = atol(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 = atol(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 = atol(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 = atol(argv[3]);
retries = atoi(argv[5]);
device = argv[6];
}
else
{
fprintf(stderr,"usage: %s [-d] [-b BAUDRATE] [-r RETRIES] device\n", argv[0]);
if (optind >= argc) {
fprintf(stderr,"usage: %s [-d] [-b BAUDRATE] [-r RETRIES] [-t TIMEOUT] device\n",
argv[0]);
return 0;
}
device = argv[optind];
if ((handle = mbus_context_serial(device)) == NULL)
{
fprintf(stderr,"Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str());
@ -132,6 +116,12 @@ main(int argc, char **argv)
return 1;
}
if (mbus_context_set_option(handle, MBUS_OPTION_TIMEOUT_OFFSET, timeout) == -1)
{
fprintf(stderr,"Failed to set timeout offset\n");
return 1;
}
if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{
fprintf(stderr,"Failed to set baud rate.\n");

View File

@ -10,7 +10,7 @@ dnl ----------------------------------------------------------------------------
LT_CONFIG_LTDL_DIR([libltdl])
AC_INIT([libmbus], [0.9.0], [info@rscada.se], [libmbus], [http://www.rscada.se/libmbus/])
AC_INIT([libmbus], [0.8.0], [info@rscada.se], [libmbus], [http://www.rscada.se/libmbus/])
AC_CONFIG_AUX_DIR([libltdl/config])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
@ -18,7 +18,7 @@ AM_PROG_LIBTOOL
# fix for automake 1.11 & 1.12
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
LDFLAGS="$LDFLAGS -version-info 0:9:0"
LDFLAGS="$LDFLAGS -version-info 0:8:0"
dnl ----------------------
dnl

View File

@ -11,10 +11,10 @@
Summary: Open source M-bus (Meter-Bus) library
Name: libmbus
Version: 0.9.0
Version: 0.8.0
Release: 1
Source: https://github.com/rscada/%{name}/archive/%{version}.tar.gz
URL: https://github.com/rscada/libmbus/
Source: http://www.rscada.se/public-dist/%{name}-%{version}.tar.gz
URL: http://www.rscada.se/libmbus/
License: BSD
Vendor: Raditex Control AB
Packager: Stefan Wahren <info@lategoodbye.de>
@ -68,8 +68,9 @@ rm -rf "%buildroot"
%{_bindir}/mbus-serial-*
%{_bindir}/mbus-tcp-*
%{_libdir}/libmbus.so*
%{_mandir}/man1/libmbus.1
%{_mandir}/man1/mbus-*
# man pages doesn't exist in this version
# %{_mandir}/man1/libmbus.1
# %{_mandir}/man1/mbus-*
%files devel
%defattr (-,root,root)
@ -79,9 +80,5 @@ rm -rf "%buildroot"
%{_libdir}/pkgconfig/libmbus.pc
%changelog
* Fri Feb 22 2019 Stefan Wahren <info@lategoodbye.de> - 0.9.0-1
- switch to github repo
- enable man pages
* Fri Mar 29 2013 Stefan Wahren <info@lategoodbye.de> - 0.8.0-1
- Initial package based on the last official release

View File

@ -1519,6 +1519,7 @@ mbus_context_serial(const char *device)
handle->max_data_retry = 3;
handle->max_search_retry = 1;
handle->timeout_offset = 0;
handle->is_serial = 1;
handle->purge_first_frame = MBUS_FRAME_PURGE_M2S;
handle->auxdata = serial_data;
@ -1567,6 +1568,7 @@ mbus_context_tcp(const char *host, uint16_t port)
handle->max_data_retry = 3;
handle->max_search_retry = 1;
handle->timeout_offset = 0;
handle->is_serial = 0;
handle->purge_first_frame = MBUS_FRAME_PURGE_M2S;
handle->auxdata = tcp_data;
@ -1652,6 +1654,13 @@ mbus_context_set_option(mbus_handle * handle, mbus_context_option option, long v
return 0;
}
break;
case MBUS_OPTION_TIMEOUT_OFFSET:
if ((value >= 0) && (value <= 100))
{
handle->timeout_offset = value;
return 0;
}
break;
case MBUS_OPTION_PURGE_FIRST_FRAME:
if ((value == MBUS_FRAME_PURGE_NONE) ||
(value == MBUS_FRAME_PURGE_M2S) ||

View File

@ -87,6 +87,7 @@ typedef struct _mbus_handle {
int fd;
int max_data_retry;
int max_search_retry;
unsigned int timeout_offset;
char purge_first_frame;
char is_serial; /**< _handle type (non zero for serial) */
int (*open) (struct _mbus_handle *handle);
@ -154,7 +155,8 @@ typedef struct _mbus_record {
typedef enum _mbus_context_option {
MBUS_OPTION_MAX_DATA_RETRY, /**< option defines the maximum attempts of data request retransmission */
MBUS_OPTION_MAX_SEARCH_RETRY, /**< option defines the maximum attempts of search request retransmission */
MBUS_OPTION_PURGE_FIRST_FRAME /**< option controls the echo cancelation for mbus_recv_frame */
MBUS_OPTION_PURGE_FIRST_FRAME, /**< option controls the echo cancelation for mbus_recv_frame */
MBUS_OPTION_TIMEOUT_OFFSET, /**< option defines the additional timeout offset */
} mbus_context_option;
/**

View File

@ -461,9 +461,9 @@ mbus_data_bcd_encode(unsigned char *bcd_data, size_t bcd_data_size, int value)
int v0, v1, v2, x1, x2;
size_t i;
if (bcd_data && bcd_data_size)
if (bcd_data && bcd_data_size && (value >= 0))
{
v2 = abs(value);
v2 = value;
for (i = 0; i < bcd_data_size; i++)
{
@ -477,11 +477,6 @@ mbus_data_bcd_encode(unsigned char *bcd_data, size_t bcd_data_size, int value)
bcd_data[bcd_data_size-1-i] = (x2 << 4) | x1;
}
if (value < 0)
{
bcd_data[bcd_data_size-1] |= 0xF0;
}
return 0;
}
@ -503,20 +498,8 @@ mbus_data_bcd_decode(unsigned char *bcd_data, size_t bcd_data_size)
{
for (i = bcd_data_size; i > 0; i--)
{
val = (val * 10);
if (bcd_data[i-1]>>4 < 0xA)
{
val += ((bcd_data[i-1]>>4) & 0xF);
}
val = (val * 10) + ( bcd_data[i-1] & 0xF);
}
// hex code Fh in the MSD position signals a negative BCD number
if (bcd_data[bcd_data_size-1]>>4 == 0xF)
{
val *= -1;
val = (val * 10) + ((bcd_data[i-1]>>4) & 0xF);
val = (val * 10) + ( bcd_data[i-1] & 0xF);
}
return val;
@ -1105,9 +1088,6 @@ mbus_data_product_name(mbus_data_variable_header *header)
case 0x28:
strcpy(buff,"ABB F95 Typ US770");
break;
case 0x2F:
strcpy(buff,"Hydrometer Sharky 775");
break;
}
}
else if (manufacturer == mbus_manufacturer_id("JAN"))

View File

@ -72,13 +72,10 @@ mbus_serial_connect(mbus_handle *handle)
// between the end of a master send telegram and the beginning of the response telegram of the slave shall be
// between 11 bit times and (330 bit times + 50ms).
//
// Nowadays the usage of USB to serial adapter is very common, which could
// result in additional delay of 100 ms in worst case.
//
// For 2400Bd this means (330 + 11) / 2400 + 0.15 = 292 ms (added 11 bit periods to receive first byte).
// I.e. timeout of 0.3s seems appropriate for 2400Bd.
// For 2400Bd this means (330 + 11) / 2400 + 0.05 = 188.75 ms (added 11 bit periods to receive first byte).
// I.e. timeout of 0.2s seems appropriate for 2400Bd.
term->c_cc[VTIME] = (cc_t) 3; // Timeout in 1/10 sec
term->c_cc[VTIME] = (cc_t) 2 + handle->timeout_offset; // Timeout in 1/10 sec
cfsetispeed(term, B2400);
cfsetospeed(term, B2400);
@ -116,48 +113,51 @@ mbus_serial_set_baudrate(mbus_handle *handle, long baudrate)
{
case 300:
speed = B300;
serial_data->t.c_cc[VTIME] = (cc_t) 13; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 12; // Timeout in 1/10 sec
break;
case 600:
speed = B600;
serial_data->t.c_cc[VTIME] = (cc_t) 8; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 6; // Timeout in 1/10 sec
break;
case 1200:
speed = B1200;
serial_data->t.c_cc[VTIME] = (cc_t) 5; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 4; // Timeout in 1/10 sec
break;
case 2400:
speed = B2400;
serial_data->t.c_cc[VTIME] = (cc_t) 3; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
break;
case 4800:
speed = B4800;
serial_data->t.c_cc[VTIME] = (cc_t) 3; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
break;
case 9600:
speed = B9600;
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 1; // Timeout in 1/10 sec
break;
case 19200:
speed = B19200;
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 1; // Timeout in 1/10 sec
break;
case 38400:
speed = B38400;
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 1; // Timeout in 1/10 sec
break;
default:
return -1; // unsupported baudrate
}
// Add timeout offset for additional delay
serial_data->t.c_cc[VTIME] += handle->timeout_offset;
// Set input baud rate
if (cfsetispeed(&(serial_data->t), speed) != 0)
{

View File

@ -1,14 +1,5 @@
Release notes for libmbus
Version 0.9.0 (2019-02-22):
Added support for negative BCD numbers (type A) and date time CP48 (type I),
new program (set primary address), extended XML output (storage number,
tariff, device), echo cancelation and better retry handling. Also this version
has countless bug fixes.
Many thanks to all contributers
Version 0.8.0 (2012-06-18):
--------------------------