xref: /illumos-gate/usr/src/cmd/tip/aculib/ventel.c (revision 8d489c7a)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
5*8d489c7aSmuffin 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
87c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
97c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
107c478bd9Sstevel@tonic-gate  */
11*8d489c7aSmuffin 
12*8d489c7aSmuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate /*
157c478bd9Sstevel@tonic-gate  * Routines for calling up on a Ventel Modem
167c478bd9Sstevel@tonic-gate  * Define VENNOECHO if the Ventel is strapped for "no echo".
177c478bd9Sstevel@tonic-gate  */
187c478bd9Sstevel@tonic-gate #include "tip.h"
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate #define	MAXRETRY	5
217c478bd9Sstevel@tonic-gate 
22*8d489c7aSmuffin static int	vensync(int);
23*8d489c7aSmuffin static int	gobble(char);
24*8d489c7aSmuffin static void	echo(char *);
25*8d489c7aSmuffin static void	sigALRM(void);
26*8d489c7aSmuffin static int	timeout = 0;
27*8d489c7aSmuffin static sigjmp_buf	timeoutbuf;
28*8d489c7aSmuffin 
29*8d489c7aSmuffin void	ven_disconnect(void);
307c478bd9Sstevel@tonic-gate 
31*8d489c7aSmuffin /* ARGSUSED */
32*8d489c7aSmuffin int
33*8d489c7aSmuffin ven_dialer(char *num, char *acu)
347c478bd9Sstevel@tonic-gate {
35*8d489c7aSmuffin 	char *cp;
36*8d489c7aSmuffin 	int connected = 0;
377c478bd9Sstevel@tonic-gate 	struct termios buf;
387c478bd9Sstevel@tonic-gate #ifdef ACULOG
397c478bd9Sstevel@tonic-gate 	char line[80];
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate 	/*
427c478bd9Sstevel@tonic-gate 	 * Get in synch with a couple of carriage returns
437c478bd9Sstevel@tonic-gate 	 */
447c478bd9Sstevel@tonic-gate 	if (!vensync(FD)) {
45*8d489c7aSmuffin 		(void) printf("can't synchronize with ventel\n");
467c478bd9Sstevel@tonic-gate #ifdef ACULOG
477c478bd9Sstevel@tonic-gate 		logent(value(HOST), num, "ventel", "can't synch up");
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate 		return (0);
507c478bd9Sstevel@tonic-gate 	}
517c478bd9Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
52*8d489c7aSmuffin 		(void) printf("\ndialing...");
53*8d489c7aSmuffin 	(void) fflush(stdout);
54*8d489c7aSmuffin 	(void) ioctl(FD, TCGETS, &buf);
557c478bd9Sstevel@tonic-gate 	buf.c_cflag |= HUPCL;
56*8d489c7aSmuffin 	(void) ioctl(FD, TCSETSF, &buf);
577c478bd9Sstevel@tonic-gate #ifdef VENNOECHO
587c478bd9Sstevel@tonic-gate 	echo("#k$\r$\n$D$I$A$L$:$ ");
597c478bd9Sstevel@tonic-gate 	for (cp = num; *cp; cp++) {
60*8d489c7aSmuffin 		(void) sleep(1);
61*8d489c7aSmuffin 		(void) write(FD, cp, 1);
627c478bd9Sstevel@tonic-gate 	}
637c478bd9Sstevel@tonic-gate 	echo("\r$\n");
647c478bd9Sstevel@tonic-gate #else
657c478bd9Sstevel@tonic-gate 	echo("k$\r$\n$D$I$A$L$:$ <");
667c478bd9Sstevel@tonic-gate 	for (cp = num; *cp; cp++) {
677c478bd9Sstevel@tonic-gate 		char c;
687c478bd9Sstevel@tonic-gate 
69*8d489c7aSmuffin 		(void) sleep(1);
70*8d489c7aSmuffin 		(void) write(FD, cp, 1);
71*8d489c7aSmuffin 		(void) read(FD, &c, 1);
727c478bd9Sstevel@tonic-gate 	}
737c478bd9Sstevel@tonic-gate 	echo(">\r$\n");
747c478bd9Sstevel@tonic-gate #endif
757c478bd9Sstevel@tonic-gate 	if (gobble('\n'))
767c478bd9Sstevel@tonic-gate 		connected = gobble('!');
77*8d489c7aSmuffin 	(void) ioctl(FD, TCFLSH, TCIOFLUSH);
787c478bd9Sstevel@tonic-gate #ifdef ACULOG
797c478bd9Sstevel@tonic-gate 	if (timeout) {
80*8d489c7aSmuffin 		(void) sprintf(line, "%d second dial timeout",
81*8d489c7aSmuffin 		    number(value(DIALTIMEOUT)));
827c478bd9Sstevel@tonic-gate 		logent(value(HOST), num, "ventel", line);
837c478bd9Sstevel@tonic-gate 	}
847c478bd9Sstevel@tonic-gate #endif
857c478bd9Sstevel@tonic-gate 	if (timeout)
867c478bd9Sstevel@tonic-gate 		ven_disconnect();	/* insurance */
877c478bd9Sstevel@tonic-gate 	return (connected);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate 
90*8d489c7aSmuffin void
91*8d489c7aSmuffin ven_disconnect(void)
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate 
94*8d489c7aSmuffin 	(void) close(FD);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
97*8d489c7aSmuffin void
98*8d489c7aSmuffin ven_abort(void)
997c478bd9Sstevel@tonic-gate {
1007c478bd9Sstevel@tonic-gate 
101*8d489c7aSmuffin 	(void) write(FD, "\03", 1);
102*8d489c7aSmuffin 	(void) close(FD);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate 
105*8d489c7aSmuffin static void
106*8d489c7aSmuffin echo(char *s)
1077c478bd9Sstevel@tonic-gate {
1087c478bd9Sstevel@tonic-gate 	char c;
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	while (c = *s++) {
1117c478bd9Sstevel@tonic-gate 		switch (c) {
1127c478bd9Sstevel@tonic-gate 		case '$':
113*8d489c7aSmuffin 			(void) read(FD, &c, 1);
1147c478bd9Sstevel@tonic-gate 			s++;
1157c478bd9Sstevel@tonic-gate 			break;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 		case '#':
1187c478bd9Sstevel@tonic-gate 			c = *s++;
119*8d489c7aSmuffin 			(void) write(FD, &c, 1);
1207c478bd9Sstevel@tonic-gate 			break;
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 		default:
123*8d489c7aSmuffin 			(void) write(FD, &c, 1);
124*8d489c7aSmuffin 			(void) read(FD, &c, 1);
1257c478bd9Sstevel@tonic-gate 		}
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate static void
130*8d489c7aSmuffin sigALRM(void)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 
133*8d489c7aSmuffin 	(void) printf("\07timeout waiting for reply\n");
1347c478bd9Sstevel@tonic-gate 	timeout = 1;
1357c478bd9Sstevel@tonic-gate 	siglongjmp(timeoutbuf, 1);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate static int
139*8d489c7aSmuffin gobble(char match)
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate 	char c;
1427c478bd9Sstevel@tonic-gate 	sig_handler_t f;
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
1457c478bd9Sstevel@tonic-gate 	timeout = 0;
1467c478bd9Sstevel@tonic-gate 	do {
1477c478bd9Sstevel@tonic-gate 		if (sigsetjmp(timeoutbuf, 1)) {
148*8d489c7aSmuffin 			(void) signal(SIGALRM, f);
1497c478bd9Sstevel@tonic-gate 			return (0);
1507c478bd9Sstevel@tonic-gate 		}
151*8d489c7aSmuffin 		(void) alarm(number(value(DIALTIMEOUT)));
152*8d489c7aSmuffin 		(void) read(FD, &c, 1);
153*8d489c7aSmuffin 		(void) alarm(0);
1547c478bd9Sstevel@tonic-gate 		c &= 0177;
1557c478bd9Sstevel@tonic-gate #ifdef notdef
1567c478bd9Sstevel@tonic-gate 		if (boolean(value(VERBOSE)))
157*8d489c7aSmuffin 			(void) putchar(c);
1587c478bd9Sstevel@tonic-gate #endif
1597c478bd9Sstevel@tonic-gate 	} while (c != '\n' && c != match);
160*8d489c7aSmuffin 	(void) signal(SIGALRM, SIG_DFL);
1617c478bd9Sstevel@tonic-gate 	return (c == match);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate #define	min(a, b)	(((a) > (b)) ? (b) : (a))
1657c478bd9Sstevel@tonic-gate /*
1667c478bd9Sstevel@tonic-gate  * This convoluted piece of code attempts to get
1677c478bd9Sstevel@tonic-gate  * the ventel in sync.  If you don't have FIONREAD
1687c478bd9Sstevel@tonic-gate  * there are gory ways to simulate this.
1697c478bd9Sstevel@tonic-gate  */
1707c478bd9Sstevel@tonic-gate static int
171*8d489c7aSmuffin vensync(int fd)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate 	int already = 0, nread;
1747c478bd9Sstevel@tonic-gate 	char buf[60];
1757c478bd9Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	/*
1787c478bd9Sstevel@tonic-gate 	 * Toggle DTR to force anyone off that might have left
1797c478bd9Sstevel@tonic-gate 	 * the modem connected, and insure a consistent state
1807c478bd9Sstevel@tonic-gate 	 * to start from.
1817c478bd9Sstevel@tonic-gate 	 *
1827c478bd9Sstevel@tonic-gate 	 * If you don't have the ioctl calls to diddle directly
1837c478bd9Sstevel@tonic-gate 	 * with DTR, you can always try setting the baud rate to 0.
1847c478bd9Sstevel@tonic-gate 	 */
185*8d489c7aSmuffin 	(void) ioctl(FD, TIOCMBIC, &dtr);
186*8d489c7aSmuffin 	(void) sleep(2);
187*8d489c7aSmuffin 	(void) ioctl(FD, TIOCMBIS, &dtr);
1887c478bd9Sstevel@tonic-gate 	while (already < MAXRETRY) {
1897c478bd9Sstevel@tonic-gate 		/*
1907c478bd9Sstevel@tonic-gate 		 * After reseting the modem, send it two \r's to
1917c478bd9Sstevel@tonic-gate 		 * autobaud on. Make sure to delay between them
1927c478bd9Sstevel@tonic-gate 		 * so the modem can frame the incoming characters.
1937c478bd9Sstevel@tonic-gate 		 */
194*8d489c7aSmuffin 		(void) write(fd, "\r", 1);
1957c478bd9Sstevel@tonic-gate #ifdef VMUNIX
1967c478bd9Sstevel@tonic-gate 		{
1977c478bd9Sstevel@tonic-gate #include <sys/time.h>
1987c478bd9Sstevel@tonic-gate 		struct timeval tv = {0, 500000};
1997c478bd9Sstevel@tonic-gate 
200*8d489c7aSmuffin 		(void) select(0, 0, 0, 0, &tv);
2017c478bd9Sstevel@tonic-gate 		}
2027c478bd9Sstevel@tonic-gate #else
203*8d489c7aSmuffin 		(void) sleep(1);
2047c478bd9Sstevel@tonic-gate #endif
205*8d489c7aSmuffin 		(void) write(fd, "\r", 1);
206*8d489c7aSmuffin 		(void) sleep(3);
2077c478bd9Sstevel@tonic-gate 		if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
2087c478bd9Sstevel@tonic-gate 			perror("tip: ioctl");
2097c478bd9Sstevel@tonic-gate 			continue;
2107c478bd9Sstevel@tonic-gate 		}
2117c478bd9Sstevel@tonic-gate 		while (nread > 0) {
212*8d489c7aSmuffin 			(void) read(fd, buf, min(nread, 60));
2137c478bd9Sstevel@tonic-gate 			if ((buf[nread - 1] & 0177) == '$')
2147c478bd9Sstevel@tonic-gate 				return (1);
2157c478bd9Sstevel@tonic-gate 			nread -= min(nread, 60);
2167c478bd9Sstevel@tonic-gate 		}
217*8d489c7aSmuffin 		(void) sleep(1);
2187c478bd9Sstevel@tonic-gate 		already++;
2197c478bd9Sstevel@tonic-gate 	}
2207c478bd9Sstevel@tonic-gate 	return (0);
2217c478bd9Sstevel@tonic-gate }
222