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