1 /* ventel.c 1.2 82/07/29 */ 2 3 #if VENTEL 4 /* 5 * Routines for calling up on a Ventel Modem 6 */ 7 #include "tip.h" 8 #include <setjmp.h> 9 #include <errno.h> 10 11 #define MAXRETRY 5 12 #define DISCONNECT "\03" /* ^C */ 13 14 static int sigALRM(); 15 static int timeout = 0; 16 17 ven_dialer(num, acu) 18 register char *num; 19 char *acu; 20 { 21 register char *cp; 22 register int connected = 0; 23 char c; 24 #ifdef ACULOG 25 char line[80]; 26 #endif 27 /* 28 * Get in synch with a couple of carriage returns 29 */ 30 if (!vensync(FD)) { 31 printf("can't synchronize with ventel\n"); 32 #ifdef ACULOG 33 logent(value(HOST), num, "ventel", "can't synch up"); 34 #endif 35 return (0); 36 } 37 if (boolean(value(VERBOSE))) 38 printf("\ndialing..."); 39 fflush(stdout); 40 ioctl(FD, TIOCHPCL, 0); 41 echo("k$\r$\n$D$I$A$L$:$ <"); 42 for (cp = num; *cp; cp++) { 43 sleep(1); 44 write(FD, cp, 1); 45 read(FD, &c, 1); 46 } 47 echo(">\r$\n"); 48 if (gobble('\n')) 49 connected = gobble('!'); 50 ioctl(FD, TIOCFLUSH); 51 #ifdef ACULOG 52 if (timeout) { 53 sprintf(line, "%d second dial timeout", 54 number(value(DIALTIMEOUT))); 55 logent(value(HOST), num, "ventel", line); 56 } 57 #endif 58 if (timeout) 59 ven_disconnect(); /* insurance */ 60 return (connected); 61 } 62 63 ven_disconnect() 64 { 65 close(FD); 66 } 67 68 ven_abort() 69 { 70 write(FD, "\03", 1); 71 close(FD); 72 } 73 74 static int 75 echo(s) 76 register char *s; 77 { 78 char c; 79 80 while (c = *s++) switch (c) { 81 82 case '$': 83 read(FD, &c, 1); 84 s++; 85 break; 86 87 case '#': 88 c = *s++; 89 write(FD, &c, 1); 90 break; 91 92 default: 93 write(FD, &c, 1); 94 read(FD, &c, 1); 95 } 96 } 97 98 static int 99 sigALRM() 100 { 101 signal(SIGALRM, SIG_IGN); 102 printf("\07timeout waiting for reply\n"); 103 timeout = 1; 104 } 105 106 static int 107 gobble(s) 108 register char s; 109 { 110 char c; 111 112 signal(SIGALRM, sigALRM); 113 timeout = 0; 114 do { 115 alarm(number(value(DIALTIMEOUT))); 116 read(FD, &c, 1); 117 c &= 0177; 118 alarm(0); 119 #ifdef notdef 120 if (boolean(value(VERBOSE))) 121 putchar(c); 122 #endif 123 if (timeout) 124 return (0); 125 } while (c != '\n' && c != s); 126 signal(SIGALRM, SIG_DFL); 127 return (c == s); 128 } 129 130 #define min(a,b) ((a)>(b)?(b):(a)) 131 /* 132 * This convoluted piece of code attempts to get 133 * the ventel in sync. If you don't have the capacity or nread 134 * call there are gory ways to simulate this. 135 */ 136 static int 137 vensync(fd) 138 { 139 long nread; 140 register int already = 0, nbytes; 141 char buf[60]; 142 143 /* 144 * Toggle DTR to force anyone off that might have left 145 * the modem connected, and insure a consistent state 146 * to start from. 147 * 148 * If you don't have the ioctl calls to diddle directly 149 * with DTR, you can always try setting the baud rate to 0. 150 */ 151 ioctl(FD, TIOCCDTR, 0); 152 sleep(2); 153 ioctl(FD, TIOCSDTR, 0); 154 while (already < MAXRETRY) { 155 /* 156 * After reseting the modem, send it two \r's to 157 * autobaud on. Make sure to delay between them 158 * so the modem can frame the incoming characters. 159 */ 160 write(fd, "\r", 1); 161 sleep(1); 162 write(fd, "\r", 1); 163 sleep(3); 164 if (ioctl(fd, FIONREAD, (caddr_t)&nread) >= 0) { 165 nbytes = nread; 166 while (nbytes > 0) { 167 read(fd, buf, min(nbytes, 60)); 168 if ((buf[nbytes-1]&0177) == '$') 169 return (1); 170 nbytes -= min(nbytes, 60); 171 } 172 sleep(1); 173 already++; 174 } 175 } 176 return (0); 177 } 178 #endif 179