Merge pull request #46 from lategoodbye/master

experimental feature application reset, better primary scan, equalize stderr output
This commit is contained in:
Robert Johansson
2013-04-29 19:12:46 -07:00
12 changed files with 233 additions and 79 deletions

View File

@ -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

View File

@ -10,9 +10,9 @@ the communication with M-Bus devices.
B<mbus-serial-switch-baudrate> [-b BAUDRATE] device address target-baudrate
B<mbus-serial-scan> [-d] [-b BAUDRATE] device
B<mbus-serial-scan> [-d] [-b BAUDRATE] [-r RETRIES] device
B<mbus-tcp-scan> [-d] host port
B<mbus-tcp-scan> [-d] [-r RETRIES] host port
B<mbus-serial-scan-secondary> [-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<RETRIES>
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.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -13,15 +13,48 @@
#include <stdio.h>
#include <mbus/mbus.h>
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) */

View File

@ -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);
}

View File

@ -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
//------------------------------------------------------------------------------

View File

@ -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
*