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