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