Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/con/hayes.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
 
4
void setspeed(int, int);
5
int getspeed(char*, int);
6
void godial(int, int, char*);
7
int readmsg(int, int);
8
void punt(char*, ...);
9
 
10
int pulsed;
11
int verbose;
12
char msgbuf[128];		/* last message read */
13
 
14
enum
15
{
16
	Ok,
17
	Success,
18
	Failure,
19
	Noise,
20
};
21
 
22
typedef struct Msg	Msg;
23
struct Msg
24
{
25
	char	*text;
26
	int	type;
27
};
28
 
29
 
30
Msg msgs[] =
31
{
32
	{ "OK",			Ok, },
33
	{ "NO CARRIER", 	Failure, },
34
	{ "ERROR",		Failure, },
35
	{ "NO DIALTONE",	Failure, },
36
	{ "BUSY",		Failure, },
37
	{ "NO ANSWER",		Failure, },
38
	{ "CONNECT",		Success, },
39
	{ 0,			0 },
40
};
41
 
42
void
43
usage(void)
44
{
45
	punt("usage: hayes [-p] telno [device]");
46
}
47
 
48
void
49
main(int argc, char **argv)
50
{
51
	int data = -1;
52
	int ctl = -1;
53
	char *cname;
54
 
55
	ARGBEGIN{
56
	case 'p':
57
		pulsed = 1;
58
		break;
59
	case 'v':
60
		verbose = 1;
61
		break;
62
	default:
63
		usage();
64
	}ARGEND
65
 
66
	switch(argc){
67
	case 1:
68
		data = 1;
69
		break;
70
	case 2:
71
		data = open(argv[1], ORDWR);
72
		if(data < 0){
73
			fprint(2, "hayes: %r opening %s\n", argv[1]);
74
			exits("hayes");
75
		}
76
		cname = malloc(strlen(argv[1])+4);
77
		sprint(cname, "%sctl", argv[1]);
78
		ctl = open(cname, ORDWR);
79
		free(cname);
80
		break;
81
	default:
82
		usage();
83
	}
84
	godial(data, ctl, argv[0]);
85
	exits(0);
86
}
87
 
88
int
89
send(int fd, char *x)
90
{
91
	return write(fd, x, strlen(x));
92
}
93
 
94
void
95
godial(int data, int ctl, char *number)
96
{
97
	char *dialstr;
98
	int m;
99
	int baud;
100
 
101
	/* get the modem's attention */
102
	if(send(data, "\r+++\r") < 0)
103
		punt("failed write");
104
	readmsg(data, 2);
105
	sleep(1000);
106
 
107
	/* initialize */
108
	if(send(data, "ATZ\r") < 0)
109
		punt("failed write");
110
	m = readmsg(data, 2);
111
	if(m < 0)
112
		punt("can't get modem's attention");
113
 
114
	/*
115
	 *	Q0 = report result codes
116
	 * 	V1 = full word result codes
117
	 *	W1 = negotiation progress codes enabled
118
	 *	E1 = echo commands
119
	 *	M1 = speaker on until on-line
120
	 */
121
	if(send(data, "ATQ0V1E1M1\r") < 0)
122
		punt("failed write");
123
	m = readmsg(data, 2);
124
	if(m != Ok)
125
		punt("can't get modem's attention");
126
	if(send(data, "ATW1\r") < 0)
127
		punt("failed write");
128
	readmsg(data, 2);
129
	sleep(1000);
130
 
131
	/* godial */
132
	dialstr = malloc(6+strlen(number));
133
	sprint(dialstr, "ATD%c%s\r", pulsed ? 'P' : 'T', number);
134
	if(send(data, dialstr) < 0) {
135
		free(dialstr);
136
		punt("failed write");
137
	}
138
	free(dialstr);
139
	m = readmsg(data, 60);
140
	if(m != Success)
141
		punt("dial failed: %s", msgbuf);
142
	baud = getspeed(msgbuf, 9600);
143
	setspeed(ctl, baud);
144
	fprint(2, "hayes: connected at %d baud\n", baud);
145
}
146
 
147
/*
148
 *  read until we see a message or we time out
149
 */
150
int
151
readmsg(int f, int secs)
152
{
153
	ulong start;
154
	char *p;
155
	int len;
156
	Dir *d;
157
	Msg *pp;
158
 
159
	p = msgbuf;
160
	len = sizeof(msgbuf) - 1;
161
	for(start = time(0); time(0) <= start+secs;){
162
		if((d = dirfstat(f)) == nil)
163
			punt("failed read");
164
		if(d->length == 0){
165
			free(d);
166
			sleep(100);
167
			continue;
168
		}
169
		free(d);
170
		if(read(f, p, 1) <= 0)
171
			punt("failed read");
172
		if(*p == '\n' || *p == '\r' || len == 0){
173
			*p = 0;
174
			if(verbose && p != msgbuf)
175
				fprint(2, "%s\n", msgbuf);
176
			for(pp = msgs; pp->text; pp++)
177
				if(strncmp(pp->text, msgbuf, strlen(pp->text))==0)
178
					return pp->type;
179
			start = time(0);
180
			p = msgbuf;
181
			len = sizeof(msgbuf) - 1;
182
			continue;
183
		}
184
		len--;
185
		p++;
186
	}
187
	strcpy(msgbuf, "No response from modem");
188
	return Noise;
189
}
190
 
191
/*
192
 *  get baud rate from a connect message
193
 */
194
int
195
getspeed(char *msg, int speed)
196
{
197
	char *p;
198
	int s;
199
 
200
	p = msg + sizeof("CONNECT") - 1;
201
	while(*p == ' ' || *p == '\t')
202
		p++;
203
	s = atoi(p);
204
	if(s <= 0)
205
		return speed;
206
	else
207
		return s;
208
}
209
 
210
/*
211
 *  set speed and RTS/CTS modem flow control
212
 */
213
void
214
setspeed(int ctl, int baud)
215
{
216
	char buf[32];
217
 
218
	if(ctl < 0)
219
		return;
220
	sprint(buf, "b%d", baud);
221
	write(ctl, buf, strlen(buf));
222
	write(ctl, "m1", 2);
223
}
224
 
225
 
226
void
227
punt(char *fmt, ...)
228
{
229
	char buf[256];
230
	va_list arg;
231
	int n;
232
 
233
	strcpy(buf, "hayes: ");
234
	va_start(arg, fmt);
235
	n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;
236
	va_end(arg);
237
	buf[n] = '\n';
238
	write(2, buf, n+1);
239
	exits("hayes");
240
}