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