1047 lines
22 KiB
C
1047 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, "ttm", 3) == 0) {
|
|
if (p1 > 0) {
|
|
int hh, mm;
|
|
hh = msg[p1] / 6;
|
|
mm = msg[p1] % 6 * 10;
|
|
sprintf(buf, "%02d:%02d", hh, mm);
|
|
} 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;
|
|
float ff;
|
|
uin = msg[p1] + (msg[p2] << 8);
|
|
|
|
ff = uin * com[id].elem[elem].d_fac;
|
|
sprintf(buf, "%f", ff);
|
|
} else {
|
|
goto on_error;
|
|
}
|
|
|
|
} else if (strncasecmp(com[id].elem[elem].d_type, "sin", 3) == 0) {
|
|
if (p1 > 0 && p2 > 0) {
|
|
int sin;
|
|
float ff;
|
|
sin = msg[p1] + (msg[p2] << 8);
|
|
|
|
ff = sin * com[id].elem[elem].d_fac;
|
|
sprintf(buf, "%f", ff);
|
|
} 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;
|
|
float ff;
|
|
ulg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24);
|
|
|
|
ff = ulg * com[id].elem[elem].d_fac;
|
|
sprintf(buf, "%f", ff);
|
|
} 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;
|
|
float ff;
|
|
slg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24);
|
|
|
|
ff = slg * com[id].elem[elem].d_fac;
|
|
sprintf(buf, "%f", ff);
|
|
} 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);
|
|
|
|
ff *= com[id].elem[elem].d_fac;
|
|
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, "str", 3) == 0) {
|
|
for (i = 0; i < (int) 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[BUS_DEVICE_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 < (int) 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 ((int) 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);
|
|
|
|
}
|
|
|