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