[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
+
+*/