[vhffs-dev] [1345] added a quick and dirty tool to monitor dry contacts connected on serial port

[ Thread Index | Date Index | More vhffs.org/vhffs-dev Archives ]


Revision: 1345
Author:   gradator
Date:     2009-02-20 01:06:24 +0100 (Fri, 20 Feb 2009)

Log Message:
-----------
added a quick and dirty tool to monitor dry contacts connected on serial port

Added Paths:
-----------
    trunk/vhffs-stsmon/
    trunk/vhffs-stsmon/stsmon.c


Added: trunk/vhffs-stsmon/stsmon.c
===================================================================
--- trunk/vhffs-stsmon/stsmon.c	                        (rev 0)
+++ trunk/vhffs-stsmon/stsmon.c	2009-02-20 00:06:24 UTC (rev 1345)
@@ -0,0 +1,275 @@
+/*
+ *  STSMON: Quick and dirty tool to monitor dry contacts connected
+ *          on serial port
+ *
+ *  Copyright 2008  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+
+/*
+ *   HOW-TO Wire the stuff
+ *
+ *   TCP port 	Name	DB9 pin		Wiring (example)
+ *
+ *  		DTR	4		_________________________.
+ *					                         |
+ *   13000	CTS	8               ___________ \____________|
+ *   13001	CD	1		___________ \____________|
+ *   13002	RI	9		___________ \____________|
+ *   13003	DSR	6		___________ \____________|
+ *
+ *
+ *   Note: there is a negative source on RTS (pin 7) that can be used instead of DTR
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/termios.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define SERIAL_DEVICE "/dev/ttyS0"
+
+
+int stsmon_listentoport(uint16_t port) {
+
+	struct sockaddr_in src;
+	int fd, flags, opt;
+
+	/* listening for network connections */
+	if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0) {
+		fprintf(stderr, "socket() failed: %s\n", strerror(errno));
+		return -1;
+	}
+
+	/* set listenfd to non-blocking */
+	flags = fcntl(fd, F_GETFL);
+	if(flags >= 0) {
+		flags |= O_NONBLOCK;
+		fcntl(fd, F_SETFL, flags);
+	}
+
+	/* add the ability to listen on a TIME_WAIT */
+	opt = 1;
+	if( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt) ) )  {
+		fprintf(stderr, "setsockopt() failed on socket %d: %s\n", fd, strerror(errno));
+	}
+
+	src.sin_addr.s_addr = INADDR_ANY;
+	src.sin_family = AF_INET;
+	src.sin_port = htons(port);
+	if( bind(fd, (struct sockaddr*)&src, sizeof(src) ) < 0) {
+		fprintf(stderr, "bind() failed on socket %d: %s\n", fd, strerror(errno));
+		close(fd);
+		return -1;
+	}
+
+	if( listen(fd, SOMAXCONN) < 0) {
+		fprintf(stderr, "listen() failed on socket %d: %s\n", fd, strerror(errno));
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}
+
+
+int main(int argc, char *argv[]) {
+	int serialfd;
+	int status;
+
+	int listencts = 0;
+	int listencd = 0;
+	int listenri = 0;
+	int listendsr = 0;
+	int fd;
+
+	if(fork()) exit(0);
+
+	signal(SIGPIPE, SIG_IGN);
+
+	serialfd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
+	if(serialfd < 0) {
+		perror(SERIAL_DEVICE);
+		exit(-1);
+	}
+
+	// power-up DTR and power-down RTS
+	// can be used as a ~12v power source
+	ioctl(serialfd, TIOCMGET, &status);
+	status |= TIOCM_DTR;
+	status &= ~TIOCM_RTS;
+	ioctl(serialfd, TIOCMSET, &status);
+
+	while(1) {
+		ioctl(serialfd, TIOCMGET, &status);
+
+//		printf("%.2X\n", status);
+//		puts("----------------------");
+
+		// inputs
+		if( status & TIOCM_CTS ) {
+//			puts("CTS (clear to send)");
+			if(!listencts) {
+				listencts = stsmon_listentoport(13000);
+				if(listencts < 0) listencts = 0;
+			}
+		}
+		else {
+			if(listencts) {
+				close(listencts);
+				listencts = 0;
+			}
+		}
+		while(listencts) {
+			fd = accept(listencts, NULL, NULL);
+			if(fd < 0) break;
+			shutdown(fd, SHUT_RDWR);
+			close(fd);
+		}
+
+		if( status & TIOCM_CD ) {
+//			puts("DCD (data carrier detect)");
+			if(!listencd) {
+				listencd = stsmon_listentoport(13001);
+				if(listencd < 0) listencd = 0;
+			}
+		}
+		else {
+			if(listencd) {
+				close(listencd);
+				listencd = 0;
+			}
+		}
+		while(listencd) {
+			fd = accept(listencd, NULL, NULL);
+			if(fd < 0) break;
+			shutdown(fd, SHUT_RDWR);
+			close(fd);
+		}
+
+		if( status & TIOCM_RI ) {
+//			puts("RI (ring)");
+			if(!listenri) {
+				listenri = stsmon_listentoport(13002);
+				if(listenri < 0) listenri = 0;
+			}
+		}
+		else {
+			if(listenri) {
+				close(listenri);
+				listenri = 0;
+			}
+		}
+		while(listenri) {
+			fd = accept(listenri, NULL, NULL);
+			if(fd < 0) break;
+			shutdown(fd, SHUT_RDWR);
+			close(fd);
+		}
+
+		if( status & TIOCM_DSR ) {
+//			puts("DSR (data set ready)");
+			if(!listendsr) {
+				listendsr = stsmon_listentoport(13003);
+				if(listendsr < 0) listendsr = 0;
+			}
+		}
+		else {
+			if(listendsr) {
+				close(listendsr);
+				listendsr = 0;
+			}
+		}
+		while(listendsr) {
+			fd = accept(listendsr, NULL, NULL);
+			if(fd < 0) break;
+			shutdown(fd, SHUT_RDWR);
+			close(fd);
+		}
+
+/*
+		// outputs
+		if( status & TIOCM_DTR ) {
+			puts("DTR (data terminal ready)");
+		}
+		if( status & TIOCM_RTS ) {
+			puts("RTS (request to send)");
+		}
+*/
+/*
+		// unused
+		if( status & TIOCM_LE ) {
+			puts("DSR (data set ready/line enable)");
+		}
+		if( status & TIOCM_ST ) {
+			puts("Secondary TXD (transmit)");
+		}
+		if( status & TIOCM_SR ) {
+			puts("Secondary RXD (receive)");
+		}
+*/
+
+		sleep(1);
+	}
+
+	close(serialfd);
+	return 0;
+}
+
+
+/*
+
+TIOCM_LE		DSR (data set ready/line enable)
+TIOCM_DTR		DTR (data terminal ready)
+TIOCM_RTS		RTS (request to send)
+TIOCM_ST		Secondary TXD (transmit)
+TIOCM_SR		Secondary RXD (receive)
+TIOCM_CTS		CTS (clear to send)
+TIOCM_CAR / TIOCM_CD	DCD (data carrier detect)
+TIOCM_RNG / TIOCM_RI	RNG (ring)
+TIOCM_DSR		DSR (data set ready)
+
+
+DB9  	DB25  	Nom  	DTE  	DCE  	Description
+x  	1  	PG  	x  	x 	Masse de protection (PG = Protecting Ground)    Ne pas utiliser comme masse du signal !
+3 	2 	TD 	S 	E 	Transmission de données (TD = Transmit Data)
+2 	3 	RD 	E 	S 	Réception de données (RD = Receive Data)
+7 	4 	RTS 	S 	E 	Demande d'autorisation à émettre (RTS = Request To Send)
+8 	5 	CTS 	E 	S 	Autorisation d'émettre (CTS = Clear To Send)
+6 	6 	DSR 	E 	S 	Prêt à recevoir (DSR = Data Set Ready)
+5 	7 	SG 	x 	x 	Masse du signal (SG = Signal Ground)
+1 	8 	DCD 	E 	S 	Détection de porteuse (DCD = Data Carrier Detect)
+4 	20 	DTR 	S 	E 	Équipement prêt (DTR = Data Terminal Ready)
+9 	22 	RI 	E 	S 	Détection de sonnerie (RI = Ring Indicator)
+
+
+1 = 7.71v
+0 = -5.76v
+
+*/


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/