X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fmodbus.c;h=efcf6be8950d3b302227bac029288be746348780;hp=5d29791d337553f6defc8a039d0050e4d647095d;hb=d486225f89ea52d8ed2b4242eba2ad94c409f837;hpb=ffaf9b893b6042a76e1c0dadd83ce06904fcc89a diff --git a/src/modbus.c b/src/modbus.c index 5d29791d..efcf6be8 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -76,9 +76,13 @@ enum mb_register_type_e /* {{{ */ { REG_TYPE_INT16, REG_TYPE_INT32, + REG_TYPE_INT32_CDAB, REG_TYPE_UINT16, REG_TYPE_UINT32, - REG_TYPE_FLOAT }; /* }}} */ + REG_TYPE_UINT32_CDAB, + REG_TYPE_FLOAT, + REG_TYPE_FLOAT_CDAB }; /* }}} */ + enum mb_mreg_type_e /* {{{ */ { MREG_HOLDING, MREG_INPUT }; /* }}} */ @@ -131,7 +135,7 @@ struct mb_host_s /* {{{ */ #else modbus_t *connection; #endif - _Bool is_connected; + bool is_connected; }; /* }}} */ typedef struct mb_host_s mb_host_t; @@ -148,7 +152,7 @@ struct mb_data_group_s /* {{{ */ /* * Global variables */ -static mb_data_t *data_definitions = NULL; +static mb_data_t *data_definitions; /* * Functions @@ -156,13 +160,13 @@ static mb_data_t *data_definitions = NULL; static mb_data_t *data_get_by_name(mb_data_t *src, /* {{{ */ const char *name) { if (name == NULL) - return (NULL); + return NULL; for (mb_data_t *ptr = src; ptr != NULL; ptr = ptr->next) if (strcasecmp(ptr->name, name) == 0) - return (ptr); + return ptr; - return (NULL); + return NULL; } /* }}} mb_data_t *data_get_by_name */ static int data_append(mb_data_t **dst, mb_data_t *src) /* {{{ */ @@ -170,13 +174,13 @@ static int data_append(mb_data_t **dst, mb_data_t *src) /* {{{ */ mb_data_t *ptr; if ((dst == NULL) || (src == NULL)) - return (EINVAL); + return EINVAL; ptr = *dst; if (ptr == NULL) { *dst = src; - return (0); + return 0; } while (ptr->next != NULL) @@ -184,7 +188,7 @@ static int data_append(mb_data_t **dst, mb_data_t *src) /* {{{ */ ptr->next = src; - return (0); + return 0; } /* }}} int data_append */ /* Copy a single mb_data_t and append it to another list. */ @@ -194,11 +198,11 @@ static int data_copy(mb_data_t **dst, const mb_data_t *src) /* {{{ */ int status; if ((dst == NULL) || (src == NULL)) - return (EINVAL); + return EINVAL; tmp = malloc(sizeof(*tmp)); if (tmp == NULL) - return (ENOMEM); + return ENOMEM; memcpy(tmp, src, sizeof(*tmp)); tmp->name = NULL; tmp->next = NULL; @@ -206,17 +210,17 @@ static int data_copy(mb_data_t **dst, const mb_data_t *src) /* {{{ */ tmp->name = strdup(src->name); if (tmp->name == NULL) { sfree(tmp); - return (ENOMEM); + return ENOMEM; } status = data_append(dst, tmp); if (status != 0) { sfree(tmp->name); sfree(tmp); - return (status); + return status; } - return (0); + return 0; } /* }}} int data_copy */ /* Lookup a single mb_data_t instance, copy it and append the copy to another @@ -226,13 +230,13 @@ static int data_copy_by_name(mb_data_t **dst, mb_data_t *src, /* {{{ */ mb_data_t *ptr; if ((dst == NULL) || (src == NULL) || (name == NULL)) - return (EINVAL); + return EINVAL; ptr = data_get_by_name(src, name); if (ptr == NULL) - return (ENOENT); + return ENOENT; - return (data_copy(dst, ptr)); + return data_copy(dst, ptr); } /* }}} int data_copy_by_name */ /* Read functions */ @@ -242,13 +246,13 @@ static int mb_submit(mb_host_t *host, mb_slave_t *slave, /* {{{ */ value_list_t vl = VALUE_LIST_INIT; if ((host == NULL) || (slave == NULL) || (data == NULL)) - return (EINVAL); + return EINVAL; if (host->interval == 0) host->interval = plugin_get_interval(); if (slave->instance[0] == 0) - ssnprintf(slave->instance, sizeof(slave->instance), "slave_%i", slave->id); + snprintf(slave->instance, sizeof(slave->instance), "slave_%i", slave->id); vl.values = &value; vl.values_len = 1; @@ -259,7 +263,7 @@ static int mb_submit(mb_host_t *host, mb_slave_t *slave, /* {{{ */ sstrncpy(vl.type, data->type, sizeof(vl.type)); sstrncpy(vl.type_instance, data->instance, sizeof(vl.type_instance)); - return (plugin_dispatch_values(&vl)); + return plugin_dispatch_values(&vl); } /* }}} int mb_submit */ static float mb_register_to_float(uint16_t hi, uint16_t lo) /* {{{ */ @@ -283,7 +287,7 @@ static float mb_register_to_float(uint16_t hi, uint16_t lo) /* {{{ */ conv.b[0] = (hi >> 8) & 0x00ff; #endif - return (conv.f); + return conv.f; } /* }}} float mb_register_to_float */ #if LEGACY_LIBMODBUS @@ -293,7 +297,7 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ int status; if (host == NULL) - return (EINVAL); + return EINVAL; #if COLLECT_DEBUG modbus_set_debug(&host->connection, 1); @@ -325,11 +329,11 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ if (status != 0) { ERROR("Modbus plugin: modbus_connect (%s, %i) failed with status %i.", host->node, host->port ? host->port : host->baudrate, status); - return (status); + return status; } - host->is_connected = 1; - return (0); + host->is_connected = true; + return 0; } /* }}} int mb_init_connection */ /* #endif LEGACY_LIBMODBUS */ @@ -340,10 +344,10 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ int status; if (host == NULL) - return (EINVAL); + return EINVAL; if (host->connection != NULL) - return (0); + return 0; if (host->conntype == MBCONN_TCP) { if ((host->port < 1) || (host->port > 65535)) @@ -355,7 +359,7 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ host->connection = modbus_new_tcp(host->node, host->port); if (host->connection == NULL) { ERROR("Modbus plugin: Creating new Modbus/TCP object failed."); - return (-1); + return -1; } } else { DEBUG("Modbus plugin: Trying to connect to \"%s\", baudrate %i.", @@ -364,7 +368,7 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ host->connection = modbus_new_rtu(host->node, host->baudrate, 'N', 8, 1); if (host->connection == NULL) { ERROR("Modbus plugin: Creating new Modbus/RTU object failed."); - return (-1); + return -1; } } @@ -381,10 +385,10 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ host->node, host->port ? host->port : host->baudrate, status); modbus_free(host->connection); host->connection = NULL; - return (status); + return status; } - return (0); + return 0; } /* }}} int mb_init_connection */ #endif /* !LEGACY_LIBMODBUS */ @@ -408,24 +412,26 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ int status = 0; if ((host == NULL) || (slave == NULL) || (data == NULL)) - return (EINVAL); + return EINVAL; ds = plugin_get_ds(data->type); if (ds == NULL) { ERROR("Modbus plugin: Type \"%s\" is not defined.", data->type); - return (-1); + return -1; } if (ds->ds_num != 1) { - ERROR("Modbus plugin: The type \"%s\" has %zu data sources. " + ERROR("Modbus plugin: The type \"%s\" has %" PRIsz " data sources. " "I can only handle data sets with only one data source.", data->type, ds->ds_num); - return (-1); + return -1; } if ((ds->ds[0].type != DS_TYPE_GAUGE) && (data->register_type != REG_TYPE_INT32) && - (data->register_type != REG_TYPE_UINT32)) { + (data->register_type != REG_TYPE_INT32_CDAB) && + (data->register_type != REG_TYPE_UINT32) && + (data->register_type != REG_TYPE_UINT32_CDAB)) { NOTICE( "Modbus plugin: The data source of type \"%s\" is %s, not gauge. " "This will most likely result in problems, because the register type " @@ -434,8 +440,11 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ } if ((data->register_type == REG_TYPE_INT32) || + (data->register_type == REG_TYPE_INT32_CDAB) || (data->register_type == REG_TYPE_UINT32) || - (data->register_type == REG_TYPE_FLOAT)) + (data->register_type == REG_TYPE_UINT32_CDAB) || + (data->register_type == REG_TYPE_FLOAT) || + (data->register_type == REG_TYPE_FLOAT_CDAB)) values_num = 2; else values_num = 1; @@ -456,9 +465,9 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ if (status != 0) { ERROR("Modbus plugin: mb_init_connection (%s/%s) failed. ", host->host, host->node); - host->is_connected = 0; + host->is_connected = false; host->connection = NULL; - return (-1); + return -1; } } else if (status != 0) { #if LEGACY_LIBMODBUS @@ -480,7 +489,7 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ if (status != 0) { ERROR("Modbus plugin: modbus_set_slave (%i) failed with status %i.", slave->id, status); - return (-1); + return -1; } #endif if (data->modbus_register_type == MREG_INPUT) { @@ -496,8 +505,8 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ } if (status != values_num) { ERROR("Modbus plugin: modbus read function (%s/%s) failed. " - " status = %i, values_num = %i. Giving up.", - host->host, host->node, status, values_num); + " status = %i, start_addr = %i, values_num = %i. Giving up.", + host->host, host->node, status, data->register_base, values_num); #if LEGACY_LIBMODBUS modbus_close(&host->connection); #else @@ -505,7 +514,7 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ modbus_free(host->connection); #endif host->connection = NULL; - return (-1); + return -1; } DEBUG("Modbus plugin: mb_read_data: Success! " @@ -523,6 +532,17 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ CAST_TO_VALUE_T(ds, vt, float_value); mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_FLOAT_CDAB) { + float float_value; + value_t vt; + + float_value = mb_register_to_float(values[1], values[0]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned float value is %g", + (double)float_value); + + CAST_TO_VALUE_T(ds, vt, float_value); + mb_submit(host, slave, data, vt); } else if (data->register_type == REG_TYPE_INT32) { union { uint32_t u32; @@ -537,6 +557,20 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ CAST_TO_VALUE_T(ds, vt, v.i32); mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_INT32_CDAB) { + union { + uint32_t u32; + int32_t i32; + } v; + value_t vt; + + v.u32 = (((uint32_t)values[1]) << 16) | ((uint32_t)values[0]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned int32 value is %" PRIi32, + v.i32); + + CAST_TO_VALUE_T(ds, vt, v.i32); + mb_submit(host, slave, data, vt); } else if (data->register_type == REG_TYPE_INT16) { union { uint16_t u16; @@ -563,6 +597,17 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ CAST_TO_VALUE_T(ds, vt, v32); mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_UINT32_CDAB) { + uint32_t v32; + value_t vt; + + v32 = (((uint32_t)values[1]) << 16) | ((uint32_t)values[0]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned uint32 value is %" PRIu32, + v32); + + CAST_TO_VALUE_T(ds, vt, v32); + mb_submit(host, slave, data, vt); } else /* if (data->register_type == REG_TYPE_UINT16) */ { value_t vt; @@ -575,7 +620,7 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ mb_submit(host, slave, data, vt); } - return (0); + return 0; } /* }}} int mb_read_data */ static int mb_read_slave(mb_host_t *host, mb_slave_t *slave) /* {{{ */ @@ -584,7 +629,7 @@ static int mb_read_slave(mb_host_t *host, mb_slave_t *slave) /* {{{ */ int status; if ((host == NULL) || (slave == NULL)) - return (EINVAL); + return EINVAL; success = 0; for (mb_data_t *data = slave->collect; data != NULL; data = data->next) { @@ -594,9 +639,9 @@ static int mb_read_slave(mb_host_t *host, mb_slave_t *slave) /* {{{ */ } if (success == 0) - return (-1); + return -1; else - return (0); + return 0; } /* }}} int mb_read_slave */ static int mb_read(user_data_t *user_data) /* {{{ */ @@ -606,7 +651,7 @@ static int mb_read(user_data_t *user_data) /* {{{ */ int status; if ((user_data == NULL) || (user_data->data == NULL)) - return (EINVAL); + return EINVAL; host = user_data->data; @@ -618,9 +663,9 @@ static int mb_read(user_data_t *user_data) /* {{{ */ } if (success == 0) - return (-1); + return -1; else - return (0); + return 0; } /* }}} int mb_read */ /* Free functions */ @@ -681,7 +726,7 @@ static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string(ci, &data.name); if (status != 0) - return (status); + return status; for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -702,12 +747,18 @@ static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */ data.register_type = REG_TYPE_INT16; else if (strcasecmp("Int32", tmp) == 0) data.register_type = REG_TYPE_INT32; + else if (strcasecmp("Int32LE", tmp) == 0) + data.register_type = REG_TYPE_INT32_CDAB; else if (strcasecmp("Uint16", tmp) == 0) data.register_type = REG_TYPE_UINT16; else if (strcasecmp("Uint32", tmp) == 0) data.register_type = REG_TYPE_UINT32; + else if (strcasecmp("Uint32LE", tmp) == 0) + data.register_type = REG_TYPE_UINT32_CDAB; else if (strcasecmp("Float", tmp) == 0) data.register_type = REG_TYPE_FLOAT; + else if (strcasecmp("FloatLE", tmp) == 0) + data.register_type = REG_TYPE_FLOAT_CDAB; else { ERROR("Modbus plugin: The register type \"%s\" is unknown.", tmp); status = -1; @@ -752,7 +803,7 @@ static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */ sfree(data.name); - return (status); + return status; } /* }}} int mb_config_add_data */ static int mb_config_set_host_address(mb_host_t *host, /* {{{ */ @@ -761,7 +812,7 @@ static int mb_config_set_host_address(mb_host_t *host, /* {{{ */ int status; if ((host == NULL) || (address == NULL)) - return (EINVAL); + return EINVAL; struct addrinfo ai_hints = { /* XXX: libmodbus can only handle IPv4 addresses. */ @@ -770,11 +821,9 @@ static int mb_config_set_host_address(mb_host_t *host, /* {{{ */ status = getaddrinfo(address, /* service = */ NULL, &ai_hints, &ai_list); if (status != 0) { - char errbuf[1024]; ERROR("Modbus plugin: getaddrinfo failed: %s", - (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) - : gai_strerror(status)); - return (status); + (status == EAI_SYSTEM) ? STRERRNO : gai_strerror(status)); + return status; } for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; @@ -797,7 +846,7 @@ static int mb_config_set_host_address(mb_host_t *host, /* {{{ */ host->node); } - return (status); + return status; } /* }}} int mb_config_set_host_address */ static int mb_config_add_slave(mb_host_t *host, oconfig_item_t *ci) /* {{{ */ @@ -806,11 +855,11 @@ static int mb_config_add_slave(mb_host_t *host, oconfig_item_t *ci) /* {{{ */ int status; if ((host == NULL) || (ci == NULL)) - return (EINVAL); + return EINVAL; slave = realloc(host->slaves, sizeof(*slave) * (host->slaves_num + 1)); if (slave == NULL) - return (ENOMEM); + return ENOMEM; host->slaves = slave; slave = host->slaves + host->slaves_num; memset(slave, 0, sizeof(*slave)); @@ -818,7 +867,7 @@ static int mb_config_add_slave(mb_host_t *host, oconfig_item_t *ci) /* {{{ */ status = cf_util_get_int(ci, &slave->id); if (status != 0) - return (status); + return status; for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -852,7 +901,7 @@ static int mb_config_add_slave(mb_host_t *host, oconfig_item_t *ci) /* {{{ */ else /* if (status != 0) */ data_free_all(slave->collect); - return (status); + return status; } /* }}} int mb_config_add_slave */ static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ @@ -862,17 +911,17 @@ static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ host = calloc(1, sizeof(*host)); if (host == NULL) - return (ENOMEM); + return ENOMEM; host->slaves = NULL; status = cf_util_get_string_buffer(ci, host->host, sizeof(host->host)); if (status != 0) { sfree(host); - return (status); + return status; } if (host->host[0] == 0) { sfree(host); - return (EINVAL); + return EINVAL; } for (int i = 0; i < ci->children_num; i++) { @@ -934,7 +983,7 @@ static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ if (status == 0) { char name[1024]; - ssnprintf(name, sizeof(name), "modbus-%s", host->host); + snprintf(name, sizeof(name), "modbus-%s", host->host); plugin_register_complex_read(/* group = */ NULL, name, /* callback = */ mb_read, @@ -946,13 +995,13 @@ static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ host_free(host); } - return (status); + return status; } /* }}} int mb_config_add_host */ static int mb_config(oconfig_item_t *ci) /* {{{ */ { if (ci == NULL) - return (EINVAL); + return EINVAL; for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -965,7 +1014,7 @@ static int mb_config(oconfig_item_t *ci) /* {{{ */ ERROR("Modbus plugin: Unknown configuration option: %s", child->key); } - return (0); + return 0; } /* }}} int mb_config */ /* ========= */ @@ -975,12 +1024,10 @@ static int mb_shutdown(void) /* {{{ */ data_free_all(data_definitions); data_definitions = NULL; - return (0); + return 0; } /* }}} int mb_shutdown */ void module_register(void) { plugin_register_complex_config("modbus", mb_config); plugin_register_shutdown("modbus", mb_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */