|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)hayes.c 5.3 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: * Routines for calling up on a Hayes Modem ! 26: * (based on the old VenTel driver). ! 27: * The modem is expected to be strapped for "echo". ! 28: * Also, the switches enabling the DTR and CD lines ! 29: * must be set correctly. ! 30: * NOTICE: ! 31: * The easy way to hang up a modem is always simply to ! 32: * clear the DTR signal. However, if the +++ sequence ! 33: * (which switches the modem back to local mode) is sent ! 34: * before modem is hung up, removal of the DTR signal ! 35: * has no effect (except that it prevents the modem from ! 36: * recognizing commands). ! 37: * (by Helge Skrivervik, Calma Company, Sunnyvale, CA. 1984) ! 38: */ ! 39: /* ! 40: * TODO: ! 41: * It is probably not a good idea to switch the modem ! 42: * state between 'verbose' and terse (status messages). ! 43: * This should be kicked out and we should use verbose ! 44: * mode only. This would make it consistent with normal ! 45: * interactive use thru the command 'tip dialer'. ! 46: */ ! 47: #include "tip.h" ! 48: ! 49: #define min(a,b) ((a < b) ? a : b) ! 50: ! 51: static int sigALRM(); ! 52: static int timeout = 0; ! 53: static jmp_buf timeoutbuf; ! 54: static char gobble(); ! 55: #define DUMBUFLEN 40 ! 56: static char dumbuf[DUMBUFLEN]; ! 57: ! 58: #define DIALING 1 ! 59: #define IDLE 2 ! 60: #define CONNECTED 3 ! 61: #define FAILED 4 ! 62: static int state = IDLE; ! 63: ! 64: hay_dialer(num, acu) ! 65: register char *num; ! 66: char *acu; ! 67: { ! 68: register char *cp; ! 69: register int connected = 0; ! 70: char dummy; ! 71: #ifdef ACULOG ! 72: char line[80]; ! 73: #endif ! 74: if (hay_sync() == 0) /* make sure we can talk to the modem */ ! 75: return(0); ! 76: if (boolean(value(VERBOSE))) ! 77: printf("\ndialing..."); ! 78: fflush(stdout); ! 79: ioctl(FD, TIOCHPCL, 0); ! 80: ioctl(FD, TIOCFLUSH, 0); /* get rid of garbage */ ! 81: write(FD, "ATv0\r", 5); /* tell modem to use short status codes */ ! 82: gobble("\r"); ! 83: gobble("\r"); ! 84: write(FD, "ATTD", 4); /* send dial command */ ! 85: write(FD, num, strlen(num)); ! 86: state = DIALING; ! 87: write(FD, "\r", 1); ! 88: connected = 0; ! 89: if (gobble("\r")) { ! 90: if ((dummy = gobble("01234")) != '1') ! 91: error_rep(dummy); ! 92: else ! 93: connected = 1; ! 94: } ! 95: if (connected) ! 96: state = CONNECTED; ! 97: else { ! 98: state = FAILED; ! 99: return (connected); /* lets get out of here.. */ ! 100: } ! 101: ioctl(FD, TIOCFLUSH, 0); ! 102: #ifdef ACULOG ! 103: if (timeout) { ! 104: sprintf(line, "%d second dial timeout", ! 105: number(value(DIALTIMEOUT))); ! 106: logent(value(HOST), num, "hayes", line); ! 107: } ! 108: #endif ! 109: if (timeout) ! 110: hay_disconnect(); /* insurance */ ! 111: return (connected); ! 112: } ! 113: ! 114: ! 115: hay_disconnect() ! 116: { ! 117: char c; ! 118: int len, rlen; ! 119: ! 120: /* first hang up the modem*/ ! 121: #ifdef DEBUG ! 122: printf("\rdisconnecting modem....\n\r"); ! 123: #endif ! 124: ioctl(FD, TIOCCDTR, 0); ! 125: sleep(1); ! 126: ioctl(FD, TIOCSDTR, 0); ! 127: goodbye(); ! 128: } ! 129: ! 130: hay_abort() ! 131: { ! 132: ! 133: char c; ! 134: ! 135: write(FD, "\r", 1); /* send anything to abort the call */ ! 136: hay_disconnect(); ! 137: } ! 138: ! 139: static int ! 140: sigALRM() ! 141: { ! 142: ! 143: printf("\07timeout waiting for reply\n\r"); ! 144: timeout = 1; ! 145: longjmp(timeoutbuf, 1); ! 146: } ! 147: ! 148: static char ! 149: gobble(match) ! 150: register char *match; ! 151: { ! 152: char c; ! 153: int (*f)(); ! 154: int i, status = 0; ! 155: ! 156: signal(SIGALRM, sigALRM); ! 157: timeout = 0; ! 158: #ifdef DEBUG ! 159: printf("\ngobble: waiting for %s\n", match); ! 160: #endif ! 161: do { ! 162: if (setjmp(timeoutbuf)) { ! 163: signal(SIGALRM, f); ! 164: return (0); ! 165: } ! 166: alarm(number(value(DIALTIMEOUT))); ! 167: read(FD, &c, 1); ! 168: alarm(0); ! 169: c &= 0177; ! 170: #ifdef DEBUG ! 171: printf("%c 0x%x ", c, c); ! 172: #endif ! 173: for (i = 0; i < strlen(match); i++) ! 174: if (c == match[i]) ! 175: status = c; ! 176: } while (status == 0); ! 177: signal(SIGALRM, SIG_DFL); ! 178: #ifdef DEBUG ! 179: printf("\n"); ! 180: #endif ! 181: return (status); ! 182: } ! 183: ! 184: error_rep(c) ! 185: register char c; ! 186: { ! 187: printf("\n\r"); ! 188: switch (c) { ! 189: ! 190: case '0': ! 191: printf("OK"); ! 192: break; ! 193: ! 194: case '1': ! 195: printf("CONNECT"); ! 196: break; ! 197: ! 198: case '2': ! 199: printf("RING"); ! 200: break; ! 201: ! 202: case '3': ! 203: printf("NO CARRIER"); ! 204: break; ! 205: ! 206: case '4': ! 207: printf("ERROR in input"); ! 208: break; ! 209: ! 210: case '5': ! 211: printf("CONNECT 1200"); ! 212: break; ! 213: ! 214: default: ! 215: printf("Unknown Modem error: %c (0x%x)", c, c); ! 216: } ! 217: printf("\n\r"); ! 218: return; ! 219: } ! 220: ! 221: /* ! 222: * set modem back to normal verbose status codes. ! 223: */ ! 224: goodbye() ! 225: { ! 226: int len, rlen; ! 227: char c; ! 228: ! 229: ioctl(FD, TIOCFLUSH, &len); /* get rid of trash */ ! 230: if (hay_sync()) { ! 231: sleep(1); ! 232: #ifndef DEBUG ! 233: ioctl(FD, TIOCFLUSH, 0); ! 234: #endif ! 235: write(FD, "ATH0\r", 5); /* insurance */ ! 236: #ifndef DEBUG ! 237: c = gobble("03"); ! 238: if (c != '0' && c != '3') { ! 239: printf("cannot hang up modem\n\r"); ! 240: printf("please use 'tip dialer' to make sure the line is hung up\n\r"); ! 241: } ! 242: #endif ! 243: sleep(1); ! 244: ioctl(FD, FIONREAD, &len); ! 245: #ifdef DEBUG ! 246: printf("goodbye1: len=%d -- ", len); ! 247: rlen = read(FD, dumbuf, min(len, DUMBUFLEN)); ! 248: dumbuf[rlen] = '\0'; ! 249: printf("read (%d): %s\r\n", rlen, dumbuf); ! 250: #endif ! 251: write(FD, "ATv1\r", 5); ! 252: sleep(1); ! 253: #ifdef DEBUG ! 254: ioctl(FD, FIONREAD, &len); ! 255: printf("goodbye2: len=%d -- ", len); ! 256: rlen = read(FD, dumbuf, min(len, DUMBUFLEN)); ! 257: dumbuf[rlen] = '\0'; ! 258: printf("read (%d): %s\r\n", rlen, dumbuf); ! 259: #endif ! 260: } ! 261: ioctl(FD, TIOCFLUSH, 0); /* clear the input buffer */ ! 262: ioctl(FD, TIOCCDTR, 0); /* clear DTR (insurance) */ ! 263: close(FD); ! 264: } ! 265: ! 266: #define MAXRETRY 5 ! 267: ! 268: hay_sync() ! 269: { ! 270: int len, retry = 0; ! 271: ! 272: while (retry++ <= MAXRETRY) { ! 273: write(FD, "AT\r", 3); ! 274: sleep(1); ! 275: ioctl(FD, FIONREAD, &len); ! 276: if (len) { ! 277: len = read(FD, dumbuf, min(len, DUMBUFLEN)); ! 278: if (index(dumbuf, '0') || ! 279: (index(dumbuf, 'O') && index(dumbuf, 'K'))) ! 280: return(1); ! 281: #ifdef DEBUG ! 282: dumbuf[len] = '\0'; ! 283: printf("hay_sync: (\"%s\") %d\n\r", dumbuf, retry); ! 284: #endif ! 285: } ! 286: ioctl(FD, TIOCCDTR, 0); ! 287: ioctl(FD, TIOCSDTR, 0); ! 288: } ! 289: printf("Cannot synchronize with hayes...\n\r"); ! 290: return(0); ! 291: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.