119816Sdist /* 235492Sbostic * Copyright (c) 1983 The Regents of the University of California. 335492Sbostic * All rights reserved. 435492Sbostic * 5*42770Sbostic * %sccs.include.redist.c% 619816Sdist */ 719816Sdist 813281Ssam #ifndef lint 9*42770Sbostic static char sccsid[] = "@(#)ventel.c 5.3 (Berkeley) 06/01/90"; 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 2013281Ssam static int 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]; 4115195Ssam 426562Sshannon /* 436562Sshannon * Get in synch with a couple of carriage returns 446562Sshannon */ 456562Sshannon if (!vensync(FD)) { 466562Sshannon printf("can't synchronize with ventel\n"); 476562Sshannon #ifdef ACULOG 486562Sshannon logent(value(HOST), num, "ventel", "can't synch up"); 496562Sshannon #endif 506562Sshannon return (0); 516562Sshannon } 527592Sshannon if (boolean(value(VERBOSE))) 537592Sshannon printf("\ndialing..."); 547592Sshannon fflush(stdout); 556562Sshannon ioctl(FD, TIOCHPCL, 0); 5613281Ssam echo("#k$\r$\n$D$I$A$L$:$ "); 576562Sshannon for (cp = num; *cp; cp++) { 5818636Smiriam delay(1, 10); 596562Sshannon write(FD, cp, 1); 606562Sshannon } 6118636Smiriam delay(1, 10); 6218636Smiriam write(FD, "\r", 1); 6318636Smiriam gobble('\n', line); 6415195Ssam if (gobble('\n', line)) 6515195Ssam connected = gobble('!', line); 666562Sshannon ioctl(FD, TIOCFLUSH); 676562Sshannon #ifdef ACULOG 686562Sshannon if (timeout) { 696562Sshannon sprintf(line, "%d second dial timeout", 706562Sshannon number(value(DIALTIMEOUT))); 716562Sshannon logent(value(HOST), num, "ventel", line); 726562Sshannon } 736562Sshannon #endif 746562Sshannon if (timeout) 756562Sshannon ven_disconnect(); /* insurance */ 7615195Ssam if (connected || timeout || !boolean(value(VERBOSE))) 7715195Ssam return (connected); 7815195Ssam /* call failed, parse response for user */ 7915195Ssam cp = index(line, '\r'); 8015195Ssam if (cp) 8115195Ssam *cp = '\0'; 8215195Ssam for (cp = line; cp = index(cp, ' '); cp++) 8315195Ssam if (cp[1] == ' ') 8415195Ssam break; 8515195Ssam if (cp) { 8615195Ssam while (*cp == ' ') 8715195Ssam cp++; 8815195Ssam msg = cp; 8915195Ssam while (*cp) { 9015195Ssam if (isupper(*cp)) 9115195Ssam *cp = tolower(*cp); 9215195Ssam cp++; 9315195Ssam } 9415195Ssam printf("%s...", msg); 9515195Ssam } 966562Sshannon return (connected); 976562Sshannon } 986562Sshannon 996562Sshannon ven_disconnect() 1006562Sshannon { 10113281Ssam 1026562Sshannon close(FD); 1036562Sshannon } 1046562Sshannon 1056562Sshannon ven_abort() 1066562Sshannon { 10713281Ssam 1086562Sshannon write(FD, "\03", 1); 1096562Sshannon close(FD); 1106562Sshannon } 1116562Sshannon 1126562Sshannon static int 1136562Sshannon echo(s) 1146562Sshannon register char *s; 1156562Sshannon { 1166562Sshannon char c; 1176562Sshannon 1186562Sshannon while (c = *s++) switch (c) { 1196562Sshannon 1206562Sshannon case '$': 1216562Sshannon read(FD, &c, 1); 1226562Sshannon s++; 1236562Sshannon break; 1246562Sshannon 1256562Sshannon case '#': 1266562Sshannon c = *s++; 1276562Sshannon write(FD, &c, 1); 1286562Sshannon break; 1296562Sshannon 1306562Sshannon default: 1316562Sshannon write(FD, &c, 1); 1326562Sshannon read(FD, &c, 1); 1336562Sshannon } 1346562Sshannon } 1356562Sshannon 1366562Sshannon static int 1376562Sshannon sigALRM() 1386562Sshannon { 13913281Ssam 1406562Sshannon printf("\07timeout waiting for reply\n"); 1416562Sshannon timeout = 1; 14213281Ssam longjmp(timeoutbuf, 1); 1436562Sshannon } 1446562Sshannon 1456562Sshannon static int 14615195Ssam gobble(match, response) 14713281Ssam register char match; 14815195Ssam char response[]; 1496562Sshannon { 15015195Ssam register char *cp = response; 1516562Sshannon char c; 15213281Ssam int (*f)(); 1536562Sshannon 1546562Sshannon signal(SIGALRM, sigALRM); 1556562Sshannon timeout = 0; 1566562Sshannon do { 15713281Ssam if (setjmp(timeoutbuf)) { 15813281Ssam signal(SIGALRM, f); 15915195Ssam *cp = '\0'; 16013281Ssam return (0); 16113281Ssam } 1626562Sshannon alarm(number(value(DIALTIMEOUT))); 16315195Ssam read(FD, cp, 1); 16413281Ssam alarm(0); 16515195Ssam c = (*cp++ &= 0177); 1666562Sshannon #ifdef notdef 1676562Sshannon if (boolean(value(VERBOSE))) 1687592Sshannon putchar(c); 1696562Sshannon #endif 17013281Ssam } while (c != '\n' && c != match); 1716562Sshannon signal(SIGALRM, SIG_DFL); 17215195Ssam *cp = '\0'; 17313281Ssam return (c == match); 1746562Sshannon } 1756562Sshannon 1766562Sshannon #define min(a,b) ((a)>(b)?(b):(a)) 1776562Sshannon /* 1786562Sshannon * This convoluted piece of code attempts to get 17913281Ssam * the ventel in sync. If you don't have FIONREAD 18013281Ssam * there are gory ways to simulate this. 1816562Sshannon */ 1826562Sshannon static int 1836562Sshannon vensync(fd) 1846562Sshannon { 18513281Ssam int already = 0, nread; 1866562Sshannon char buf[60]; 1876562Sshannon 1886562Sshannon /* 1896562Sshannon * Toggle DTR to force anyone off that might have left 1906562Sshannon * the modem connected, and insure a consistent state 1916562Sshannon * to start from. 1926562Sshannon * 1936562Sshannon * If you don't have the ioctl calls to diddle directly 1946562Sshannon * with DTR, you can always try setting the baud rate to 0. 1956562Sshannon */ 1966562Sshannon ioctl(FD, TIOCCDTR, 0); 19718636Smiriam sleep(1); 1986562Sshannon ioctl(FD, TIOCSDTR, 0); 1996562Sshannon while (already < MAXRETRY) { 2006562Sshannon /* 2016562Sshannon * After reseting the modem, send it two \r's to 2026562Sshannon * autobaud on. Make sure to delay between them 2036562Sshannon * so the modem can frame the incoming characters. 2046562Sshannon */ 2056562Sshannon write(fd, "\r", 1); 20618636Smiriam delay(1,10); 2076562Sshannon write(fd, "\r", 1); 20818636Smiriam sleep(2); 20913281Ssam if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { 21013281Ssam perror("tip: ioctl"); 21113281Ssam continue; 2126562Sshannon } 21313281Ssam while (nread > 0) { 21413281Ssam read(fd, buf, min(nread, 60)); 21513281Ssam if ((buf[nread - 1] & 0177) == '$') 21613281Ssam return (1); 21713281Ssam nread -= min(nread, 60); 21813281Ssam } 21913281Ssam sleep(1); 22013281Ssam already++; 2216562Sshannon } 2226562Sshannon return (0); 2236562Sshannon } 22418636Smiriam 225