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