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: }

Defined functions

error_rep defined in line 171; used 1 times
  • in line 78
gobble defined in line 135; used 6 times
goodbye defined in line 211; used 1 times
hay_abort defined in line 117; never used
hay_dialer defined in line 51; never used
hay_disconnect defined in line 102; used 2 times
hay_sync defined in line 255; used 2 times
sigALRM defined in line 126; used 2 times

Defined variables

dumbuf defined in line 43; used 12 times
sccsid defined in line 8; never used
state defined in line 49; used 3 times
timeout defined in line 39; used 4 times

Defined macros

CONNECTED defined in line 47; used 1 times
  • in line 83
DIALING defined in line 45; used 1 times
  • in line 73
DUMBUFLEN defined in line 42; used 4 times
FAILED defined in line 48; used 1 times
  • in line 85
IDLE defined in line 46; used 1 times
  • in line 49
MAXRETRY defined in line 253; used 1 times
min defined in line 36; used 3 times
Last modified: 1985-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1170
Valid CSS Valid XHTML 1.0 Strict