mirror of https://github.com/sfeakes/AqualinkD.git
Update for spa temp & rs485
parent
56be24db66
commit
3265491d53
9
Makefile
9
Makefile
|
@ -24,13 +24,16 @@ CFLAGS = -Wall $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_AUTH -
|
|||
SRCS = aqualinkd.c utils.c config.c aq_serial.c init_buttons.c aq_programmer.c net_services.c json_messages.c mongoose.c
|
||||
|
||||
SL_SRC = serial_logger.c aq_serial.c utils.c
|
||||
AL_SRC = aquarite_logger.c aq_serial.c utils.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
SL_OBJS = $(SL_SRC:.c=.o)
|
||||
AL_OBJS = $(AL_SRC:.c=.o)
|
||||
|
||||
# define the executable file
|
||||
MAIN = ./release/aqualinkd
|
||||
SLOG = ./release/serial_logger
|
||||
AQUARITELOG = ./release/aquarite_logger
|
||||
|
||||
all: $(MAIN)
|
||||
@echo: $(MAIN) have been compiled
|
||||
|
@ -45,6 +48,12 @@ slog: $(SLOG)
|
|||
$(SLOG): $(SL_OBJS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $(SLOG) $(SL_OBJS)
|
||||
|
||||
aquaritelog: $(AQUARITELOG)
|
||||
@echo: $(AQUARITELOG) have been compiled
|
||||
|
||||
$(AQUARITELOG): $(AL_OBJS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $(AQUARITELOG) $(AL_OBJS)
|
||||
|
||||
# this is a suffix replacement rule for building .o's from .c's
|
||||
# it uses automatic variables $<: the name of the prerequisite of
|
||||
# the rule(a .c file) and $@: the name of the target of the rule (a .o file)
|
||||
|
|
66
aq_serial.c
66
aq_serial.c
|
@ -31,22 +31,42 @@
|
|||
|
||||
static struct termios _oldtio;
|
||||
|
||||
void log_packet(unsigned char* packet, int length)
|
||||
|
||||
|
||||
|
||||
void log_packet(char *init_str, unsigned char* packet, int length)
|
||||
{
|
||||
if ( getLogLevel() < LOG_DEBUG)
|
||||
return;
|
||||
|
||||
int cnt;
|
||||
int i;
|
||||
char buff[MAXLEN];
|
||||
|
||||
cnt = sprintf(buff, "%s", init_str);
|
||||
cnt += sprintf(buff+cnt, " | HEX: ");
|
||||
//printHex(packet_buffer, packet_length);
|
||||
for (i=0;i<length;i++)
|
||||
cnt += sprintf(buff+cnt, "0x%02hhx|",packet[i]);
|
||||
|
||||
cnt += sprintf(buff+cnt, "\n");
|
||||
logMessage(LOG_DEBUG, buff);
|
||||
/*
|
||||
int i;
|
||||
char temp_string[64];
|
||||
char message_buffer[MAXLEN];
|
||||
|
||||
sprintf(temp_string, "%02x ", packet[0]);
|
||||
sprintf(temp_string, "Send 0x%02hhx|", packet[0]);
|
||||
strcpy(message_buffer, temp_string);
|
||||
|
||||
for (i = 1; i < length; i++) {
|
||||
sprintf(temp_string, "%02x ", packet[i]);
|
||||
sprintf(temp_string, "0x%02hhx|", packet[i]);
|
||||
strcat(message_buffer, temp_string);
|
||||
}
|
||||
|
||||
strcat(message_buffer, "\n");
|
||||
logMessage(LOG_DEBUG, message_buffer);
|
||||
*/
|
||||
}
|
||||
|
||||
const char* get_packet_type(unsigned char* packet, int length)
|
||||
|
@ -71,7 +91,7 @@ const char* get_packet_type(unsigned char* packet, int length)
|
|||
return "Probe";
|
||||
break;
|
||||
default:
|
||||
sprintf(buf, "Unknown '0x%02hhx'\n", packet[PKT_CMD]);
|
||||
sprintf(buf, "Unknown '0x%02hhx'", packet[PKT_CMD]);
|
||||
return buf;
|
||||
break;
|
||||
}
|
||||
|
@ -195,6 +215,36 @@ void test_cmd()
|
|||
print_hex((char *)ackPacket, length);
|
||||
}
|
||||
|
||||
void send_test_cmd(int fd, unsigned char destination, unsigned char b1, unsigned char b2, unsigned char b3)
|
||||
{
|
||||
const int length = 11;
|
||||
unsigned char ackPacket[] = { NUL, DLE, STX, DEV_MASTER, CMD_ACK, NUL, NUL, 0x13, DLE, ETX, NUL };
|
||||
//unsigned char ackPacket[] = { NUL, DLE, STX, DEV_MASTER, NUL, NUL, NUL, 0x13, DLE, ETX, NUL };
|
||||
|
||||
// Update the packet and checksum if command argument is not NUL.
|
||||
ackPacket[3] = destination;
|
||||
ackPacket[4] = b1;
|
||||
ackPacket[5] = b2;
|
||||
ackPacket[6] = b3;
|
||||
ackPacket[7] = generate_checksum(ackPacket, length-1);
|
||||
|
||||
log_packet("Sent ", ackPacket, length);
|
||||
|
||||
#ifdef BLOCKING_MODE
|
||||
write(fd, ackPacket, length);
|
||||
#else
|
||||
int nwrite, i;
|
||||
for (i=0; i<length; i += nwrite) {
|
||||
nwrite = write(fd, ackPacket + i, length - i);
|
||||
if (nwrite < 0)
|
||||
logMessage(LOG_ERR, "write to serial port failed\n");
|
||||
}
|
||||
//logMessage(LOG_DEBUG_SERIAL, "Send %d bytes to serial\n",length);
|
||||
//tcdrain(fd);
|
||||
//logMessage(LOG_DEBUG, "Send '0x%02hhx' to '0x%02hhx'\n", command, destination);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void send_ack(int fd, unsigned char command)
|
||||
{
|
||||
|
@ -214,14 +264,14 @@ void send_ack(int fd, unsigned char command)
|
|||
aqualink_cmd = NUL;
|
||||
}
|
||||
*/
|
||||
log_packet(ackPacket, length);
|
||||
log_packet("Sent ", ackPacket, length);
|
||||
// In debug mode, log the packet to the private log file.
|
||||
//log_packet(ackPacket, length);
|
||||
}
|
||||
|
||||
// Send the packet to the master device.
|
||||
//write(fd, ackPacket, length);
|
||||
logMessage(LOG_DEBUG, "Send '0x%02hhx' to controller\n", command);
|
||||
//logMessage(LOG_DEBUG, "Send '0x%02hhx' to controller\n", command);
|
||||
|
||||
#ifdef BLOCKING_MODE
|
||||
write(fd, ackPacket, length);
|
||||
|
@ -334,9 +384,11 @@ int get_packet(int fd, unsigned char* packet)
|
|||
|
||||
if (generate_checksum(packet, index) != packet[index-3]){
|
||||
logMessage(LOG_WARNING, "Serial read bad checksum, ignoring\n");
|
||||
log_packet("Bad packet ", packet, index);
|
||||
return 0;
|
||||
} else if (index < AQ_MINPKTLEN) {
|
||||
logMessage(LOG_WARNING, "Serial read too small, (but good checksum), need to understand this better\n");
|
||||
logMessage(LOG_WARNING, "Serial read too small\n");
|
||||
log_packet("Bad packet ", packet, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,5 +137,6 @@ int get_packet(int file_descriptor, unsigned char* packet);
|
|||
//void process_status(void const * const ptr);
|
||||
void process_status(unsigned char* ptr);
|
||||
const char* get_packet_type(unsigned char* packet, int length);
|
||||
void send_test_cmd(int fd, unsigned char destination, unsigned char b1, unsigned char b2, unsigned char b3);
|
||||
|
||||
#endif // AQ_SERIAL_H_
|
||||
#endif // AQ_SERIAL_H_
|
||||
|
|
49
aqualinkd.c
49
aqualinkd.c
|
@ -312,6 +312,11 @@ void processMessage(char *message)
|
|||
}
|
||||
else if(strncasecmp(msg, MSG_POOL_TEMP, MSG_POOL_TEMP_LEN) == 0) {
|
||||
_aqualink_data.pool_temp = atoi(msg+9);
|
||||
/* NSF add config option to support
|
||||
if (_config_parameters.spa_temp_follow_pool == true && _aqualink_data.aqbuttons[SPA_INDEX].led->state == OFF ) {
|
||||
_aqualink_data.spa_temp = _aqualink_data.pool_temp
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if(strncasecmp(msg, MSG_SPA_TEMP, MSG_SPA_TEMP_LEN) == 0) {
|
||||
_aqualink_data.spa_temp = atoi(msg+8);
|
||||
|
@ -615,6 +620,48 @@ int main(int argc, char *argv[]) {
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
void debugPacketPrint(unsigned char ID, unsigned char *packet_buffer, int packet_length)
|
||||
{
|
||||
char buff[1000];
|
||||
int i=0;
|
||||
int cnt = 0;
|
||||
|
||||
cnt = sprintf(buff, "%4.4s 0x%02hhx of type %8.8s", (packet_buffer[PKT_DEST]==0x00?"From":"To"), ID, get_packet_type(packet_buffer, packet_length));
|
||||
cnt += sprintf(buff+cnt, " | HEX: ");
|
||||
//printHex(packet_buffer, packet_length);
|
||||
for (i=0;i<packet_length;i++)
|
||||
cnt += sprintf(buff+cnt, "0x%02hhx|",packet_buffer[i]);
|
||||
|
||||
if (packet_buffer[PKT_CMD] == CMD_MSG) {
|
||||
cnt += sprintf(buff+cnt, " Message : ");
|
||||
//fwrite(packet_buffer + 4, 1, packet_length - 4, stdout);
|
||||
strncpy(buff+cnt, (char*)packet_buffer+PKT_DATA+1, AQ_MSGLEN);
|
||||
cnt += AQ_MSGLEN;
|
||||
}
|
||||
|
||||
if (packet_buffer[PKT_DEST]==0x00)
|
||||
cnt += sprintf(buff+cnt,"\n\n");
|
||||
else
|
||||
cnt += sprintf(buff+cnt,"\n");
|
||||
|
||||
logMessage(LOG_NOTICE, "- AQUA SWG - \n%s", buff);
|
||||
}
|
||||
void debugPacket(unsigned char *packet_buffer, int packet_length)
|
||||
{
|
||||
static unsigned char lastID;
|
||||
|
||||
if (packet_buffer[PKT_DEST] == DEV_MASTER && (lastID == 0x50 || lastID == 0x58)) {
|
||||
debugPacketPrint(lastID, packet_buffer, packet_length);
|
||||
} else if (packet_buffer[PKT_DEST] == 0x50 || packet_buffer[PKT_DEST] == 0x58) {
|
||||
debugPacketPrint(packet_buffer[PKT_DEST], packet_buffer, packet_length);
|
||||
}
|
||||
|
||||
lastID = packet_buffer[PKT_DEST];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void main_loop() {
|
||||
struct mg_mgr mgr;
|
||||
int rs_fd;
|
||||
|
@ -674,6 +721,8 @@ void main_loop() {
|
|||
} else if (packet_length > 0) {
|
||||
blank_read = 0;
|
||||
|
||||
//debugPacket(packet_buffer, packet_length);
|
||||
|
||||
if (packet_length > 0 && packet_buffer[PKT_DEST] == _config_parameters.device_id) {
|
||||
/*
|
||||
send_ack(rs_fd, _aqualink_data.aq_command);
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aq_serial.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define SLOG_MAX 80
|
||||
#define PACKET_MAX 10000
|
||||
|
||||
bool _keepRunning = true;
|
||||
|
||||
void intHandler(int dummy) {
|
||||
_keepRunning = false;
|
||||
logMessage(LOG_NOTICE, "Stopping!");
|
||||
}
|
||||
|
||||
|
||||
void printHex(char *pk, int length)
|
||||
{
|
||||
int i=0;
|
||||
for (i=0;i<length;i++)
|
||||
{
|
||||
printf("0x%02hhx|",pk[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printPacket(unsigned char ID, unsigned char *packet_buffer, int packet_length)
|
||||
{
|
||||
if (packet_buffer[PKT_DEST] != 0x00)
|
||||
printf("\n");
|
||||
|
||||
printf("%4.4s 0x%02hhx of type %8.8s", (packet_buffer[PKT_DEST]==0x00?"From":"To"), (packet_buffer[PKT_DEST]==0x00?ID:packet_buffer[PKT_DEST]), get_packet_type(packet_buffer, packet_length));
|
||||
printf(" | HEX: ");
|
||||
printHex((char *)packet_buffer, packet_length);
|
||||
|
||||
if (packet_buffer[PKT_CMD] == CMD_MSG || packet_buffer[PKT_CMD] == CMD_MSG_LONG) {
|
||||
printf(" Message : ");
|
||||
//fwrite(packet_buffer + 4, 1, AQ_MSGLEN+1, stdout);
|
||||
fwrite(packet_buffer + 4, 1, packet_length-7, stdout);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rs_fd;
|
||||
int packet_length;
|
||||
unsigned char packet_buffer[AQ_MAXPKTLEN];
|
||||
unsigned char lastID;
|
||||
int received_packets = 0;
|
||||
|
||||
|
||||
if (getuid() != 0) {
|
||||
fprintf(stderr, "ERROR %s Can only be run as root\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
//if (idMode)
|
||||
setLoggingPrms(LOG_DEBUG, false, false);
|
||||
//else
|
||||
// setLoggingPrms(LOG_DEBUG_SERIAL, false, false);
|
||||
|
||||
if (argc < 2) {
|
||||
logMessage(LOG_DEBUG, "ERROR, first param must be serial port, ie:-\n %s /dev/ttyUSB0\n\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rs_fd = init_serial_port(argv[1]);
|
||||
|
||||
signal(SIGINT, intHandler);
|
||||
signal(SIGTERM, intHandler);
|
||||
|
||||
while (_keepRunning == true) {
|
||||
if (rs_fd < 0) {
|
||||
logMessage(LOG_DEBUG, "ERROR, serial port disconnect\n");
|
||||
}
|
||||
|
||||
packet_length = get_packet(rs_fd, packet_buffer);
|
||||
|
||||
if (packet_length == -1) {
|
||||
// Unrecoverable read error. Force an attempt to reconnect.
|
||||
logMessage(LOG_DEBUG, "ERROR, on serial port\n");
|
||||
_keepRunning = false;
|
||||
} else if (packet_length == 0) {
|
||||
// Nothing read
|
||||
} else if (packet_length > 0) {
|
||||
|
||||
//printPacket(lastID, packet_buffer, packet_length);
|
||||
|
||||
if ((packet_buffer[PKT_DEST] == DEV_MASTER && (lastID == 0x50 || lastID == 0x58))
|
||||
|| packet_buffer[PKT_DEST] == 0x50 || packet_buffer[PKT_DEST] == 0x58)
|
||||
printPacket(lastID, packet_buffer, packet_length);
|
||||
else if (packet_buffer[PKT_CMD] == CMD_MSG || packet_buffer[PKT_CMD] == CMD_MSG_LONG) {
|
||||
printf(" To 0x%02hhx of Type Message | ",packet_buffer[PKT_DEST]);
|
||||
fwrite(packet_buffer + 4, 1, packet_length-7, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
if (received_packets == 10 || received_packets == 20) {
|
||||
send_test_cmd(rs_fd, 0x50, 0x11, 0x32, 0x7d);
|
||||
//send_test_cmd(rs_fd, 0x80, CMD_PROBE, NUL, NUL);
|
||||
//send_test_cmd(rs_fd, 0x50, 0x11, 0x0a, NUL); // Set salt to 10%
|
||||
//send_test_cmd(rs_fd, 0x50, 0x14, 0x01, 0x77); // Send initial string AquaPure (0x14 is the comand, others should be NUL)
|
||||
//0x10|0x02|0x50|0x14|0x01|0x77|0x10|0x03|
|
||||
//0x10|0x02|0x50|0x14|0x01|0x77|0x10|0x03|
|
||||
// 10 02 50 11 0a 7d 10 03
|
||||
|
||||
// 0x11 is set %
|
||||
|
||||
printf(" *** SENT TEST *** \n");
|
||||
}
|
||||
*/
|
||||
lastID = packet_buffer[PKT_DEST];
|
||||
received_packets++;
|
||||
}
|
||||
|
||||
|
||||
if (received_packets >= PACKET_MAX) {
|
||||
_keepRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -229,6 +229,11 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
_last_mqtt_aqualinkdata.spa_temp = _aqualink_data->spa_temp;
|
||||
send_mqtt_temp_msg(nc, SPA_TEMP_TOPIC, _aqualink_data->spa_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_spa_water_temp, _aqualink_data->spa_temp);
|
||||
} else if (_aqualink_data->pool_temp != TEMP_UNKNOWN && _aqualink_data->pool_temp != _last_mqtt_aqualinkdata.spa_temp) {
|
||||
// Use Pool Temp is Spa is not available
|
||||
_last_mqtt_aqualinkdata.spa_temp = _aqualink_data->pool_temp;
|
||||
send_mqtt_temp_msg(nc, SPA_TEMP_TOPIC, _aqualink_data->pool_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_spa_water_temp, _aqualink_data->pool_temp);
|
||||
}
|
||||
if (_aqualink_data->pool_htr_set_point != TEMP_UNKNOWN && _aqualink_data->pool_htr_set_point != _last_mqtt_aqualinkdata.pool_htr_set_point) {
|
||||
_last_mqtt_aqualinkdata.pool_htr_set_point = _aqualink_data->pool_htr_set_point;
|
||||
|
@ -345,6 +350,10 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
mg_send_head(nc, 200, strlen(GET_RTN_OK), "Content-Type: text/plain");
|
||||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
|
||||
} else if (strcmp(command, "diag") == 0) {
|
||||
aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, _aqualink_data);
|
||||
mg_send_head(nc, 200, strlen(GET_RTN_OK), "Content-Type: text/plain");
|
||||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < TOTAL_BUTTONS; i++) {
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -16,8 +16,8 @@ web_directory=/var/www/aqualinkd/
|
|||
# so, NOTICE also prints WARNING & ERROR
|
||||
# DEBUG_SERIAL would print everything possible
|
||||
|
||||
#log_level=DEBUG
|
||||
log_level=INFO
|
||||
log_level=DEBUG
|
||||
#log_level=INFO
|
||||
#log_level=NOTICE
|
||||
|
||||
# The socket port that the daemon listens to
|
||||
|
@ -56,8 +56,8 @@ light_programming_mode=0
|
|||
air_temp_dzidx=13
|
||||
pool_water_temp_dzidx=14
|
||||
spa_water_temp_dzidx=15
|
||||
#SWG_percent_dzidx=998
|
||||
#SWG_PPM_dzidx=999
|
||||
SWG_percent_dzidx=151
|
||||
SWG_PPM_dzidx=153
|
||||
|
||||
# Labels for standard butons (shown in web UI), and domoticz idx's
|
||||
button_01_label=Filter Pump
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,108 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int set_interface_attribs(int fd, int speed)
|
||||
{
|
||||
struct termios tty;
|
||||
|
||||
if (tcgetattr(fd, &tty) < 0) {
|
||||
printf("Error from tcgetattr: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfsetospeed(&tty, (speed_t)speed);
|
||||
cfsetispeed(&tty, (speed_t)speed);
|
||||
|
||||
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
|
||||
tty.c_cflag &= ~CSIZE;
|
||||
tty.c_cflag |= CS8; /* 8-bit characters */
|
||||
tty.c_cflag &= ~PARENB; /* no parity bit */
|
||||
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
|
||||
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
|
||||
|
||||
/* setup for non-canonical mode */
|
||||
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
tty.c_oflag &= ~OPOST;
|
||||
|
||||
/* fetch bytes as they become available */
|
||||
tty.c_cc[VMIN] = 1;
|
||||
tty.c_cc[VTIME] = 1;
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
|
||||
printf("Error from tcsetattr: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void set_mincount(int fd, int mcount)
|
||||
{
|
||||
struct termios tty;
|
||||
|
||||
if (tcgetattr(fd, &tty) < 0) {
|
||||
printf("Error tcgetattr: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
tty.c_cc[VMIN] = mcount ? 1 : 0;
|
||||
tty.c_cc[VTIME] = 5; /* half second timer */
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, &tty) < 0)
|
||||
printf("Error tcsetattr: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
char *portname = "/dev/ttyUSB0";
|
||||
int fd;
|
||||
int wlen;
|
||||
|
||||
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
|
||||
if (fd < 0) {
|
||||
printf("Error opening %s: %s\n", portname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/*baudrate 115200, 8 bits, no parity, 1 stop bit */
|
||||
set_interface_attribs(fd, B9600);
|
||||
//set_mincount(fd, 0); /* set to pure timed read */
|
||||
|
||||
/* simple output */
|
||||
wlen = write(fd, "Hello!\n", 7);
|
||||
if (wlen != 7) {
|
||||
printf("Error from write: %d, %d\n", wlen, errno);
|
||||
}
|
||||
tcdrain(fd); /* delay for output */
|
||||
|
||||
|
||||
/* simple noncanonical input */
|
||||
do {
|
||||
unsigned char buf[80];
|
||||
int rdlen;
|
||||
|
||||
rdlen = read(fd, buf, sizeof(buf) - 1);
|
||||
if (rdlen > 0) {
|
||||
#ifdef DISPLAY_STRING
|
||||
buf[rdlen] = 0;
|
||||
printf("Read %d: \"%s\"\n", rdlen, buf);
|
||||
#else /* display hex */
|
||||
unsigned char *p;
|
||||
printf("Read %02d:", rdlen);
|
||||
for (p = buf; rdlen-- > 0; p++)
|
||||
//printf(" 0x%x", *p);
|
||||
printf(" 0x%02hhx", *p);
|
||||
printf("\n");
|
||||
#endif
|
||||
} else if (rdlen < 0) {
|
||||
printf("Error from read: %d: %s\n", rdlen, strerror(errno));
|
||||
}
|
||||
/* repeat read to get full message */
|
||||
} while (1);
|
||||
}
|
150
serial_logger.c
150
serial_logger.c
|
@ -1,11 +1,11 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "aq_serial.h"
|
||||
#include "utils.h"
|
||||
|
@ -13,98 +13,145 @@
|
|||
#define SLOG_MAX 80
|
||||
#define PACKET_MAX 1000
|
||||
|
||||
/*
|
||||
typedef enum used {
|
||||
yes,
|
||||
no,
|
||||
unknown
|
||||
} used;
|
||||
*/
|
||||
|
||||
typedef struct serial_id_log {
|
||||
unsigned char ID;
|
||||
bool inuse;
|
||||
} serial_id_log;
|
||||
|
||||
bool _keepRunning = true;
|
||||
bool _keepRunning = true;
|
||||
|
||||
unsigned char _goodID[] = { 0x0a, 0x0b, 0x08, 0x09 };
|
||||
unsigned char _goodID[] = {0x0a, 0x0b, 0x08, 0x09};
|
||||
|
||||
void intHandler(int dummy) {
|
||||
_keepRunning = false;
|
||||
logMessage(LOG_NOTICE, "Stopping!");
|
||||
}
|
||||
|
||||
bool canUse(unsigned char ID)
|
||||
{
|
||||
bool canUse(unsigned char ID) {
|
||||
int i;
|
||||
for (i=0; i < strlen((char*)_goodID); i++ ) {
|
||||
for (i = 0; i < strlen((char *)_goodID); i++) {
|
||||
if (ID == _goodID[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printHex(char *pk, int length)
|
||||
{
|
||||
int i=0;
|
||||
for (i=0;i<length;i++)
|
||||
{
|
||||
printf("0x%02hhx|",pk[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printPacket(unsigned char ID, unsigned char *packet_buffer, int packet_length)
|
||||
{
|
||||
if (packet_buffer[PKT_DEST] != 0x00)
|
||||
printf("\n");
|
||||
|
||||
printf("%4.4s 0x%02hhx of type %8.8s", (packet_buffer[PKT_DEST]==0x00?"From":"To"), (packet_buffer[PKT_DEST]==0x00?ID:packet_buffer[PKT_DEST]), get_packet_type(packet_buffer, packet_length));
|
||||
printf(" | HEX: ");
|
||||
printHex((char *)packet_buffer, packet_length);
|
||||
|
||||
if (packet_buffer[PKT_CMD] == CMD_MSG || packet_buffer[PKT_CMD] == CMD_MSG_LONG) {
|
||||
printf(" Message : ");
|
||||
//fwrite(packet_buffer + 4, 1, AQ_MSGLEN+1, stdout);
|
||||
fwrite(packet_buffer + 4, 1, packet_length-7, stdout);
|
||||
}
|
||||
|
||||
//if (packet_buffer[PKT_DEST]==0x00)
|
||||
// printf("\n\n");
|
||||
//else
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rs_fd;
|
||||
int packet_length;
|
||||
unsigned char packet_buffer[AQ_MAXPKTLEN];
|
||||
unsigned char packet_buffer[AQ_MAXPKTLEN];
|
||||
unsigned char lastID;
|
||||
int i=0;
|
||||
int i = 0;
|
||||
bool found;
|
||||
serial_id_log slog[SLOG_MAX];
|
||||
int sindex = 0;
|
||||
int received_packets=0;
|
||||
int received_packets = 0;
|
||||
//char buffer[256];
|
||||
bool idMode = true;
|
||||
|
||||
if (getuid() != 0) {
|
||||
fprintf(stderr, "ERROR %s Can only be run as root\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
setLoggingPrms(LOG_DEBUG_SERIAL, false, false);
|
||||
//if (idMode)
|
||||
setLoggingPrms(LOG_DEBUG, false, false);
|
||||
//else
|
||||
// setLoggingPrms(LOG_DEBUG_SERIAL, false, false);
|
||||
|
||||
if (argc < 2) {
|
||||
logMessage(LOG_DEBUG_SERIAL, "ERROR, first param must be serial port, ie:-\n %s /dev/ttyUSB0\n\n", argv[0]);
|
||||
logMessage(LOG_DEBUG, "ERROR, first param must be serial port, ie:-\n %s /dev/ttyUSB0\n\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rs_fd = init_serial_port(argv[1]);
|
||||
|
||||
|
||||
signal(SIGINT, intHandler);
|
||||
signal(SIGTERM, intHandler);
|
||||
|
||||
while (_keepRunning == true) {
|
||||
if ( rs_fd < 0 ) {
|
||||
logMessage(LOG_DEBUG_SERIAL, "ERROR, serial port disconnect\n");
|
||||
if (rs_fd < 0) {
|
||||
logMessage(LOG_DEBUG, "ERROR, serial port disconnect\n");
|
||||
}
|
||||
|
||||
packet_length = get_packet(rs_fd, packet_buffer);
|
||||
|
||||
|
||||
if (packet_length == -1) {
|
||||
// Unrecoverable read error. Force an attempt to reconnect.
|
||||
logMessage(LOG_DEBUG_SERIAL, "ERROR, on serial port\n");
|
||||
logMessage(LOG_DEBUG, "ERROR, on serial port\n");
|
||||
_keepRunning = false;
|
||||
} else if (packet_length == 0) {
|
||||
// Nothing read
|
||||
} else if (packet_length > 0) {
|
||||
logMessage(LOG_DEBUG_SERIAL, "Received Packet for ID 0x%02hhx of type %s\n",packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length));
|
||||
|
||||
if (packet_buffer[PKT_DEST] != DEV_MASTER) {
|
||||
found=false;
|
||||
for (i=0; i <= sindex; i++) {
|
||||
if (slog[i].ID == packet_buffer[PKT_DEST]) {
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found != true && sindex < SLOG_MAX) {
|
||||
slog[sindex].ID = packet_buffer[PKT_DEST];
|
||||
slog[sindex].inuse = false;
|
||||
sindex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet_buffer[PKT_DEST] == DEV_MASTER && packet_buffer[PKT_CMD] == CMD_ACK) {
|
||||
logMessage(LOG_DEBUG_SERIAL, "ID is in use 0x%02hhx\n",lastID);
|
||||
for (i=0; i <= sindex; i++) {
|
||||
if (slog[i].ID == lastID) {
|
||||
slog[i].inuse = true;
|
||||
break;
|
||||
//logMessage(LOG_DEBUG_SERIAL, "Received Packet for ID 0x%02hhx of type %s\n", packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length));
|
||||
printPacket(lastID, packet_buffer, packet_length);
|
||||
|
||||
if (packet_buffer[PKT_DEST] != DEV_MASTER) {
|
||||
found = false;
|
||||
for (i = 0; i <= sindex; i++) {
|
||||
if (slog[i].ID == packet_buffer[PKT_DEST]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found != true && sindex < SLOG_MAX) {
|
||||
slog[sindex].ID = packet_buffer[PKT_DEST];
|
||||
slog[sindex].inuse = false;
|
||||
sindex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (packet_buffer[PKT_DEST] == DEV_MASTER && packet_buffer[PKT_CMD] == CMD_ACK) {
|
||||
//logMessage(LOG_DEBUG_SERIAL, "ID is in use 0x%02hhx %x\n", lastID, lastID);
|
||||
for (i = 0; i <= sindex; i++) {
|
||||
if (slog[i].ID == lastID) {
|
||||
slog[i].inuse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lastID = packet_buffer[PKT_DEST];
|
||||
received_packets++;
|
||||
|
@ -115,15 +162,14 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
logMessage(LOG_DEBUG_SERIAL, "\n");
|
||||
logMessage(LOG_DEBUG, "\n");
|
||||
if (sindex >= SLOG_MAX)
|
||||
logMessage(LOG_DEBUG_SERIAL, "Ran out of storage, some ID's were not captured, please increase SLOG_MAX and recompile\n");
|
||||
logMessage(LOG_DEBUG_SERIAL, "ID's found\n");
|
||||
for (i=0; i <= sindex; i++) {
|
||||
logMessage(LOG_DEBUG_SERIAL, "ID 0x%02hhx is %s %s\n",slog[i].ID,
|
||||
slog[i].inuse==true?"in use":"not used",
|
||||
slog[i].inuse==false && canUse(slog[i].ID)==true?" <-- can use for Aqualinkd":"");
|
||||
logMessage(LOG_DEBUG, "Ran out of storage, some ID's were not captured, please increase SLOG_MAX and recompile\n");
|
||||
logMessage(LOG_DEBUG, "ID's found\n");
|
||||
for (i = 0; i <= sindex; i++) {
|
||||
logMessage(LOG_DEBUG, "ID 0x%02hhx is %s %s\n", slog[i].ID, slog[i].inuse == true ? "in use" : "not used",
|
||||
slog[i].inuse == false && canUse(slog[i].ID) == true ? " <-- can use for Aqualinkd" : "");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue