X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fmodbus.c;h=7349dc564976b2a91aa44b7bb760e8d33a9bf4e0;hb=f8379dd45f4a43595f4027992696ee8d02908bff;hp=8a9fe93fd83eaf3b6a32221ea9c92598c225802a;hpb=c7b0f0b0267f2ab7c84eea8306f0a516f5b8f769;p=collectd.git diff --git a/src/modbus.c b/src/modbus.c index 8a9fe93f..7349dc56 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -27,7 +27,7 @@ #include -#include +#include #ifndef LIBMODBUS_VERSION_CHECK /* Assume version 2.0.3 */ @@ -115,7 +115,6 @@ struct mb_host_s /* {{{ */ modbus_t *connection; #endif _Bool is_connected; - _Bool have_reconnected; }; /* }}} */ typedef struct mb_host_s mb_host_t; @@ -260,6 +259,7 @@ static float mb_register_to_float (uint16_t hi, uint16_t lo) /* {{{ */ union { uint8_t b[4]; + uint16_t s[2]; float f; } conv; @@ -288,14 +288,9 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ if (host == NULL) return (EINVAL); - if (host->is_connected) - return (0); - - /* Only reconnect once per interval. */ - if (host->have_reconnected) - return (-1); - +#if COLLECT_DEBUG modbus_set_debug (&host->connection, 1); +#endif /* We'll do the error handling ourselves. */ modbus_set_error_handling (&host->connection, NOP_ON_ERROR); @@ -319,7 +314,6 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ } host->is_connected = 1; - host->have_reconnected = 1; return (0); } /* }}} int mb_init_connection */ /* #endif LEGACY_LIBMODBUS */ @@ -336,10 +330,6 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ if (host->connection != NULL) return (0); - /* Only reconnect once per interval. */ - if (host->have_reconnected) - return (-1); - if ((host->port < 1) || (host->port > 65535)) host->port = MODBUS_TCP_DEFAULT_PORT; @@ -349,12 +339,13 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ host->connection = modbus_new_tcp (host->node, host->port); if (host->connection == NULL) { - host->have_reconnected = 1; ERROR ("Modbus plugin: Creating new Modbus/TCP object failed."); return (-1); } +#if COLLECT_DEBUG modbus_set_debug (host->connection, 1); +#endif /* We'll do the error handling ourselves. */ modbus_set_error_recovery (host->connection, 0); @@ -369,7 +360,6 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ return (status); } - host->have_reconnected = 1; return (0); } /* }}} int mb_init_connection */ #endif /* !LEGACY_LIBMODBUS */ @@ -391,8 +381,7 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ uint16_t values[2]; int values_num; const data_set_t *ds; - int status; - int i; + int status = 0; if ((host == NULL) || (slave == NULL) || (data == NULL)) return (EINVAL); @@ -429,6 +418,43 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ else values_num = 1; + if (host->connection == NULL) + { + status = EBADF; + } + else + { + struct sockaddr sockaddr; + socklen_t saddrlen = sizeof (sockaddr); + + status = getpeername (modbus_get_socket (host->connection), + &sockaddr, &saddrlen); + if (status != 0) + status = errno; + } + + if ((status == EBADF) || (status == ENOTSOCK) || (status == ENOTCONN)) + { + status = mb_init_connection (host); + if (status != 0) + { + ERROR ("Modbus plugin: mb_init_connection (%s/%s) failed. ", + host->host, host->node); + host->is_connected = 0; + host->connection = NULL; + return (-1); + } + } + else if (status != 0) + { +#if LEGACY_LIBMODBUS + modbus_close (&host->connection); +#else + modbus_close (host->connection); + modbus_free (host->connection); +#endif + } + #if LEGACY_LIBMODBUS /* Version 2.0.3: Pass the connection struct as a pointer and pass the slave * id to each call of "read_holding_registers". */ @@ -445,51 +471,22 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ } #endif - for (i = 0; i < 2; i++) - { - status = modbus_read_registers (host->connection, + status = modbus_read_registers (host->connection, /* start_addr = */ data->register_base, /* num_registers = */ values_num, /* buffer = */ values); - if (status > 0) - break; - - if (host->is_connected) - { + if (status != values_num) + { + ERROR ("Modbus plugin: modbus_read_registers (%s/%s) failed. status = %i, values_num = %i " + "Giving up.", host->host, host->node, status, values_num); #if LEGACY_LIBMODBUS - modbus_close (&host->connection); - host->is_connected = 0; + modbus_close (&host->connection); #else - modbus_close (host->connection); - modbus_free (host->connection); - host->connection = NULL; + modbus_close (host->connection); + modbus_free (host->connection); #endif - } - - /* If we already tried reconnecting this round, give up. */ - if (host->have_reconnected) - { - ERROR ("Modbus plugin: modbus_read_registers (%s) failed. " - "Reconnecting has already been tried. Giving up.", host->host); - return (-1); - } - - /* Maybe the device closed the connection during the waiting interval. - * Try re-establishing the connection. */ - status = mb_init_connection (host); - if (status != 0) - { - ERROR ("Modbus plugin: modbus_read_registers (%s) failed. " - "While trying to reconnect, connecting to \"%s\" failed. " - "Giving up.", - host->host, host->node); - return (-1); - } - - DEBUG ("Modbus plugin: Re-established connection to %s", host->host); - - /* try again */ - continue; - } /* for (i = 0, 1) */ + host->connection = NULL; + return (-1); + } DEBUG ("Modbus plugin: mb_read_data: Success! " "modbus_read_registers returned with status %i.", status); @@ -602,9 +599,6 @@ static int mb_read (user_data_t *user_data) /* {{{ */ host = user_data->data; - /* Clear the reconnect flag. */ - host->have_reconnected = 0; - success = 0; for (i = 0; i < host->slaves_num; i++) { @@ -686,7 +680,6 @@ static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - status = 0; if (strcasecmp ("Type", child->key) == 0) status = cf_util_get_string_buffer (child, @@ -825,7 +818,6 @@ static int mb_config_add_slave (mb_host_t *host, oconfig_item_t *ci) /* {{{ */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - status = 0; if (strcasecmp ("Instance", child->key) == 0) status = cf_util_get_string_buffer (child, @@ -876,9 +868,15 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host)); if (status != 0) + { + sfree (host); return (status); + } if (host->host[0] == 0) + { + sfree (host); return (EINVAL); + } for (i = 0; i < ci->children_num; i++) {