Files
ebusd/lib/ebus-cmd.c
T

1023 lines
22 KiB
C

/*
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
*
* This file is part of ebusd.
*
* ebusd is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ebusd is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ebusd. If not, see http://www.gnu.org/licenses/.
*/
/**
* @file ebus-cmd.c
* @brief ebus command file functions
* @author roland.jax@liwest.at
* @version 0.1
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <dirent.h>
#include "log.h"
#include "ebus-decode.h"
#include "ebus-cmd.h"
static struct cycbuf *cyc = NULL;
static int cyclen = 0;
static struct commands *com = NULL;
static int comlen = 0;
void
eb_cmd_uppercase(char *buf)
{
while (*buf++ != '\0')
*buf = toupper((unsigned char) *buf);
}
int
eb_cmd_check_type(int id, const char *type)
{
if (strncasecmp(com[id].type, type, 3) == 0)
return YES;
else
return NO;
}
int
eb_cmd_get_s_type(int id)
{
if (strncasecmp(com[id].s_type, EBUS_MSG_BROADCAST_TXT, 2) == 0) {
return EBUS_MSG_BROADCAST;
} else if(strncasecmp(com[id].s_type, EBUS_MSG_MASTER_MASTER_TXT, 2) == 0) {
return EBUS_MSG_MASTER_MASTER;
} else if(strncasecmp(com[id].s_type, EBUS_MSG_MASTER_SLAVE_TXT, 2) == 0) {
return EBUS_MSG_MASTER_SLAVE;
} else {
log_print(L_ERR, "message type %s unkown", com[id].s_type);
return -1;
}
}
void
eb_cmd_set_cyc_buf(int id, const unsigned char *msg, int msglen)
{
int i;
for (i = 0; i < cyclen; i++)
if (cyc[i].id == com[id].id)
break;
memcpy(cyc[i].buf, msg, msglen);
cyc[i].buflen = msglen;
}
void
eb_cmd_get_cyc_buf(int id, unsigned char *msg, int *msglen)
{
int i;
for (i = 0; i < cyclen; i++)
if (cyc[i].id == com[id].id)
break;
*msglen = cyc[i].buflen;
memcpy(msg, cyc[i].buf, *msglen);
}
int
eb_cmd_search_com_cyc(const unsigned char *hex, int hexlen)
{
unsigned char hlp[(CMD_SIZE_S_MSG * 2) + 1];
int i;
if (hexlen > (CMD_SIZE_S_MSG * 2)) {
log_print(L_ERR, "hexlen: %d > hlp: %d ", hexlen, (CMD_SIZE_S_MSG * 2));
return -2;
}
memset(hlp, '\0', sizeof(hlp));
for (i = 0; i < hexlen; i++)
sprintf((char *) &hlp[2 * i], "%02X", hex[i]);
for (i = 0; i < cyclen; i++) {
if (memcmp(hlp, cyc[i].msg, strlen((const char *) cyc[i].msg)) == 0) {
log_print(L_NOT, " found: %s type: %s ==> id: %d",
cyc[i].msg, com[cyc[i].id].s_type, cyc[i].id);
return cyc[i].id;
}
}
return -1;
}
int
eb_cmd_search_com_id(const char *type, const char *class, const char *cmd)
{
int i;
for (i = 0; i < comlen; i++) {
if ((strncasecmp(type, com[i].type, strlen(com[i].type)) == 0)
&& (strncasecmp(class, com[i].class, strlen(com[i].class)) == 0)
&& strlen(class) == strlen(com[i].class)
&& (strncasecmp(cmd, com[i].cmd, strlen(com[i].cmd)) == 0)
&& strlen(cmd) == strlen(com[i].cmd)) {
log_print(L_NOT, " found: %s%s%02X%s type: %s ==> id: %d",
com[i].s_zz, com[i].s_cmd, com[i].s_len,
com[i].s_msg, com[i].s_type, i);
return i;
}
}
return -1;
}
int
eb_cmd_search_com(char *buf, char *data)
{
char *type, *class, *cmd, *tok;
int id;
type = strtok(buf, " ");
class = strtok(NULL, " .");
cmd = strtok(NULL, " .\n\r\t");
if (class != NULL && cmd != NULL) {
if (strncasecmp(type, "get", 3) == 0 ||
strncasecmp(type, "set", 3) == 0 ||
strncasecmp(type, "cyc", 3) == 0) {
log_print(L_NOT, "search: %s %s.%s", type, class, cmd);
id = eb_cmd_search_com_id(type, class, cmd);
if (id < 0)
return -1;
tok = strtok(NULL, "\n\r");
if (tok == NULL)
strncpy(data, "-", 1);
else
strncpy(data, tok, strlen(tok));
log_print(L_NOT, " data: %s", data);
return id;
}
}
return -1;
}
int
eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf)
{
char *c1, *c2, *c3, *c4;
char d_pos[CMD_SIZE_D_POS + 1];
int ret, i, j, p1, p2, p3, p4;
memset(d_pos, '\0', sizeof(d_pos));
strncpy(d_pos, com[id].elem[elem].d_pos, strlen(com[id].elem[elem].d_pos));
c1 = strtok(d_pos, " ,\n");
c2 = strtok(NULL, " ,\n");
c3 = strtok(NULL, " ,\n");
c4 = strtok(NULL, " ,\n");
p1 = c1 ? atoi(c1) : 0;
p2 = c2 ? atoi(c2) : 0;
p3 = c3 ? atoi(c3) : 0;
p4 = c4 ? atoi(c4) : 0;
log_print(L_DBG, "id: %d elem: %d p1: %d p2: %d p3: %d p4: %d", id, elem, p1, p2, p3, p4);
if (strncasecmp(com[id].elem[elem].d_type, "str", 3) == 0) {
sprintf(buf, "%s", &msg[1]);
} else if (strncasecmp(com[id].elem[elem].d_type, "bcd", 3) == 0) {
if (p1 > 0) {
int ii;
ret = eb_bcd_to_int(msg[p1], &ii);
ii *= com[id].elem[elem].d_fac;
sprintf(buf, "%d", ii);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d1b", 3) == 0) {
if (p1 > 0) {
int ii;
float ff;
ret = eb_d1b_to_int(msg[p1], &ii);
ff = ii * com[id].elem[elem].d_fac;
sprintf(buf, "%f", ff);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d1c", 3) == 0) {
if (p1 > 0) {
float ff;
ret = eb_d1c_to_float(msg[p1], &ff);
ff *= com[id].elem[elem].d_fac;
sprintf(buf, "%f", ff);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d2b", 3) == 0) {
if (p1 > 0 && p2 > 0) {
float ff;
if (p1 > p2)
ret = eb_d2b_to_float(msg[p2], msg[p1], &ff);
else
ret = eb_d2b_to_float(msg[p1], msg[p2], &ff);
ff *= com[id].elem[elem].d_fac;
sprintf(buf, "%f", ff);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d2c", 3) == 0) {
if (p1 > 0 && p2 > 0) {
float ff;
if (p1 > p2)
ret = eb_d2c_to_float(msg[p2], msg[p1], &ff);
else
ret = eb_d2c_to_float(msg[p1], msg[p2], &ff);
ff *= com[id].elem[elem].d_fac;
sprintf(buf, "%f", ff);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "bda", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0) {
int dd, mm, yy;
ret = eb_bcd_to_int(msg[p1], &dd);
ret = eb_bcd_to_int(msg[p2], &mm);
ret = eb_bcd_to_int(msg[p3], &yy);
ret = eb_dat_to_str(dd, mm, yy, buf);
if (ret < 0)
sprintf(buf, "error %s ==> %02x %02x %02x",
com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "hda", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0) {
ret = eb_dat_to_str(msg[p1], msg[p2], msg[p3], buf);
if (ret < 0)
sprintf(buf, "error %s ==> %02x %02x %02x",
com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "bti", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0) {
int hh, mm, ss;
ret = eb_bcd_to_int(msg[p1], &hh);
ret = eb_bcd_to_int(msg[p2], &mm);
ret = eb_bcd_to_int(msg[p3], &ss);
ret = eb_tim_to_str(hh, mm, ss, buf);
if (ret < 0)
sprintf(buf, "error %s ==> %02x %02x %02x",
com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "hti", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0) {
ret = eb_tim_to_str(msg[p1], msg[p2], msg[p3], buf);
if (ret < 0)
sprintf(buf, "error %s ==> %02x %02x %02x",
com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "bdy", 3) == 0) {
if (p1 > 0)
ret = eb_day_to_str(msg[p1], buf);
else
goto on_error;
} else if (strncasecmp(com[id].elem[elem].d_type, "hdy", 3) == 0) {
if (p1 > 0) {
msg[p1] = msg[p1] - 0x01;
ret = eb_day_to_str(msg[p1], buf);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "hex", 3) == 0) {
if (p1 > 0) {
if (p2 > msg[0])
p2 = msg[0];
if (p2 == 0 || p2 < p1)
p2 = p1;
for (i = 0, j = p1 - 1; i <= p2 - p1; i++, j++)
sprintf(&buf[3 * i], "%02x ", msg[j + 1]);
buf[i * 3 - 1] = '\0';
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "uch", 3) == 0) {
if (p1 > 0) {
unsigned char uch;
uch = msg[p1];
sprintf(buf, "%u", uch);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "sch", 3) == 0) {
if (p1 > 0) {
char sch;
sch = msg[p1];
sprintf(buf, "%d", sch);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "uin", 3) == 0) {
if (p1 > 0 && p2 > 0) {
unsigned int uin;
uin = msg[p1] + (msg[p2] << 8);
sprintf(buf, "%u", uin);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "sin", 3) == 0) {
if (p1 > 0 && p2 > 0) {
int sin;
sin = msg[p1] + (msg[p2] << 8);
sprintf(buf, "%d", sin);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "ulg", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) {
unsigned long ulg;
ulg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24);
sprintf(buf, "%lu", ulg);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "slg", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) {
long slg;
slg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24);
sprintf(buf, "%ld", slg);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "flt", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) {
float ff;
ff = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24);
sprintf(buf, "%f", ff);
} else {
goto on_error;
}
}
log_print(L_DBG, "buf: %s", buf);
return 0;
on_error:
strcpy(buf, "error decode");
return -1;
}
int
eb_cmd_decode(int id, char *part, char *data, unsigned char *msg, char *buf)
{
char *tok;
char tmp[CMD_DATA_SIZE], hlp[CMD_DATA_SIZE];
int ret, i, found;
/* walk through all elements */
for (i = 0; i < com[id].d_elem; i++) {
memset(tmp, '\0', sizeof(tmp));
strncpy(tmp, data, strlen(data));
/* "-" indicate no sub command, so we print all */
tok = strtok(tmp, " \n\r\t");
if (tok == NULL || strncasecmp(tok, "-", 1) == 0)
found = YES;
else
found = NO;
/* search sub command */
while (tok != NULL && found == NO) {
if (strncasecmp(com[id].elem[i].d_sub, tok,
strlen(com[id].elem[i].d_sub)) == 0 &&
strncasecmp(com[id].elem[i].d_part, part, 2) == 0) {
found = YES;
break;
}
tok = strtok(NULL, " \n\r\t");
}
if (strncasecmp(com[id].elem[i].d_part, part, 2) == 0 &&
found == YES) {
memset(hlp, '\0', sizeof(hlp));
ret = eb_cmd_decode_value(id, i, msg, hlp);
if (ret < 0) {
strncat(buf, "\n", 1);
return -1;
}
if (i > 0)
strncat(buf, " ", 1);
strncat(buf, hlp, strlen(hlp));
}
}
return 0;
}
int
eb_cmd_encode_value(int id, int elem, char *data, unsigned char *msg, char *buf)
{
char *c1, *c2, *c3;
char d_pos[CMD_SIZE_D_POS + 1];
unsigned char bcd, d1b, d1c, d2b[2], d2c[2];
int ret, i, j, p1, p2, p3;
float f;
memset(d_pos, '\0', sizeof(d_pos));
strncpy(d_pos, com[id].elem[elem].d_pos, strlen(com[id].elem[elem].d_pos));
c1 = strtok(d_pos, " ,\n");
c2 = strtok(NULL, " ,\n");
c3 = strtok(NULL, " ,\n");
p1 = c1 ? atoi(c1) : 0;
p2 = c2 ? atoi(c2) : 0;
p3 = c3 ? atoi(c3) : 0;
log_print(L_DBG, "id: %d elem: %d p1: %d p2: %d p3: %d data: %s",
id, elem, p1, p2, p3, data);
if (strncasecmp(com[id].elem[elem].d_type, "asc", 3) == 0) {
for (i = 0; i < strlen(data); i++)
sprintf((char *) &msg[i * 2], "%02x", data[i]);
} else if (strncasecmp(com[id].elem[elem].d_type, "bcd", 3) == 0) {
if (p1 > 0) {
i = (int) (atof(data) / com[id].elem[elem].d_fac);
ret = eb_int_to_bcd(i, &bcd);
sprintf((char *) msg, "%02x", bcd);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d1b", 3) == 0) {
if (p1 > 0) {
i = (int) (atof(data) / com[id].elem[elem].d_fac);
ret = eb_int_to_d1b(i, &d1b);
sprintf((char *) msg, "%02x", d1b);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d1c", 3) == 0) {
if (p1 > 0) {
f = (atof(data) / com[id].elem[elem].d_fac);
ret = eb_float_to_d1c(f, &d1c);
sprintf((char *) msg, "%02x", d1c);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d2b", 3) == 0) {
if (p1 > 0 && p2 > 0) {
f = (atof(data) / com[id].elem[elem].d_fac);
if (p1 > p2)
ret = eb_float_to_d2b(f, &d2b[1], &d2b[0]);
else
ret = eb_float_to_d2b(f, &d2b[0], &d2b[1]);
sprintf((char *) msg, "%02x%02x", d2b[0], d2b[1]);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "d2c", 3) == 0) {
if (p1 > 0 && p2 > 0) {
f = (atof(data) / com[id].elem[elem].d_fac);
if (p1 > p2)
ret = eb_float_to_d2c(f, &d2c[1], &d2c[0]);
else
ret = eb_float_to_d2c(f, &d2c[0], &d2c[1]);
sprintf((char *) msg, "%02x%02x", d2c[0], d2c[1]);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "hda", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0) {
int dd, mm, yy;
dd = atoi(strtok(data, " .\n"));
mm = atoi(strtok(NULL, " .\n"));
yy = atoi(strtok(NULL, " .\n"));
ret = eb_str_to_dat(dd, mm, yy, msg);
if (ret < 0)
sprintf(buf, "error ==> %d.%d.%d", dd, mm, yy);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "hti", 3) == 0) {
if (p1 > 0 && p2 > 0 && p3 > 0) {
int hh, mm, ss;
hh = atoi(strtok(data, " :\n"));
mm = atoi(strtok(NULL, " :\n"));
ss = atoi(strtok(NULL, " :\n"));
ret = eb_str_to_tim(hh, mm, ss, msg);
if (ret < 0)
sprintf(buf, "error ==> %d:%d:%d", hh, mm, ss);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "hdy", 3) == 0) {
if (p1 > 0) {
int day;
day = atoi(data);
sprintf((char *) msg, "%02x", day);
} else {
goto on_error;
}
} else if (strncasecmp(com[id].elem[elem].d_type, "hex", 3) == 0) {
for (i = 0, j = 0; data[i]; i++) {
if (isxdigit(data[i])) {
msg[j] = tolower(data[i]);
j++;
} else if (data[i] != ' ') {
goto on_error;
}
}
}
return 0;
on_error:
strcpy(buf, "error encode");
return -1;
}
int
eb_cmd_encode(int id, char *data, unsigned char *msg, char *buf)
{
char *tok, *toksave;
unsigned char hlp[CMD_SIZE_S_MSG + 1];
int ret, i;
tok = strtok_r(data, " \n\r\t", &toksave);
/* walk through all elements */
for (i = 0; i < com[id].d_elem; i++) {
if (tok != NULL) {
memset(hlp, '\0', sizeof(hlp));
ret = eb_cmd_encode_value(id, i, tok, hlp, buf);
if (ret < 0) {
strncat(buf, "\n", 1);
return -1;
}
strncat((char *) msg, (const char *) hlp, strlen((const char *) hlp));
} else {
return -1;
}
tok = strtok_r(NULL, " \n\r\t", &toksave);
}
if (strlen(buf) > 0)
strncat(buf, "\n", 1);
return 0;
}
void
eb_cmd_prepare(int id, char *data, unsigned char *msg, int *msglen, char *buf)
{
unsigned char tmp[CMD_SIZE_S_MSG + 1];
char str[CMD_SIZE_S_ZZ + CMD_SIZE_S_CMD + 2 + CMD_SIZE_S_MSG + 1];
char byte;
int ret, i, j, k;
int in[SERIAL_BUFSIZE];
/* encode msg */
memset(tmp, '\0', sizeof(tmp));
if (strncasecmp(com[id].type, "set", 3) == 0)
eb_cmd_encode(id, data, tmp, buf);
memset(str, '\0', sizeof(str));
sprintf(str, "%s%s%02X%s%s",
com[id].s_zz, com[id].s_cmd, com[id].s_len, com[id].s_msg, tmp);
memset(in, '\0', sizeof(in));
i = 0;
j = 0;
while (str[j] != '\0') {
byte = str[j];
if (i < sizeof(in)) {
ret = eb_htoi(&byte);
if (ret != -1) {
in[i] = ret;
i++;
}
}
j++;
}
memset(msg, '\0', sizeof(msg));
for (j = 0, k = 0; j < i; j += 2, k++)
msg[k] = (unsigned char) (in[j]*16 + in[j+1]);
*msglen = k;
}
void
eb_cmd_print(const char *type, int all, int detail)
{
int i, j;
for (i = 0; i < comlen; i++) {
if (strncasecmp(com[i].type, type, 1) == 0 || all) {
log_print(L_INF, "[%03d] %s : %22s.%-42s\t(type: %s)" \
" %s%s%-10s (len: %d) [%d] ==> %s",
com[i].id,
com[i].type,
com[i].class,
com[i].cmd,
com[i].s_type,
com[i].s_zz,
com[i].s_cmd,
com[i].s_msg,
com[i].s_len,
com[i].d_elem,
com[i].com
);
if (detail) {
for (j = 0; j < com[i].d_elem; j++) {
log_print(L_INF, "\t\t %-20s %-2s " \
"pos: %-10s\t%s [%5.2f] [%s] \t%s\t%s",
com[i].elem[j].d_sub,
com[i].elem[j].d_part,
com[i].elem[j].d_pos,
com[i].elem[j].d_type,
com[i].elem[j].d_fac,
com[i].elem[j].d_unit,
com[i].elem[j].d_valid,
com[i].elem[j].d_com
);
}
log_print(L_INF, "");
}
}
}
}
int
eb_cmd_fill(const char *tok)
{
int i;
com = (struct commands *) realloc(com, (comlen + 1) * sizeof(struct commands));
err_ret_if(com == NULL, -1);
memset(com + comlen, '\0', sizeof(struct commands));
/* id */
com[comlen].id = comlen;
/* type */
strncpy(com[comlen].type, tok, strlen(tok));
/* class */
tok = strtok(NULL, ";");
strncpy(com[comlen].class, tok, strlen(tok));
/* cmd */
tok = strtok(NULL, ";");
strncpy(com[comlen].cmd, tok, strlen(tok));
/* com */
tok = strtok(NULL, ";");
strncpy(com[comlen].com, tok, strlen(tok));
/* s_type */
tok = strtok(NULL, ";");
strncpy(com[comlen].s_type, tok, strlen(tok));
eb_cmd_uppercase(com[comlen].s_type);
/* s_zz */
tok = strtok(NULL, ";");
strncpy(com[comlen].s_zz, tok, strlen(tok));
eb_cmd_uppercase(com[comlen].s_zz);
/* s_cmd */
tok = strtok(NULL, ";");
strncpy(com[comlen].s_cmd, tok, strlen(tok));
eb_cmd_uppercase(com[comlen].s_cmd);
/* s_len */
tok = strtok(NULL, ";");
com[comlen].s_len = atoi(tok);
/* s_msg */
tok = strtok(NULL, ";");
if (strncasecmp(tok, "-", 1) != 0) {
strncpy(com[comlen].s_msg, tok, strlen(tok));
eb_cmd_uppercase(com[comlen].s_msg);
}
/* d_elem */
tok = strtok(NULL, ";");
com[comlen].d_elem = atoi(tok);
com[comlen].elem = (struct element *) malloc(com[comlen].d_elem * sizeof(struct element));
err_ret_if(com[comlen].elem == NULL, -1);
memset(com[comlen].elem, '\0', com[comlen].d_elem * sizeof(struct element));
for (i = 0; i < com[comlen].d_elem; i++) {
/* d_sub */
tok = strtok(NULL, ";");
if (strncasecmp(tok, "-", 1) != 0)
strncpy(com[comlen].elem[i].d_sub, tok, strlen(tok));
/* d_part */
tok = strtok(NULL, ";");
strncpy(com[comlen].elem[i].d_part, tok, strlen(tok));
/* d_pos */
tok = strtok(NULL, ";");
strncpy(com[comlen].elem[i].d_pos, tok, strlen(tok));
/* d_type */
tok = strtok(NULL, ";");
strncpy(com[comlen].elem[i].d_type, tok, strlen(tok));
/* d_fac */
tok = strtok(NULL, ";");
com[comlen].elem[i].d_fac = atof(tok);
/* d_unit */
tok = strtok(NULL, ";");
strncpy(com[comlen].elem[i].d_unit, tok, strlen(tok));
/* d_valid */
tok = strtok(NULL, ";");
strncpy(com[comlen].elem[i].d_valid, tok, strlen(tok));
/* d_com */
tok = strtok(NULL, ";");
strncpy(com[comlen].elem[i].d_com, tok, strlen(tok));
com[comlen].elem[i].d_com[strcspn(com[comlen].elem[i].d_com, "\n")] = '\0';
}
if (strncasecmp(com[comlen].type, "cyc", 3) == 0) {
cyc = (struct cycbuf *) realloc(cyc, (cyclen + 1) * sizeof(struct cycbuf));
err_ret_if(cyc == NULL, -1);
memset(cyc + cyclen, '\0', sizeof(struct cycbuf));
/* id */
cyc[cyclen].id = com[comlen].id;
/* msg */
sprintf((char *) cyc[cyclen].msg, "%s%s%02X%s",
com[comlen].s_zz, com[comlen].s_cmd,
com[comlen].s_len, com[comlen].s_msg);
cyclen++;
}
comlen++;
return 0;
}
int
eb_cmd_num_c(const char *str, const char c)
{
const char *p = str;
int i = 0;
do {
if (*p == c)
i++;
} while (*(p++));
return i;
}
int
eb_cmd_file_read(const char *file)
{
int ret;
char line[CMD_LINELEN];
char *tok;
FILE *fp = NULL;
log_print(L_NOT, "%s", file);
/* open config file */
fp = fopen(file, "r");
err_ret_if(fp == NULL, -1);
/* read each line and fill cmd array */
while (fgets(line, CMD_LINELEN, fp) != NULL) {
tok = strtok(line, ";\n");
if (tok != NULL && tok[0] != '#' ) {
ret = eb_cmd_fill(tok);
if (ret < 0)
return -2;
}
}
/* close config file */
ret = fclose(fp);
err_ret_if(ret == EOF, -1);
log_print(L_NOT, "%s success", file);
return 0;
}
int
eb_cmd_dir_read(const char *cfgdir, const char *extension)
{
struct dirent **dir;
int ret, i, j, files, extlen;
char file[CMD_FILELEN], extprep[11];
char *ext;
extlen = strlen(extension) + 1;
memset(extprep, '\0', sizeof(extprep));
extprep[0] = '.';
strncpy(&extprep[1], extension, strlen(extension));
files = scandir(cfgdir, &dir, 0, alphasort);
if (files < 0) {
log_print(L_WAR, "configuration directory %s not found.", cfgdir);
return 1;
}
i = 0;
j = 0;
while (i < files) {
ext = strrchr(dir[i]->d_name, '.');
if (ext != NULL) {
if (strlen(ext) == extlen
&& dir[i]->d_type == DT_REG
&& strncasecmp(ext, extprep, extlen) == 0 ) {
memset(file, '\0', sizeof(file));
sprintf(file, "%s/%s", cfgdir, dir[i]->d_name);
ret = eb_cmd_file_read(file);
if (ret < 0)
return -1;
j++;
}
}
free(dir[i]);
i++;
}
free(dir);
if (j == 0) {
log_print(L_WAR, "no command files found ==> decode disabled.");
return 2;
}
return 0;
}
void
eb_cmd_dir_free(void)
{
int i;
if (comlen > 0) {
for (i = 0; i < comlen; i++)
free(&com[i].elem[0]);
free(com);
}
if (cyclen > 0)
free(cyc);
}