Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1726701
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
38 KB
Subscribers
None
View Options
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CC=gcc
+CFLAGS=-I. -I/usr/include
+LIBS=-liniparser
+DEPS = dns320l.h
+OBJ = dns320l-daemon.o
+
+%.o: %.c $(DEPS)
+ $(CC) -c -o $@ $< $(CFLAGS)
+
+dns320l-daemon: $(OBJ)
+ gcc -o $@ $^ $(CFLAGS) $(LIBS)
+
+clean:
+ rm -f *.o
diff --git a/daemon.c b/daemon.c
deleted file mode 100644
--- a/daemon.c
+++ /dev/null
@@ -1,568 +0,0 @@
-#include <errno.h>
-#include <termios.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <signal.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/uio.h>
-
-#include "dns320l.h"
-
-#define FAN_POLL_TIME 15
-#define GPIO_POLL_TIME 1
-#define SERVER_PORT 57367
-#define SYSFS_GPIO_DIR "/sys/class/gpio"
-
-int ls;
-int fd;
-
-int gpio_get_value(unsigned int gpio, unsigned int *value)
-{
- int fd, len;
- char buf[100];
- char ch;
-
- len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
-
- fd = open(buf, O_RDONLY);
- if (fd < 0) {
- perror("gpio/get-value");
- return fd;
- }
-
- read(fd, &ch, 1);
-
- if (ch != '0') {
- *value = 1;
- } else {
- *value = 0;
- }
-
- close(fd);
- return 0;
-}
-
-
-void cleanup(int shut,int s,int howmany)
-{
- int retval;
-
- /*
- * Shutdown and close sock1 completely.
- */
- if (shut)
- {
- retval = shutdown(s,howmany);
- if (retval == -1)
- perror ("shutdown");
- }
- retval = close (s);
- if (retval)
- perror ("close");
-}
-
-void sighandler(int sig)
-{
- if (sig == SIGINT){
- cleanup(0, ls,1);
- exit(EXIT_SUCCESS);
- }
-}
-
-void declsighandler()
-{
- struct sigaction action;
-
- sigemptyset(&action.sa_mask);
- sigaddset(&action.sa_mask,SIGINT);
- action.sa_flags = 0;
- action.sa_handler = sighandler;
- sigaction(SIGINT,&action,NULL);
-}
-
-int set_interface_attribs (int fd, int speed, int parity)
-{
- struct termios tty;
- memset (&tty, 0, sizeof tty);
- if (tcgetattr (fd, &tty) != 0)
- {
- printf("error %d from tcgetattr", errno);
- return -1;
- }
-
- cfsetospeed (&tty, speed);
- cfsetispeed (&tty, speed);
-
- tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
- // disable IGNBRK for mismatched speed tests; otherwise receive break
- // as \000 chars
- tty.c_iflag &= ~IGNBRK; // ignore break signal
- tty.c_lflag = 0; // no signaling chars, no echo,
- // no canonical processing
- tty.c_oflag = 0; // no remapping, no delays
- tty.c_cc[VMIN] = 0; // read doesn't block
- tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
-
- tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
-
- tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
- // enable reading
- tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
- tty.c_cflag |= parity;
- tty.c_cflag &= ~CSTOPB;
- tty.c_cflag &= ~CRTSCTS;
-
- if (tcsetattr (fd, TCSANOW, &tty) != 0)
- {
- printf("error %d from tcsetattr", errno);
- return -1;
- }
- return 0;
-}
-
-void set_blocking (int fd, int should_block)
-{
- struct termios tty;
- memset (&tty, 0, sizeof tty);
- if (tcgetattr (fd, &tty) != 0)
- {
- printf("error %d from tggetattr", errno);
- return;
- }
-
- tty.c_cc[VMIN] = should_block ? 1 : 0;
- tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
-
- if (tcsetattr (fd, TCSANOW, &tty) != 0)
- printf("error %d setting term attributes", errno);
-}
-
-int CheckResponse(char *buf, const char *cmd, int len)
-{
- int i;
- int tmp;
-
- for(i=0;i<5;i++)
- {
- if(buf[i] != cmd[i])
- {
- printf("Char %i is %i but should be %i\n", i, buf[i], cmd[i]);
- return ERR_WRONG_ANSWER;
- }
- }
- if(buf[len-1] != cmd[len-1])
- return ERR_WRONG_ANSWER;
- tmp = (unsigned char)buf[5];
- return tmp;
-}
-
-int SendCommand(int fd, const char *cmd, int checkAnswer)
-{
- int n;
- int i;
- unsigned int tmp;
-
- char buf[15]; // We need to keep the DateAndTime values here
- // Yes, we're sending byte by byte here - b/c the lenght of
- // commands and responses can vary!
-
- i=0;
- do
- {
- write(fd, &cmd[i], 1);
- i++;
- } while(cmd[i-1] != CMD_STOP_MAGIC);
-
- i=0;
- do
- {
- n = read(fd, &buf[i], 1);
- i++;
- } while((n == 1) && (buf[i-1] != CMD_STOP_MAGIC));
-
-
- if(buf[i-1] != CMD_STOP_MAGIC)
- {
- printf("Got no stop magic!\n");
- return ERR_WRONG_ANSWER;
- }
- else
- {
- if(checkAnswer)
- {
- tmp = CheckResponse(buf, cmd, i);
- usleep(20000); // Give the µC some time to answer...
-
- i=0;
- do
- {
- n = read(fd, &buf[i], 1);
- i++;
- } while((n == 1) && (buf[i-1] != CMD_STOP_MAGIC));
-
-
- if(buf[i-1] != CMD_STOP_MAGIC)
- {
- printf("Got no stop magic!\n");
- return ERR_WRONG_ANSWER;
- }
-
- CheckResponse(buf, AckFromSerial, i);
- return tmp;
- }
- else
- {
- return CheckResponse(buf, AckFromSerial, i);
- }
- }
-}
-
-int HandleCommand(char *message, int messageLen, char *retMessage, int bufSize)
-{
- int tmp;
- int len;
- int i;
- char cmp[] = "DeviceReady";
- printf("Handling Command: %s\n", message);
-
- if(strncmp(message, "DeviceReady", messageLen) == 0)
- {
- printf("DeviceReady\n");
- if(SendCommand(fd, DeviceReadyCmd, 0) == 0)
- strncpy(retMessage, "OK\n", bufSize);
- else
- strncpy(retMessage, "ERR\n", bufSize);
- }
- else if(strncmp(message, "GetTemperature", messageLen) == 0)
- {
- printf("GetTemperature\n");
- tmp = SendCommand(fd, ThermalStatusGetCmd, 1);
- tmp = ThermalTable[tmp];
- sprintf(retMessage, "%d", tmp);
- len = strlen(retMessage);
- retMessage[len] = '\n';
- retMessage[len+1] = '\0';
- }
- else if(strncmp(message, "DeviceShutdown", strlen("DeviceShutdown")) == 0)
- {
- printf("DeviceShutdown");
- if(messageLen >= (strlen("DeviceShutdown") + 2))
- {
- //tmp = atoi(&message[strlen("DeviceShutdown") + 1]); // FIXME: The parameter is never passed, we default to 10s here..
- //printf("%s\n", tmp);
- if(SendCommand(fd, DeviceShutdownCmd, 0) == 0)
- strncpy(retMessage, "OK\n", bufSize);
- else
- strncpy(retMessage, "ERR\n", bufSize);
- }
- }
- else if(strncmp(message, "quit", messageLen) == 0)
- {
- printf("Quit\n");
- strncpy(retMessage, "Bye\n", bufSize);
- return 1;
- }
- else
- {
- strncpy(retMessage, "Command not Understood!\n", bufSize);
- }
-
-
- //strcpy(retMessage, "OK\n");
-
- return 0;
-}
-
-int main(int args, char *argv[])
-{
-
- char *portname = "/dev/ttyS1"; // We hardcode the path, as this daemon is inteded to run on one box only
- char response[100];
- int n;
- int i;
- int j;
- int powerBtn;
- int pressed;
- int opt;
- int sleepCount;
- int pollTimeMs;
- char buf[100];
- int temperature;
- int fanSpeed;
- struct sockaddr_in s_name;
- struct pollfd *fds = NULL;
- nfds_t nfds;
- int retval;
- int ret;
- int atmark;
- int msgIdx;
- char message[100];
- socklen_t namelength;
- pressed = 0;
- nfds = 1;
- opt = 1;
- sleepCount = 0;
- pollTimeMs = 10; // Sleep 10ms for every loop
- fanSpeed = -1;
-
- if ((ls = socket (AF_INET, SOCK_STREAM, 0)) == -1){
- perror( "socket");
- exit(EXIT_FAILURE);
- }
-
- if (setsockopt(ls,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt)<0){
- printf ("setsockopt (SO_RESUSEADDR): %s\r\n",strerror(errno));
- exit(EXIT_FAILURE);
- }
-
-
- s_name.sin_family = AF_INET;
- s_name.sin_port = htons(SERVER_PORT);
- s_name.sin_addr.s_addr = htonl(INADDR_ANY);
-
- printf(" \t Bind name to ls. \n");
- retval = bind (ls,(struct sockaddr *)&s_name, sizeof s_name);
- if (retval)
- {
- perror("bind");
- cleanup(0, ls,1);
- exit(EXIT_FAILURE);
- }
-
- printf(" \t Listen on ls for connections. \n");
- retval = listen (ls, 5);
- if (retval)
- {
- perror("listen");
- cleanup(0, ls,1);
- exit(EXIT_FAILURE);
- }
- declsighandler();
-
-
- fds = (struct pollfd *)calloc(1,nfds*sizeof(struct pollfd));
- fds->fd = ls;
- fds->events = POLLIN | POLLPRI;
-
-
-
-
-
- fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
- if (fd < 0)
- {
- printf("error %d opening %s: %s", errno, portname, strerror (errno));
- return;
- }
-
- set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity)
- set_blocking (fd, 0); // set no blocking
-
- // Flush the serial port first...
-
- read(fd, buf, 100);
-
-
- if(SendCommand(fd, DeviceReadyCmd, 0) == 0)
- printf("DeviceReady command sent, going to Fan Control Mode...\n");
- else
- {
- printf("Error sending DeviceReady command, exit!\n");
- return 1;
- }
-
- while(1)
- {
- sleepCount = 0;
- temperature = SendCommand(fd, ThermalStatusGetCmd, 1);
- if(temperature > 0)
- {
- temperature = ThermalTable[temperature];
- printf("Read Temperature: %i\n", temperature);
- if(temperature < (TEMP_LOW - HYSTERESIS))
- {
- if(fanSpeed != 0)
- {
- printf("Set Fan Stop\n");
- SendCommand(fd, FanStopCmd, 0);
- fanSpeed = 0;
- }
- }
- else if(temperature < TEMP_LOW)
- {
- if(fanSpeed > 1)
- {
- printf("Set Fan Half\n");
- SendCommand(fd, FanHalfCmd, 0);
- fanSpeed = 1;
- }
- }
- else if(temperature < (TEMP_HIGH - HYSTERESIS))
- {
- if(fanSpeed != 1)
- {
- printf("Set Fan Half\n");
- SendCommand(fd, FanHalfCmd, 0);
- fanSpeed = 1;
- }
- }
- else if(temperature < TEMP_HIGH)
- {
- if(fanSpeed < 1)
- {
- printf("Set Fan Half\n");
- SendCommand(fd, FanHalfCmd, 0);
- fanSpeed = 1;
- }
- }
- else
- {
- if(fanSpeed != 2)
- {
- printf("Set Fan Full\n");
- SendCommand(fd, FanFullCmd, 0);
- fanSpeed = 2;
- }
- }
- }
- else
- {
- printf("Error reading Temperature!\n");
- }
-
-
- while((sleepCount * pollTimeMs) < (FAN_POLL_TIME * 1000))
- {
- if(((sleepCount * pollTimeMs) % (GPIO_POLL_TIME * 1000)) == 0)
- {
- if(gpio_get_value(GPIO_BUTTON_POWER, &powerBtn) == 0)
- {
- if((powerBtn == 0) && !pressed)
- {
- pressed = 1;
- printf("Power Button Pressed!\n");
- }
- }
-
- }
- sleepCount++;
-
- ret=poll(fds,nfds,pollTimeMs); // Time out after pollTimeMs
- if (ret == -1){
- perror ("poll");
- exit(EXIT_FAILURE);
- }
- for (i=0;(i<nfds) && (ret);i++)
- {
- if (!(fds+i)->revents)
- continue;
- printf(" after : revents=0x%x, ret=%d\n\n",
- (fds+i)->revents,
- ret);
- ret--;
- if (((fds+i)->fd == ls) && ((fds+i)->revents & POLLIN))
- {
- /*
- * Accept connection from socket ls:
- * accepted connection will be on socket (fds+nfds)->fd.
- */
- printf(" \t POLLIN on ls. Accepting connection\n");
- namelength = sizeof (s_name);
- fds = (struct pollfd *)realloc(fds,(nfds+1)*sizeof(struct pollfd));
- (fds+nfds)->fd = accept (ls, (struct sockaddr *)&s_name, &namelength);
- if ((fds+nfds)->fd == -1)
- {
- perror ("accept");
- cleanup(0, (fds+nfds)->fd, 1);
- fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
- continue;
- }
- (fds+nfds)->events = POLLIN | POLLRDNORM;
- nfds++;
- continue;
- }
- if ((fds+i)->revents & POLLNVAL)
- {
- printf ("POLLNVAL on socket. Freeing resource\n");
- nfds--;
- memcpy(fds+i,fds+i+1,nfds-i);
- fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
- continue;
- }
- if ((fds+i)->revents & POLLHUP)
- {
- printf ("\t POLLHUP => peer reset connection ...\n");
- cleanup(0,(fds+i)->fd,2);
- nfds--;
- memcpy(fds+i,fds+i+1,nfds-i);
- fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
- continue;
- }
- if ((fds+i)->revents & POLLERR){
- printf ("\t POLLERR => peer reset connection ...\n");
- cleanup(0,(fds+i)->fd,2);
- nfds--;
- memcpy(fds+i,fds+i+1,nfds-i);
- fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
- continue;
- }
- if ((fds+i)->revents & POLLRDNORM)
- {
- retval = recv((fds+i)->fd, message, sizeof(message)-1, 0); // Don't forget the string terminator here!
- printf(" \t -> (recv) retval = %d.\n",retval); /* ped */
- msgIdx = retval;
- if (retval <=0)
- {
- if (retval == 0)
- {
- printf ("\t recv()==0 => peer disconnected...\n");
- cleanup(1,(fds+i)->fd,2);
- }
- else
- {
- perror ("\t receive");
- cleanup( 0, (fds+i)->fd,1);
- }
- nfds--;
- memcpy(fds+i,fds+i+1,nfds-i);
- fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
- continue;
- }
- while((retval > 0) && (message[msgIdx-2] != '\r') && ((msgIdx+1) < sizeof(message)))
- {
- retval = recv((fds+i)->fd, &message[msgIdx-2], sizeof(message) - retval - 1, 0);
- printf(" \t -> (recv) retval = %d.\n", retval);
- if(retval > 0)
- msgIdx += retval - 2;
- }
- if(msgIdx > 1)
- if(message[msgIdx-1] == '\n')
- if(message[msgIdx-2] == '\r')
- message[msgIdx-2] = '\0';
- else
- message[msgIdx-1] = '\0';
-
- printf (" \t Normal message : %.*s\n",retval,message);
- msgIdx = HandleCommand(message, msgIdx, response, sizeof(response));
- retval = send((fds+i)->fd, response, strlen(response), 0);
- if((retval < 0) || (msgIdx == 1))
- {
- printf("\t send()==0 => peer disconnected...\n");
- cleanup(1,(fds+1)->fd, 2);
- }
- continue;
- }
- }
- }
- }
-
- return 0;
-}
diff --git a/dns320l-daemon.c b/dns320l-daemon.c
new file mode 100644
--- /dev/null
+++ b/dns320l-daemon.c
@@ -0,0 +1,671 @@
+#include <errno.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <signal.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <syslog.h>
+#include <iniparser.h>
+
+#include "dns320l.h"
+
+
+int ls;
+int fd;
+
+int gpio_get_value(unsigned int gpio, unsigned int *value, char *gpioDir)
+{
+ int fd, len;
+ char buf[100];
+ char ch;
+
+ len = snprintf(buf, sizeof(buf), "%s/gpio%d/value", gpioDir, gpio);
+
+ fd = open(buf, O_RDONLY);
+ if (fd < 0) {
+ syslog(LOG_ERR, "gpio/get-value");
+ return fd;
+ }
+
+ read(fd, &ch, 1);
+
+ if (ch != '0') {
+ *value = 1;
+ } else {
+ *value = 0;
+ }
+
+ close(fd);
+ return 0;
+}
+
+
+void cleanup(int shut,int s,int howmany)
+{
+ int retval;
+
+ /*
+ * Shutdown and close sock1 completely.
+ */
+ if (shut)
+ {
+ retval = shutdown(s,howmany);
+ if (retval == -1)
+ syslog(LOG_ERR, "shutdown");
+ }
+ retval = close (s);
+ if (retval)
+ syslog(LOG_ERR, "close");
+}
+
+static void sighandler(int sig)
+{
+ syslog(LOG_DEBUG, "Signal Handler called\n");
+ switch(sig)
+ {
+ case SIGINT:
+ cleanup(0, ls, 1);
+ exit(EXIT_SUCCESS);
+ break;
+ case SIGTERM:
+ cleanup(0, ls, 1);
+ syslog(LOG_INFO, "Shutting down machine in 10s...\n");
+ SendCommand(fd, DeviceShutdownCmd, 0);
+ exit(EXIT_SUCCESS);
+ break;
+ }
+}
+
+int set_interface_attribs (int fd, int speed, int parity)
+{
+ struct termios tty;
+ memset (&tty, 0, sizeof tty);
+ if (tcgetattr (fd, &tty) != 0)
+ {
+ syslog(LOG_ERR, "error %d from tcgetattr", errno);
+ return -1;
+ }
+
+ cfsetospeed (&tty, speed);
+ cfsetispeed (&tty, speed);
+
+ tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
+ // disable IGNBRK for mismatched speed tests; otherwise receive break
+ // as \000 chars
+ tty.c_iflag &= ~IGNBRK; // ignore break signal
+ tty.c_lflag = 0; // no signaling chars, no echo,
+ // no canonical processing
+ tty.c_oflag = 0; // no remapping, no delays
+ tty.c_cc[VMIN] = 0; // read doesn't block
+ tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
+
+ tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
+
+ tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
+ // enable reading
+ tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
+ tty.c_cflag |= parity;
+ tty.c_cflag &= ~CSTOPB;
+ tty.c_cflag &= ~CRTSCTS;
+
+ if (tcsetattr (fd, TCSANOW, &tty) != 0)
+ {
+ syslog(LOG_ERR, "error %d from tcsetattr", errno);
+ return -1;
+ }
+ return 0;
+}
+
+void set_blocking (int fd, int should_block)
+{
+ struct termios tty;
+ memset (&tty, 0, sizeof tty);
+ if (tcgetattr (fd, &tty) != 0)
+ {
+ syslog(LOG_ERR, "error %d from tggetattr", errno);
+ return;
+ }
+
+ tty.c_cc[VMIN] = should_block ? 1 : 0;
+ tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
+
+ if (tcsetattr (fd, TCSANOW, &tty) != 0)
+ syslog(LOG_ERR, "error %d setting term attributes", errno);
+}
+
+int CheckResponse(char *buf, const char *cmd, int len)
+{
+ int i;
+ int tmp;
+
+ for(i=0;i<5;i++)
+ {
+ if(buf[i] != cmd[i])
+ {
+ syslog(LOG_ERR, "Char %i is %i but should be %i\n", i, buf[i], cmd[i]);
+ return ERR_WRONG_ANSWER;
+ }
+ }
+ if(buf[len-1] != cmd[len-1])
+ return ERR_WRONG_ANSWER;
+ tmp = (unsigned char)buf[5];
+ return tmp;
+}
+
+int SendCommand(int fd, const char *cmd, int checkAnswer)
+{
+ int n;
+ int i;
+ unsigned int tmp;
+
+ char buf[15]; // We need to keep the DateAndTime values here
+ // Yes, we're sending byte by byte here - b/c the lenght of
+ // commands and responses can vary!
+
+ i=0;
+ do
+ {
+ write(fd, &cmd[i], 1);
+ i++;
+ } while(cmd[i-1] != CMD_STOP_MAGIC);
+
+ i=0;
+ do
+ {
+ n = read(fd, &buf[i], 1);
+ i++;
+ } while((n == 1) && (buf[i-1] != CMD_STOP_MAGIC));
+
+
+ if(buf[i-1] != CMD_STOP_MAGIC)
+ {
+ syslog(LOG_ERR, "Got no stop magic!\n");
+ return ERR_WRONG_ANSWER;
+ }
+ else
+ {
+ if(checkAnswer)
+ {
+ tmp = CheckResponse(buf, cmd, i);
+ usleep(20000); // Give the µC some time to answer...
+
+ i=0;
+ do
+ {
+ n = read(fd, &buf[i], 1);
+ i++;
+ } while((n == 1) && (buf[i-1] != CMD_STOP_MAGIC));
+
+
+ if(buf[i-1] != CMD_STOP_MAGIC)
+ {
+ syslog(LOG_ERR, "Got no stop magic!\n");
+ return ERR_WRONG_ANSWER;
+ }
+
+ CheckResponse(buf, AckFromSerial, i);
+ return tmp;
+ }
+ else
+ {
+ return CheckResponse(buf, AckFromSerial, i);
+ }
+ }
+}
+
+int HandleCommand(char *message, int messageLen, char *retMessage, int bufSize)
+{
+ int tmp;
+ int len;
+ int i;
+ char cmp[] = "DeviceReady";
+ syslog(LOG_DEBUG, "Handling Command: %s\n", message);
+
+ if(strncmp(message, "DeviceReady", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "DeviceReady\n");
+ if(SendCommand(fd, DeviceReadyCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "GetTemperature", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "GetTemperature\n");
+ tmp = SendCommand(fd, ThermalStatusGetCmd, 1);
+ tmp = ThermalTable[tmp];
+ sprintf(retMessage, "%d", tmp);
+ len = strlen(retMessage);
+ retMessage[len] = '\n';
+ retMessage[len+1] = '\0';
+ }
+ else if(strncmp(message, "DeviceShutdown", strlen("DeviceShutdown")) == 0)
+ {
+ syslog(LOG_DEBUG, "DeviceShutdown");
+ if(messageLen >= (strlen("DeviceShutdown") + 2))
+ {
+ //tmp = atoi(&message[strlen("DeviceShutdown") + 1]); // FIXME: The parameter is never passed, we default to 10s here..
+ //printf("%s\n", tmp);
+ if(SendCommand(fd, DeviceShutdownCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ }
+ else if(strncmp(message, "quit", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "Quit\n");
+ strncpy(retMessage, "Bye\n", bufSize);
+ return 1;
+ }
+ else if(strncmp(message, "EnablePowerRecovery", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "EnablePowerRecovery");
+ if(SendCommand(fd, APREnableCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "DisablePowerRecovery", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "DisablePowerRecovery");
+ if(SendCommand(fd, APRDisableCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "GetPowerRecoveryState", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "GetPowerRecoveryState");
+ tmp = SendCommand(fd, APRStatusCmd, 1);
+ sprintf(retMessage, "%d", tmp);
+ len = strlen(retMessage);
+ retMessage[len] = '\n';
+ retMessage[len+1] = '\0';
+ }
+ else if(strncmp(message, "EnableWOL", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "EnableWOL");
+ if(SendCommand(fd, WOLStatusEnableCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "DisableWOL", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "DisableWOL");
+ if(SendCommand(fd, WOLStatusDisableCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "GetWOLState", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "GetWOLState");
+ tmp = SendCommand(fd, WOLStatusGetCmd, 1);
+ sprintf(retMessage, "%d", tmp);
+ len = strlen(retMessage);
+ retMessage[len] = '\n';
+ retMessage[len+1] = '\0';
+ }
+ else if(strncmp(message, "PowerLedOn", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "PowerLedOn");
+ if(SendCommand(fd, PwrLedOnCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "PowerLedOff", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "PowerLedOff");
+ if(SendCommand(fd, PwrLedOffCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "PowerLedBlink", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "PowerLedBlink");
+ if(SendCommand(fd, PwrLedBlinkCmd, 0) == 0)
+ strncpy(retMessage, "OK\n", bufSize);
+ else
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "systohc", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "systohc");
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "hctosys", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "hctosys");
+ strncpy(retMessage, "ERR\n", bufSize);
+ }
+ else if(strncmp(message, "help", messageLen) == 0)
+ {
+ syslog(LOG_DEBUG, "help");
+ strncpy(retMessage, "Available Commands: DeviceReady, GetTemperature, DeviceShutdown, "
+ "EnablePowerRecovery, DisablePowerRecovery, GetPowerRecoveryState, "
+ "EnableWOL, DisableWOL, GetWOLState, PowerLedOn, "
+ "PowerLedOff, PowerLedBlink, quit\n", bufSize);
+ }
+ else
+ {
+ strncpy(retMessage, "Command not Understood!\n", bufSize);
+ }
+
+ return 0;
+}
+
+int main(int args, char *argv[])
+{
+
+ char *portname; // We hardcode the path, as this daemon is inteded to run on one box only
+ char *gpioDir;
+ int serverPort;
+ int fanPollTime;
+ int gpioPollTime;
+ char response[500];
+ int i;
+ int powerBtn;
+ int pressed;
+ int opt;
+ int sleepCount;
+ int pollTimeMs;
+ char buf[100];
+ int temperature;
+ int fanSpeed;
+ struct sockaddr_in s_name;
+ struct pollfd *fds = NULL;
+ nfds_t nfds;
+ int retval;
+ int ret;
+ int msgIdx;
+ int tempLow;
+ int tempHigh;
+ int hysteresis;
+ char message[500];
+ dictionary *iniFile;
+ socklen_t namelength;
+ pressed = 0;
+ nfds = 1;
+ opt = 1;
+ sleepCount = 0;
+ pollTimeMs = 10; // Sleep 10ms for every loop
+ fanSpeed = -1;
+
+ signal(SIGTERM, sighandler);
+ signal(SIGINT, sighandler);
+
+
+ iniFile = iniparser_load("/etc/dns320l-daemon.ini");
+ portname = iniparser_getstring(iniFile, "Serial:Port", "/dev/ttyS1");
+ fanPollTime = iniparser_getint(iniFile, "Fan:PollTime", 15);
+ tempLow = iniparser_getint(iniFile, "Fan:TempLow", 45);
+ tempHigh = iniparser_getint(iniFile, "Fan:TempHigh", 50);
+ hysteresis = iniparser_getint(iniFile, "Fan:Hysteresis", 2);
+ gpioPollTime = iniparser_getint(iniFile, "GPIO:PollTime", 1);
+ gpioDir = iniparser_getstring(iniFile, "GPIO:SysfsGpioDir", "/sys/class/gpio");
+ serverPort = iniparser_getint(iniFile, "Daemon:ServerPort", 57367);
+
+
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+ openlog("dns320l-daemon", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
+
+ if ((ls = socket (AF_INET, SOCK_STREAM, 0)) == -1){
+ syslog(LOG_ERR, "socket");
+ exit(EXIT_FAILURE);
+ }
+
+ if (setsockopt(ls,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt)<0){
+ syslog(LOG_ERR, "setsockopt (SO_RESUSEADDR): %s\r\n",strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+
+ s_name.sin_family = AF_INET;
+ s_name.sin_port = htons(serverPort);
+ s_name.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ syslog(LOG_DEBUG, "Bind name to ls. \n");
+ retval = bind (ls,(struct sockaddr *)&s_name, sizeof s_name);
+ if (retval)
+ {
+ syslog(LOG_ERR, "bind");
+ cleanup(0, ls,1);
+ exit(EXIT_FAILURE);
+ }
+
+ syslog(LOG_DEBUG, "Listen on ls for connections. \n");
+ retval = listen (ls, 5);
+ if (retval)
+ {
+ syslog(LOG_ERR, "listen");
+ cleanup(0, ls,1);
+ exit(EXIT_FAILURE);
+ }
+ syslog(LOG_INFO, "Server startup success on port %i\n", serverPort);
+
+ fds = (struct pollfd *)calloc(1,nfds*sizeof(struct pollfd));
+ fds->fd = ls;
+ fds->events = POLLIN | POLLPRI;
+
+ fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
+ if (fd < 0)
+ {
+ syslog(LOG_ERR, "error %d opening %s: %s", errno, portname, strerror (errno));
+ return;
+ }
+
+ set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity)
+ set_blocking (fd, 0); // set no blocking
+
+ // Flush the serial port first...
+
+ read(fd, buf, 100);
+
+
+ if(SendCommand(fd, DeviceReadyCmd, 0) == 0)
+ syslog(LOG_INFO, "dns320l-daemon startup complete, going to FanControl mode");
+ else
+ {
+ syslog(LOG_ERR, "Error sending DeviceReady command, exit!\n");
+ return EXIT_FAILURE;
+ }
+
+ while(1)
+ {
+ sleepCount = 0;
+ temperature = SendCommand(fd, ThermalStatusGetCmd, 1);
+ if(temperature > 0)
+ {
+ temperature = ThermalTable[temperature];
+ syslog(LOG_DEBUG, "Read Temperature: %i\n", temperature);
+ if(temperature < (tempLow - hysteresis))
+ {
+ if(fanSpeed != 0)
+ {
+ syslog(LOG_DEBUG, "Set Fan Stop\n");
+ SendCommand(fd, FanStopCmd, 0);
+ fanSpeed = 0;
+ }
+ }
+ else if(temperature < tempLow)
+ {
+ if(fanSpeed > 1)
+ {
+ syslog(LOG_DEBUG, "Set Fan Half\n");
+ SendCommand(fd, FanHalfCmd, 0);
+ fanSpeed = 1;
+ }
+ }
+ else if(temperature < (tempHigh - hysteresis))
+ {
+ if(fanSpeed != 1)
+ {
+ syslog(LOG_DEBUG, "Set Fan Half\n");
+ SendCommand(fd, FanHalfCmd, 0);
+ fanSpeed = 1;
+ }
+ }
+ else if(temperature < tempHigh)
+ {
+ if(fanSpeed < 1)
+ {
+ syslog(LOG_DEBUG, "Set Fan Half\n");
+ SendCommand(fd, FanHalfCmd, 0);
+ fanSpeed = 1;
+ }
+ }
+ else
+ {
+ if(fanSpeed != 2)
+ {
+ syslog(LOG_DEBUG, "Set Fan Full\n");
+ SendCommand(fd, FanFullCmd, 0);
+ fanSpeed = 2;
+ }
+ }
+ }
+ else
+ {
+ syslog(LOG_ERR, "Error reading Temperature!\n");
+ }
+
+
+ while((sleepCount * pollTimeMs) < (fanPollTime * 1000))
+ {
+ if(((sleepCount * pollTimeMs) % (gpioPollTime* 1000)) == 0)
+ {
+ if(gpio_get_value(GPIO_BUTTON_POWER, &powerBtn, gpioDir) == 0)
+ {
+ if((powerBtn == 0) && !pressed)
+ {
+ pressed = 1;
+ syslog(LOG_INFO, "Power Button Pressed, shutting down system!\n");
+ SendCommand(fd, DeviceShutdownCmd, 0);
+ execl("/sbin/shutdown", "shutdown", "-h", "now", (char *)0);
+ }
+ }
+
+ }
+ sleepCount++;
+
+ ret=poll(fds,nfds,pollTimeMs); // Time out after pollTimeMs
+ if (ret == -1){
+ syslog(LOG_ERR, "poll");
+ exit(EXIT_FAILURE);
+ }
+ for (i=0;(i<nfds) && (ret);i++)
+ {
+ if (!(fds+i)->revents)
+ continue;
+ ret--;
+ if (((fds+i)->fd == ls) && ((fds+i)->revents & POLLIN))
+ {
+ /*
+ * Accept connection from socket ls:
+ * accepted connection will be on socket (fds+nfds)->fd.
+ */
+ syslog(LOG_DEBUG, "POLLIN on ls. Accepting connection\n");
+ namelength = sizeof (s_name);
+ fds = (struct pollfd *)realloc(fds,(nfds+1)*sizeof(struct pollfd));
+ (fds+nfds)->fd = accept (ls, (struct sockaddr *)&s_name, &namelength);
+ if ((fds+nfds)->fd == -1)
+ {
+ syslog(LOG_ERR, "accept");
+ cleanup(0, (fds+nfds)->fd, 1);
+ fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
+ continue;
+ }
+ (fds+nfds)->events = POLLIN | POLLRDNORM;
+ nfds++;
+ continue;
+ }
+ if ((fds+i)->revents & POLLNVAL)
+ {
+ syslog(LOG_DEBUG, "POLLNVAL on socket. Freeing resource\n");
+ nfds--;
+ memcpy(fds+i,fds+i+1,nfds-i);
+ fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
+ continue;
+ }
+ if ((fds+i)->revents & POLLHUP)
+ {
+ syslog(LOG_DEBUG, "POLLHUP => peer reset connection ...\n");
+ cleanup(0,(fds+i)->fd,2);
+ nfds--;
+ memcpy(fds+i,fds+i+1,nfds-i);
+ fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
+ continue;
+ }
+ if ((fds+i)->revents & POLLERR){
+ syslog(LOG_DEBUG, "POLLERR => peer reset connection ...\n");
+ cleanup(0,(fds+i)->fd,2);
+ nfds--;
+ memcpy(fds+i,fds+i+1,nfds-i);
+ fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
+ continue;
+ }
+ if ((fds+i)->revents & POLLRDNORM)
+ {
+ retval = recv((fds+i)->fd, message, sizeof(message)-1, 0); // Don't forget the string terminator here!
+ syslog(LOG_DEBUG, "-> (recv) retval = %d.\n",retval); /* ped */
+ msgIdx = retval;
+ if (retval <=0)
+ {
+ if (retval == 0)
+ {
+ syslog(LOG_DEBUG, "recv()==0 => peer disconnected...\n");
+ cleanup(1,(fds+i)->fd,2);
+ }
+ else
+ {
+ syslog(LOG_ERR, "receive");
+ cleanup( 0, (fds+i)->fd,1);
+ }
+ nfds--;
+ memcpy(fds+i,fds+i+1,nfds-i);
+ fds = (struct pollfd *)realloc(fds,nfds*sizeof(struct pollfd));
+ continue;
+ }
+ while((retval > 0) && (message[msgIdx-2] != '\r') && ((msgIdx+1) < sizeof(message)))
+ {
+ retval = recv((fds+i)->fd, &message[msgIdx-2], sizeof(message) - retval - 1, 0);
+ syslog(LOG_DEBUG, " \t -> (recv) retval = %d.\n", retval);
+ if(retval > 0)
+ msgIdx += retval - 2;
+ }
+ if(msgIdx > 1)
+ if(message[msgIdx-1] == '\n')
+ if(message[msgIdx-2] == '\r')
+ message[msgIdx-2] = '\0';
+ else
+ message[msgIdx-1] = '\0';
+
+ syslog(LOG_DEBUG, "Normal message : %.*s\n",retval,message);
+ msgIdx = HandleCommand(message, msgIdx, response, sizeof(response));
+ retval = send((fds+i)->fd, response, strlen(response), 0);
+ if((retval < 0) || (msgIdx == 1))
+ {
+ syslog(LOG_DEBUG, "send()==0 => peer disconnected...\n");
+ cleanup(1,(fds+1)->fd, 2);
+ }
+ continue;
+ }
+ }
+ }
+ }
+ iniparser_freedict(iniFile);
+ return 0;
+}
diff --git a/dns320l.h b/dns320l.h
--- a/dns320l.h
+++ b/dns320l.h
@@ -1,43 +1,48 @@
#ifndef DNS320L_H
#define DNS320L_H
#define ERR_WRONG_ANSWER -1
-#define TEMP_LOW 45
-#define TEMP_HIGH 50
-#define HYSTERESIS 2
#define CMD_START_MAGIC 0xfa
#define CMD_STOP_MAGIC 0xfb
#define GPIO_BUTTON_POWER 29
const char DeviceReadyCmd[] = {0xfa, 0x03, 0x01, 0x00, 0x00, 0x00, 0xfb};
const char AckFromSerial[] = {0xfa, 0x30, 0x00, 0x00, 0x00, 0x00, 0xfb};
const char ThermalStatusGetCmd[] = {0xfa, 0x03, 0x08, 0x00, 0x00, 0x00, 0xfb};
const char FanStopCmd[] = {0xfa, 0x02, 0x00, 0x00, 0x00, 0x00, 0xfb};
const char FanHalfCmd[] = {0xfa, 0x02, 0x00, 0x01, 0x00, 0x00, 0xfb};
const char FanFullCmd[] = {0xfa, 0x02, 0x00, 0x02, 0x00, 0x00, 0xfb};
const char DeviceShutdownCmd[] = {0xfa, 0x03, 0x03, 0x01, 0x01, 0x0a, 0xfb};
-
+const char APREnableCmd[] = {0xfa, 0x03, 0x02, 0x01, 0x00, 0x00, 0xfb};
+const char APRDisableCmd[] = {0xfa, 0x03, 0x02, 0x00, 0x00, 0x00, 0xfb};
+const char APRStatusCmd[] = {0xfa, 0x03, 0x02, 0x02, 0x00, 0x00, 0xfb};
+const char PwrLedOnCmd[] = {0xfa, 0x03, 0x06, 0x01, 0x00, 0x01, 0xfb};
+const char PwrLedOffCmd[] = {0xfa, 0x03, 0x06, 0x00, 0x00, 0x01, 0xfb};
+const char PwrLedBlinkCmd[] = {0xfa, 0x03, 0x06, 0x02, 0x00, 0x01, 0xfb};
+const char WOLStatusEnableCmd[] = {0xfa, 0x03, 0x0a, 0x01, 0x00, 0x00, 0xfb};
+const char WOLStatusDisableCmd[] = {0xfa, 0x03, 0x0a, 0x00, 0x00, 0x00, 0xfb};
+const char WOLStatusGetCmd[] = {0xfa, 0x03, 0x0a, 0x02, 0x00, 0x00, 0xfb};
const char ThermalTable[] = {0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B,
0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61,
0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57,
0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D,
0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43,
0x42, 0x41, 0x41, 0x40, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D, 0x3C,
0x3B, 0x3A, 0x3A, 0x39, 0x38, 0x38, 0x37, 0x36, 0x36, 0x35,
0x34, 0x34, 0x33, 0x33, 0x32, 0x31, 0x31, 0x30, 0x30, 0x2F,
0x2F, 0x2E, 0x2E, 0x2D, 0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A,
0x29, 0x29, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, 0x25,
0x25, 0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21, 0x21,
0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1C,
0x1C, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x19, 0x19, 0x19, 0x18,
0x18, 0x17, 0x17, 0x25, 0x1B, 0x1B, 0x19, 0x19, 0x19, 0x18,
0x18, 0x17, 0x17, 0x16, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14,
0x14, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10,
0x10, 0xF, 0xF, 0xE, 0xE, 0xE, 0xD, 0xD, 0xC, 0xC, 0xC, 0xB,
0xB, 0xA, 0xA, 9, 9, 9, 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3,
3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
#endif //DNS320L_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Dec 5, 1:04 PM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
533746
Default Alt Text
(38 KB)
Attached To
rDNSD DNS-320L Daemon
Event Timeline
Log In to Comment