1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 1983 Regents of the University of California. 8 * All rights reserved. The Berkeley software License Agreement 9 * specifies the terms and conditions for redistribution. 10 */ 11 12 #include "tip.h" 13 14 static int hayes_sync(int); 15 static void sigALRM(void); 16 static sigjmp_buf timeoutbuf; 17 18 void hayes_disconnect(void); 19 20 /* 21 * Dial up on a Hayes Smart Modem 1200 or 2400 22 */ 23 /* ARGSUSED */ 24 int 25 hayes_dialer(char *num, char *acu) 26 { 27 char code = 0, cr = 0; 28 sig_handler_t f; 29 struct termios buf; 30 31 f = signal(SIGALRM, (sig_handler_t)sigALRM); 32 33 if (!hayes_sync(FD)) { 34 (void) printf("can't synchronize with hayes\n"); 35 #ifdef ACULOG 36 logent(value(HOST), num, "hayes", "can't synch up"); 37 #endif 38 (void) signal(SIGALRM, f); 39 return (0); 40 } 41 if (boolean(value(VERBOSE))) 42 (void) printf("\ndialing..."); 43 (void) fflush(stdout); 44 (void) ioctl(FD, TCGETS, &buf); 45 buf.c_cflag |= HUPCL; 46 (void) ioctl(FD, TCSETS, &buf); 47 (void) ioctl(FD, TCFLSH, TCIOFLUSH); 48 49 if (sigsetjmp(timeoutbuf, 1)) { 50 #ifdef ACULOG 51 char line[80]; 52 53 (void) sprintf(line, "%d second dial timeout", 54 number(value(DIALTIMEOUT))); 55 logent(value(HOST), num, "hayes", line); 56 #endif 57 hayes_disconnect(); 58 (void) signal(SIGALRM, f); 59 return (0); 60 } 61 (void) alarm(number(value(DIALTIMEOUT))); 62 (void) ioctl(FD, TCFLSH, TCIOFLUSH); 63 if (*num == 'S') 64 (void) write(FD, "AT", 2); 65 else 66 (void) write(FD, "ATDT", 4); /* use tone dialing */ 67 (void) write(FD, num, strlen(num)); 68 (void) write(FD, "\r", 1); 69 (void) read(FD, &code, 1); 70 (void) read(FD, &cr, 1); 71 if (code == '1' && cr == '0') 72 (void) read(FD, &cr, 1); 73 (void) alarm(0); 74 (void) signal(SIGALRM, f); 75 if ((code == '1' || code == '5') && cr == '\r') 76 return (1); 77 return (0); 78 } 79 80 void 81 hayes_disconnect(void) 82 { 83 (void) close(FD); 84 } 85 86 void 87 hayes_abort(void) 88 { 89 int dtr = TIOCM_DTR; 90 91 (void) alarm(0); 92 (void) ioctl(FD, TIOCMBIC, &dtr); 93 (void) sleep(2); 94 (void) ioctl(FD, TCFLSH, TCIOFLUSH); 95 (void) close(FD); 96 } 97 98 static void 99 sigALRM(void) 100 { 101 siglongjmp(timeoutbuf, 1); 102 } 103 104 /* 105 * This piece of code attempts to get the hayes in sync. 106 */ 107 static int 108 hayes_sync(int fd) 109 { 110 int tries; 111 char code = 0, cr = 0; 112 int dtr = TIOCM_DTR; 113 114 /* 115 * Toggle DTR to force anyone off that might have left 116 * the modem connected, and insure a consistent state 117 * to start from. 118 */ 119 (void) ioctl(fd, TIOCMBIC, &dtr); 120 (void) sleep(1); 121 (void) ioctl(fd, TIOCMBIS, &dtr); 122 for (tries = 0; tries < 3; tries++) { 123 /* 124 * After reseting the modem, initialize all 125 * parameters to required vaules: 126 * 127 * V0 - result codes are single digits 128 * Q0 - result codes ARE sent 129 * E0 - do not echo 130 * S0=1 - automatically answer phone 131 * S2=255 - disable escape character 132 * S12=255 - longest possible escape guard time 133 */ 134 (void) write(fd, "ATV0Q0E0S0=1S2=255S12=255\r", 26); 135 (void) sleep(1); 136 /* flush any echoes or return codes */ 137 (void) ioctl(fd, TCFLSH, TCIOFLUSH); 138 /* now see if the modem is talking to us properly */ 139 (void) write(fd, "AT\r", 3); 140 if (sigsetjmp(timeoutbuf, 1) == 0) { 141 (void) alarm(2); 142 (void) read(FD, &code, 1); 143 (void) read(FD, &cr, 1); 144 if (code == '0' && cr == '\r') 145 return (1); 146 } 147 } 148 return (0); 149 } 150