[vhffs-dev] [1346] Improved stsmon, added getopt() support and many options |
[ Thread Index |
Date Index
| More vhffs.org/vhffs-dev Archives
]
Revision: 1346
Author: gradator
Date: 2009-02-20 03:32:06 +0100 (Fri, 20 Feb 2009)
Log Message:
-----------
Improved stsmon, added getopt() support and many options
Modified Paths:
--------------
trunk/vhffs-stsmon/stsmon.c
Modified: trunk/vhffs-stsmon/stsmon.c
===================================================================
--- trunk/vhffs-stsmon/stsmon.c 2009-02-20 00:06:24 UTC (rev 1345)
+++ trunk/vhffs-stsmon/stsmon.c 2009-02-20 02:32:06 UTC (rev 1346)
@@ -2,7 +2,7 @@
* STSMON: Quick and dirty tool to monitor dry contacts connected
* on serial port
*
- * Copyright 2008 Sylvain Rochet <gradator@xxxxxxxxxxxx>
+ * Copyright 2008-2009 Sylvain Rochet <gradator@xxxxxxxxxxxx>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,16 +48,46 @@
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
+#include <getopt.h>
-#define SERIAL_DEVICE "/dev/ttyS0"
+#define FALSE 0
+#define TRUE !FALSE
-int stsmon_listentoport(uint16_t port) {
+void addlogline(char *line, char *logfile) {
+ FILE *lf = NULL;
+
+ struct timeval tv;
+ char date[64];
+
+ gettimeofday(&tv, NULL);
+ ctime_r(&tv.tv_sec, date);
+ date[strlen(date)-1] = '\0';
+
+ if(logfile) {
+ lf = fopen(logfile, "a");
+ }
+
+ if(lf) {
+ fprintf(lf, "%s: %s\n", date, line);
+ fclose(lf);
+ }
+ else {
+ // use stdout if logfile is not available
+ fprintf(stdout, "%s: %s\n", date, line);
+ }
+}
+
+
+int stsmon_listentoport(uint32_t bindaddr, uint16_t port) {
+
struct sockaddr_in src;
int fd, flags, opt;
@@ -80,7 +110,7 @@
fprintf(stderr, "setsockopt() failed on socket %d: %s\n", fd, strerror(errno));
}
- src.sin_addr.s_addr = INADDR_ANY;
+ src.sin_addr.s_addr = bindaddr;
src.sin_family = AF_INET;
src.sin_port = htons(port);
if( bind(fd, (struct sockaddr*)&src, sizeof(src) ) < 0) {
@@ -99,6 +129,26 @@
}
+static void usage_exit(int ret_code, char *progname) {
+ printf ("Usage: %s [OPTION]...\n"
+ "Quick and dirty tool to monitor dry contacts connected on serial port\n\n"
+ " -f, --foreground\t\tDo not daemonise, default is to daemonise\n"
+ " -d, --device\t\t\tDevice to use, default to /dev/ttyS0\n"
+ " -b, --bind=IP\t\t\tListen to the specified IP address\n"
+ " -p, --baseport=PORT\t\tBase port, will listen from BASEPORT to BASEPORT+3, default to 13000\n"
+ " -l, --logfile=LOGFILE\t\tPath to logfile, default is to log on stdout\n"
+ " -i, --interval=SECONDS\tDelay between each probe, default to 1s\n"
+ " --namects=NAME\t\tSet the name of the CTS(Clear To Send) input\n"
+ " --namecd=NAME\t\tSet the name of the CD(Carrier Detected) input\n"
+ " --nameri=NAME\t\tSet the name of the RI(Ring Indicator) input\n"
+ " --namedsr=NAME\t\tSet the name of the DSR(Data Set Ready) input\n"
+ " -h, --help\t\t\tDisplay this help and exit\n"
+ " -v, --version\t\t\tOutput version information and exit\n",
+ progname);
+ exit(ret_code);
+}
+
+
int main(int argc, char *argv[]) {
int serialfd;
int status;
@@ -107,18 +157,122 @@
int listencd = 0;
int listenri = 0;
int listendsr = 0;
- int fd;
- if(fork()) exit(0);
+ char *logfile = NULL;
+ char *device = "/dev/ttyS0";
+ int foreground = FALSE;
+ long waittime = 100;
+ uint32_t bindaddr = INADDR_ANY;
+ uint16_t baseport = 13000;
+ char *namects = "CTS";
+ char *namecd = "CD";
+ char *nameri = "RI";
+ char *namedsr = "DSR";
+ struct option long_options[] = {
+ { "foreground", no_argument, NULL, 'f' },
+ { "device", required_argument, NULL, 'd' },
+ { "bind", required_argument, NULL, 'b' },
+ { "baseport", required_argument, NULL, 'p' },
+ { "logfile", required_argument, NULL, 'l' },
+ { "interval", required_argument, NULL, 'i' },
+ { "namects", required_argument, NULL, 1000 },
+ { "namecd", required_argument, NULL, 1001 },
+ { "nameri", required_argument, NULL, 1002 },
+ { "namedsr", required_argument, NULL, 1003 },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { 0, 0, 0, 0 }
+ };
+
+ while(1) {
+ int option_index = 0, c;
+ c = getopt_long(argc, argv, "fd:b:p:l:i:hv", long_options, &option_index);
+ if(c == -1)
+ break;
+
+ switch(c) {
+ case 'f':
+ foreground = TRUE;
+ break;
+
+ case 'd':
+ device = strdup(optarg);
+ break;
+
+ case 'b':
+ bindaddr = inet_addr(optarg);
+ break;
+
+ case 'p':
+ baseport = atoi(optarg);
+ break;
+
+ case 'l':
+ logfile = strdup(optarg);
+ break;
+
+ case 'i':
+ waittime = (long)(atof(optarg)*100.0);
+ break;
+
+ case 1000:
+ namects = strdup(optarg);
+ break;
+
+ case 1001:
+ namecd = strdup(optarg);
+ break;
+
+ case 1002:
+ nameri = strdup(optarg);
+ break;
+
+ case 1003:
+ namedsr = strdup(optarg);
+ break;
+
+ case 'h':
+ usage_exit(0, argv[0]);
+
+ case 'v':
+#ifdef VERSION
+ fputs("stsmon " VERSION "\n", stdout);
+#else
+ fputs("stsmon\n", stdout);
+#endif
+ exit(0);
+
+ case '?':
+ /* `getopt_long' already printed an error message. */
+ fprintf(stderr,"Try `%s --help' for more information.\n", argv[0]);
+ exit(1);
+
+ default:
+ abort();
+ }
+ }
+
+ if(optind != argc)
+ usage_exit(1, argv[0]);
+
signal(SIGPIPE, SIG_IGN);
- serialfd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ serialfd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
if(serialfd < 0) {
- perror(SERIAL_DEVICE);
+ perror(device);
exit(-1);
}
+ addlogline("Starting stsmon", logfile);
+
+ if(!foreground) {
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ if(fork()) exit(0);
+ }
+
// power-up DTR and power-down RTS
// can be used as a ~12v power source
ioctl(serialfd, TIOCMGET, &status);
@@ -127,6 +281,8 @@
ioctl(serialfd, TIOCMSET, &status);
while(1) {
+ char line[128];
+
ioctl(serialfd, TIOCMGET, &status);
// printf("%.2X\n", status);
@@ -136,18 +292,24 @@
if( status & TIOCM_CTS ) {
// puts("CTS (clear to send)");
if(!listencts) {
- listencts = stsmon_listentoport(13000);
+ listencts = stsmon_listentoport(bindaddr, baseport+0);
if(listencts < 0) listencts = 0;
+
+ snprintf(line, 128, "%s on", namects);
+ addlogline(line, logfile);
}
}
else {
if(listencts) {
close(listencts);
listencts = 0;
+
+ snprintf(line, 128, "%s off", namects);
+ addlogline(line, logfile);
}
}
while(listencts) {
- fd = accept(listencts, NULL, NULL);
+ int fd = accept(listencts, NULL, NULL);
if(fd < 0) break;
shutdown(fd, SHUT_RDWR);
close(fd);
@@ -156,18 +318,24 @@
if( status & TIOCM_CD ) {
// puts("DCD (data carrier detect)");
if(!listencd) {
- listencd = stsmon_listentoport(13001);
+ listencd = stsmon_listentoport(bindaddr, baseport+1);
if(listencd < 0) listencd = 0;
+
+ snprintf(line, 128, "%s on", namecd);
+ addlogline(line, logfile);
}
}
else {
if(listencd) {
close(listencd);
listencd = 0;
+
+ snprintf(line, 128, "%s off", namecd);
+ addlogline(line, logfile);
}
}
while(listencd) {
- fd = accept(listencd, NULL, NULL);
+ int fd = accept(listencd, NULL, NULL);
if(fd < 0) break;
shutdown(fd, SHUT_RDWR);
close(fd);
@@ -176,18 +344,24 @@
if( status & TIOCM_RI ) {
// puts("RI (ring)");
if(!listenri) {
- listenri = stsmon_listentoport(13002);
+ listenri = stsmon_listentoport(bindaddr, baseport+2);
if(listenri < 0) listenri = 0;
+
+ snprintf(line, 128, "%s on", nameri);
+ addlogline(line, logfile);
}
}
else {
if(listenri) {
close(listenri);
listenri = 0;
+
+ snprintf(line, 128, "%s off", nameri);
+ addlogline(line, logfile);
}
}
while(listenri) {
- fd = accept(listenri, NULL, NULL);
+ int fd = accept(listenri, NULL, NULL);
if(fd < 0) break;
shutdown(fd, SHUT_RDWR);
close(fd);
@@ -196,18 +370,24 @@
if( status & TIOCM_DSR ) {
// puts("DSR (data set ready)");
if(!listendsr) {
- listendsr = stsmon_listentoport(13003);
+ listendsr = stsmon_listentoport(bindaddr, baseport+3);
if(listendsr < 0) listendsr = 0;
+
+ snprintf(line, 128, "%s on", namedsr);
+ addlogline(line, logfile);
}
}
else {
if(listendsr) {
close(listendsr);
listendsr = 0;
+
+ snprintf(line, 128, "%s off", namedsr);
+ addlogline(line, logfile);
}
}
while(listendsr) {
- fd = accept(listendsr, NULL, NULL);
+ int fd = accept(listendsr, NULL, NULL);
if(fd < 0) break;
shutdown(fd, SHUT_RDWR);
close(fd);
@@ -235,7 +415,8 @@
}
*/
- sleep(1);
+ if(waittime/100) sleep(waittime/100);
+ if(waittime%100) usleep((waittime%100)*10000);
}
close(serialfd);