xref: /csrg-svn/usr.bin/tip/aculib/ventel.c (revision 62317)
119816Sdist /*
2*62317Sbostic  * Copyright (c) 1983, 1993
3*62317Sbostic  *	The Regents of the University of California.  All rights reserved.
435492Sbostic  *
542770Sbostic  * %sccs.include.redist.c%
619816Sdist  */
719816Sdist 
813281Ssam #ifndef lint
9*62317Sbostic static char sccsid[] = "@(#)ventel.c	8.1 (Berkeley) 06/06/93";
1035492Sbostic #endif /* not lint */
116562Sshannon 
126562Sshannon /*
136562Sshannon  * Routines for calling up on a Ventel Modem
1418636Smiriam  * The Ventel is expected to be strapped for local echo (just like uucp)
156562Sshannon  */
166562Sshannon #include "tip.h"
176562Sshannon 
186562Sshannon #define	MAXRETRY	5
196562Sshannon 
2046867Sbostic static	void sigALRM();
2113281Ssam static	int timeout = 0;
2213281Ssam static	jmp_buf timeoutbuf;
236562Sshannon 
2418636Smiriam /*
2518636Smiriam  * some sleep calls have been replaced by this macro
2618636Smiriam  * because some ventel modems require two <cr>s in less than
2718636Smiriam  * a second in order to 'wake up'... yes, it is dirty...
2818636Smiriam  */
2918636Smiriam #define delay(num,denom) busyloop(CPUSPEED*num/denom)
3018636Smiriam #define CPUSPEED 1000000	/* VAX 780 is 1MIPS */
3118636Smiriam #define	DELAY(n)	{ register long N = (n); while (--N > 0); }
busyloop(n)3218636Smiriam busyloop(n) { DELAY(n); }
3318636Smiriam 
ven_dialer(num,acu)346562Sshannon ven_dialer(num, acu)
356562Sshannon 	register char *num;
366562Sshannon 	char *acu;
376562Sshannon {
386562Sshannon 	register char *cp;
396562Sshannon 	register int connected = 0;
4015195Ssam 	char *msg, *index(), line[80];
4146867Sbostic 	static int gobble(), vensync();
4246867Sbostic 	static void echo();
4315195Ssam 
446562Sshannon 	/*
456562Sshannon 	 * Get in synch with a couple of carriage returns
466562Sshannon 	 */
476562Sshannon 	if (!vensync(FD)) {
486562Sshannon 		printf("can't synchronize with ventel\n");
496562Sshannon #ifdef ACULOG
506562Sshannon 		logent(value(HOST), num, "ventel", "can't synch up");
516562Sshannon #endif
526562Sshannon 		return (0);
536562Sshannon 	}
547592Sshannon 	if (boolean(value(VERBOSE)))
557592Sshannon 		printf("\ndialing...");
567592Sshannon 	fflush(stdout);
576562Sshannon 	ioctl(FD, TIOCHPCL, 0);
5813281Ssam 	echo("#k$\r$\n$D$I$A$L$:$ ");
596562Sshannon 	for (cp = num; *cp; cp++) {
6018636Smiriam 		delay(1, 10);
616562Sshannon 		write(FD, cp, 1);
626562Sshannon 	}
6318636Smiriam 	delay(1, 10);
6418636Smiriam 	write(FD, "\r", 1);
6518636Smiriam 	gobble('\n', line);
6615195Ssam 	if (gobble('\n', line))
6715195Ssam 		connected = gobble('!', line);
686562Sshannon 	ioctl(FD, TIOCFLUSH);
696562Sshannon #ifdef ACULOG
706562Sshannon 	if (timeout) {
716562Sshannon 		sprintf(line, "%d second dial timeout",
726562Sshannon 			number(value(DIALTIMEOUT)));
736562Sshannon 		logent(value(HOST), num, "ventel", line);
746562Sshannon 	}
756562Sshannon #endif
766562Sshannon 	if (timeout)
776562Sshannon 		ven_disconnect();	/* insurance */
7815195Ssam 	if (connected || timeout || !boolean(value(VERBOSE)))
7915195Ssam 		return (connected);
8015195Ssam 	/* call failed, parse response for user */
8115195Ssam 	cp = index(line, '\r');
8215195Ssam 	if (cp)
8315195Ssam 		*cp = '\0';
8415195Ssam 	for (cp = line; cp = index(cp, ' '); cp++)
8515195Ssam 		if (cp[1] == ' ')
8615195Ssam 			break;
8715195Ssam 	if (cp) {
8815195Ssam 		while (*cp == ' ')
8915195Ssam 			cp++;
9015195Ssam 		msg = cp;
9115195Ssam 		while (*cp) {
9215195Ssam 			if (isupper(*cp))
9315195Ssam 				*cp = tolower(*cp);
9415195Ssam 			cp++;
9515195Ssam 		}
9615195Ssam 		printf("%s...", msg);
9715195Ssam 	}
986562Sshannon 	return (connected);
996562Sshannon }
1006562Sshannon 
ven_disconnect()1016562Sshannon ven_disconnect()
1026562Sshannon {
10313281Ssam 
1046562Sshannon 	close(FD);
1056562Sshannon }
1066562Sshannon 
ven_abort()1076562Sshannon ven_abort()
1086562Sshannon {
10913281Ssam 
1106562Sshannon 	write(FD, "\03", 1);
1116562Sshannon 	close(FD);
1126562Sshannon }
1136562Sshannon 
11446867Sbostic static void
echo(s)1156562Sshannon echo(s)
1166562Sshannon 	register char *s;
1176562Sshannon {
1186562Sshannon 	char c;
1196562Sshannon 
1206562Sshannon 	while (c = *s++) switch (c) {
1216562Sshannon 
1226562Sshannon 	case '$':
1236562Sshannon 		read(FD, &c, 1);
1246562Sshannon 		s++;
1256562Sshannon 		break;
1266562Sshannon 
1276562Sshannon 	case '#':
1286562Sshannon 		c = *s++;
1296562Sshannon 		write(FD, &c, 1);
1306562Sshannon 		break;
1316562Sshannon 
1326562Sshannon 	default:
1336562Sshannon 		write(FD, &c, 1);
1346562Sshannon 		read(FD, &c, 1);
1356562Sshannon 	}
1366562Sshannon }
1376562Sshannon 
13846867Sbostic static void
sigALRM()1396562Sshannon sigALRM()
1406562Sshannon {
1416562Sshannon 	printf("\07timeout waiting for reply\n");
1426562Sshannon 	timeout = 1;
14313281Ssam 	longjmp(timeoutbuf, 1);
1446562Sshannon }
1456562Sshannon 
1466562Sshannon static int
gobble(match,response)14715195Ssam gobble(match, response)
14813281Ssam 	register char match;
14915195Ssam 	char response[];
1506562Sshannon {
15115195Ssam 	register char *cp = response;
15246867Sbostic 	sig_t f;
1536562Sshannon 	char c;
1546562Sshannon 
15546867Sbostic 	f = signal(SIGALRM, sigALRM);
1566562Sshannon 	timeout = 0;
1576562Sshannon 	do {
15813281Ssam 		if (setjmp(timeoutbuf)) {
15913281Ssam 			signal(SIGALRM, f);
16015195Ssam 			*cp = '\0';
16113281Ssam 			return (0);
16213281Ssam 		}
1636562Sshannon 		alarm(number(value(DIALTIMEOUT)));
16415195Ssam 		read(FD, cp, 1);
16513281Ssam 		alarm(0);
16615195Ssam 		c = (*cp++ &= 0177);
1676562Sshannon #ifdef notdef
1686562Sshannon 		if (boolean(value(VERBOSE)))
1697592Sshannon 			putchar(c);
1706562Sshannon #endif
17113281Ssam 	} while (c != '\n' && c != match);
1726562Sshannon 	signal(SIGALRM, SIG_DFL);
17315195Ssam 	*cp = '\0';
17413281Ssam 	return (c == match);
1756562Sshannon }
1766562Sshannon 
1776562Sshannon #define min(a,b)	((a)>(b)?(b):(a))
1786562Sshannon /*
1796562Sshannon  * This convoluted piece of code attempts to get
18013281Ssam  * the ventel in sync.  If you don't have FIONREAD
18113281Ssam  * there are gory ways to simulate this.
1826562Sshannon  */
1836562Sshannon static int
vensync(fd)1846562Sshannon vensync(fd)
1856562Sshannon {
18613281Ssam 	int already = 0, nread;
1876562Sshannon 	char buf[60];
1886562Sshannon 
1896562Sshannon 	/*
1906562Sshannon 	 * Toggle DTR to force anyone off that might have left
1916562Sshannon 	 * the modem connected, and insure a consistent state
1926562Sshannon 	 * to start from.
1936562Sshannon 	 *
1946562Sshannon 	 * If you don't have the ioctl calls to diddle directly
1956562Sshannon 	 * with DTR, you can always try setting the baud rate to 0.
1966562Sshannon 	 */
1976562Sshannon 	ioctl(FD, TIOCCDTR, 0);
19818636Smiriam 	sleep(1);
1996562Sshannon 	ioctl(FD, TIOCSDTR, 0);
2006562Sshannon 	while (already < MAXRETRY) {
2016562Sshannon 		/*
2026562Sshannon 		 * After reseting the modem, send it two \r's to
2036562Sshannon 		 * autobaud on. Make sure to delay between them
2046562Sshannon 		 * so the modem can frame the incoming characters.
2056562Sshannon 		 */
2066562Sshannon 		write(fd, "\r", 1);
20718636Smiriam 		delay(1,10);
2086562Sshannon 		write(fd, "\r", 1);
20918636Smiriam 		sleep(2);
21013281Ssam 		if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
21113281Ssam 			perror("tip: ioctl");
21213281Ssam 			continue;
2136562Sshannon 		}
21413281Ssam 		while (nread > 0) {
21513281Ssam 			read(fd, buf, min(nread, 60));
21613281Ssam 			if ((buf[nread - 1] & 0177) == '$')
21713281Ssam 				return (1);
21813281Ssam 			nread -= min(nread, 60);
21913281Ssam 		}
22013281Ssam 		sleep(1);
22113281Ssam 		already++;
2226562Sshannon 	}
2236562Sshannon 	return (0);
2246562Sshannon }
22518636Smiriam 
226