#include "mb2hal.h"
retCode parse_main_args(int argc, char **argv)
{
char *fnct_name = "parse_main_args";
char *arg_filename;
char *tmp;
if (argc != 2) {
ERR(gbl.init_dbg, "wrong number of args");
return retERR;
}
if (strncmp(argv[1], "config=", 7) != 0) { ERR(gbl.init_dbg, "config parameter not found");
return retERR;
}
arg_filename = argv[1];
arg_filename += 7;
if (*arg_filename == '\"') { arg_filename++;
tmp = arg_filename;
while (*tmp != '\"' && *tmp != 0) {
tmp++;
}
*tmp = 0; }
gbl.ini_file_path = strdup(arg_filename);
return retOK;
}
retCode parse_ini_file()
{
char *fnct_name = "parse_ini_file";
int counter;
if (gbl.ini_file_ptr == NULL) {
ERR(gbl.init_dbg, "gbl.ini_file_ptr NULL pointer");
return retERR;
}
if (parse_common_section() != retOK) {
ERR(gbl.init_dbg, "parse_common_section failed");
return retERR;
}
gbl.mb_links = malloc(sizeof(mb_link_t) * gbl.tot_mb_tx);
if (gbl.mb_links == NULL) {
ERR(gbl.init_dbg, "malloc gbl.mb_links failed [%s]", strerror(errno));
return retERR;
}
memset(gbl.mb_links, 0, sizeof(mb_link_t) * gbl.tot_mb_tx);
gbl.mb_tx = malloc(sizeof(mb_tx_t) * gbl.tot_mb_tx);
if (gbl.mb_tx == NULL) {
ERR(gbl.init_dbg, "malloc gbl.mb_tx failed [%s]", strerror(errno));
return retERR;
}
memset(gbl.mb_tx, 0, sizeof(mb_tx_t) * gbl.tot_mb_tx);
for (counter = 0; counter < gbl.tot_mb_tx; counter++) {
if (parse_transaction_section(counter) != retOK) {
ERR(gbl.init_dbg, "parse_transaction_section %d failed", counter);
return retERR;
}
OK(gbl.init_dbg, "parse_transaction_section %d OK", counter);
}
return retOK;
}
retCode parse_common_section()
{
char *fnct_name = "parse_common_section";
char *section = "MB2HAL_INIT", *tag;
const char *tmpstr;
if (gbl.ini_file_ptr == NULL) {
ERR(gbl.init_dbg, "gbl.ini_file_ptr NULL pointer");
return retERR;
}
tag = "INIT_DEBUG"; iniFindInt(gbl.ini_file_ptr, tag, section, &gbl.init_dbg);
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, gbl.init_dbg);
tag = "HAL_MODULE_NAME"; tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
gbl.hal_mod_name = strdup(tmpstr);
}
DBG(gbl.init_dbg, "[%s] [%s] [%s]", section, tag, gbl.hal_mod_name);
tag = "SLOWDOWN"; iniFindDouble(gbl.ini_file_ptr, tag, section, &gbl.slowdown);
DBG(gbl.init_dbg, "[%s] [%s] [%0.3f]", section, tag, gbl.slowdown);
tag = "TOTAL_TRANSACTIONS"; if (iniFindInt(gbl.ini_file_ptr, tag, section, &gbl.tot_mb_tx) != 0) {
ERR(gbl.init_dbg, "required [%s] [%s] not found", section, tag);
return retERR;
}
if (gbl.tot_mb_tx <= 0) {
ERR(gbl.init_dbg, "[%s] [%s] [%d], must be > 0", section, tag, gbl.tot_mb_tx);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, gbl.tot_mb_tx);
return retOK;
}
#define NAME_ALLOC_SIZE 5
retCode parse_pin_names(const char * names_string, mb_tx_t *this_mb_tx)
{
char *fnct_name = "parse_pin_names";
int name_count = 0;
int name_buf_size = NAME_ALLOC_SIZE;
char **name_ptrs = malloc(sizeof(char *) * name_buf_size);
char *names = malloc(strlen(names_string) + 1);
if(name_ptrs == NULL || names == NULL)
{
ERR(gbl.init_dbg, "Failed allocating memory");
return retERR;
}
strcpy(names, names_string); char * name = strtok(names, ",");
while(name)
{
if(strlen(name) > HAL_NAME_LEN - 15) {
ERR(gbl.init_dbg, "pin name '%s' is too long", name);
return retERR;
}
if(name_count >= name_buf_size)
{
name_count += NAME_ALLOC_SIZE;
name_ptrs = realloc(name_ptrs, sizeof(char *) * name_buf_size);
if(name_ptrs == NULL)
{
ERR(gbl.init_dbg, "Failed allocating memory");
return retERR;
}
}
name_ptrs[name_count++]=name;
name = strtok(NULL, ",");
}
if(name_count == 0)
{
ERR(gbl.init_dbg, "no pin names specified");
return retERR;
}
this_mb_tx->mb_tx_nelem = name_count;
this_mb_tx->mb_tx_names = name_ptrs;
return retOK;
}
retCode parse_transaction_section(const int mb_tx_num)
{
char *fnct_name = "parse_transaction_section";
char section[20];
char *tag;
const char *tmpstr;
mb_tx_t *this_mb_tx;
if (gbl.ini_file_ptr == NULL) {
ERR(gbl.init_dbg, "gbl.ini_file_ptr NULL pointer");
return retERR;
}
if (mb_tx_num < 0 || mb_tx_num > gbl.tot_mb_tx) {
ERR(gbl.init_dbg, "out of range");
return retERR;
}
this_mb_tx = &gbl.mb_tx[mb_tx_num];
if (gbl.ini_file_ptr == NULL || mb_tx_num < 0 || mb_tx_num > gbl.tot_mb_tx) {
ERR(gbl.init_dbg, "parameter error");
return retERR;
}
snprintf(section, sizeof(section)-1, "TRANSACTION_%02d", mb_tx_num);
tag = "LINK_TYPE"; tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
if (strcasecmp(tmpstr, "tcp") == retOK) {
this_mb_tx->cfg_link_type = linkTCP;
strcpy(this_mb_tx->cfg_link_type_str, tmpstr);
}
else if (strcasecmp(tmpstr, "serial") == retOK) {
this_mb_tx->cfg_link_type = linkRTU;
strcpy(this_mb_tx->cfg_link_type_str, tmpstr);
}
else {
this_mb_tx->cfg_link_type = -1;
strcpy(this_mb_tx->cfg_link_type_str, "");
ERR(gbl.init_dbg, "[%s] [%s] [%s] is not valid", section, tag, tmpstr);
return retERR;
}
}
else {
if (mb_tx_num > 0) { this_mb_tx->cfg_link_type = gbl.mb_tx[mb_tx_num-1].cfg_link_type;
strcpy(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str);
}
else { this_mb_tx->cfg_link_type = -1;
strcpy(this_mb_tx->cfg_link_type_str, "");
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%s] [%d]", section, tag, this_mb_tx->cfg_link_type_str, this_mb_tx->cfg_link_type);
if (this_mb_tx->cfg_link_type == linkTCP) { if (parse_tcp_subsection(section, mb_tx_num) != retOK) {
ERR(gbl.init_dbg, "parsing error");
return retERR;
}
}
else { if (parse_serial_subsection(section, mb_tx_num) != retOK) {
ERR(gbl.init_dbg, "parsing error");
return retERR;
}
}
tag = "MB_SLAVE_ID"; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->mb_tx_slave_id) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->mb_tx_slave_id = gbl.mb_tx[mb_tx_num-1].mb_tx_slave_id;
}
else {
this_mb_tx->mb_tx_slave_id = -1;
ERR(gbl.init_dbg, "required [%s] [%s] not found, and previous LINK_TYPE is useless", section, tag);
return retERR;
}
}
else { this_mb_tx->mb_tx_slave_id = -1;
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->mb_tx_slave_id);
tag = "FIRST_ELEMENT"; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->mb_tx_1st_addr) != 0) {
ERR(gbl.init_dbg, "required [%s] [%s] not found", section, tag);
return retERR;
}
if (this_mb_tx->mb_tx_1st_addr < 0) {
ERR(gbl.init_dbg, "[%s] [%s] [%d] out of range", section, tag, this_mb_tx->mb_tx_1st_addr);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->mb_tx_1st_addr);
tag = "PIN_NAMES";
tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
if(parse_pin_names(tmpstr, this_mb_tx) != retOK)
{
ERR(gbl.init_dbg, "[%s] [%s] [%s] list format error", section, tag, tmpstr);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%s]", section, tag, tmpstr);
}
else {
this_mb_tx->mb_tx_names = NULL;
}
tag = "NELEMENTS"; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->mb_tx_nelem) != 0 &&
this_mb_tx->mb_tx_names == NULL) {
ERR(gbl.init_dbg, "required [%s] [%s] or [%s] [PIN_NAMES] were not found", section, tag, section);
return retERR;
}
if (this_mb_tx->mb_tx_nelem < 1) {
ERR(gbl.init_dbg, "[%s] [%s] [%d] out of range", section, tag, this_mb_tx->mb_tx_nelem);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->mb_tx_nelem);
tag = "MAX_UPDATE_RATE"; this_mb_tx->cfg_update_rate = 0; if (iniFindDouble(gbl.ini_file_ptr, tag, section, &this_mb_tx->cfg_update_rate) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->cfg_update_rate = gbl.mb_tx[mb_tx_num-1].cfg_update_rate;
}
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%0.3f]", section, tag, this_mb_tx->cfg_update_rate);
tag = "MB_RESPONSE_TIMEOUT_MS"; this_mb_tx->mb_response_timeout_ms = MB2HAL_DEFAULT_MB_RESPONSE_TIMEOUT_MS; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->mb_response_timeout_ms) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->mb_response_timeout_ms = gbl.mb_tx[mb_tx_num-1].mb_response_timeout_ms;
}
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->mb_response_timeout_ms);
tag = "MB_BYTE_TIMEOUT_MS"; this_mb_tx->mb_byte_timeout_ms = MB2HAL_DEFAULT_MB_BYTE_TIMEOUT_MS; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->mb_byte_timeout_ms) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->mb_byte_timeout_ms = gbl.mb_tx[mb_tx_num-1].mb_byte_timeout_ms;
}
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->mb_byte_timeout_ms);
tag = "DEBUG"; this_mb_tx->cfg_debug = debugERR; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->cfg_debug) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->cfg_debug = gbl.mb_tx[mb_tx_num-1].cfg_debug;
}
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->cfg_debug);
tag = "MB_TX_CODE"; tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
int i;
for (i=0 ; i<mbtxMAX; i++) {
if (strcasecmp(tmpstr, gbl.mb_tx_fncts[i]) == 0) {
this_mb_tx->mb_tx_fnct = i;
strncpy(this_mb_tx->mb_tx_fnct_name, tmpstr, sizeof(this_mb_tx->mb_tx_fnct_name)-1);
break;
}
}
if (this_mb_tx->mb_tx_fnct <= mbtxERR || this_mb_tx->mb_tx_fnct >= mbtxMAX) {
ERR(gbl.init_dbg, "[%s] [%s] [%s] out of range", section, tag, tmpstr);
return retERR;
}
}
else {
ERR(gbl.init_dbg, "required [%s] [%s] not found", section, tag);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%s] [%d]", section, tag, this_mb_tx->mb_tx_fnct_name, this_mb_tx->mb_tx_fnct);
tag = "HAL_TX_NAME"; tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
strncpy(this_mb_tx->hal_tx_name, tmpstr, HAL_NAME_LEN);
}
else {
sprintf(this_mb_tx->hal_tx_name, "%02d", mb_tx_num);
}
DBG(gbl.init_dbg, "[%s] [%s] [%s]", section, tag, this_mb_tx->hal_tx_name);
return retOK;
}
retCode parse_tcp_subsection(const char *section, const int mb_tx_num)
{
char *fnct_name="parse_tcp_subsection";
char *tag;
const char *tmpstr;
mb_tx_t *this_mb_tx;
if (gbl.ini_file_ptr == NULL || section == NULL) {
ERR(gbl.init_dbg, "gbl.ini_file_ptr NULL pointer");
return retERR;
}
if (mb_tx_num < 0 || mb_tx_num > gbl.tot_mb_tx) {
ERR(gbl.init_dbg, "out of range");
return retERR;
}
this_mb_tx = &gbl.mb_tx[mb_tx_num];
tag = "TCP_IP"; tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
strncpy(this_mb_tx->cfg_tcp_ip, tmpstr, sizeof(this_mb_tx->cfg_tcp_ip)-1);
}
else {
if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
strcpy(this_mb_tx->cfg_tcp_ip, gbl.mb_tx[mb_tx_num-1].cfg_tcp_ip);
}
else {
strcpy(this_mb_tx->cfg_tcp_ip, "");
ERR(gbl.init_dbg, "required [%s] [%s] not found, and previous LINK_TYPE is useless", section, tag);
return retERR;
}
}
else { strcpy(this_mb_tx->cfg_tcp_ip, "");
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%s]", section, tag, this_mb_tx->cfg_tcp_ip);
tag = "TCP_PORT"; this_mb_tx->cfg_tcp_port = MB2HAL_DEFAULT_TCP_PORT; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->cfg_tcp_port) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->cfg_tcp_port = gbl.mb_tx[mb_tx_num-1].cfg_tcp_port;
}
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->cfg_tcp_port);
return retOK;
}
retCode parse_serial_subsection(const char *section, const int mb_tx_num)
{
char *fnct_name="parse_serial_subsection";
char *tag;
const char *tmpstr;
mb_tx_t *this_mb_tx;
if (gbl.ini_file_ptr == NULL || section == NULL) {
ERR(gbl.init_dbg, "gbl.ini_file_ptr NULL pointer");
return retERR;
}
if (mb_tx_num < 0 || mb_tx_num > gbl.tot_mb_tx) {
ERR(gbl.init_dbg, "out of range");
return retERR;
}
this_mb_tx = &gbl.mb_tx[mb_tx_num];
tag = "SERIAL_PORT"; tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
strncpy(this_mb_tx->cfg_serial_device, tmpstr, sizeof(this_mb_tx->cfg_serial_device)-1);
}
else {
if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
strcpy(this_mb_tx->cfg_serial_device, gbl.mb_tx[mb_tx_num-1].cfg_serial_device);
}
else {
strcpy(this_mb_tx->cfg_serial_device, "");
ERR(gbl.init_dbg, "required [%s] [%s] not found, and previous LINK_TYPE is useless", section, tag);
return retERR;
}
}
else { strcpy(this_mb_tx->cfg_serial_device, "");
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%s]", section, tag, this_mb_tx->cfg_serial_device);
tag = "SERIAL_BAUD"; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->cfg_serial_baud) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->cfg_serial_baud = gbl.mb_tx[mb_tx_num-1].cfg_serial_baud;
}
else {
this_mb_tx->cfg_serial_baud = -1;
ERR(gbl.init_dbg, "required [%s] [%s] not found, and previous LINK_TYPE is useless", section, tag);
return retERR;
}
}
else { this_mb_tx->cfg_serial_baud = -1;
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->cfg_serial_baud);
tag = "SERIAL_BITS"; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->cfg_serial_data_bit) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->cfg_serial_data_bit = gbl.mb_tx[mb_tx_num-1].cfg_serial_data_bit;
}
else {
this_mb_tx->cfg_serial_data_bit = -1;
ERR(gbl.init_dbg, "required [%s] [%s] not found, and previous LINK_TYPE is useless", section, tag);
return retERR;
}
}
else { this_mb_tx->cfg_serial_data_bit = -1;
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
if (check_int_in(4, this_mb_tx->cfg_serial_data_bit, 5, 6, 7, 8) != retOK) {
ERR(gbl.init_dbg, "[%s] [%s] [%d] out of range", section, tag, this_mb_tx->cfg_serial_data_bit);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->cfg_serial_data_bit);
tag = "SERIAL_PARITY"; tmpstr = iniFind(gbl.ini_file_ptr, tag, section);
if (tmpstr != NULL) {
strncpy(this_mb_tx->cfg_serial_parity, tmpstr, sizeof(this_mb_tx->cfg_serial_parity)-1);
}
else {
if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
strcpy(this_mb_tx->cfg_serial_parity, gbl.mb_tx[mb_tx_num-1].cfg_serial_parity);
}
else {
strcpy(this_mb_tx->cfg_serial_parity, "");
ERR(gbl.init_dbg, "required [%s] [%s] not found, and previous LINK_TYPE is useless", section, tag);
return retERR;
}
}
else { strcpy(this_mb_tx->cfg_serial_parity, "");
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
if (check_str_in(3, this_mb_tx->cfg_serial_parity, "even", "odd", "none") != retOK) {
ERR(gbl.init_dbg, "[%s] [%s] [%s] out of range", section, tag, this_mb_tx->cfg_serial_parity);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%s]", section, tag, this_mb_tx->cfg_serial_parity);
tag = "SERIAL_STOP"; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->cfg_serial_stop_bit) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->cfg_serial_stop_bit = gbl.mb_tx[mb_tx_num-1].cfg_serial_stop_bit;
}
else {
this_mb_tx->cfg_serial_stop_bit = -1;
ERR(gbl.init_dbg, "required [%s] [%s] not found, and previous LINK_TYPE is useless", section, tag);
return retERR;
}
}
else { this_mb_tx->cfg_serial_stop_bit = -1;
ERR(gbl.init_dbg, "required 1st time [%s] [%s] not found", section, tag);
return retERR;
}
}
if (check_int_in(2, this_mb_tx->cfg_serial_stop_bit, 1, 2) != retOK) {
ERR(gbl.init_dbg, "[%s] [%s] [%d] out of range", section, tag, this_mb_tx->cfg_serial_stop_bit);
return retERR;
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->cfg_serial_stop_bit);
tag = "SERIAL_DELAY_MS"; this_mb_tx->cfg_serial_delay_ms = 0; if (iniFindInt(gbl.ini_file_ptr, tag, section, &this_mb_tx->cfg_serial_delay_ms) != 0) { if (mb_tx_num > 0) { if (strcasecmp(this_mb_tx->cfg_link_type_str, gbl.mb_tx[mb_tx_num-1].cfg_link_type_str) == 0) {
this_mb_tx->cfg_serial_delay_ms = gbl.mb_tx[mb_tx_num-1].cfg_serial_delay_ms;
}
}
}
DBG(gbl.init_dbg, "[%s] [%s] [%d]", section, tag, this_mb_tx->cfg_serial_delay_ms);
return retOK;
}
retCode check_int_in(int n_args, const int int_value, ...)
{
va_list ap;
int counter;
va_start(ap, int_value);
for (counter = 2; counter < (n_args+2); counter++) {
if (int_value == va_arg(ap, int)) {
va_end(ap);
return retOK; }
}
va_end(ap);
return retERR; }
retCode check_str_in(int n_args, const char *str_value, ...)
{
va_list ap;
int counter;
if (str_value == NULL) {
return retERR; }
va_start(ap, str_value);
for (counter = 2; counter < (n_args+2); counter++) {
if (strcasecmp(str_value, va_arg(ap, char *)) == 0) {
va_end(ap);
return retOK; }
}
va_end(ap);
return retERR; }
retCode init_mb_links()
{
char *fnct_name="init_mb_links";
int tx_counter, lk_counter;
int isNewLink;
mb_link_t *this_mb_link;
mb_tx_t *this_mb_tx;
gbl.tot_mb_links = 0;
for (tx_counter = 0; tx_counter < gbl.tot_mb_tx; tx_counter++) {
this_mb_tx = &gbl.mb_tx[tx_counter];
isNewLink = 1; if (this_mb_tx->cfg_link_type == linkRTU) { for (lk_counter = 0; lk_counter < gbl.tot_mb_links; lk_counter++) {
if (strcasecmp(this_mb_tx->cfg_serial_device, gbl.mb_links[lk_counter].lp_serial_device) == 0) {
isNewLink = 0; this_mb_tx->mb_link_num = lk_counter; break;
}
}
}
else { for (lk_counter = 0; lk_counter < gbl.tot_mb_links; lk_counter++) {
if (strcasecmp(this_mb_tx->cfg_tcp_ip, gbl.mb_links[lk_counter].lp_tcp_ip) == 0) {
isNewLink = 0; this_mb_tx->mb_link_num = lk_counter; break;
}
}
}
if (isNewLink != 0) { this_mb_tx->mb_link_num = gbl.mb_links[gbl.tot_mb_links].mb_link_num = gbl.tot_mb_links; this_mb_link = &gbl.mb_links[gbl.tot_mb_links];
this_mb_link->lp_link_type = this_mb_tx->cfg_link_type;
if (this_mb_link->lp_link_type == linkRTU) { strncpy(this_mb_link->lp_serial_device, this_mb_tx->cfg_serial_device, MB2HAL_MAX_DEVICE_LENGTH-1);
this_mb_link->lp_serial_baud=this_mb_tx->cfg_serial_baud;
if (strcasecmp(this_mb_tx->cfg_serial_parity, "even") == 0) {
this_mb_link->lp_serial_parity = 'E';
}
else if (strcasecmp(this_mb_tx->cfg_serial_parity, "odd") == 0) {
this_mb_link->lp_serial_parity = 'O';
}
else { this_mb_link->lp_serial_parity = 'N';
}
this_mb_link->lp_serial_data_bit=this_mb_tx->cfg_serial_data_bit;
this_mb_link->lp_serial_stop_bit=this_mb_tx->cfg_serial_stop_bit;
this_mb_link->modbus = modbus_new_rtu(this_mb_link->lp_serial_device,
this_mb_link->lp_serial_baud, this_mb_link->lp_serial_parity,
this_mb_link->lp_serial_data_bit, this_mb_link->lp_serial_stop_bit);
if (this_mb_link->modbus == NULL) {
ERR(gbl.init_dbg, "modbus_new_rtu failed [%s] [%d] [%c] [%d] [%d]", this_mb_link->lp_serial_device,
this_mb_link->lp_serial_baud, this_mb_link->lp_serial_parity, this_mb_link->lp_serial_data_bit,
this_mb_link->lp_serial_stop_bit);
return retERR;
}
}
else { strncpy(this_mb_link->lp_tcp_ip, this_mb_tx->cfg_tcp_ip, sizeof(this_mb_tx->cfg_tcp_ip)-1);
this_mb_link->lp_tcp_port=this_mb_tx->cfg_tcp_port;
this_mb_link->modbus = modbus_new_tcp(this_mb_link->lp_tcp_ip, this_mb_link->lp_tcp_port);
if (this_mb_link->modbus == NULL) {
ERR(gbl.init_dbg, "modbus_new_tcp failed [%s] [%d]", this_mb_link->lp_tcp_ip, this_mb_link->lp_tcp_port);
return retERR;
}
}
if (this_mb_link->modbus)
{
gbl.tot_mb_links++; }
}
}
for (lk_counter = 0; lk_counter < gbl.tot_mb_links; lk_counter++) {
this_mb_link = &gbl.mb_links[lk_counter];
if (this_mb_link->lp_link_type == linkRTU) { DBG(gbl.init_dbg, "LINK %d (RTU) link_type[%d] device[%s] baud[%d] data[%d] parity[%c] stop[%d] fd[%d]",
lk_counter, this_mb_link->lp_link_type, this_mb_link->lp_serial_device,
this_mb_link->lp_serial_baud, this_mb_link->lp_serial_data_bit, this_mb_link->lp_serial_parity,
this_mb_link->lp_serial_stop_bit, modbus_get_socket(this_mb_link->modbus));
}
else { DBG(gbl.init_dbg, "LINK %d (TCP) link_type[%d] IP[%s] port[%d] fd[%d]",
lk_counter, this_mb_link->lp_link_type, this_mb_link->lp_tcp_ip,
this_mb_link->lp_tcp_port, modbus_get_socket(this_mb_link->modbus));
}
}
gbl.mb_links = realloc(gbl.mb_links, sizeof(mb_link_t) * gbl.tot_mb_links);
if (gbl.mb_links == NULL) {
DBG(gbl.init_dbg, "realloc gbl.mb_links failed [%s]", strerror(errno));
return retERR;
}
return retOK;
}
retCode init_mb_tx()
{
char *fnct_name="init_mb_tx";
int tx_counter;
mb_tx_t *this_mb_tx;
for (tx_counter = 0; tx_counter < gbl.tot_mb_tx; tx_counter++) {
this_mb_tx = &gbl.mb_tx[tx_counter];
this_mb_tx->mb_tx_num = tx_counter;
this_mb_tx->protocol_debug = (this_mb_tx->cfg_debug >= debugDEBUG)? 1 : 0;
if (this_mb_tx->cfg_update_rate > 0) {
this_mb_tx->time_increment = 1.0 / this_mb_tx->cfg_update_rate; }
this_mb_tx->next_time = 0;
DBG(gbl.init_dbg, "MB_TX %d lk_n[%d] tx_n[%d] cfg_dbg[%d] lk_dbg[%d] t_inc[%0.3f] nxt_t[%0.3f]",
tx_counter, this_mb_tx->mb_link_num, this_mb_tx->mb_tx_num, this_mb_tx->cfg_debug,
this_mb_tx->protocol_debug, this_mb_tx->time_increment, this_mb_tx->next_time);
}
return retOK;
}