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