xref: /csrg-svn/usr.bin/tip/aculib/ventel.c (revision 19816)
1*19816Sdist /*
2*19816Sdist  * Copyright (c) 1983 Regents of the University of California.
3*19816Sdist  * All rights reserved.  The Berkeley software License Agreement
4*19816Sdist  * specifies the terms and conditions for redistribution.
5*19816Sdist  */
6*19816Sdist 
713281Ssam #ifndef lint
8*19816Sdist static char sccsid[] = "@(#)ventel.c	5.1 (Berkeley) 04/30/85";
9*19816Sdist #endif not lint
106562Sshannon 
116562Sshannon /*
126562Sshannon  * Routines for calling up on a Ventel Modem
1318636Smiriam  * The Ventel is expected to be strapped for local echo (just like uucp)
146562Sshannon  */
156562Sshannon #include "tip.h"
166562Sshannon 
176562Sshannon #define	MAXRETRY	5
186562Sshannon 
1913281Ssam static	int sigALRM();
2013281Ssam static	int timeout = 0;
2113281Ssam static	jmp_buf timeoutbuf;
226562Sshannon 
2318636Smiriam /*
2418636Smiriam  * some sleep calls have been replaced by this macro
2518636Smiriam  * because some ventel modems require two <cr>s in less than
2618636Smiriam  * a second in order to 'wake up'... yes, it is dirty...
2718636Smiriam  */
2818636Smiriam #define delay(num,denom) busyloop(CPUSPEED*num/denom)
2918636Smiriam #define CPUSPEED 1000000	/* VAX 780 is 1MIPS */
3018636Smiriam #define	DELAY(n)	{ register long N = (n); while (--N > 0); }
3118636Smiriam busyloop(n) { DELAY(n); }
3218636Smiriam 
336562Sshannon ven_dialer(num, acu)
346562Sshannon 	register char *num;
356562Sshannon 	char *acu;
366562Sshannon {
376562Sshannon 	register char *cp;
386562Sshannon 	register int connected = 0;
3915195Ssam 	char *msg, *index(), line[80];
4015195Ssam 
416562Sshannon 	/*
426562Sshannon 	 * Get in synch with a couple of carriage returns
436562Sshannon 	 */
446562Sshannon 	if (!vensync(FD)) {
456562Sshannon 		printf("can't synchronize with ventel\n");
466562Sshannon #ifdef ACULOG
476562Sshannon 		logent(value(HOST), num, "ventel", "can't synch up");
486562Sshannon #endif
496562Sshannon 		return (0);
506562Sshannon 	}
517592Sshannon 	if (boolean(value(VERBOSE)))
527592Sshannon 		printf("\ndialing...");
537592Sshannon 	fflush(stdout);
546562Sshannon 	ioctl(FD, TIOCHPCL, 0);
5513281Ssam 	echo("#k$\r$\n$D$I$A$L$:$ ");
566562Sshannon 	for (cp = num; *cp; cp++) {
5718636Smiriam 		delay(1, 10);
586562Sshannon 		write(FD, cp, 1);
596562Sshannon 	}
6018636Smiriam 	delay(1, 10);
6118636Smiriam 	write(FD, "\r", 1);
6218636Smiriam 	gobble('\n', line);
6315195Ssam 	if (gobble('\n', line))
6415195Ssam 		connected = gobble('!', line);
656562Sshannon 	ioctl(FD, TIOCFLUSH);
666562Sshannon #ifdef ACULOG
676562Sshannon 	if (timeout) {
686562Sshannon 		sprintf(line, "%d second dial timeout",
696562Sshannon 			number(value(DIALTIMEOUT)));
706562Sshannon 		logent(value(HOST), num, "ventel", line);
716562Sshannon 	}
726562Sshannon #endif
736562Sshannon 	if (timeout)
746562Sshannon 		ven_disconnect();	/* insurance */
7515195Ssam 	if (connected || timeout || !boolean(value(VERBOSE)))
7615195Ssam 		return (connected);
7715195Ssam 	/* call failed, parse response for user */
7815195Ssam 	cp = index(line, '\r');
7915195Ssam 	if (cp)
8015195Ssam 		*cp = '\0';
8115195Ssam 	for (cp = line; cp = index(cp, ' '); cp++)
8215195Ssam 		if (cp[1] == ' ')
8315195Ssam 			break;
8415195Ssam 	if (cp) {
8515195Ssam 		while (*cp == ' ')
8615195Ssam 			cp++;
8715195Ssam 		msg = cp;
8815195Ssam 		while (*cp) {
8915195Ssam 			if (isupper(*cp))
9015195Ssam 				*cp = tolower(*cp);
9115195Ssam 			cp++;
9215195Ssam 		}
9315195Ssam 		printf("%s...", msg);
9415195Ssam 	}
956562Sshannon 	return (connected);
966562Sshannon }
976562Sshannon 
986562Sshannon ven_disconnect()
996562Sshannon {
10013281Ssam 
1016562Sshannon 	close(FD);
1026562Sshannon }
1036562Sshannon 
1046562Sshannon ven_abort()
1056562Sshannon {
10613281Ssam 
1076562Sshannon 	write(FD, "\03", 1);
1086562Sshannon 	close(FD);
1096562Sshannon }
1106562Sshannon 
1116562Sshannon static int
1126562Sshannon echo(s)
1136562Sshannon 	register char *s;
1146562Sshannon {
1156562Sshannon 	char c;
1166562Sshannon 
1176562Sshannon 	while (c = *s++) switch (c) {
1186562Sshannon 
1196562Sshannon 	case '$':
1206562Sshannon 		read(FD, &c, 1);
1216562Sshannon 		s++;
1226562Sshannon 		break;
1236562Sshannon 
1246562Sshannon 	case '#':
1256562Sshannon 		c = *s++;
1266562Sshannon 		write(FD, &c, 1);
1276562Sshannon 		break;
1286562Sshannon 
1296562Sshannon 	default:
1306562Sshannon 		write(FD, &c, 1);
1316562Sshannon 		read(FD, &c, 1);
1326562Sshannon 	}
1336562Sshannon }
1346562Sshannon 
1356562Sshannon static int
1366562Sshannon sigALRM()
1376562Sshannon {
13813281Ssam 
1396562Sshannon 	printf("\07timeout waiting for reply\n");
1406562Sshannon 	timeout = 1;
14113281Ssam 	longjmp(timeoutbuf, 1);
1426562Sshannon }
1436562Sshannon 
1446562Sshannon static int
14515195Ssam gobble(match, response)
14613281Ssam 	register char match;
14715195Ssam 	char response[];
1486562Sshannon {
14915195Ssam 	register char *cp = response;
1506562Sshannon 	char c;
15113281Ssam 	int (*f)();
1526562Sshannon 
1536562Sshannon 	signal(SIGALRM, sigALRM);
1546562Sshannon 	timeout = 0;
1556562Sshannon 	do {
15613281Ssam 		if (setjmp(timeoutbuf)) {
15713281Ssam 			signal(SIGALRM, f);
15815195Ssam 			*cp = '\0';
15913281Ssam 			return (0);
16013281Ssam 		}
1616562Sshannon 		alarm(number(value(DIALTIMEOUT)));
16215195Ssam 		read(FD, cp, 1);
16313281Ssam 		alarm(0);
16415195Ssam 		c = (*cp++ &= 0177);
1656562Sshannon #ifdef notdef
1666562Sshannon 		if (boolean(value(VERBOSE)))
1677592Sshannon 			putchar(c);
1686562Sshannon #endif
16913281Ssam 	} while (c != '\n' && c != match);
1706562Sshannon 	signal(SIGALRM, SIG_DFL);
17115195Ssam 	*cp = '\0';
17213281Ssam 	return (c == match);
1736562Sshannon }
1746562Sshannon 
1756562Sshannon #define min(a,b)	((a)>(b)?(b):(a))
1766562Sshannon /*
1776562Sshannon  * This convoluted piece of code attempts to get
17813281Ssam  * the ventel in sync.  If you don't have FIONREAD
17913281Ssam  * there are gory ways to simulate this.
1806562Sshannon  */
1816562Sshannon static int
1826562Sshannon vensync(fd)
1836562Sshannon {
18413281Ssam 	int already = 0, nread;
1856562Sshannon 	char buf[60];
1866562Sshannon 
1876562Sshannon 	/*
1886562Sshannon 	 * Toggle DTR to force anyone off that might have left
1896562Sshannon 	 * the modem connected, and insure a consistent state
1906562Sshannon 	 * to start from.
1916562Sshannon 	 *
1926562Sshannon 	 * If you don't have the ioctl calls to diddle directly
1936562Sshannon 	 * with DTR, you can always try setting the baud rate to 0.
1946562Sshannon 	 */
1956562Sshannon 	ioctl(FD, TIOCCDTR, 0);
19618636Smiriam 	sleep(1);
1976562Sshannon 	ioctl(FD, TIOCSDTR, 0);
1986562Sshannon 	while (already < MAXRETRY) {
1996562Sshannon 		/*
2006562Sshannon 		 * After reseting the modem, send it two \r's to
2016562Sshannon 		 * autobaud on. Make sure to delay between them
2026562Sshannon 		 * so the modem can frame the incoming characters.
2036562Sshannon 		 */
2046562Sshannon 		write(fd, "\r", 1);
20518636Smiriam 		delay(1,10);
2066562Sshannon 		write(fd, "\r", 1);
20718636Smiriam 		sleep(2);
20813281Ssam 		if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
20913281Ssam 			perror("tip: ioctl");
21013281Ssam 			continue;
2116562Sshannon 		}
21213281Ssam 		while (nread > 0) {
21313281Ssam 			read(fd, buf, min(nread, 60));
21413281Ssam 			if ((buf[nread - 1] & 0177) == '$')
21513281Ssam 				return (1);
21613281Ssam 			nread -= min(nread, 60);
21713281Ssam 		}
21813281Ssam 		sleep(1);
21913281Ssam 		already++;
2206562Sshannon 	}
2216562Sshannon 	return (0);
2226562Sshannon }
22318636Smiriam 
224