ventel.c revision 7527
17527Sjkh/* 27527Sjkh * Copyright (c) 1983, 1993 37527Sjkh * The Regents of the University of California. All rights reserved. 47527Sjkh * 57527Sjkh * Redistribution and use in source and binary forms, with or without 67527Sjkh * modification, are permitted provided that the following conditions 77527Sjkh * are met: 87527Sjkh * 1. Redistributions of source code must retain the above copyright 97527Sjkh * notice, this list of conditions and the following disclaimer. 107527Sjkh * 2. Redistributions in binary form must reproduce the above copyright 117527Sjkh * notice, this list of conditions and the following disclaimer in the 127527Sjkh * documentation and/or other materials provided with the distribution. 137527Sjkh * 3. All advertising materials mentioning features or use of this software 147527Sjkh * must display the following acknowledgement: 157527Sjkh * This product includes software developed by the University of 167527Sjkh * California, Berkeley and its contributors. 177527Sjkh * 4. Neither the name of the University nor the names of its contributors 187527Sjkh * may be used to endorse or promote products derived from this software 197527Sjkh * without specific prior written permission. 207527Sjkh * 217527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 227527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 237527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 247527Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 257527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 267527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 277527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 287527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 297527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 307527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 317527Sjkh * SUCH DAMAGE. 327527Sjkh */ 337527Sjkh 347527Sjkh#ifndef lint 357527Sjkhstatic char sccsid[] = "@(#)ventel.c 8.1 (Berkeley) 6/6/93"; 367527Sjkh#endif /* not lint */ 377527Sjkh 387527Sjkh/* 397527Sjkh * Routines for calling up on a Ventel Modem 407527Sjkh * The Ventel is expected to be strapped for local echo (just like uucp) 417527Sjkh */ 427527Sjkh#include "tipconf.h" 437527Sjkh#include "tip.h" 447527Sjkh 457527Sjkh#define MAXRETRY 5 467527Sjkh 477527Sjkhstatic void sigALRM(); 487527Sjkhstatic int timeout = 0; 497527Sjkhstatic jmp_buf timeoutbuf; 507527Sjkh 517527Sjkh/* 527527Sjkh * some sleep calls have been replaced by this macro 537527Sjkh * because some ventel modems require two <cr>s in less than 547527Sjkh * a second in order to 'wake up'... yes, it is dirty... 557527Sjkh */ 567527Sjkh#define delay(num,denom) busyloop(CPUSPEED*num/denom) 577527Sjkh#define CPUSPEED 1000000 /* VAX 780 is 1MIPS */ 587527Sjkh#define DELAY(n) { register long N = (n); while (--N > 0); } 597527Sjkhbusyloop(n) { DELAY(n); } 607527Sjkh 617527Sjkhven_dialer(num, acu) 627527Sjkh register char *num; 637527Sjkh char *acu; 647527Sjkh{ 657527Sjkh register char *cp; 667527Sjkh register int connected = 0; 677527Sjkh char *msg, *index(), line[80]; 687527Sjkh static int gobble(), vensync(); 697527Sjkh static void echo(); 707527Sjkh 717527Sjkh /* 727527Sjkh * Get in synch with a couple of carriage returns 737527Sjkh */ 747527Sjkh if (!vensync(FD)) { 757527Sjkh printf("can't synchronize with ventel\n"); 767527Sjkh#if ACULOG 777527Sjkh logent(value(HOST), num, "ventel", "can't synch up"); 787527Sjkh#endif 797527Sjkh return (0); 807527Sjkh } 817527Sjkh if (boolean(value(VERBOSE))) 827527Sjkh printf("\ndialing..."); 837527Sjkh fflush(stdout); 847527Sjkh acu_hupcl (); 857527Sjkh echo("#k$\r$\n$D$I$A$L$:$ "); 867527Sjkh for (cp = num; *cp; cp++) { 877527Sjkh delay(1, 10); 887527Sjkh write(FD, cp, 1); 897527Sjkh } 907527Sjkh delay(1, 10); 917527Sjkh write(FD, "\r", 1); 927527Sjkh gobble('\n', line); 937527Sjkh if (gobble('\n', line)) 947527Sjkh connected = gobble('!', line); 957527Sjkh acu_flush (); 967527Sjkh#if ACULOG 977527Sjkh if (timeout) { 987527Sjkh sprintf(line, "%d second dial timeout", 997527Sjkh number(value(DIALTIMEOUT))); 1007527Sjkh logent(value(HOST), num, "ventel", line); 1017527Sjkh } 1027527Sjkh#endif 1037527Sjkh if (timeout) 1047527Sjkh ven_disconnect(); /* insurance */ 1057527Sjkh if (connected || timeout || !boolean(value(VERBOSE))) 1067527Sjkh return (connected); 1077527Sjkh /* call failed, parse response for user */ 1087527Sjkh cp = index(line, '\r'); 1097527Sjkh if (cp) 1107527Sjkh *cp = '\0'; 1117527Sjkh for (cp = line; cp = index(cp, ' '); cp++) 1127527Sjkh if (cp[1] == ' ') 1137527Sjkh break; 1147527Sjkh if (cp) { 1157527Sjkh while (*cp == ' ') 1167527Sjkh cp++; 1177527Sjkh msg = cp; 1187527Sjkh while (*cp) { 1197527Sjkh if (isupper(*cp)) 1207527Sjkh *cp = tolower(*cp); 1217527Sjkh cp++; 1227527Sjkh } 1237527Sjkh printf("%s...", msg); 1247527Sjkh } 1257527Sjkh return (connected); 1267527Sjkh} 1277527Sjkh 1287527Sjkhven_disconnect() 1297527Sjkh{ 1307527Sjkh 1317527Sjkh close(FD); 1327527Sjkh} 1337527Sjkh 1347527Sjkhven_abort() 1357527Sjkh{ 1367527Sjkh 1377527Sjkh write(FD, "\03", 1); 1387527Sjkh close(FD); 1397527Sjkh} 1407527Sjkh 1417527Sjkhstatic void 1427527Sjkhecho(s) 1437527Sjkh register char *s; 1447527Sjkh{ 1457527Sjkh char c; 1467527Sjkh 1477527Sjkh while (c = *s++) switch (c) { 1487527Sjkh 1497527Sjkh case '$': 1507527Sjkh read(FD, &c, 1); 1517527Sjkh s++; 1527527Sjkh break; 1537527Sjkh 1547527Sjkh case '#': 1557527Sjkh c = *s++; 1567527Sjkh write(FD, &c, 1); 1577527Sjkh break; 1587527Sjkh 1597527Sjkh default: 1607527Sjkh write(FD, &c, 1); 1617527Sjkh read(FD, &c, 1); 1627527Sjkh } 1637527Sjkh} 1647527Sjkh 1657527Sjkhstatic void 1667527SjkhsigALRM() 1677527Sjkh{ 1687527Sjkh printf("\07timeout waiting for reply\n"); 1697527Sjkh timeout = 1; 1707527Sjkh longjmp(timeoutbuf, 1); 1717527Sjkh} 1727527Sjkh 1737527Sjkhstatic int 1747527Sjkhgobble(match, response) 1757527Sjkh register char match; 1767527Sjkh char response[]; 1777527Sjkh{ 1787527Sjkh register char *cp = response; 1797527Sjkh sig_t f; 1807527Sjkh char c; 1817527Sjkh 1827527Sjkh f = signal(SIGALRM, sigALRM); 1837527Sjkh timeout = 0; 1847527Sjkh do { 1857527Sjkh if (setjmp(timeoutbuf)) { 1867527Sjkh signal(SIGALRM, f); 1877527Sjkh *cp = '\0'; 1887527Sjkh return (0); 1897527Sjkh } 1907527Sjkh alarm(number(value(DIALTIMEOUT))); 1917527Sjkh read(FD, cp, 1); 1927527Sjkh alarm(0); 1937527Sjkh c = (*cp++ &= 0177); 1947527Sjkh#ifdef notdef 1957527Sjkh if (boolean(value(VERBOSE))) 1967527Sjkh putchar(c); 1977527Sjkh#endif 1987527Sjkh } while (c != '\n' && c != match); 1997527Sjkh signal(SIGALRM, SIG_DFL); 2007527Sjkh *cp = '\0'; 2017527Sjkh return (c == match); 2027527Sjkh} 2037527Sjkh 2047527Sjkh#define min(a,b) ((a)>(b)?(b):(a)) 2057527Sjkh/* 2067527Sjkh * This convoluted piece of code attempts to get 2077527Sjkh * the ventel in sync. If you don't have FIONREAD 2087527Sjkh * there are gory ways to simulate this. 2097527Sjkh */ 2107527Sjkhstatic int 2117527Sjkhvensync(fd) 2127527Sjkh{ 2137527Sjkh int already = 0, nread; 2147527Sjkh char buf[60]; 2157527Sjkh 2167527Sjkh /* 2177527Sjkh * Toggle DTR to force anyone off that might have left 2187527Sjkh * the modem connected, and insure a consistent state 2197527Sjkh * to start from. 2207527Sjkh * 2217527Sjkh * If you don't have the ioctl calls to diddle directly 2227527Sjkh * with DTR, you can always try setting the baud rate to 0. 2237527Sjkh */ 2247527Sjkh ioctl(FD, TIOCCDTR, 0); 2257527Sjkh sleep(1); 2267527Sjkh ioctl(FD, TIOCSDTR, 0); 2277527Sjkh while (already < MAXRETRY) { 2287527Sjkh /* 2297527Sjkh * After reseting the modem, send it two \r's to 2307527Sjkh * autobaud on. Make sure to delay between them 2317527Sjkh * so the modem can frame the incoming characters. 2327527Sjkh */ 2337527Sjkh write(fd, "\r", 1); 2347527Sjkh delay(1,10); 2357527Sjkh write(fd, "\r", 1); 2367527Sjkh sleep(2); 2377527Sjkh if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { 2387527Sjkh perror("tip: ioctl"); 2397527Sjkh continue; 2407527Sjkh } 2417527Sjkh while (nread > 0) { 2427527Sjkh read(fd, buf, min(nread, 60)); 2437527Sjkh if ((buf[nread - 1] & 0177) == '$') 2447527Sjkh return (1); 2457527Sjkh nread -= min(nread, 60); 2467527Sjkh } 2477527Sjkh sleep(1); 2487527Sjkh already++; 2497527Sjkh } 2507527Sjkh return (0); 2517527Sjkh} 2527527Sjkh 253