[BACK_ICON] Return to repeater.c CVS log [FILE_ICON] [DIR_ICON] Up to [SourceForge] / repeater / repeater

File: [SourceForge] / repeater / repeater / repeater.c (download)
Revision 1.3 , Tue Dec 25 15:26:14 2001 UTC (5 months, 2 weeks ago) by k5okc
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +100 -9 lines
Initial Test Program

/*
 *	repeater.c
 *
 *	This module controls the RTS pin 5 signal of the DB-25,
 *	or pin 7 of the DB-9 connector, and the DCD pin 8 of the
 *	DB-25, or pin 1 of the DB-9.
 *
 *	The RTS signal is used to control the Push-To-Talk (PTT),
 *	and the DCD signal is used to detect the Carrier Operated
 *	Squelch (COS) of a Radio Repeater.
 *
 *	Tested with Red Hat Linux 6.2 (Kernel 2.2.14)
 *
 *	Compile with: cc -O -s repeater.c -o repeater
 */

/* Includes */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>	/* TIO stuff in bits/ioctl.h and asm/ioctl.h */
#include <sys/time.h>
#include <sys/types.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

/* Defines */

typedef unsigned char BYTE;

#define	FALSE		(0)
#define	TRUE		(!FALSE)           

/* Globals */

int	fd;
int	terminate = FALSE;
int	port_signal;
int	state_tx;
char	portname[16];

/* Subroutines */

void intHandler(int signum)
{
	terminate = TRUE;
}

void killHandler(int signum)
{
	exit(0);
}

/*
 *	Wait up to sec seconds for file descriptor fd
 *	to become readable
 *
 *	if sec is 0, returns immediately
 *
 *	returns:
 *
 *	> 0 if descriptor is readable
 *	< 0 if error (errno set by select())
 *	== 0 if timeout
 */

int timeout(int fd, int sec) 
{ 
	struct timeval	tv; 
	fd_set 		rset; 
   
	FD_ZERO(&rset); 
	FD_SET(fd, &rset);

	tv.tv_sec = sec; 
	tv.tv_usec = 0;

	return (select(fd+1, &rset, NULL, NULL, &tv)); 
} 

/* Main Program */

int main(int argc, char **argv)
{
	struct	timeval	tv;
	int	port;
	pid_t	pid;

	if (argc != 2)
	{
		fprintf(stderr, "Usage: repeater port\n");
		fprintf(stderr, "Where ports 1 through 4 are valid\n");
		exit(1);
	}

	port = atoi(argv[1]) - 1;

	if (port < 0 || port > 3)
	{
		fprintf(stderr, "Valid ports are 1 through 4\n");
		exit(2);
	}

	sprintf(portname, "/dev/ttyS%d", port);

	if ((fd = open(portname, O_RDWR | O_NONBLOCK)) < 0)
	{
		perror(portname);
		exit(3);
	}

	/*
	 *	Don't need these anymore
	 */

	close(0);close(1);close(2);

	port_signal = TIOCM_RTS;

	/*
	 *	Bail out on Terminate Signal (kill -15)
	 */

	signal(SIGTERM, intHandler);

	/*
	 *	Daemonize
	 */

	if ((pid = fork()) < 0)	/* Error */
	{
		perror("daemonize");
		exit(5);
	}

	if (pid != 0) {
		/*
		 *	Parent Process, so Exit
		 */

		exit(0);
	}

	/*
	 *	Child process continues
	 *
	 *	Fork a second time into control and timer
	 */

	if ((pid = fork()) < 0)	/* Error */
	{
		perror("repeater fork");
		exit(6);
	}

	if (pid == 0)	/* Child Process */
	{
		/*
		 *	Timer process
		 *
		 *	Set 9 minute, 3 minute, and 30 sec timers
		 */

		strcpy(argv[0], "Repeater Timer");

		signal(SIGTERM, killHandler);

		for (;;)
		{
		}
	}

	if (pid != 0 )	/* Parent Process */
	{
		/*
		 *	While the COS signal on the DCD line is true
		 *	enable the PTT signal on the RTS line.
		 */

		strcpy(argv[0], "Repeater Control");

		for (;;)
		{
			int	status;

			if (terminate) {
				state_tx = 0;
				ioctl(fd, TIOCMBIC, &port_signal); /* clear */
				kill(pid, SIGTERM);
				sleep(1);
				close(fd);
				exit(0);
			}

			ioctl(fd, TIOCMGET, &status);	/* get Modem bits */

			if ((status & TIOCM_CAR) && !state_tx)
			{
				state_tx = 1;
				ioctl(fd, TIOCMBIS, &port_signal); /* set */
			}

			if (!(status & TIOCM_CAR) && state_tx)
			{
				state_tx = 0;
				ioctl(fd, TIOCMBIC, &port_signal); /* clear */
			}
		}
	}
}

Back to SourceForge
Powered by
ViewCVS 0.8