1*19816Sdist /* 2*19816Sdist * Copyright (c) 1983 Regents of the University of California. 3*19816Sdist * All rights reserved. The Berkeley software License Agreement 4*19816Sdist * specifies the terms and conditions for redistribution. 5*19816Sdist */ 6*19816Sdist 713281Ssam #ifndef lint 8*19816Sdist static char sccsid[] = "@(#)ventel.c 5.1 (Berkeley) 04/30/85"; 9*19816Sdist #endif not lint 106562Sshannon 116562Sshannon /* 126562Sshannon * Routines for calling up on a Ventel Modem 1318636Smiriam * The Ventel is expected to be strapped for local echo (just like uucp) 146562Sshannon */ 156562Sshannon #include "tip.h" 166562Sshannon 176562Sshannon #define MAXRETRY 5 186562Sshannon 1913281Ssam static int sigALRM(); 2013281Ssam static int timeout = 0; 2113281Ssam static jmp_buf timeoutbuf; 226562Sshannon 2318636Smiriam /* 2418636Smiriam * some sleep calls have been replaced by this macro 2518636Smiriam * because some ventel modems require two <cr>s in less than 2618636Smiriam * a second in order to 'wake up'... yes, it is dirty... 2718636Smiriam */ 2818636Smiriam #define delay(num,denom) busyloop(CPUSPEED*num/denom) 2918636Smiriam #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */ 3018636Smiriam #define DELAY(n) { register long N = (n); while (--N > 0); } 3118636Smiriam busyloop(n) { DELAY(n); } 3218636Smiriam 336562Sshannon ven_dialer(num, acu) 346562Sshannon register char *num; 356562Sshannon char *acu; 366562Sshannon { 376562Sshannon register char *cp; 386562Sshannon register int connected = 0; 3915195Ssam char *msg, *index(), line[80]; 4015195Ssam 416562Sshannon /* 426562Sshannon * Get in synch with a couple of carriage returns 436562Sshannon */ 446562Sshannon if (!vensync(FD)) { 456562Sshannon printf("can't synchronize with ventel\n"); 466562Sshannon #ifdef ACULOG 476562Sshannon logent(value(HOST), num, "ventel", "can't synch up"); 486562Sshannon #endif 496562Sshannon return (0); 506562Sshannon } 517592Sshannon if (boolean(value(VERBOSE))) 527592Sshannon printf("\ndialing..."); 537592Sshannon fflush(stdout); 546562Sshannon ioctl(FD, TIOCHPCL, 0); 5513281Ssam echo("#k$\r$\n$D$I$A$L$:$ "); 566562Sshannon for (cp = num; *cp; cp++) { 5718636Smiriam delay(1, 10); 586562Sshannon write(FD, cp, 1); 596562Sshannon } 6018636Smiriam delay(1, 10); 6118636Smiriam write(FD, "\r", 1); 6218636Smiriam gobble('\n', line); 6315195Ssam if (gobble('\n', line)) 6415195Ssam connected = gobble('!', line); 656562Sshannon ioctl(FD, TIOCFLUSH); 666562Sshannon #ifdef ACULOG 676562Sshannon if (timeout) { 686562Sshannon sprintf(line, "%d second dial timeout", 696562Sshannon number(value(DIALTIMEOUT))); 706562Sshannon logent(value(HOST), num, "ventel", line); 716562Sshannon } 726562Sshannon #endif 736562Sshannon if (timeout) 746562Sshannon ven_disconnect(); /* insurance */ 7515195Ssam if (connected || timeout || !boolean(value(VERBOSE))) 7615195Ssam return (connected); 7715195Ssam /* call failed, parse response for user */ 7815195Ssam cp = index(line, '\r'); 7915195Ssam if (cp) 8015195Ssam *cp = '\0'; 8115195Ssam for (cp = line; cp = index(cp, ' '); cp++) 8215195Ssam if (cp[1] == ' ') 8315195Ssam break; 8415195Ssam if (cp) { 8515195Ssam while (*cp == ' ') 8615195Ssam cp++; 8715195Ssam msg = cp; 8815195Ssam while (*cp) { 8915195Ssam if (isupper(*cp)) 9015195Ssam *cp = tolower(*cp); 9115195Ssam cp++; 9215195Ssam } 9315195Ssam printf("%s...", msg); 9415195Ssam } 956562Sshannon return (connected); 966562Sshannon } 976562Sshannon 986562Sshannon ven_disconnect() 996562Sshannon { 10013281Ssam 1016562Sshannon close(FD); 1026562Sshannon } 1036562Sshannon 1046562Sshannon ven_abort() 1056562Sshannon { 10613281Ssam 1076562Sshannon write(FD, "\03", 1); 1086562Sshannon close(FD); 1096562Sshannon } 1106562Sshannon 1116562Sshannon static int 1126562Sshannon echo(s) 1136562Sshannon register char *s; 1146562Sshannon { 1156562Sshannon char c; 1166562Sshannon 1176562Sshannon while (c = *s++) switch (c) { 1186562Sshannon 1196562Sshannon case '$': 1206562Sshannon read(FD, &c, 1); 1216562Sshannon s++; 1226562Sshannon break; 1236562Sshannon 1246562Sshannon case '#': 1256562Sshannon c = *s++; 1266562Sshannon write(FD, &c, 1); 1276562Sshannon break; 1286562Sshannon 1296562Sshannon default: 1306562Sshannon write(FD, &c, 1); 1316562Sshannon read(FD, &c, 1); 1326562Sshannon } 1336562Sshannon } 1346562Sshannon 1356562Sshannon static int 1366562Sshannon sigALRM() 1376562Sshannon { 13813281Ssam 1396562Sshannon printf("\07timeout waiting for reply\n"); 1406562Sshannon timeout = 1; 14113281Ssam longjmp(timeoutbuf, 1); 1426562Sshannon } 1436562Sshannon 1446562Sshannon static int 14515195Ssam gobble(match, response) 14613281Ssam register char match; 14715195Ssam char response[]; 1486562Sshannon { 14915195Ssam register char *cp = response; 1506562Sshannon char c; 15113281Ssam int (*f)(); 1526562Sshannon 1536562Sshannon signal(SIGALRM, sigALRM); 1546562Sshannon timeout = 0; 1556562Sshannon do { 15613281Ssam if (setjmp(timeoutbuf)) { 15713281Ssam signal(SIGALRM, f); 15815195Ssam *cp = '\0'; 15913281Ssam return (0); 16013281Ssam } 1616562Sshannon alarm(number(value(DIALTIMEOUT))); 16215195Ssam read(FD, cp, 1); 16313281Ssam alarm(0); 16415195Ssam c = (*cp++ &= 0177); 1656562Sshannon #ifdef notdef 1666562Sshannon if (boolean(value(VERBOSE))) 1677592Sshannon putchar(c); 1686562Sshannon #endif 16913281Ssam } while (c != '\n' && c != match); 1706562Sshannon signal(SIGALRM, SIG_DFL); 17115195Ssam *cp = '\0'; 17213281Ssam return (c == match); 1736562Sshannon } 1746562Sshannon 1756562Sshannon #define min(a,b) ((a)>(b)?(b):(a)) 1766562Sshannon /* 1776562Sshannon * This convoluted piece of code attempts to get 17813281Ssam * the ventel in sync. If you don't have FIONREAD 17913281Ssam * there are gory ways to simulate this. 1806562Sshannon */ 1816562Sshannon static int 1826562Sshannon vensync(fd) 1836562Sshannon { 18413281Ssam int already = 0, nread; 1856562Sshannon char buf[60]; 1866562Sshannon 1876562Sshannon /* 1886562Sshannon * Toggle DTR to force anyone off that might have left 1896562Sshannon * the modem connected, and insure a consistent state 1906562Sshannon * to start from. 1916562Sshannon * 1926562Sshannon * If you don't have the ioctl calls to diddle directly 1936562Sshannon * with DTR, you can always try setting the baud rate to 0. 1946562Sshannon */ 1956562Sshannon ioctl(FD, TIOCCDTR, 0); 19618636Smiriam sleep(1); 1976562Sshannon ioctl(FD, TIOCSDTR, 0); 1986562Sshannon while (already < MAXRETRY) { 1996562Sshannon /* 2006562Sshannon * After reseting the modem, send it two \r's to 2016562Sshannon * autobaud on. Make sure to delay between them 2026562Sshannon * so the modem can frame the incoming characters. 2036562Sshannon */ 2046562Sshannon write(fd, "\r", 1); 20518636Smiriam delay(1,10); 2066562Sshannon write(fd, "\r", 1); 20718636Smiriam sleep(2); 20813281Ssam if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { 20913281Ssam perror("tip: ioctl"); 21013281Ssam continue; 2116562Sshannon } 21213281Ssam while (nread > 0) { 21313281Ssam read(fd, buf, min(nread, 60)); 21413281Ssam if ((buf[nread - 1] & 0177) == '$') 21513281Ssam return (1); 21613281Ssam nread -= min(nread, 60); 21713281Ssam } 21813281Ssam sleep(1); 21913281Ssam already++; 2206562Sshannon } 2216562Sshannon return (0); 2226562Sshannon } 22318636Smiriam 224