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
hayes_dialer(char * num,char * acu)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
hayes_disconnect(void)81 hayes_disconnect(void)
82 {
83 (void) close(FD);
84 }
85
86 void
hayes_abort(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
sigALRM(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
hayes_sync(int fd)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