xref: /illumos-gate/usr/src/cmd/tip/aculib/hayes.c (revision 8d489c7a)
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
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
83 hayes_disconnect(void)
84 {
85 	(void) close(FD);
86 }
87 
88 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
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
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