Initial commit on github.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
noinst_LIBRARIES = libebus.a liblog.a
|
||||
|
||||
libebus_a_SOURCES = ebus-decode.c ebus-decode.h \
|
||||
ebus-cmd.c ebus-cmd.h \
|
||||
ebus-bus.c ebus-bus.h
|
||||
|
||||
liblog_a_SOURCES = log.c log.h
|
||||
|
||||
distclean-local:
|
||||
-rm -f Makefile.in
|
||||
|
||||
+1195
File diff suppressed because it is too large
Load Diff
+325
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* 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-bus.h
|
||||
* @brief ebus communication functions
|
||||
* @author roland.jax@liwest.at
|
||||
* @version 0.1
|
||||
*/
|
||||
|
||||
#ifndef EBUS_BUS_H_
|
||||
#define EBUS_BUS_H_
|
||||
|
||||
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ebus-common.h"
|
||||
|
||||
|
||||
|
||||
#define TMP_BUFSIZE 1024
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief sending data structure
|
||||
*/
|
||||
struct send_data {
|
||||
unsigned char crc; /**< crc of escaped message */
|
||||
unsigned char msg[SERIAL_BUFSIZE + 1]; /**< original message */
|
||||
int len; /**< length of original message */
|
||||
unsigned char msg_esc[SERIAL_BUFSIZE + 1]; /**< esacaped message */
|
||||
int len_esc; /**< length of esacaped message */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief receiving data structure
|
||||
*/
|
||||
struct recv_data {
|
||||
unsigned char crc_recv; /**< received crc */
|
||||
unsigned char crc_calc; /**< calculated crc */
|
||||
unsigned char msg[SERIAL_BUFSIZE + 1]; /**< unescaped message */
|
||||
int len; /**< length of unescaped message */
|
||||
unsigned char msg_esc[SERIAL_BUFSIZE + 1]; /**< received message */
|
||||
int len_esc; /**< length of received message */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief set rawdump
|
||||
* @param [in] YES | NO
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_rawdump(int dump);
|
||||
|
||||
/**
|
||||
* @brief set showraw
|
||||
* @param [in] YES | NO
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_showraw(int show);
|
||||
|
||||
/**
|
||||
* @brief set own ebus address
|
||||
* @param [in] src ebus address
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_qq(unsigned char src);
|
||||
|
||||
/**
|
||||
* @brief set number of retry to get bus
|
||||
* @param [in] retry
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_get_retry(int retry);
|
||||
|
||||
/**
|
||||
* @brief set number of skipped SYN if an error occurred while getting the bus
|
||||
* @param [in] skip is only the start value (skip = skip_ack + retry;)
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_skip_ack(int skip);
|
||||
|
||||
/**
|
||||
* @brief set max wait time between send and receive of own address (QQ)
|
||||
* @param [in] usec wait time in usec
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_max_wait(long usec);
|
||||
|
||||
/**
|
||||
* @brief set number of retry to send message
|
||||
* @param [in] retry
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_send_retry(int retry);
|
||||
|
||||
/**
|
||||
* @brief set number of printed hex bytes
|
||||
* @param [in] size
|
||||
* @return none
|
||||
*/
|
||||
void eb_set_print_size(int size);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief calculate delte time of given time stamps
|
||||
* @param [in] *tact newer time stamp
|
||||
* @param [in] *tlast older time stamp
|
||||
* @param [out] *tdiff calculated time difference
|
||||
* @return 0 positive | -1 negative ??? lol
|
||||
*/
|
||||
int eb_diff_time(const struct timeval *tact, const struct timeval *tlast, struct timeval *tdiff);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Open a file in write mode.
|
||||
* @param [in] *file device
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_raw_file_open(const char *file);
|
||||
|
||||
/**
|
||||
* @brief close a file.
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_raw_file_close(void);
|
||||
|
||||
/**
|
||||
* @brief write bytes into file
|
||||
* @param [in] *buf pointer to a byte array
|
||||
* @param [in] buflen length of byte array
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_raw_file_write(const unsigned char *buf, int buflen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check if serial FD is vaild.
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_serial_valid();
|
||||
|
||||
/**
|
||||
* @brief Open serial device in raw mode. 1 Byte is then minimum input length.
|
||||
* @param [in] *dev serial device
|
||||
* @param [out] *fd file descriptor from opened serial device
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_serial_open(const char *dev, int *fd);
|
||||
|
||||
/**
|
||||
* @brief close serial device and set settings to default.
|
||||
* @return 0 ok | -1 error | -2 bad file descriptor
|
||||
*/
|
||||
int eb_serial_close(void);
|
||||
|
||||
/**
|
||||
* @brief send bytes to serial device
|
||||
* @param [in] *buf pointer to a byte array
|
||||
* @param [in] buflen length of byte array
|
||||
* @return 0 ok | -1 error | -2 bad file descriptor
|
||||
*/
|
||||
int eb_serial_send(const unsigned char *buf, int buflen);
|
||||
|
||||
/**
|
||||
* @brief receive bytes from serial device
|
||||
* @param [out] *buf pointer to a byte array received bytes
|
||||
* @param [out] *buflen length of received bytes
|
||||
* @return 0 ok | -1 error | -2 bad file descriptor | -3 received data > BUFFER
|
||||
*/
|
||||
int eb_serial_recv(unsigned char *buf, int *buflen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief print received results in a specific format
|
||||
* @return none
|
||||
*/
|
||||
void eb_print_result(void);
|
||||
|
||||
/**
|
||||
* @brief print received data with hex format
|
||||
* @param [in] *buf pointer to a byte array of received bytes
|
||||
* @param [in] buflen length of received bytes
|
||||
* @return none
|
||||
*/
|
||||
void eb_print_hex(const unsigned char *buf, int buflen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief get received data
|
||||
* @param [out] *buf pointer to a byte array of received bytes
|
||||
* @param [out] *buflen length of received bytes
|
||||
* @return none
|
||||
*/
|
||||
void eb_recv_data_get(unsigned char *buf, int *buflen);
|
||||
|
||||
/**
|
||||
* @brief prepare received data
|
||||
* @param [in] *buf pointer to a byte array of received bytes
|
||||
* @param [in] buflen length of received bytes
|
||||
* @return none
|
||||
*/
|
||||
void eb_recv_data_prepare(const unsigned char *buf, int buflen);
|
||||
|
||||
/**
|
||||
* @brief receive bytes from serial device
|
||||
* @param [out] *buf pointer to a byte array of received bytes
|
||||
* @param [out] buflen length of received bytes
|
||||
* @return 0 ok | -1 error | -2 syn no answer from slave
|
||||
* | -3 SYN received after answer from slave
|
||||
*/
|
||||
int eb_recv_data(unsigned char *buf, int *buflen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief receive bytes from serial device until SYN byte was received
|
||||
* @param [in] *skip number skipped SYN bytes
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_bus_wait_syn(int *skip);
|
||||
|
||||
/**
|
||||
* @brief try to get bus for sending
|
||||
* \li wait SYN byte, send our ebus address and wait for minimun of ~4200 usec
|
||||
* \li read at least one byte and compare it with sent byte.
|
||||
* @return 0 ok | -1 error | 1 max retry was reached
|
||||
*/
|
||||
int eb_bus_wait(void);
|
||||
|
||||
/**
|
||||
* @brief free bus after syn was sent
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_bus_free(void);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief receive ACK byte from serial device
|
||||
* @param [out] *buf pointer to a byte array of received bytes
|
||||
* @param [out] buflen length of received bytes
|
||||
* @return 0 ok | 1 negative ACK | -1 error | -2 send and recv msg are different
|
||||
* | -3 syn received (no answer from slave) | -4 we should never reach this
|
||||
*/
|
||||
int eb_send_data_get_ack(unsigned char *buf, int *buflen);
|
||||
|
||||
/**
|
||||
* @brief prepare send data
|
||||
* @param [in] *buf pointer to a byte array of send bytes
|
||||
* @param [in] buflen length of send bytes
|
||||
* @return none
|
||||
*/
|
||||
void eb_send_data_prepare(const unsigned char *buf, int buflen);
|
||||
|
||||
/**
|
||||
* @brief handle sending ebus data
|
||||
*
|
||||
* \li Given input data will be prepared (escape, crc) and send to ebus.
|
||||
* \li Answer will be received, prepared (unescape, crc) and return as result.
|
||||
*
|
||||
* @param [in] *buf pointer to a byte array
|
||||
* @param [in] buflen length of byte array
|
||||
* @param [in] type is the type of message to send
|
||||
* @param [out] *bus pointer to answer array
|
||||
* @param [out] *buslen point to answer length
|
||||
* @return 0 ok | 1 neg. ACK from Slave | -1 error
|
||||
*/
|
||||
int eb_send_data(const unsigned char *buf, int buflen, int type, unsigned char *bus, int *buslen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief handle send ebus cmd
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] *data pointer to data bytes for decode/encode
|
||||
* @param [out] *buf pointer to answer array
|
||||
* @param [out] *buflen point to answer length
|
||||
* @return none
|
||||
*/
|
||||
void eb_execute(int id, char *data, char *buf, int *buflen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief handle one collected message
|
||||
* @param [in] *buf pointer to a byte array
|
||||
* @param [in] buflen length of byte array
|
||||
* @return 0-x msg number of collected msg | -1 msg not found | -2 error
|
||||
*/
|
||||
int eb_cyc_data_process(const unsigned char *buf, int buflen);
|
||||
|
||||
/**
|
||||
* @brief handle reading cycle ebus data
|
||||
* @return 0-x length of collected msg | -1 error
|
||||
*/
|
||||
int eb_cyc_data_recv();
|
||||
|
||||
|
||||
|
||||
#endif /* EBUS_BUS_H_ */
|
||||
+953
@@ -0,0 +1,953 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return com[id].s_type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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: %d ==> 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: %d ==> 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;
|
||||
float f;
|
||||
unsigned long l;
|
||||
|
||||
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, "asc", 3) == 0) {
|
||||
sprintf(buf, "%s", &msg[1]);
|
||||
|
||||
} else if (strncasecmp(com[id].elem[elem].d_type, "bcd", 3) == 0) {
|
||||
if (p1 > 0) {
|
||||
ret = eb_bcd_to_int(msg[p1], &i);
|
||||
|
||||
i *= com[id].elem[elem].d_fac;
|
||||
sprintf(buf, "%d", i);
|
||||
} else {
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
} else if (strncasecmp(com[id].elem[elem].d_type, "d1b", 3) == 0) {
|
||||
if (p1 > 0) {
|
||||
ret = eb_d1b_to_int(msg[p1], &i);
|
||||
|
||||
f = i * com[id].elem[elem].d_fac;
|
||||
sprintf(buf, "%f", f);
|
||||
} else {
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
} else if (strncasecmp(com[id].elem[elem].d_type, "d1c", 3) == 0) {
|
||||
if (p1 > 0) {
|
||||
ret = eb_d1c_to_float(msg[p1], &f);
|
||||
|
||||
f *= com[id].elem[elem].d_fac;
|
||||
sprintf(buf, "%f", f);
|
||||
} else {
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
} else if (strncasecmp(com[id].elem[elem].d_type, "d2b", 3) == 0) {
|
||||
if (p1 > 0 && p2 > 0) {
|
||||
if (p1 > p2)
|
||||
ret = eb_d2b_to_float(msg[p2], msg[p1], &f);
|
||||
else
|
||||
ret = eb_d2b_to_float(msg[p1], msg[p2], &f);
|
||||
|
||||
f *= com[id].elem[elem].d_fac;
|
||||
sprintf(buf, "%f", f);
|
||||
} else {
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
} else if (strncasecmp(com[id].elem[elem].d_type, "d2c", 3) == 0) {
|
||||
if (p1 > 0 && p2 > 0) {
|
||||
if (p1 > p2)
|
||||
ret = eb_d2c_to_float(msg[p2], msg[p1], &f);
|
||||
else
|
||||
ret = eb_d2c_to_float(msg[p1], msg[p2], &f);
|
||||
|
||||
f *= com[id].elem[elem].d_fac;
|
||||
sprintf(buf, "%f", f);
|
||||
} 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, "ulg", 3) == 0) {
|
||||
if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) {
|
||||
l = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24);
|
||||
sprintf(buf, "%lu", l);
|
||||
} 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 : %5s.%-32s\t(type: %d)" \
|
||||
" %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, ";");
|
||||
com[comlen].s_type = atoi(tok);
|
||||
|
||||
/* 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);
|
||||
|
||||
}
|
||||
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
* 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.h
|
||||
* @brief ebus command file functions
|
||||
* @author roland.jax@liwest.at
|
||||
* @version 0.1
|
||||
*/
|
||||
|
||||
#ifndef EBUS_CMD_H_
|
||||
#define EBUS_CMD_H_
|
||||
|
||||
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ebus-common.h"
|
||||
|
||||
|
||||
|
||||
#define CMD_LINELEN 512
|
||||
#define CMD_FILELEN 1024
|
||||
|
||||
#define CMD_SIZE_TYPE 3
|
||||
#define CMD_SIZE_CLASS 20
|
||||
#define CMD_SIZE_CMD 30
|
||||
#define CMD_SIZE_COM 256
|
||||
#define CMD_SIZE_S_ZZ 2
|
||||
#define CMD_SIZE_S_CMD 4
|
||||
#define CMD_SIZE_S_MSG 32
|
||||
|
||||
#define CMD_SIZE_D_SUB 20
|
||||
#define CMD_SIZE_D_PART 2
|
||||
#define CMD_SIZE_D_POS 10
|
||||
#define CMD_SIZE_D_TYPE 3
|
||||
#define CMD_SIZE_D_UNIT 6
|
||||
#define CMD_SIZE_D_VALID 30
|
||||
#define CMD_SIZE_D_COM 256
|
||||
|
||||
#define CMD_PART_MD "MD"
|
||||
#define CMD_PART_SA "SA"
|
||||
#define CMD_PART_SD "SD"
|
||||
#define CMD_PART_MA "MA"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief cycbuf structure
|
||||
*/
|
||||
struct cycbuf {
|
||||
int id; /**< command id from command buffer */
|
||||
unsigned char msg[CMD_SIZE_S_MSG + 1]; /**< zz + cmd + len + msg */
|
||||
unsigned char buf[CMD_DATA_SIZE + 1]; /**< whole message - unescaped */
|
||||
int buflen; /**< len of saved message */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief commands structure
|
||||
*/
|
||||
struct commands {
|
||||
int id; /**< command id */
|
||||
char type[CMD_SIZE_TYPE + 1]; /**< type of message */
|
||||
char class[CMD_SIZE_CLASS + 1]; /**< ci */
|
||||
char cmd[CMD_SIZE_CMD + 1]; /**< hydraulic */
|
||||
char com[CMD_SIZE_COM + 1]; /**< just a comment */
|
||||
int s_type; /**< message type */
|
||||
char s_zz[CMD_SIZE_S_ZZ + 1]; /**< zz */
|
||||
char s_cmd[CMD_SIZE_S_CMD + 1]; /**< pb sb */
|
||||
int s_len; /**< number of send bytes */
|
||||
char s_msg[CMD_SIZE_S_MSG + 1]; /**< max 15 data bytes */
|
||||
int d_elem; /**< number of elements */
|
||||
struct element *elem; /**< pointer of array with elements */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief element structure
|
||||
*/
|
||||
struct element {
|
||||
char d_sub[CMD_SIZE_D_SUB + 1]; /**< pin1 */
|
||||
char d_part[CMD_SIZE_D_PART + 1]; /**< part of message */
|
||||
char d_pos[CMD_SIZE_D_POS + 1]; /**< data position at bytes */
|
||||
char d_type[CMD_SIZE_D_TYPE + 1]; /**< data type */
|
||||
float d_fac; /**< facter */
|
||||
char d_unit[CMD_SIZE_D_UNIT + 1]; /**< unit of data like °C,...) */
|
||||
char d_valid[CMD_SIZE_D_VALID + 1]; /**< valid data */
|
||||
char d_com[CMD_SIZE_D_COM + 1]; /**< just a comment */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert string to uppercase
|
||||
* @param [out] *buf pointer to buffer array
|
||||
*/
|
||||
void eb_cmd_uppercase(char *buf);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief compare given type with type of given command id
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] type for lookup
|
||||
* @return YES or NO
|
||||
*/
|
||||
int eb_cmd_check_type(int id, const char *type);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief returns s_type of given id
|
||||
* @param [in] id is index in command array
|
||||
* @return s_type of ebus command
|
||||
*/
|
||||
int eb_cmd_get_s_type(int id);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief set buf from cyc array
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] *msg pointer to message array
|
||||
* @param [in] msglen pointer to message length
|
||||
* @return none
|
||||
*/
|
||||
void eb_cmd_set_cyc_buf(int id, const unsigned char *msg, int msglen);
|
||||
|
||||
|
||||
/**
|
||||
* @brief get buf from cyc array
|
||||
* @param [in] id is index in command array
|
||||
* @param [out] *msg pointer to message array
|
||||
* @param [out] *msglen pointer to message length
|
||||
* @return none
|
||||
*/
|
||||
void eb_cmd_get_cyc_buf(int id, unsigned char *msg, int *msglen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief search given strings in cycbuf array
|
||||
* @param [in] *hex pointer to hex string
|
||||
* @return 0-x id of found ebus command in array
|
||||
* -1 command not found | -2 hexlen too long
|
||||
*/
|
||||
int eb_cmd_search_com_cyc(const unsigned char *hex, int hexlen);
|
||||
|
||||
/**
|
||||
* @brief search given strings in command array
|
||||
* @param [in] *type pointer to message type
|
||||
* @param [in] *class pointer to a ebus class
|
||||
* @param [in] *cmd pointer to a ebus command
|
||||
* @return 0-x id of found ebus command in array | -1 command not found
|
||||
*/
|
||||
int eb_cmd_search_com_id(const char *type, const char *class, const char *cmd);
|
||||
|
||||
/**
|
||||
* @brief search given strings in command array
|
||||
* @param [in] *buf pointer to a byte array
|
||||
* @param [out] *data pointer to data array for passing to decode/encode
|
||||
* @return 0-x id of found ebus command in array | -1 command not found
|
||||
*/
|
||||
int eb_cmd_search_com(char *buf, char *data);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief decode given element
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] elem is index of data position
|
||||
* @param [out] *msg pointer to message array
|
||||
* @param [out] *buf pointer to decoded answer
|
||||
* @return 0 ok | -1 error at decode
|
||||
*/
|
||||
int eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf);
|
||||
|
||||
/**
|
||||
* @brief decode msg
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] *part point to part type for decode
|
||||
* @param [in] *data pointer to data bytes for decode
|
||||
* @param [out] *msg pointer to message array
|
||||
* @param [out] *buf pointer to decoded answer
|
||||
* @return 0 ok | -1 error at decode
|
||||
*/
|
||||
int eb_cmd_decode(int id, char *part, char *data, unsigned char *msg, char *buf);
|
||||
|
||||
/**
|
||||
* @brief decode given element
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] elem is index of data position
|
||||
* @param [in] *data pointer to data bytes for encode
|
||||
* @param [out] *msg pointer to message array
|
||||
* @param [out] *buf pointer to decoded answer
|
||||
* @return 0 ok | -1 error at decode
|
||||
*/
|
||||
int eb_cmd_encode_value(int id, int elem, char *data, unsigned char *msg, char *buf);
|
||||
|
||||
/**
|
||||
* @brief encode msg
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] *data pointer to data bytes for encode
|
||||
* @param [out] *msg pointer to message array
|
||||
* @param [out] *buf pointer to decoded answer
|
||||
* @return 0 ok | -1 error at encode
|
||||
*/
|
||||
int eb_cmd_encode(int id, char *data, unsigned char *msg, char *buf);
|
||||
|
||||
/**
|
||||
* @brief prepare message string for given ebus cmd from array
|
||||
* @param [in] id is index in command array
|
||||
* @param [in] *data pointer to data bytes for decode/encode
|
||||
* @param [out] *msg pointer to message array
|
||||
* @param [out] *msglen pointer to message length
|
||||
* @param [out] *buf pointer to decoded answer
|
||||
* @return none
|
||||
*/
|
||||
void eb_cmd_prepare(int id, char *data, unsigned char *msg, int *msglen, char *buf);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief print readed ebus commands
|
||||
* @param [in] *type (get/set/cyc)
|
||||
* @param [in] all print all
|
||||
* @param [in] detail show details of command
|
||||
* @return none
|
||||
*/
|
||||
void eb_cmd_print(const char *type, int all, int detail);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief fill command structure
|
||||
* @param [in] *tok pointer to given token
|
||||
* @return 0 ok | -1 error
|
||||
*/
|
||||
int eb_cmd_fill(const char *tok);
|
||||
|
||||
/**
|
||||
* @brief prevent buffer overflow
|
||||
*
|
||||
* number of tokens must be >= number of columns - 1 of file
|
||||
*
|
||||
* @param [in] *buf pointer to a byte array
|
||||
* @param [in] delimeter
|
||||
* @return number of found delimeters
|
||||
*/
|
||||
int eb_cmd_num_c(const char *buf, const char c);
|
||||
|
||||
/**
|
||||
* @brief set cfgdir address
|
||||
* @param [in] *file pointer to configuration file with *.csv
|
||||
* @return 0 ok | -1 error | -2 read token error
|
||||
*/
|
||||
int eb_cmd_file_read(const char *file);
|
||||
|
||||
/**
|
||||
* @brief get all files with given extension from given configuration directory
|
||||
* @param [in] *cfgdir pointer to configuration directory
|
||||
* @param [in] *suffix pointer to given extension
|
||||
* @return 0 ok | -1 error | 1 read file error | 2 no command files found
|
||||
*/
|
||||
int eb_cmd_dir_read(const char *cfgdir, const char *extension);
|
||||
|
||||
/**
|
||||
* @brief free mem for ebus commands
|
||||
* @return none
|
||||
*/
|
||||
void eb_cmd_dir_free(void);
|
||||
|
||||
|
||||
|
||||
#endif /* EBUS_CMD_H_ */
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
* crc calculations from http://www.mikrocontroller.net/topic/75698
|
||||
*
|
||||
* 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-common.h
|
||||
* @brief ebus common defines
|
||||
* @author roland.jax@liwest.at
|
||||
* @version 0.1
|
||||
*/
|
||||
|
||||
#ifndef EBUS_COMMON_H_
|
||||
#define EBUS_COMMON_H_
|
||||
|
||||
|
||||
|
||||
#define EBUS_SYN 0xAA
|
||||
#define EBUS_SYN_ESC_A9 0xA9
|
||||
#define EBUS_SYN_ESC_01 0x01
|
||||
#define EBUS_SYN_ESC_00 0x00
|
||||
|
||||
#define EBUS_ACK 0x00
|
||||
#define EBUS_NAK 0xFF
|
||||
|
||||
#define EBUS_QQ 0xFF
|
||||
|
||||
#define EBUS_GET_RETRY 3
|
||||
#define EBUS_GET_RETRY_MAX 10
|
||||
#define EBUS_SKIP_ACK 1
|
||||
#define EBUS_MAX_WAIT 4000
|
||||
#define EBUS_SEND_RETRY 2
|
||||
#define EBUS_SEND_RETRY_MAX 10
|
||||
#define EBUS_PRINT_SIZE 30
|
||||
|
||||
#define EBUS_MSG_BROADCAST 1
|
||||
#define EBUS_MSG_MASTER_MASTER 2
|
||||
#define EBUS_MSG_MASTER_SLAVE 3
|
||||
|
||||
#define SERIAL_DEVICE "/dev/ttyUSB0"
|
||||
#define SERIAL_BAUDRATE B2400
|
||||
#define SERIAL_BUFSIZE 100
|
||||
|
||||
#define CMD_DATA_SIZE 50 /* 5+16+3+16+2 = 42 || 256 */
|
||||
|
||||
enum enum_bool {UNSET = -1, NO, YES};
|
||||
|
||||
|
||||
|
||||
#endif /* EBUS_COMMON_H_ */
|
||||
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
* crc calculations from http://www.mikrocontroller.net/topic/75698
|
||||
*
|
||||
* 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-decode.c
|
||||
* @brief ebus decode 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 <ctype.h>
|
||||
|
||||
#include "ebus-decode.h"
|
||||
|
||||
|
||||
|
||||
const char *days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_htoi(const char *buf)
|
||||
{
|
||||
int ret;
|
||||
ret = -1;
|
||||
|
||||
if (isxdigit(*buf)) {
|
||||
if (isalpha(*buf))
|
||||
ret = 55;
|
||||
else
|
||||
ret = 48;
|
||||
|
||||
ret = toupper(*buf) - ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
eb_esc(unsigned char *buf, int *buflen)
|
||||
{
|
||||
unsigned char tmp[SERIAL_BUFSIZE];
|
||||
int tmplen, i;
|
||||
|
||||
memset(tmp, '\0', sizeof(tmp));
|
||||
i = 0;
|
||||
tmplen = 0;
|
||||
|
||||
while (i < *buflen) {
|
||||
|
||||
if (buf[i] == EBUS_SYN) {
|
||||
tmp[tmplen] = EBUS_SYN_ESC_A9;
|
||||
tmplen++;
|
||||
tmp[tmplen] = EBUS_SYN_ESC_01;
|
||||
tmplen++;
|
||||
} else if (buf[i] == EBUS_SYN_ESC_A9) {
|
||||
tmp[tmplen] = EBUS_SYN_ESC_A9;
|
||||
tmplen++;
|
||||
tmp[tmplen] = EBUS_SYN_ESC_00;
|
||||
tmplen++;
|
||||
} else {
|
||||
tmp[tmplen] = buf[i];
|
||||
tmplen++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
for (i = 0; i < tmplen; i++)
|
||||
buf[i] = tmp[i];
|
||||
|
||||
*buflen = tmplen;
|
||||
}
|
||||
|
||||
void
|
||||
eb_unesc(unsigned char *buf, int *buflen)
|
||||
{
|
||||
unsigned char tmp[SERIAL_BUFSIZE];
|
||||
int tmplen, i, found;
|
||||
|
||||
memset(tmp, '\0', sizeof(tmp));
|
||||
i = 0;
|
||||
tmplen = 0;
|
||||
found = 0;
|
||||
|
||||
while (i < *buflen) {
|
||||
|
||||
if (buf[i] == EBUS_SYN_ESC_A9) {
|
||||
found = 1;
|
||||
} else if (found == 1) {
|
||||
if (buf[i] == EBUS_SYN_ESC_01) {
|
||||
tmp[tmplen] = EBUS_SYN;
|
||||
tmplen++;
|
||||
} else {
|
||||
tmp[tmplen] = EBUS_SYN_ESC_A9;
|
||||
tmplen++;
|
||||
}
|
||||
|
||||
found = 0;
|
||||
} else {
|
||||
tmp[tmplen] = buf[i];
|
||||
tmplen++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
for (i = 0; i < tmplen; i++)
|
||||
buf[i] = tmp[i];
|
||||
|
||||
*buflen = tmplen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_day_to_str(unsigned char day, char *tgt)
|
||||
{
|
||||
int dd;
|
||||
|
||||
if (dd >= 0x00 && dd <= 0x06) {
|
||||
eb_bcd_to_int(day, &dd);
|
||||
sprintf(tgt, "%s", days[day]);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_dat_to_str(unsigned char dd, unsigned char mm, unsigned char yy, char *tgt)
|
||||
{
|
||||
if (dd >= 0x00 && dd <= 0x1F &&
|
||||
mm >= 0x00 && mm <= 0x0C &&
|
||||
yy >= 0x00 && yy <= 0x63 )
|
||||
sprintf(tgt, "%02d.%02d.%04d", dd, mm, yy + 2000);
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eb_str_to_dat(int dd, int mm, int yy, unsigned char *tgt)
|
||||
{
|
||||
if (yy > 2000)
|
||||
yy -= 2000;
|
||||
|
||||
if (dd >= 0 && dd <= 31 &&
|
||||
mm >= 0 && mm <= 12 &&
|
||||
yy >= 0 && yy <= 99 )
|
||||
sprintf((char *) tgt, "%02x%02x%02x", dd, mm, yy);
|
||||
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_tim_to_str(unsigned char hh, unsigned char mm, unsigned char ss, char *tgt)
|
||||
{
|
||||
if (hh >= 0x00 && hh <= 0x17 &&
|
||||
mm >= 0x00 && mm <= 0x3B &&
|
||||
ss >= 0x00 && ss <= 0x3B )
|
||||
sprintf(tgt, "%02d:%02d:%02d", hh, mm, ss);
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eb_str_to_tim(int hh, int mm, int ss, unsigned char *tgt)
|
||||
{
|
||||
|
||||
if (hh >= 0 && hh <= 23 &&
|
||||
mm >= 0 && mm <= 59 &&
|
||||
ss >= 0 && ss <= 59 )
|
||||
sprintf((char *) tgt, "%02x%02x%02x", hh, mm, ss);
|
||||
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_bcd_to_int(unsigned char src, int *tgt)
|
||||
{
|
||||
if ((src & 0x0F) > 0x09 || ((src >> 4) & 0x0F) > 0x09) {
|
||||
*tgt = (int) (0xFF);
|
||||
return 0;
|
||||
} else {
|
||||
*tgt = (int) ( ( ((src & 0xF0) >> 4) * 10) + (src & 0x0F) );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eb_int_to_bcd(int src, unsigned char *tgt)
|
||||
{
|
||||
if (src > 99) {
|
||||
*tgt = (unsigned char) (0xFF);
|
||||
return 0;
|
||||
} else {
|
||||
*tgt = (unsigned char) ( ((src / 10) << 4) | (src % 10) );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_d1b_to_int(unsigned char src, int *tgt)
|
||||
{
|
||||
if ((src & 0x80) == 0x80) {
|
||||
*tgt = (int) (- ( ((unsigned char) (~ src)) + 1) );
|
||||
|
||||
if (*tgt == -0x80)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
*tgt = (int) (src);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eb_int_to_d1b(int src, unsigned char *tgt)
|
||||
{
|
||||
if (src < -127 || src > 127) {
|
||||
*tgt = (unsigned char) (0x80);
|
||||
return 0;
|
||||
} else {
|
||||
if (src >= 0) {
|
||||
*tgt = (unsigned char) (src);
|
||||
return 1;
|
||||
} else {
|
||||
*tgt = (unsigned char) (- (~ (src - 1) ) );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_d1c_to_float(unsigned char src, float *tgt)
|
||||
{
|
||||
if (src > 0xC8) {
|
||||
*tgt = (float) (0xFF);
|
||||
return 0;
|
||||
} else {
|
||||
*tgt = (float) (src / 2.0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eb_float_to_d1c(float src, unsigned char *tgt)
|
||||
{
|
||||
if (src < 0.0 || src > 100.0) {
|
||||
*tgt = (unsigned char) (0xFF);
|
||||
return 0;
|
||||
} else {
|
||||
*tgt = (unsigned char) (src * 2.0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_d2b_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt)
|
||||
{
|
||||
if ((src_msb & 0x80) == 0x80) {
|
||||
*tgt = (float)
|
||||
(- ( ((unsigned char) (~ src_msb)) +
|
||||
( ( ((unsigned char) (~ src_lsb)) + 1) / 256.0) ) );
|
||||
|
||||
if (src_msb == 0x80 && src_lsb == 0x00)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
*tgt = (float) (src_msb + (src_lsb / 256.0));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eb_float_to_d2b(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb)
|
||||
{
|
||||
if (src < -127.999 || src > 127.999) {
|
||||
*tgt_msb = (unsigned char) (0x80);
|
||||
*tgt_lsb = (unsigned char) (0x00);
|
||||
return 0;
|
||||
} else {
|
||||
*tgt_lsb = (unsigned char) ((src - ((unsigned char) src)) * 256.0);
|
||||
|
||||
if (src < 0.0 && *tgt_lsb != 0x00)
|
||||
*tgt_msb = (unsigned char) (src - 1);
|
||||
else
|
||||
*tgt_msb = (unsigned char) (src);
|
||||
|
||||
if (src >= 0.0)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_d2c_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt)
|
||||
{
|
||||
if ((src_msb & 0x80) == 0x80) {
|
||||
*tgt = (float)
|
||||
(- ( ( ( ((unsigned char) (~ src_msb)) * 16.0) ) +
|
||||
( ( ((unsigned char) (~ src_lsb)) & 0xF0) >> 4) +
|
||||
( ( ( ((unsigned char) (~ src_lsb)) & 0x0F) +1 ) / 16.0) ) );
|
||||
|
||||
if (src_msb == 0x80 && src_lsb == 0x00)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
*tgt = (float) ( (src_msb * 16.0) + ((src_lsb & 0xF0) >> 4) +
|
||||
((src_lsb & 0x0F) / 16.0) );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eb_float_to_d2c(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb)
|
||||
{
|
||||
if (src < -2047.999 || src > 2047.999) {
|
||||
*tgt_msb = (unsigned char) (0x80);
|
||||
*tgt_lsb = (unsigned char) (0x00);
|
||||
return 0;
|
||||
} else {
|
||||
*tgt_lsb =
|
||||
( ((unsigned char) ( ((unsigned char) src) % 16) << 4) +
|
||||
((unsigned char) ( (src - ((unsigned char) src)) * 16.0)) );
|
||||
|
||||
if (src < 0.0 && *tgt_lsb != 0x00)
|
||||
*tgt_msb = (unsigned char) ((src / 16.0) - 1);
|
||||
else
|
||||
*tgt_msb = (unsigned char) (src / 16.0);
|
||||
|
||||
if (src >= 0.0)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char
|
||||
eb_calc_crc_byte(unsigned char byte, unsigned char init_crc)
|
||||
{
|
||||
unsigned char crc, polynom;
|
||||
int i;
|
||||
|
||||
crc = init_crc;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
||||
if (crc & 0x80)
|
||||
polynom = (unsigned char) 0x9B;
|
||||
else
|
||||
polynom = (unsigned char) 0;
|
||||
|
||||
crc = (unsigned char) ((crc & ~0x80) << 1);
|
||||
|
||||
if (byte & 0x80)
|
||||
crc = (unsigned char) (crc | 1);
|
||||
|
||||
crc = (unsigned char) (crc ^ polynom);
|
||||
byte = (unsigned char) (byte << 1);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
eb_calc_crc(const unsigned char *buf, int buflen)
|
||||
{
|
||||
int i;
|
||||
unsigned char crc = 0;
|
||||
|
||||
for (i = 0 ; i < buflen ; i++, buf++)
|
||||
crc = eb_calc_crc_byte(*buf, crc);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
* crc calculations from http://www.mikrocontroller.net/topic/75698
|
||||
*
|
||||
* 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-decode.h
|
||||
* @brief ebus decode functions
|
||||
* @author roland.jax@liwest.at
|
||||
* @version 0.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* name type description resolution substitue
|
||||
* BCD CHAR 0 ... + 99 1 FFh
|
||||
* DATA1b SIGNED CHAR - 127 ... + 127 1 80h
|
||||
* DATA1c CHAR 0 ... + 100 0,5 FFh
|
||||
* DATA2b SIGNED INTEGER - 127,99 ... + 127,99 1/256 8000h
|
||||
* DATA2c SIGNED INTEGER -2047,9 ... + 2047,9 1/16 8000h
|
||||
*/
|
||||
|
||||
#ifndef EBUS_DECODE_H_
|
||||
#define EBUS_DECODE_H_
|
||||
|
||||
|
||||
#include "ebus-common.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief calculate integer value of given hex byte
|
||||
* @param [in] *buf hex byte
|
||||
* @return integer value | -1 if given byte is no hex value
|
||||
*/
|
||||
int eb_htoi(const char *buf);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief print received results in a specific format
|
||||
* @param [out] *buf pointer to a byte array
|
||||
* @param [out] *buflen length of byte array
|
||||
* @return none
|
||||
*/
|
||||
void eb_esc(unsigned char *buf, int *buflen);
|
||||
|
||||
/**
|
||||
* @brief print received results in a specific format
|
||||
* @param [out] *buf pointer to a byte array
|
||||
* @param [out] *buflen length of byte array
|
||||
* @return none
|
||||
*/
|
||||
void eb_unesc(unsigned char *buf, int *buflen);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert hex bytes to day
|
||||
* @param [in] day hex byte
|
||||
* @param [out] *tgt pointer to day string xxx
|
||||
* @return 0 OK | -1 values out of range
|
||||
*/
|
||||
int eb_day_to_str(unsigned char day, char *tgt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert hex bytes to date
|
||||
* @param [in] dd day hex byte
|
||||
* @param [in] mm month hex byte
|
||||
* @param [in] yy year hex byte
|
||||
* @param [out] *tgt pointer to date string dd.mm.yyyy
|
||||
* @return 0 OK | -1 values out of range
|
||||
*/
|
||||
int eb_dat_to_str(unsigned char dd, unsigned char mm, unsigned char yy, char *tgt);
|
||||
|
||||
/**
|
||||
* @brief convert char date string to hex
|
||||
* @param [in] dd day int value
|
||||
* @param [in] mm month int value
|
||||
* @param [in] yy year int value
|
||||
* @param [out] *tgt pointer to hex
|
||||
* @return 0 OK | -1 values out of range
|
||||
*/
|
||||
int eb_str_to_dat(int dd, int mm, int yy, unsigned char *tgt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert hex bytes to date
|
||||
* @param [in] hh hour hex byte
|
||||
* @param [in] mm minute hex byte
|
||||
* @param [in] ss second hex byte
|
||||
* @param [out] *tgt pointer to date string hh:mm:ss
|
||||
* @return 0 OK | -1 values out of range
|
||||
*/
|
||||
int eb_tim_to_str(unsigned char hh, unsigned char mm, unsigned char ss, char *tgt);
|
||||
|
||||
/**
|
||||
* @brief convert char time string to hex
|
||||
* @param [in] hh hour int value
|
||||
* @param [in] mm minute int value
|
||||
* @param [in] ss second int value
|
||||
* @param [out] *tgt pointer to hex
|
||||
* @return 0 OK | -1 values out of range
|
||||
*/
|
||||
int eb_str_to_tim(int hh, int mm, int ss, unsigned char *tgt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert bcd hex byte to int
|
||||
* @param [in] src bcd hex byte
|
||||
* @param [out] *tgt pointer to int value
|
||||
* @return 0 substitute value | 1 positive value
|
||||
*/
|
||||
int eb_bcd_to_int(unsigned char src, int *tgt);
|
||||
|
||||
/**
|
||||
* @brief convert int to bcd hex byte
|
||||
* @param [in] src int value
|
||||
* @param [out] *tgt pointer to hex byte
|
||||
* @return 0 substitute value | 1 positive value
|
||||
*/
|
||||
int eb_int_to_bcd(int src, unsigned char *tgt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert data1b hex byte to int
|
||||
* @param [in] src data1b hex byte
|
||||
* @param [out] *tgt pointer to int value
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_d1b_to_int(unsigned char src, int *tgt);
|
||||
|
||||
/**
|
||||
* @brief convert int to data1b hex byte
|
||||
* @param [in] src int value
|
||||
* @param [out] *tgt pointer to data1b hex byte
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_int_to_d1b(int src, unsigned char *tgt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert data1c hex byte to float
|
||||
* @param [in] src data1c hex byte
|
||||
* @param [out] *tgt pointer to float value
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_d1c_to_float(unsigned char src, float *tgt);
|
||||
|
||||
/**
|
||||
* @brief convert float to data1c hex byte
|
||||
* @param [in] src float value
|
||||
* @param [out] *tgt pointer to data1c hex byte
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_float_to_d1c(float src, unsigned char *tgt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert data2b hex bytes to float
|
||||
* @param [in] src_lsb least significant data2b hex byte
|
||||
* @param [in] src_msb most significant data2b hex byte
|
||||
* @param [out] *tgt pointer to float value
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_d2b_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt);
|
||||
|
||||
/**
|
||||
* @brief convert float to data2b hex bytes
|
||||
* @param [in] src float value
|
||||
* @param [out] *tgt_lsb pointer to least significant data2b hex byte
|
||||
* @param [out] *tgt_msb pointer to most significant data2b hex byte
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_float_to_d2b(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief convert data2c hex bytes to float
|
||||
* @param [in] src_lsb least significant data2c hex byte
|
||||
* @param [in] src_msb most significant data2c hex byte
|
||||
* @param [out] *tgt pointer to float value
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_d2c_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt);
|
||||
|
||||
/**
|
||||
* @brief convert float to data2c hex bytes
|
||||
* @param [in] src float value
|
||||
* @param [out] *tgt_lsb pointer to least significant data2c hex byte
|
||||
* @param [out] *tgt_msb pointer to most significant data2c hex byte
|
||||
* @return 0 substitute value | 1 positive value | -1 negative value
|
||||
*/
|
||||
int eb_float_to_d2c(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief calculate crc of hex byte
|
||||
* @param [in] byte byte to calculate
|
||||
* @param [in] init_crc start value for calculation
|
||||
* @return new calculated crc byte from byte and init crc byte
|
||||
*/
|
||||
unsigned char eb_calc_crc_byte(unsigned char byte, unsigned char init_crc);
|
||||
|
||||
/**
|
||||
* @brief calculate crc of given hex array
|
||||
*
|
||||
* \li crc calculation "CRC-8-WCDMA" with Polynom "x^8+x^7+x^4+x^3+x+1"
|
||||
* \li crc calculations by http://www.mikrocontroller.net/topic/75698
|
||||
*
|
||||
* @param [in] *bytes pointer to a byte array
|
||||
* @param [in] size length of given bytes
|
||||
* @return calculated crc byte
|
||||
*/
|
||||
unsigned char eb_calc_crc(const unsigned char *bytes, int size);
|
||||
|
||||
|
||||
|
||||
#endif /* EBUS_DECODE_H_ */
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
static unsigned char loglvl = L_NUL;
|
||||
static int logtxtlen = sizeof(logtxt) / sizeof(char*);
|
||||
|
||||
static FILE *logfp = NULL;
|
||||
|
||||
char *log_time(char *time);
|
||||
char *log_txt(unsigned char lvl);
|
||||
|
||||
void
|
||||
log_file(FILE *fp)
|
||||
{
|
||||
if(logfp)
|
||||
fclose(logfp);
|
||||
|
||||
logfp = fp;
|
||||
}
|
||||
|
||||
void
|
||||
log_level(char *lvl)
|
||||
{
|
||||
unsigned char tmp;
|
||||
int i;
|
||||
char *par;
|
||||
|
||||
loglvl = L_NUL;
|
||||
|
||||
par = strtok(lvl, ", ");
|
||||
while (par) {
|
||||
if (strncasecmp(par, "ALL", 3) == 0) {
|
||||
loglvl = L_ALL;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = 0x01;
|
||||
for (i = 0; i < logtxtlen; i++) {
|
||||
if (strncasecmp(par, logtxt[i], 3) == 0) {
|
||||
loglvl |= (tmp << i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
par = strtok(NULL, ", ");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
log_open(const char *file, int foreground)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
|
||||
if (foreground) {
|
||||
log_file(stdout);
|
||||
} else {
|
||||
if (file) {
|
||||
if ((fp = fopen(file, "a+")) == 0) {
|
||||
fprintf(stderr, "can't open logfile: %s\n", file);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_file(fp);
|
||||
}
|
||||
}
|
||||
|
||||
openlog(NULL, LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
log_close()
|
||||
{
|
||||
if (logfp) {
|
||||
fflush(logfp);
|
||||
fclose(logfp);
|
||||
}
|
||||
|
||||
closelog();
|
||||
}
|
||||
|
||||
char *
|
||||
log_time(char *time)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
tm = localtime(&tv.tv_sec);
|
||||
|
||||
sprintf(time, "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
|
||||
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
char *
|
||||
log_txt(unsigned char lvl)
|
||||
{
|
||||
char *type = NULL;
|
||||
if (logtxtlen > 0) {
|
||||
unsigned char tmp;
|
||||
int i;
|
||||
|
||||
tmp = 0x01;
|
||||
for (i = 0; i < logtxtlen; i++) {
|
||||
if (lvl == L_ALL) {
|
||||
type = "ALL";
|
||||
break;
|
||||
}
|
||||
|
||||
if ((lvl & (tmp << i)) != 0x00 &&
|
||||
(loglvl & (tmp << i)) != 0x00) {
|
||||
type = (char *)logtxt[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
void
|
||||
log_print(unsigned char lvl, const char *txt, ...)
|
||||
{
|
||||
char time[24];
|
||||
char buf[512];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, txt);
|
||||
vsprintf(buf, txt, ap);
|
||||
|
||||
if ((loglvl & lvl) != 0x00) {
|
||||
if (logfp) {
|
||||
//~ fprintf(logfp, "%s [0x%02x %s] %s\n",
|
||||
//~ log_time(time), lvl , log_txt(lvl), buf);
|
||||
fprintf(logfp, "%s [%s] %s\n",
|
||||
log_time(time), log_txt(lvl), buf);
|
||||
fflush(logfp);
|
||||
|
||||
} else {
|
||||
//~ syslog(LOG_INFO, "[0x%02x %s] %s\n",
|
||||
//~ lvl, log_txt(lvl), txt);
|
||||
syslog(LOG_INFO, "[%s] %s\n", log_txt(lvl), txt);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#ifndef LOG_H_
|
||||
#define LOG_H_
|
||||
|
||||
#define L_NUL 0x00
|
||||
#define L_ALL 0xFF
|
||||
|
||||
#define L_INF 0x01
|
||||
#define L_NOT 0x02
|
||||
#define L_WAR 0x04
|
||||
#define L_ERR 0x08
|
||||
#define L_DBG 0x10
|
||||
#define L_EBH 0x20
|
||||
#define L_EBS 0x40
|
||||
#define L_NET 0x80
|
||||
|
||||
#define LOGTXT "INF, NOT, WAR, ERR, DBG, EBH, EBS, NET, ALL"
|
||||
static const char *logtxt[] = {"INF","NOT","WAR","ERR","DBG","EBH","EBS","NET"};
|
||||
|
||||
#define err_if(exp) \
|
||||
if (exp) { log_print(L_ERR, "%s: %d: %s: Error %s", \
|
||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, strerror(errno));\
|
||||
}
|
||||
|
||||
#define err_ret_if(exp, ret) \
|
||||
if (exp) { log_print(L_ERR, "%s: %d: %s: Error %s", \
|
||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, strerror(errno));\
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
void log_file(FILE *fp);
|
||||
void log_level(char *lvl);
|
||||
|
||||
int log_open(const char *logfile, int foreground);
|
||||
void log_close();
|
||||
|
||||
void log_print(unsigned char lvl, const char *txt, ...);
|
||||
|
||||
#endif /* LOG_H_ */
|
||||
Reference in New Issue
Block a user