17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 5*8d489c7aSmuffin 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California. 87c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 97c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 107c478bd9Sstevel@tonic-gate */ 11*8d489c7aSmuffin 12*8d489c7aSmuffin #pragma ident "%Z%%M% %I% %E% SMI" 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate /* 157c478bd9Sstevel@tonic-gate * Routines for calling up on a Ventel Modem 167c478bd9Sstevel@tonic-gate * Define VENNOECHO if the Ventel is strapped for "no echo". 177c478bd9Sstevel@tonic-gate */ 187c478bd9Sstevel@tonic-gate #include "tip.h" 197c478bd9Sstevel@tonic-gate 207c478bd9Sstevel@tonic-gate #define MAXRETRY 5 217c478bd9Sstevel@tonic-gate 22*8d489c7aSmuffin static int vensync(int); 23*8d489c7aSmuffin static int gobble(char); 24*8d489c7aSmuffin static void echo(char *); 25*8d489c7aSmuffin static void sigALRM(void); 267c478bd9Sstevel@tonic-gate static int timeout = 0; 277c478bd9Sstevel@tonic-gate static sigjmp_buf timeoutbuf; 287c478bd9Sstevel@tonic-gate 29*8d489c7aSmuffin void ven_disconnect(void); 30*8d489c7aSmuffin 31*8d489c7aSmuffin /* ARGSUSED */ 32*8d489c7aSmuffin int 33*8d489c7aSmuffin ven_dialer(char *num, char *acu) 347c478bd9Sstevel@tonic-gate { 35*8d489c7aSmuffin char *cp; 36*8d489c7aSmuffin int connected = 0; 377c478bd9Sstevel@tonic-gate struct termios buf; 387c478bd9Sstevel@tonic-gate #ifdef ACULOG 397c478bd9Sstevel@tonic-gate char line[80]; 407c478bd9Sstevel@tonic-gate #endif 417c478bd9Sstevel@tonic-gate /* 427c478bd9Sstevel@tonic-gate * Get in synch with a couple of carriage returns 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate if (!vensync(FD)) { 45*8d489c7aSmuffin (void) printf("can't synchronize with ventel\n"); 467c478bd9Sstevel@tonic-gate #ifdef ACULOG 477c478bd9Sstevel@tonic-gate logent(value(HOST), num, "ventel", "can't synch up"); 487c478bd9Sstevel@tonic-gate #endif 497c478bd9Sstevel@tonic-gate return (0); 507c478bd9Sstevel@tonic-gate } 517c478bd9Sstevel@tonic-gate if (boolean(value(VERBOSE))) 52*8d489c7aSmuffin (void) printf("\ndialing..."); 53*8d489c7aSmuffin (void) fflush(stdout); 54*8d489c7aSmuffin (void) ioctl(FD, TCGETS, &buf); 557c478bd9Sstevel@tonic-gate buf.c_cflag |= HUPCL; 56*8d489c7aSmuffin (void) ioctl(FD, TCSETSF, &buf); 577c478bd9Sstevel@tonic-gate #ifdef VENNOECHO 587c478bd9Sstevel@tonic-gate echo("#k$\r$\n$D$I$A$L$:$ "); 597c478bd9Sstevel@tonic-gate for (cp = num; *cp; cp++) { 60*8d489c7aSmuffin (void) sleep(1); 61*8d489c7aSmuffin (void) write(FD, cp, 1); 627c478bd9Sstevel@tonic-gate } 637c478bd9Sstevel@tonic-gate echo("\r$\n"); 647c478bd9Sstevel@tonic-gate #else 657c478bd9Sstevel@tonic-gate echo("k$\r$\n$D$I$A$L$:$ <"); 667c478bd9Sstevel@tonic-gate for (cp = num; *cp; cp++) { 677c478bd9Sstevel@tonic-gate char c; 687c478bd9Sstevel@tonic-gate 69*8d489c7aSmuffin (void) sleep(1); 70*8d489c7aSmuffin (void) write(FD, cp, 1); 71*8d489c7aSmuffin (void) read(FD, &c, 1); 727c478bd9Sstevel@tonic-gate } 737c478bd9Sstevel@tonic-gate echo(">\r$\n"); 747c478bd9Sstevel@tonic-gate #endif 757c478bd9Sstevel@tonic-gate if (gobble('\n')) 767c478bd9Sstevel@tonic-gate connected = gobble('!'); 77*8d489c7aSmuffin (void) ioctl(FD, TCFLSH, TCIOFLUSH); 787c478bd9Sstevel@tonic-gate #ifdef ACULOG 797c478bd9Sstevel@tonic-gate if (timeout) { 80*8d489c7aSmuffin (void) sprintf(line, "%d second dial timeout", 817c478bd9Sstevel@tonic-gate number(value(DIALTIMEOUT))); 827c478bd9Sstevel@tonic-gate logent(value(HOST), num, "ventel", line); 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate #endif 857c478bd9Sstevel@tonic-gate if (timeout) 867c478bd9Sstevel@tonic-gate ven_disconnect(); /* insurance */ 877c478bd9Sstevel@tonic-gate return (connected); 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate 90*8d489c7aSmuffin void 91*8d489c7aSmuffin ven_disconnect(void) 927c478bd9Sstevel@tonic-gate { 937c478bd9Sstevel@tonic-gate 94*8d489c7aSmuffin (void) close(FD); 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate 97*8d489c7aSmuffin void 98*8d489c7aSmuffin ven_abort(void) 997c478bd9Sstevel@tonic-gate { 1007c478bd9Sstevel@tonic-gate 101*8d489c7aSmuffin (void) write(FD, "\03", 1); 102*8d489c7aSmuffin (void) close(FD); 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate 105*8d489c7aSmuffin static void 106*8d489c7aSmuffin echo(char *s) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate char c; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate while (c = *s++) { 1117c478bd9Sstevel@tonic-gate switch (c) { 1127c478bd9Sstevel@tonic-gate case '$': 113*8d489c7aSmuffin (void) read(FD, &c, 1); 1147c478bd9Sstevel@tonic-gate s++; 1157c478bd9Sstevel@tonic-gate break; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate case '#': 1187c478bd9Sstevel@tonic-gate c = *s++; 119*8d489c7aSmuffin (void) write(FD, &c, 1); 1207c478bd9Sstevel@tonic-gate break; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate default: 123*8d489c7aSmuffin (void) write(FD, &c, 1); 124*8d489c7aSmuffin (void) read(FD, &c, 1); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate static void 130*8d489c7aSmuffin sigALRM(void) 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate 133*8d489c7aSmuffin (void) printf("\07timeout waiting for reply\n"); 1347c478bd9Sstevel@tonic-gate timeout = 1; 1357c478bd9Sstevel@tonic-gate siglongjmp(timeoutbuf, 1); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate static int 139*8d489c7aSmuffin gobble(char match) 1407c478bd9Sstevel@tonic-gate { 1417c478bd9Sstevel@tonic-gate char c; 1427c478bd9Sstevel@tonic-gate sig_handler_t f; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate f = signal(SIGALRM, (sig_handler_t)sigALRM); 1457c478bd9Sstevel@tonic-gate timeout = 0; 1467c478bd9Sstevel@tonic-gate do { 1477c478bd9Sstevel@tonic-gate if (sigsetjmp(timeoutbuf, 1)) { 148*8d489c7aSmuffin (void) signal(SIGALRM, f); 1497c478bd9Sstevel@tonic-gate return (0); 1507c478bd9Sstevel@tonic-gate } 151*8d489c7aSmuffin (void) alarm(number(value(DIALTIMEOUT))); 152*8d489c7aSmuffin (void) read(FD, &c, 1); 153*8d489c7aSmuffin (void) alarm(0); 1547c478bd9Sstevel@tonic-gate c &= 0177; 1557c478bd9Sstevel@tonic-gate #ifdef notdef 1567c478bd9Sstevel@tonic-gate if (boolean(value(VERBOSE))) 157*8d489c7aSmuffin (void) putchar(c); 1587c478bd9Sstevel@tonic-gate #endif 1597c478bd9Sstevel@tonic-gate } while (c != '\n' && c != match); 160*8d489c7aSmuffin (void) signal(SIGALRM, SIG_DFL); 1617c478bd9Sstevel@tonic-gate return (c == match); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate #define min(a, b) (((a) > (b)) ? (b) : (a)) 1657c478bd9Sstevel@tonic-gate /* 1667c478bd9Sstevel@tonic-gate * This convoluted piece of code attempts to get 1677c478bd9Sstevel@tonic-gate * the ventel in sync. If you don't have FIONREAD 1687c478bd9Sstevel@tonic-gate * there are gory ways to simulate this. 1697c478bd9Sstevel@tonic-gate */ 1707c478bd9Sstevel@tonic-gate static int 171*8d489c7aSmuffin vensync(int fd) 1727c478bd9Sstevel@tonic-gate { 1737c478bd9Sstevel@tonic-gate int already = 0, nread; 1747c478bd9Sstevel@tonic-gate char buf[60]; 1757c478bd9Sstevel@tonic-gate int dtr = TIOCM_DTR; 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate /* 1787c478bd9Sstevel@tonic-gate * Toggle DTR to force anyone off that might have left 1797c478bd9Sstevel@tonic-gate * the modem connected, and insure a consistent state 1807c478bd9Sstevel@tonic-gate * to start from. 1817c478bd9Sstevel@tonic-gate * 1827c478bd9Sstevel@tonic-gate * If you don't have the ioctl calls to diddle directly 1837c478bd9Sstevel@tonic-gate * with DTR, you can always try setting the baud rate to 0. 1847c478bd9Sstevel@tonic-gate */ 185*8d489c7aSmuffin (void) ioctl(FD, TIOCMBIC, &dtr); 186*8d489c7aSmuffin (void) sleep(2); 187*8d489c7aSmuffin (void) ioctl(FD, TIOCMBIS, &dtr); 1887c478bd9Sstevel@tonic-gate while (already < MAXRETRY) { 1897c478bd9Sstevel@tonic-gate /* 1907c478bd9Sstevel@tonic-gate * After reseting the modem, send it two \r's to 1917c478bd9Sstevel@tonic-gate * autobaud on. Make sure to delay between them 1927c478bd9Sstevel@tonic-gate * so the modem can frame the incoming characters. 1937c478bd9Sstevel@tonic-gate */ 194*8d489c7aSmuffin (void) write(fd, "\r", 1); 1957c478bd9Sstevel@tonic-gate #ifdef VMUNIX 1967c478bd9Sstevel@tonic-gate { 1977c478bd9Sstevel@tonic-gate #include <sys/time.h> 1987c478bd9Sstevel@tonic-gate struct timeval tv = {0, 500000}; 1997c478bd9Sstevel@tonic-gate 200*8d489c7aSmuffin (void) select(0, 0, 0, 0, &tv); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate #else 203*8d489c7aSmuffin (void) sleep(1); 2047c478bd9Sstevel@tonic-gate #endif 205*8d489c7aSmuffin (void) write(fd, "\r", 1); 206*8d489c7aSmuffin (void) sleep(3); 2077c478bd9Sstevel@tonic-gate if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { 2087c478bd9Sstevel@tonic-gate perror("tip: ioctl"); 2097c478bd9Sstevel@tonic-gate continue; 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate while (nread > 0) { 212*8d489c7aSmuffin (void) read(fd, buf, min(nread, 60)); 2137c478bd9Sstevel@tonic-gate if ((buf[nread - 1] & 0177) == '$') 2147c478bd9Sstevel@tonic-gate return (1); 2157c478bd9Sstevel@tonic-gate nread -= min(nread, 60); 2167c478bd9Sstevel@tonic-gate } 217*8d489c7aSmuffin (void) sleep(1); 2187c478bd9Sstevel@tonic-gate already++; 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate return (0); 2217c478bd9Sstevel@tonic-gate } 222