119816Sdist /* 235492Sbostic * Copyright (c) 1983 The Regents of the University of California. 335492Sbostic * All rights reserved. 435492Sbostic * 542770Sbostic * %sccs.include.redist.c% 619816Sdist */ 719816Sdist 813281Ssam #ifndef lint 9*46867Sbostic static char sccsid[] = "@(#)ventel.c 5.4 (Berkeley) 03/02/91"; 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 20*46867Sbostic 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); } 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]; 41*46867Sbostic static int gobble(), vensync(); 42*46867Sbostic 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 1016562Sshannon ven_disconnect() 1026562Sshannon { 10313281Ssam 1046562Sshannon close(FD); 1056562Sshannon } 1066562Sshannon 1076562Sshannon ven_abort() 1086562Sshannon { 10913281Ssam 1106562Sshannon write(FD, "\03", 1); 1116562Sshannon close(FD); 1126562Sshannon } 1136562Sshannon 114*46867Sbostic static void 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 138*46867Sbostic static void 1396562Sshannon sigALRM() 1406562Sshannon { 1416562Sshannon printf("\07timeout waiting for reply\n"); 1426562Sshannon timeout = 1; 14313281Ssam longjmp(timeoutbuf, 1); 1446562Sshannon } 1456562Sshannon 1466562Sshannon static int 14715195Ssam gobble(match, response) 14813281Ssam register char match; 14915195Ssam char response[]; 1506562Sshannon { 15115195Ssam register char *cp = response; 152*46867Sbostic sig_t f; 1536562Sshannon char c; 1546562Sshannon 155*46867Sbostic 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 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