OpenSolaris_b135/cmd/tip/aculib/hayes.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * Copyright (c) 1983 Regents of the University of California.
 * All rights reserved. The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include "tip.h"

static int	hayes_sync(int);
static void	sigALRM(void);
static sigjmp_buf	timeoutbuf;

void	hayes_disconnect(void);

/*
 * Dial up on a Hayes Smart Modem 1200 or 2400
 */
/* ARGSUSED */
int
hayes_dialer(char *num, char *acu)
{
	char code = 0, cr = 0;
	sig_handler_t	f;
	struct termios buf;

	f = signal(SIGALRM, (sig_handler_t)sigALRM);

	if (!hayes_sync(FD)) {
		(void) printf("can't synchronize with hayes\n");
#ifdef ACULOG
		logent(value(HOST), num, "hayes", "can't synch up");
#endif
		(void) signal(SIGALRM, f);
		return (0);
	}
	if (boolean(value(VERBOSE)))
		(void) printf("\ndialing...");
	(void) fflush(stdout);
	(void) ioctl(FD, TCGETS, &buf);
	buf.c_cflag |= HUPCL;
	(void) ioctl(FD, TCSETS, &buf);
	(void) ioctl(FD, TCFLSH, TCIOFLUSH);

	if (sigsetjmp(timeoutbuf, 1)) {
#ifdef ACULOG
		char line[80];

		(void) sprintf(line, "%d second dial timeout",
		    number(value(DIALTIMEOUT)));
		logent(value(HOST), num, "hayes", line);
#endif
		hayes_disconnect();
		(void) signal(SIGALRM, f);
		return (0);
	}
	(void) alarm(number(value(DIALTIMEOUT)));
	(void) ioctl(FD, TCFLSH, TCIOFLUSH);
	if (*num == 'S')
		(void) write(FD, "AT", 2);
	else
		(void) write(FD, "ATDT", 4);	/* use tone dialing */
	(void) write(FD, num, strlen(num));
	(void) write(FD, "\r", 1);
	(void) read(FD, &code, 1);
	(void) read(FD, &cr, 1);
	if (code == '1' && cr == '0')
		(void) read(FD, &cr, 1);
	(void) alarm(0);
	(void) signal(SIGALRM, f);
	if ((code == '1' || code == '5') && cr == '\r')
		return (1);
	return (0);
}

void
hayes_disconnect(void)
{
	(void) close(FD);
}

void
hayes_abort(void)
{
	int dtr = TIOCM_DTR;

	(void) alarm(0);
	(void) ioctl(FD, TIOCMBIC, &dtr);
	(void) sleep(2);
	(void) ioctl(FD, TCFLSH, TCIOFLUSH);
	(void) close(FD);
}

static void
sigALRM(void)
{
	siglongjmp(timeoutbuf, 1);
}

/*
 * This piece of code attempts to get the hayes in sync.
 */
static int
hayes_sync(int fd)
{
	int tries;
	char code = 0, cr = 0;
	int dtr = TIOCM_DTR;

	/*
	 * Toggle DTR to force anyone off that might have left
	 * the modem connected, and insure a consistent state
	 * to start from.
	 */
	(void) ioctl(fd, TIOCMBIC, &dtr);
	(void) sleep(1);
	(void) ioctl(fd, TIOCMBIS, &dtr);
	for (tries = 0; tries < 3; tries++) {
		/*
		 * After reseting the modem, initialize all
		 * parameters to required vaules:
		 *
		 *	V0	- result codes are single digits
		 *	Q0	- result codes ARE sent
		 *	E0	- do not echo
		 *	S0=1	- automatically answer phone
		 *	S2=255	- disable escape character
		 *	S12=255	- longest possible escape guard time
		 */
		(void) write(fd, "ATV0Q0E0S0=1S2=255S12=255\r", 26);
		(void) sleep(1);
		/* flush any echoes or return codes */
		(void) ioctl(fd, TCFLSH, TCIOFLUSH);
		/* now see if the modem is talking to us properly */
		(void) write(fd, "AT\r", 3);
		if (sigsetjmp(timeoutbuf, 1) == 0) {
			(void) alarm(2);
			(void) read(FD, &code, 1);
			(void) read(FD, &cr, 1);
			if (code == '0' && cr == '\r')
				return (1);
		}
	}
	return (0);
}