/* * Copyright (c) 2017 Shaun Feakes - All rights reserved * * You may use redistribute and/or modify this code under the terms of * the GNU General Public License version 2 as published by the * Free Software Foundation. For the terms of this license, * see . * * You are free to use this software under the terms of the GNU General * Public License, 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. * * https://github.com/sfeakes/aqualinkd */ #include #include #include #include #include #include #include #include #include #include "aq_serial.h" #include "utils.h" //#define BLOCKING_MODE static struct termios _oldtio; void log_packet(char *init_str, unsigned char* packet, int length) { if ( getLogLevel() < LOG_DEBUG_SERIAL) { //logMessage(LOG_INFO, "Send '0x%02hhx'|'0x%02hhx' to controller\n", packet[5] ,packet[6]); 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= LOG_DEBUG_SERIAL) { char buf[30]; sprintf(buf, "Sent %8.8s ", get_packet_type(ackPacket+1 , length)); log_packet(buf, ackPacket, length); } } void send_messaged(int fd, unsigned char destination, char *message) { const int length = 24; int i; //unsigned char ackPacket[] = { NUL, DLE, STX, DEV_MASTER, CMD_ACK, NUL, NUL, 0x13, DLE, ETX, NUL }; unsigned char msgPacket[] = { DLE,STX,DEV_MASTER,CMD_MSG,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,NUL,DLE,ETX }; //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. msgPacket[2] = destination; for (i=0; i < strlen(message) && i < AQ_MSGLEN; i++) msgPacket[4+i] = message[i]; msgPacket[length-3] = generate_checksum(msgPacket, length-1); #ifdef BLOCKING_MODE write(fd, msgPacket, length); #else int nwrite; for (i=0; i 10) return 0; retry++; delay(10); } else if (bytesRead == 1) { started = TRUE; //if (bytesRead == 1) { if (byte == DLE) { // Found a DLE byte. Set the flag, and record the byte. foundDLE = TRUE; packet[index] = byte; } else if (byte == STX && foundDLE == TRUE) { // Found the DLE STX byte sequence. Start of packet detected. // Reset the DLE flag, and record the byte. foundDLE = FALSE; packetStarted = TRUE; packet[index] = byte; } else if (byte == NUL && foundDLE == TRUE) { // Found the DLE NUL byte sequence. Detected a delimited data byte. // Reset the DLE flag, and decrement the packet index to offset the // index increment at the end of the loop. The delimiter, [NUL], byte // is not recorded. foundDLE = FALSE; //trimmed = true; index--; } else if (byte == ETX && foundDLE == TRUE) { // Found the DLE ETX byte sequence. End of packet detected. // Reset the DLE flag, set the end of packet flag, and record // the byte. foundDLE = FALSE; packetStarted = FALSE; endOfPacket = TRUE; packet[index] = byte; } else if (packetStarted == TRUE) { // Found a data byte. Reset the DLE flag just in case it is set // to prevent anomalous detections, and record the byte. foundDLE = FALSE; packet[index] = byte; } else { // Found an extraneous byte. Probably a NUL between packets. // Ignore it, and decrement the packet index to offset the // index increment at the end of the loop. index--; } // Finished processing the byte. Increment the packet index for the // next byte. index++; // Break out of the loop if we exceed maximum packet // length. if (index >= AQ_MAXPKTLEN) { break; } } else if(bytesRead < 0) { // Got a read error. Wait one millisecond for the next byte to // arrive. logMessage(LOG_WARNING, "Read error: %d - %s\n", errno, strerror(errno)); if(errno == 9) { // Bad file descriptor. Port has been disconnected for some reason. // Return a -1. return -1; } delay(100); } } 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\n"); log_packet("Bad packet ", packet, index); return 0; } logMessage(LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index); // Return the packet length. return index; }