Sun, 15 Nov 2015 21:12:11 +0100
Fixed compiling for systems with wiringPi. Improved handling of udp sockets if there is no brewpanel running.
/***************************************************************************** * Copyright (C) 2015 * * Michiel Broek <mbroek at mbse dot eu> * * This file is part of the mbsePi-apps * * This 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 2, or (at your option) any * later version. * * mbsePi-apps 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 ThermFerm; see the file COPYING. If not, write to the Free * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #include "thermferm.h" #include "slcd.h" #include "futil.h" #include "xutil.h" #define SLCD_NULL 0x0000 #define SLCD_CLEAR 0x0001 #define SLCD_MCLEAR 0x1fff #define SLCD_HOME 0x0002 #define SLCD_MHOME 0x1ffe #define SLCD_DGRAM 0x0080 #define SLCD_MDGRAM 0x1f80 #define SLCD_DATA 0x0200 #define SLCD_MDATA 0x1e00 #define SLCD_LEDS 0x0400 #define SLCD_MLEDS 0x1c00 #define SLCD_KEYS 0x0800 #define SLCD_MKEYS 0x1800 #define SLCD_MDEV 0xe000 #define SEND_PORT 6554 struct sockaddr_in sendaddr; /* Server send socket */ int sock = -1; uint16_t keys = 0x0000; extern int debug; void putLCDsocket(int fd, uint16_t data) { socklen_t slen; uint16_t rdat; if (sock == -1) return; if (sendto(sock, &data, sizeof(uint16_t), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr)) != sizeof(uint16_t)) { syslog(LOG_NOTICE, "Socket %d send failed, closing socket: %s", sock, strerror(errno)); if (shutdown(sock, SHUT_RDWR)) { syslog(LOG_NOTICE, "Can't shutdown socket: %s", strerror(errno)); } sock = -1; } else { if (recvfrom(sock, &rdat, sizeof(uint16_t), 0, (struct sockaddr *) &sendaddr, &slen) != sizeof(uint16_t)) { syslog(LOG_NOTICE, "Socket %d recvfrom failed, closing socket: %s", sock, strerror(errno)); if (shutdown(sock, SHUT_RDWR)) { syslog(LOG_NOTICE, "Can't shutdown socket: %s", strerror(errno)); } sock = -1; } else { if ((rdat & SLCD_MKEYS) == SLCD_KEYS) { if (((rdat & 0x00ff) != keys) && debug) fprintf(stdout, "received keys %04x was %04x\n", rdat & 0x00ff, keys); keys = rdat & 0x00ff; } else { if (debug) fprintf(stdout, "received %04x\n", rdat); } } } } void slcdDummy(int fd) { putLCDsocket(fd, SLCD_NULL); } //void slcdHome(int fd) //{ //} void slcdClear(int fd) { putLCDsocket(fd, SLCD_CLEAR); putLCDsocket(fd, SLCD_HOME); } //void slcdDisplay(int fd, int state) //{ //} //void slcdCursor(int fd, int state) //{ //} //void slcdCursorBlink(int fd, int state) //{ //} //void slcdSendCommand(int fd, unsigned char command) //{ //} void slcdPosition(int fd, int x, int y) { uint16_t data = SLCD_DGRAM; data += (x & 0x1f) + ((y & 0x03) << 5); putLCDsocket(fd, data); } //void slcdCharDef(int fd, int index, unsigned char data[8]) //{ //} void slcdPutchar(int fd, unsigned char c) { uint16_t data = SLCD_DATA; data += c & 0x0ff; putLCDsocket(fd, data); } void slcdPuts(int fd, const char *string) { while (*string) slcdPutchar(fd, *string++); } //void slcdPrintf(int fd, const char *message, ...) //{ //} /* * Try to setup a udp connection to 127.0.0.1 so we duplicate the panel * display and keys of the real panel. This should fail on a production * system because there should no brewpanel program be running. If it * succeeds, all io will be duplicated over the network. */ int slcdInit(int fd, int cols, int rows) { if ((sock = socket(AF_INET, SOCK_DGRAM /*| SOCK_NONBLOCK */, 0)) < 0) { syslog(LOG_NOTICE, "slcdInit() can't create socket: %s", strerror(errno)); return -1; } /* * Setup address structure for the server socket. */ memset(&sendaddr, 0, sizeof(struct sockaddr_in)); sendaddr.sin_family = AF_INET; sendaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sendaddr.sin_port = htons(SEND_PORT); if (connect(sock, (struct sockaddr *)&sendaddr, sizeof(sendaddr)) < 0) { close(sock); sock = -1; syslog(LOG_NOTICE, "slcdInit() can't bind sendsock %s", strerror(errno)); return -1; } syslog(LOG_NOTICE, "slcdInit() socket %d to brewpanel is active", sock); return 0; }