1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 1983 Regents of the University of California. 8 * All rights reserved. The Berkeley software License Agreement 9 * specifies the terms and conditions for redistribution. 10 */ 11 12 #pragma ident "%Z%%M% %I% %E% SMI" 13 14 /* 15 * Routines for calling up on a Ventel Modem 16 * Define VENNOECHO if the Ventel is strapped for "no echo". 17 */ 18 #include "tip.h" 19 20 #define MAXRETRY 5 21 22 static int vensync(int); 23 static int gobble(char); 24 static void echo(char *); 25 static void sigALRM(void); 26 static int timeout = 0; 27 static sigjmp_buf timeoutbuf; 28 29 void ven_disconnect(void); 30 31 /* ARGSUSED */ 32 int 33 ven_dialer(char *num, char *acu) 34 { 35 char *cp; 36 int connected = 0; 37 struct termios buf; 38 #ifdef ACULOG 39 char line[80]; 40 #endif 41 /* 42 * Get in synch with a couple of carriage returns 43 */ 44 if (!vensync(FD)) { 45 (void) printf("can't synchronize with ventel\n"); 46 #ifdef ACULOG 47 logent(value(HOST), num, "ventel", "can't synch up"); 48 #endif 49 return (0); 50 } 51 if (boolean(value(VERBOSE))) 52 (void) printf("\ndialing..."); 53 (void) fflush(stdout); 54 (void) ioctl(FD, TCGETS, &buf); 55 buf.c_cflag |= HUPCL; 56 (void) ioctl(FD, TCSETSF, &buf); 57 #ifdef VENNOECHO 58 echo("#k$\r$\n$D$I$A$L$:$ "); 59 for (cp = num; *cp; cp++) { 60 (void) sleep(1); 61 (void) write(FD, cp, 1); 62 } 63 echo("\r$\n"); 64 #else 65 echo("k$\r$\n$D$I$A$L$:$ <"); 66 for (cp = num; *cp; cp++) { 67 char c; 68 69 (void) sleep(1); 70 (void) write(FD, cp, 1); 71 (void) read(FD, &c, 1); 72 } 73 echo(">\r$\n"); 74 #endif 75 if (gobble('\n')) 76 connected = gobble('!'); 77 (void) ioctl(FD, TCFLSH, TCIOFLUSH); 78 #ifdef ACULOG 79 if (timeout) { 80 (void) sprintf(line, "%d second dial timeout", 81 number(value(DIALTIMEOUT))); 82 logent(value(HOST), num, "ventel", line); 83 } 84 #endif 85 if (timeout) 86 ven_disconnect(); /* insurance */ 87 return (connected); 88 } 89 90 void 91 ven_disconnect(void) 92 { 93 94 (void) close(FD); 95 } 96 97 void 98 ven_abort(void) 99 { 100 101 (void) write(FD, "\03", 1); 102 (void) close(FD); 103 } 104 105 static void 106 echo(char *s) 107 { 108 char c; 109 110 while (c = *s++) { 111 switch (c) { 112 case '$': 113 (void) read(FD, &c, 1); 114 s++; 115 break; 116 117 case '#': 118 c = *s++; 119 (void) write(FD, &c, 1); 120 break; 121 122 default: 123 (void) write(FD, &c, 1); 124 (void) read(FD, &c, 1); 125 } 126 } 127 } 128 129 static void 130 sigALRM(void) 131 { 132 133 (void) printf("\07timeout waiting for reply\n"); 134 timeout = 1; 135 siglongjmp(timeoutbuf, 1); 136 } 137 138 static int 139 gobble(char match) 140 { 141 char c; 142 sig_handler_t f; 143 144 f = signal(SIGALRM, (sig_handler_t)sigALRM); 145 timeout = 0; 146 do { 147 if (sigsetjmp(timeoutbuf, 1)) { 148 (void) signal(SIGALRM, f); 149 return (0); 150 } 151 (void) alarm(number(value(DIALTIMEOUT))); 152 (void) read(FD, &c, 1); 153 (void) alarm(0); 154 c &= 0177; 155 #ifdef notdef 156 if (boolean(value(VERBOSE))) 157 (void) putchar(c); 158 #endif 159 } while (c != '\n' && c != match); 160 (void) signal(SIGALRM, SIG_DFL); 161 return (c == match); 162 } 163 164 #define min(a, b) (((a) > (b)) ? (b) : (a)) 165 /* 166 * This convoluted piece of code attempts to get 167 * the ventel in sync. If you don't have FIONREAD 168 * there are gory ways to simulate this. 169 */ 170 static int 171 vensync(int fd) 172 { 173 int already = 0, nread; 174 char buf[60]; 175 int dtr = TIOCM_DTR; 176 177 /* 178 * Toggle DTR to force anyone off that might have left 179 * the modem connected, and insure a consistent state 180 * to start from. 181 * 182 * If you don't have the ioctl calls to diddle directly 183 * with DTR, you can always try setting the baud rate to 0. 184 */ 185 (void) ioctl(FD, TIOCMBIC, &dtr); 186 (void) sleep(2); 187 (void) ioctl(FD, TIOCMBIS, &dtr); 188 while (already < MAXRETRY) { 189 /* 190 * After reseting the modem, send it two \r's to 191 * autobaud on. Make sure to delay between them 192 * so the modem can frame the incoming characters. 193 */ 194 (void) write(fd, "\r", 1); 195 #ifdef VMUNIX 196 { 197 #include <sys/time.h> 198 struct timeval tv = {0, 500000}; 199 200 (void) select(0, 0, 0, 0, &tv); 201 } 202 #else 203 (void) sleep(1); 204 #endif 205 (void) write(fd, "\r", 1); 206 (void) sleep(3); 207 if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { 208 perror("tip: ioctl"); 209 continue; 210 } 211 while (nread > 0) { 212 (void) read(fd, buf, min(nread, 60)); 213 if ((buf[nread - 1] & 0177) == '$') 214 return (1); 215 nread -= min(nread, 60); 216 } 217 (void) sleep(1); 218 already++; 219 } 220 return (0); 221 } 222