xref: /csrg-svn/usr.bin/tip/aculib/ventel.c (revision 18636)
113281Ssam #ifndef lint
2*18636Smiriam static char sccsid[] = "@(#)ventel.c	1.7 (Berkeley) 04/11/85";
313281Ssam #endif
46562Sshannon 
56562Sshannon /*
66562Sshannon  * Routines for calling up on a Ventel Modem
7*18636Smiriam  * The Ventel is expected to be strapped for local echo (just like uucp)
86562Sshannon  */
96562Sshannon #include "tip.h"
106562Sshannon 
116562Sshannon #define	MAXRETRY	5
126562Sshannon 
1313281Ssam static	int sigALRM();
1413281Ssam static	int timeout = 0;
1513281Ssam static	jmp_buf timeoutbuf;
166562Sshannon 
17*18636Smiriam /*
18*18636Smiriam  * some sleep calls have been replaced by this macro
19*18636Smiriam  * because some ventel modems require two <cr>s in less than
20*18636Smiriam  * a second in order to 'wake up'... yes, it is dirty...
21*18636Smiriam  */
22*18636Smiriam #define delay(num,denom) busyloop(CPUSPEED*num/denom)
23*18636Smiriam #define CPUSPEED 1000000	/* VAX 780 is 1MIPS */
24*18636Smiriam #define	DELAY(n)	{ register long N = (n); while (--N > 0); }
25*18636Smiriam busyloop(n) { DELAY(n); }
26*18636Smiriam 
276562Sshannon ven_dialer(num, acu)
286562Sshannon 	register char *num;
296562Sshannon 	char *acu;
306562Sshannon {
316562Sshannon 	register char *cp;
326562Sshannon 	register int connected = 0;
3315195Ssam 	char *msg, *index(), line[80];
3415195Ssam 
356562Sshannon 	/*
366562Sshannon 	 * Get in synch with a couple of carriage returns
376562Sshannon 	 */
386562Sshannon 	if (!vensync(FD)) {
396562Sshannon 		printf("can't synchronize with ventel\n");
406562Sshannon #ifdef ACULOG
416562Sshannon 		logent(value(HOST), num, "ventel", "can't synch up");
426562Sshannon #endif
436562Sshannon 		return (0);
446562Sshannon 	}
457592Sshannon 	if (boolean(value(VERBOSE)))
467592Sshannon 		printf("\ndialing...");
477592Sshannon 	fflush(stdout);
486562Sshannon 	ioctl(FD, TIOCHPCL, 0);
4913281Ssam 	echo("#k$\r$\n$D$I$A$L$:$ ");
506562Sshannon 	for (cp = num; *cp; cp++) {
51*18636Smiriam 		delay(1, 10);
526562Sshannon 		write(FD, cp, 1);
536562Sshannon 	}
54*18636Smiriam 	delay(1, 10);
55*18636Smiriam 	write(FD, "\r", 1);
56*18636Smiriam 	gobble('\n', line);
5715195Ssam 	if (gobble('\n', line))
5815195Ssam 		connected = gobble('!', line);
596562Sshannon 	ioctl(FD, TIOCFLUSH);
606562Sshannon #ifdef ACULOG
616562Sshannon 	if (timeout) {
626562Sshannon 		sprintf(line, "%d second dial timeout",
636562Sshannon 			number(value(DIALTIMEOUT)));
646562Sshannon 		logent(value(HOST), num, "ventel", line);
656562Sshannon 	}
666562Sshannon #endif
676562Sshannon 	if (timeout)
686562Sshannon 		ven_disconnect();	/* insurance */
6915195Ssam 	if (connected || timeout || !boolean(value(VERBOSE)))
7015195Ssam 		return (connected);
7115195Ssam 	/* call failed, parse response for user */
7215195Ssam 	cp = index(line, '\r');
7315195Ssam 	if (cp)
7415195Ssam 		*cp = '\0';
7515195Ssam 	for (cp = line; cp = index(cp, ' '); cp++)
7615195Ssam 		if (cp[1] == ' ')
7715195Ssam 			break;
7815195Ssam 	if (cp) {
7915195Ssam 		while (*cp == ' ')
8015195Ssam 			cp++;
8115195Ssam 		msg = cp;
8215195Ssam 		while (*cp) {
8315195Ssam 			if (isupper(*cp))
8415195Ssam 				*cp = tolower(*cp);
8515195Ssam 			cp++;
8615195Ssam 		}
8715195Ssam 		printf("%s...", msg);
8815195Ssam 	}
896562Sshannon 	return (connected);
906562Sshannon }
916562Sshannon 
926562Sshannon ven_disconnect()
936562Sshannon {
9413281Ssam 
956562Sshannon 	close(FD);
966562Sshannon }
976562Sshannon 
986562Sshannon ven_abort()
996562Sshannon {
10013281Ssam 
1016562Sshannon 	write(FD, "\03", 1);
1026562Sshannon 	close(FD);
1036562Sshannon }
1046562Sshannon 
1056562Sshannon static int
1066562Sshannon echo(s)
1076562Sshannon 	register char *s;
1086562Sshannon {
1096562Sshannon 	char c;
1106562Sshannon 
1116562Sshannon 	while (c = *s++) switch (c) {
1126562Sshannon 
1136562Sshannon 	case '$':
1146562Sshannon 		read(FD, &c, 1);
1156562Sshannon 		s++;
1166562Sshannon 		break;
1176562Sshannon 
1186562Sshannon 	case '#':
1196562Sshannon 		c = *s++;
1206562Sshannon 		write(FD, &c, 1);
1216562Sshannon 		break;
1226562Sshannon 
1236562Sshannon 	default:
1246562Sshannon 		write(FD, &c, 1);
1256562Sshannon 		read(FD, &c, 1);
1266562Sshannon 	}
1276562Sshannon }
1286562Sshannon 
1296562Sshannon static int
1306562Sshannon sigALRM()
1316562Sshannon {
13213281Ssam 
1336562Sshannon 	printf("\07timeout waiting for reply\n");
1346562Sshannon 	timeout = 1;
13513281Ssam 	longjmp(timeoutbuf, 1);
1366562Sshannon }
1376562Sshannon 
1386562Sshannon static int
13915195Ssam gobble(match, response)
14013281Ssam 	register char match;
14115195Ssam 	char response[];
1426562Sshannon {
14315195Ssam 	register char *cp = response;
1446562Sshannon 	char c;
14513281Ssam 	int (*f)();
1466562Sshannon 
1476562Sshannon 	signal(SIGALRM, sigALRM);
1486562Sshannon 	timeout = 0;
1496562Sshannon 	do {
15013281Ssam 		if (setjmp(timeoutbuf)) {
15113281Ssam 			signal(SIGALRM, f);
15215195Ssam 			*cp = '\0';
15313281Ssam 			return (0);
15413281Ssam 		}
1556562Sshannon 		alarm(number(value(DIALTIMEOUT)));
15615195Ssam 		read(FD, cp, 1);
15713281Ssam 		alarm(0);
15815195Ssam 		c = (*cp++ &= 0177);
1596562Sshannon #ifdef notdef
1606562Sshannon 		if (boolean(value(VERBOSE)))
1617592Sshannon 			putchar(c);
1626562Sshannon #endif
16313281Ssam 	} while (c != '\n' && c != match);
1646562Sshannon 	signal(SIGALRM, SIG_DFL);
16515195Ssam 	*cp = '\0';
16613281Ssam 	return (c == match);
1676562Sshannon }
1686562Sshannon 
1696562Sshannon #define min(a,b)	((a)>(b)?(b):(a))
1706562Sshannon /*
1716562Sshannon  * This convoluted piece of code attempts to get
17213281Ssam  * the ventel in sync.  If you don't have FIONREAD
17313281Ssam  * there are gory ways to simulate this.
1746562Sshannon  */
1756562Sshannon static int
1766562Sshannon vensync(fd)
1776562Sshannon {
17813281Ssam 	int already = 0, nread;
1796562Sshannon 	char buf[60];
1806562Sshannon 
1816562Sshannon 	/*
1826562Sshannon 	 * Toggle DTR to force anyone off that might have left
1836562Sshannon 	 * the modem connected, and insure a consistent state
1846562Sshannon 	 * to start from.
1856562Sshannon 	 *
1866562Sshannon 	 * If you don't have the ioctl calls to diddle directly
1876562Sshannon 	 * with DTR, you can always try setting the baud rate to 0.
1886562Sshannon 	 */
1896562Sshannon 	ioctl(FD, TIOCCDTR, 0);
190*18636Smiriam 	sleep(1);
1916562Sshannon 	ioctl(FD, TIOCSDTR, 0);
1926562Sshannon 	while (already < MAXRETRY) {
1936562Sshannon 		/*
1946562Sshannon 		 * After reseting the modem, send it two \r's to
1956562Sshannon 		 * autobaud on. Make sure to delay between them
1966562Sshannon 		 * so the modem can frame the incoming characters.
1976562Sshannon 		 */
1986562Sshannon 		write(fd, "\r", 1);
199*18636Smiriam 		delay(1,10);
2006562Sshannon 		write(fd, "\r", 1);
201*18636Smiriam 		sleep(2);
20213281Ssam 		if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
20313281Ssam 			perror("tip: ioctl");
20413281Ssam 			continue;
2056562Sshannon 		}
20613281Ssam 		while (nread > 0) {
20713281Ssam 			read(fd, buf, min(nread, 60));
20813281Ssam 			if ((buf[nread - 1] & 0177) == '$')
20913281Ssam 				return (1);
21013281Ssam 			nread -= min(nread, 60);
21113281Ssam 		}
21213281Ssam 		sleep(1);
21313281Ssam 		already++;
2146562Sshannon 	}
2156562Sshannon 	return (0);
2166562Sshannon }
217*18636Smiriam 
218