119816Sdist /* 2*35492Sbostic * Copyright (c) 1983 The Regents of the University of California. 3*35492Sbostic * All rights reserved. 4*35492Sbostic * 5*35492Sbostic * Redistribution and use in source and binary forms are permitted 6*35492Sbostic * provided that the above copyright notice and this paragraph are 7*35492Sbostic * duplicated in all such forms and that any documentation, 8*35492Sbostic * advertising materials, and other materials related to such 9*35492Sbostic * distribution and use acknowledge that the software was developed 10*35492Sbostic * by the University of California, Berkeley. The name of the 11*35492Sbostic * University may not be used to endorse or promote products derived 12*35492Sbostic * from this software without specific prior written permission. 13*35492Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*35492Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*35492Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1619816Sdist */ 1719816Sdist 1813281Ssam #ifndef lint 19*35492Sbostic static char sccsid[] = "@(#)ventel.c 5.2 (Berkeley) 09/13/88"; 20*35492Sbostic #endif /* not lint */ 216562Sshannon 226562Sshannon /* 236562Sshannon * Routines for calling up on a Ventel Modem 2418636Smiriam * The Ventel is expected to be strapped for local echo (just like uucp) 256562Sshannon */ 266562Sshannon #include "tip.h" 276562Sshannon 286562Sshannon #define MAXRETRY 5 296562Sshannon 3013281Ssam static int sigALRM(); 3113281Ssam static int timeout = 0; 3213281Ssam static jmp_buf timeoutbuf; 336562Sshannon 3418636Smiriam /* 3518636Smiriam * some sleep calls have been replaced by this macro 3618636Smiriam * because some ventel modems require two <cr>s in less than 3718636Smiriam * a second in order to 'wake up'... yes, it is dirty... 3818636Smiriam */ 3918636Smiriam #define delay(num,denom) busyloop(CPUSPEED*num/denom) 4018636Smiriam #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */ 4118636Smiriam #define DELAY(n) { register long N = (n); while (--N > 0); } 4218636Smiriam busyloop(n) { DELAY(n); } 4318636Smiriam 446562Sshannon ven_dialer(num, acu) 456562Sshannon register char *num; 466562Sshannon char *acu; 476562Sshannon { 486562Sshannon register char *cp; 496562Sshannon register int connected = 0; 5015195Ssam char *msg, *index(), line[80]; 5115195Ssam 526562Sshannon /* 536562Sshannon * Get in synch with a couple of carriage returns 546562Sshannon */ 556562Sshannon if (!vensync(FD)) { 566562Sshannon printf("can't synchronize with ventel\n"); 576562Sshannon #ifdef ACULOG 586562Sshannon logent(value(HOST), num, "ventel", "can't synch up"); 596562Sshannon #endif 606562Sshannon return (0); 616562Sshannon } 627592Sshannon if (boolean(value(VERBOSE))) 637592Sshannon printf("\ndialing..."); 647592Sshannon fflush(stdout); 656562Sshannon ioctl(FD, TIOCHPCL, 0); 6613281Ssam echo("#k$\r$\n$D$I$A$L$:$ "); 676562Sshannon for (cp = num; *cp; cp++) { 6818636Smiriam delay(1, 10); 696562Sshannon write(FD, cp, 1); 706562Sshannon } 7118636Smiriam delay(1, 10); 7218636Smiriam write(FD, "\r", 1); 7318636Smiriam gobble('\n', line); 7415195Ssam if (gobble('\n', line)) 7515195Ssam connected = gobble('!', line); 766562Sshannon ioctl(FD, TIOCFLUSH); 776562Sshannon #ifdef ACULOG 786562Sshannon if (timeout) { 796562Sshannon sprintf(line, "%d second dial timeout", 806562Sshannon number(value(DIALTIMEOUT))); 816562Sshannon logent(value(HOST), num, "ventel", line); 826562Sshannon } 836562Sshannon #endif 846562Sshannon if (timeout) 856562Sshannon ven_disconnect(); /* insurance */ 8615195Ssam if (connected || timeout || !boolean(value(VERBOSE))) 8715195Ssam return (connected); 8815195Ssam /* call failed, parse response for user */ 8915195Ssam cp = index(line, '\r'); 9015195Ssam if (cp) 9115195Ssam *cp = '\0'; 9215195Ssam for (cp = line; cp = index(cp, ' '); cp++) 9315195Ssam if (cp[1] == ' ') 9415195Ssam break; 9515195Ssam if (cp) { 9615195Ssam while (*cp == ' ') 9715195Ssam cp++; 9815195Ssam msg = cp; 9915195Ssam while (*cp) { 10015195Ssam if (isupper(*cp)) 10115195Ssam *cp = tolower(*cp); 10215195Ssam cp++; 10315195Ssam } 10415195Ssam printf("%s...", msg); 10515195Ssam } 1066562Sshannon return (connected); 1076562Sshannon } 1086562Sshannon 1096562Sshannon ven_disconnect() 1106562Sshannon { 11113281Ssam 1126562Sshannon close(FD); 1136562Sshannon } 1146562Sshannon 1156562Sshannon ven_abort() 1166562Sshannon { 11713281Ssam 1186562Sshannon write(FD, "\03", 1); 1196562Sshannon close(FD); 1206562Sshannon } 1216562Sshannon 1226562Sshannon static int 1236562Sshannon echo(s) 1246562Sshannon register char *s; 1256562Sshannon { 1266562Sshannon char c; 1276562Sshannon 1286562Sshannon while (c = *s++) switch (c) { 1296562Sshannon 1306562Sshannon case '$': 1316562Sshannon read(FD, &c, 1); 1326562Sshannon s++; 1336562Sshannon break; 1346562Sshannon 1356562Sshannon case '#': 1366562Sshannon c = *s++; 1376562Sshannon write(FD, &c, 1); 1386562Sshannon break; 1396562Sshannon 1406562Sshannon default: 1416562Sshannon write(FD, &c, 1); 1426562Sshannon read(FD, &c, 1); 1436562Sshannon } 1446562Sshannon } 1456562Sshannon 1466562Sshannon static int 1476562Sshannon sigALRM() 1486562Sshannon { 14913281Ssam 1506562Sshannon printf("\07timeout waiting for reply\n"); 1516562Sshannon timeout = 1; 15213281Ssam longjmp(timeoutbuf, 1); 1536562Sshannon } 1546562Sshannon 1556562Sshannon static int 15615195Ssam gobble(match, response) 15713281Ssam register char match; 15815195Ssam char response[]; 1596562Sshannon { 16015195Ssam register char *cp = response; 1616562Sshannon char c; 16213281Ssam int (*f)(); 1636562Sshannon 1646562Sshannon signal(SIGALRM, sigALRM); 1656562Sshannon timeout = 0; 1666562Sshannon do { 16713281Ssam if (setjmp(timeoutbuf)) { 16813281Ssam signal(SIGALRM, f); 16915195Ssam *cp = '\0'; 17013281Ssam return (0); 17113281Ssam } 1726562Sshannon alarm(number(value(DIALTIMEOUT))); 17315195Ssam read(FD, cp, 1); 17413281Ssam alarm(0); 17515195Ssam c = (*cp++ &= 0177); 1766562Sshannon #ifdef notdef 1776562Sshannon if (boolean(value(VERBOSE))) 1787592Sshannon putchar(c); 1796562Sshannon #endif 18013281Ssam } while (c != '\n' && c != match); 1816562Sshannon signal(SIGALRM, SIG_DFL); 18215195Ssam *cp = '\0'; 18313281Ssam return (c == match); 1846562Sshannon } 1856562Sshannon 1866562Sshannon #define min(a,b) ((a)>(b)?(b):(a)) 1876562Sshannon /* 1886562Sshannon * This convoluted piece of code attempts to get 18913281Ssam * the ventel in sync. If you don't have FIONREAD 19013281Ssam * there are gory ways to simulate this. 1916562Sshannon */ 1926562Sshannon static int 1936562Sshannon vensync(fd) 1946562Sshannon { 19513281Ssam int already = 0, nread; 1966562Sshannon char buf[60]; 1976562Sshannon 1986562Sshannon /* 1996562Sshannon * Toggle DTR to force anyone off that might have left 2006562Sshannon * the modem connected, and insure a consistent state 2016562Sshannon * to start from. 2026562Sshannon * 2036562Sshannon * If you don't have the ioctl calls to diddle directly 2046562Sshannon * with DTR, you can always try setting the baud rate to 0. 2056562Sshannon */ 2066562Sshannon ioctl(FD, TIOCCDTR, 0); 20718636Smiriam sleep(1); 2086562Sshannon ioctl(FD, TIOCSDTR, 0); 2096562Sshannon while (already < MAXRETRY) { 2106562Sshannon /* 2116562Sshannon * After reseting the modem, send it two \r's to 2126562Sshannon * autobaud on. Make sure to delay between them 2136562Sshannon * so the modem can frame the incoming characters. 2146562Sshannon */ 2156562Sshannon write(fd, "\r", 1); 21618636Smiriam delay(1,10); 2176562Sshannon write(fd, "\r", 1); 21818636Smiriam sleep(2); 21913281Ssam if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { 22013281Ssam perror("tip: ioctl"); 22113281Ssam continue; 2226562Sshannon } 22313281Ssam while (nread > 0) { 22413281Ssam read(fd, buf, min(nread, 60)); 22513281Ssam if ((buf[nread - 1] & 0177) == '$') 22613281Ssam return (1); 22713281Ssam nread -= min(nread, 60); 22813281Ssam } 22913281Ssam sleep(1); 23013281Ssam already++; 2316562Sshannon } 2326562Sshannon return (0); 2336562Sshannon } 23418636Smiriam 235