xref: /csrg-svn/usr.bin/tip/aculib/ventel.c (revision 42770)
119816Sdist /*
235492Sbostic  * Copyright (c) 1983 The Regents of the University of California.
335492Sbostic  * All rights reserved.
435492Sbostic  *
5*42770Sbostic  * %sccs.include.redist.c%
619816Sdist  */
719816Sdist 
813281Ssam #ifndef lint
9*42770Sbostic static char sccsid[] = "@(#)ventel.c	5.3 (Berkeley) 06/01/90";
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 
2013281Ssam static	int 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); }
3218636Smiriam busyloop(n) { DELAY(n); }
3318636Smiriam 
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];
4115195Ssam 
426562Sshannon 	/*
436562Sshannon 	 * Get in synch with a couple of carriage returns
446562Sshannon 	 */
456562Sshannon 	if (!vensync(FD)) {
466562Sshannon 		printf("can't synchronize with ventel\n");
476562Sshannon #ifdef ACULOG
486562Sshannon 		logent(value(HOST), num, "ventel", "can't synch up");
496562Sshannon #endif
506562Sshannon 		return (0);
516562Sshannon 	}
527592Sshannon 	if (boolean(value(VERBOSE)))
537592Sshannon 		printf("\ndialing...");
547592Sshannon 	fflush(stdout);
556562Sshannon 	ioctl(FD, TIOCHPCL, 0);
5613281Ssam 	echo("#k$\r$\n$D$I$A$L$:$ ");
576562Sshannon 	for (cp = num; *cp; cp++) {
5818636Smiriam 		delay(1, 10);
596562Sshannon 		write(FD, cp, 1);
606562Sshannon 	}
6118636Smiriam 	delay(1, 10);
6218636Smiriam 	write(FD, "\r", 1);
6318636Smiriam 	gobble('\n', line);
6415195Ssam 	if (gobble('\n', line))
6515195Ssam 		connected = gobble('!', line);
666562Sshannon 	ioctl(FD, TIOCFLUSH);
676562Sshannon #ifdef ACULOG
686562Sshannon 	if (timeout) {
696562Sshannon 		sprintf(line, "%d second dial timeout",
706562Sshannon 			number(value(DIALTIMEOUT)));
716562Sshannon 		logent(value(HOST), num, "ventel", line);
726562Sshannon 	}
736562Sshannon #endif
746562Sshannon 	if (timeout)
756562Sshannon 		ven_disconnect();	/* insurance */
7615195Ssam 	if (connected || timeout || !boolean(value(VERBOSE)))
7715195Ssam 		return (connected);
7815195Ssam 	/* call failed, parse response for user */
7915195Ssam 	cp = index(line, '\r');
8015195Ssam 	if (cp)
8115195Ssam 		*cp = '\0';
8215195Ssam 	for (cp = line; cp = index(cp, ' '); cp++)
8315195Ssam 		if (cp[1] == ' ')
8415195Ssam 			break;
8515195Ssam 	if (cp) {
8615195Ssam 		while (*cp == ' ')
8715195Ssam 			cp++;
8815195Ssam 		msg = cp;
8915195Ssam 		while (*cp) {
9015195Ssam 			if (isupper(*cp))
9115195Ssam 				*cp = tolower(*cp);
9215195Ssam 			cp++;
9315195Ssam 		}
9415195Ssam 		printf("%s...", msg);
9515195Ssam 	}
966562Sshannon 	return (connected);
976562Sshannon }
986562Sshannon 
996562Sshannon ven_disconnect()
1006562Sshannon {
10113281Ssam 
1026562Sshannon 	close(FD);
1036562Sshannon }
1046562Sshannon 
1056562Sshannon ven_abort()
1066562Sshannon {
10713281Ssam 
1086562Sshannon 	write(FD, "\03", 1);
1096562Sshannon 	close(FD);
1106562Sshannon }
1116562Sshannon 
1126562Sshannon static int
1136562Sshannon echo(s)
1146562Sshannon 	register char *s;
1156562Sshannon {
1166562Sshannon 	char c;
1176562Sshannon 
1186562Sshannon 	while (c = *s++) switch (c) {
1196562Sshannon 
1206562Sshannon 	case '$':
1216562Sshannon 		read(FD, &c, 1);
1226562Sshannon 		s++;
1236562Sshannon 		break;
1246562Sshannon 
1256562Sshannon 	case '#':
1266562Sshannon 		c = *s++;
1276562Sshannon 		write(FD, &c, 1);
1286562Sshannon 		break;
1296562Sshannon 
1306562Sshannon 	default:
1316562Sshannon 		write(FD, &c, 1);
1326562Sshannon 		read(FD, &c, 1);
1336562Sshannon 	}
1346562Sshannon }
1356562Sshannon 
1366562Sshannon static int
1376562Sshannon sigALRM()
1386562Sshannon {
13913281Ssam 
1406562Sshannon 	printf("\07timeout waiting for reply\n");
1416562Sshannon 	timeout = 1;
14213281Ssam 	longjmp(timeoutbuf, 1);
1436562Sshannon }
1446562Sshannon 
1456562Sshannon static int
14615195Ssam gobble(match, response)
14713281Ssam 	register char match;
14815195Ssam 	char response[];
1496562Sshannon {
15015195Ssam 	register char *cp = response;
1516562Sshannon 	char c;
15213281Ssam 	int (*f)();
1536562Sshannon 
1546562Sshannon 	signal(SIGALRM, sigALRM);
1556562Sshannon 	timeout = 0;
1566562Sshannon 	do {
15713281Ssam 		if (setjmp(timeoutbuf)) {
15813281Ssam 			signal(SIGALRM, f);
15915195Ssam 			*cp = '\0';
16013281Ssam 			return (0);
16113281Ssam 		}
1626562Sshannon 		alarm(number(value(DIALTIMEOUT)));
16315195Ssam 		read(FD, cp, 1);
16413281Ssam 		alarm(0);
16515195Ssam 		c = (*cp++ &= 0177);
1666562Sshannon #ifdef notdef
1676562Sshannon 		if (boolean(value(VERBOSE)))
1687592Sshannon 			putchar(c);
1696562Sshannon #endif
17013281Ssam 	} while (c != '\n' && c != match);
1716562Sshannon 	signal(SIGALRM, SIG_DFL);
17215195Ssam 	*cp = '\0';
17313281Ssam 	return (c == match);
1746562Sshannon }
1756562Sshannon 
1766562Sshannon #define min(a,b)	((a)>(b)?(b):(a))
1776562Sshannon /*
1786562Sshannon  * This convoluted piece of code attempts to get
17913281Ssam  * the ventel in sync.  If you don't have FIONREAD
18013281Ssam  * there are gory ways to simulate this.
1816562Sshannon  */
1826562Sshannon static int
1836562Sshannon vensync(fd)
1846562Sshannon {
18513281Ssam 	int already = 0, nread;
1866562Sshannon 	char buf[60];
1876562Sshannon 
1886562Sshannon 	/*
1896562Sshannon 	 * Toggle DTR to force anyone off that might have left
1906562Sshannon 	 * the modem connected, and insure a consistent state
1916562Sshannon 	 * to start from.
1926562Sshannon 	 *
1936562Sshannon 	 * If you don't have the ioctl calls to diddle directly
1946562Sshannon 	 * with DTR, you can always try setting the baud rate to 0.
1956562Sshannon 	 */
1966562Sshannon 	ioctl(FD, TIOCCDTR, 0);
19718636Smiriam 	sleep(1);
1986562Sshannon 	ioctl(FD, TIOCSDTR, 0);
1996562Sshannon 	while (already < MAXRETRY) {
2006562Sshannon 		/*
2016562Sshannon 		 * After reseting the modem, send it two \r's to
2026562Sshannon 		 * autobaud on. Make sure to delay between them
2036562Sshannon 		 * so the modem can frame the incoming characters.
2046562Sshannon 		 */
2056562Sshannon 		write(fd, "\r", 1);
20618636Smiriam 		delay(1,10);
2076562Sshannon 		write(fd, "\r", 1);
20818636Smiriam 		sleep(2);
20913281Ssam 		if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
21013281Ssam 			perror("tip: ioctl");
21113281Ssam 			continue;
2126562Sshannon 		}
21313281Ssam 		while (nread > 0) {
21413281Ssam 			read(fd, buf, min(nread, 60));
21513281Ssam 			if ((buf[nread - 1] & 0177) == '$')
21613281Ssam 				return (1);
21713281Ssam 			nread -= min(nread, 60);
21813281Ssam 		}
21913281Ssam 		sleep(1);
22013281Ssam 		already++;
2216562Sshannon 	}
2226562Sshannon 	return (0);
2236562Sshannon }
22418636Smiriam 
225