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