Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
 
5
#include "modem.h"
6
 
7
int
8
faxsend(Modem *m, int argc, char *argv[])
9
{
10
	int c, count, r, flow;
11
	char buf[128];
12
 
13
	verbose("faxsend");
14
	if((r = initfaxmodem(m)) != Eok)
15
		return r;
16
 
17
	/* telco just does the dialing */
18
	r = response(m, 120);
19
	switch(r){
20
	case Rok:
21
		break;
22
	default:
23
		r = seterror(m, Enoanswer);
24
		return r;
25
 
26
	}
27
 
28
	xonoff(m, 1);
29
	verbose("sending");
30
	m->pageno = 1;
31
	while(argc--){
32
		if(m->pageno != 1)
33
			sleep(1000);	/* let the paper catch up */
34
 
35
		m->valid &= ~(Vfhng|Vfet|Vfpts|Vftsi|Vfdcs);
36
		if((r = openfaxfile(m, *argv)) != Eok)
37
			return r;
38
 
39
		verbose("sending geometry");
40
		sprint(buf, "AT+FDT=%ld,%ld,%ld,%ld", m->df, m->vr, m->wd, m->ln);
41
		if(command(m, buf) != Eok)
42
			goto buggery;
43
		if(response(m, 20) != Rconnect){
44
			r = seterror(m, Eincompatible);
45
			goto buggery;
46
		}
47
 
48
		/*
49
		 * Write the data, stuffing DLE's.
50
		 * After each bufferfull check if the remote
51
		 * sent us anything, e.g. CAN to abort.
52
		 * This also flushes out the ^S/^Q characters
53
		 * which the driver insists on sending us.
54
		 * (Could fix the driver, of course...).
55
		 */
56
		verbose("sending data");
57
		for(;;){
58
			flow = 0;
59
			count = 0;
60
			c = 0;
61
			while(count < sizeof(buf)-1){
62
				if((c = Bgetc(m->bp)) < 0)
63
					break;
64
				buf[count++] = c;
65
				if(c == '\020')
66
					buf[count++] = c;
67
			}
68
			verbose("sending %d bytes", count);
69
			if(count && write(m->fd, buf, count) < 0){
70
				verbose("write failed: %r");
71
				r = seterror(m, Esys);
72
				goto buggery;
73
			}
74
			/*
75
			 *  this does really rough flow control since the
76
			 *  avanstar is even worse
77
			 */
78
			verbose("flow control");
79
			while((r = rawmchar(m, buf)) == Eok || flow){
80
				if(r != Eok){
81
					if(flow-- == 0)
82
						break;
83
					sleep(250);
84
					continue;
85
				}
86
				switch(buf[0]){
87
				case '\030':
88
					verbose("%c", buf[0]);
89
					if(write(m->fd, "\020\003", 2) < 0){
90
						r = seterror(m, Esys);
91
						goto buggery;
92
					}
93
					goto okexit;
94
				case '\021':
95
					flow = 0;
96
					break;
97
				case '\023':
98
					flow = 4;
99
					break;
100
				case '\n':
101
					break;
102
				default:
103
					verbose("%c", buf[0]);
104
					r = seterror(m, Eproto);
105
					goto buggery;
106
 
107
				}
108
			}
109
			if(c < 0)
110
				break;
111
		}
112
 
113
 
114
		/*
115
		 * End of page, send DLE+ETX,
116
		 * get OK in response.
117
		 */
118
		verbose("sending end of page");
119
		if(write(m->fd, "\020\003", 2) < 0){
120
			r = seterror(m, Esys);
121
			goto buggery;
122
		}
123
		verbose("waiting for OK");
124
		if(response(m, 120) != Rok){
125
			r = seterror(m, Enoresponse);
126
			goto buggery;
127
		}
128
 
129
		/*
130
		 * Did you hear me? - IT'S THE END OF THE PAGE.
131
		 * Argument is 0 if more pages to follow.
132
		 * Should get back an FPTS with an indication
133
		 * as to whether the page was successfully
134
		 * transmitted or not.
135
		 */
136
		sprint(buf, "AT+FET=%d", argc == 0? 2: 0);
137
		if(command(m, buf) != Eok)
138
			goto buggery;
139
		switch(response(m, 20)){
140
		case Rok:
141
			break;
142
		case Rhangup:
143
			if(m->fhng == 0 && argc == 0)
144
				break;
145
			r = seterror(m, Eproto);
146
			goto buggery;
147
		default:
148
			r = seterror(m, Enoresponse);
149
			goto buggery;
150
		}
151
 
152
		if((m->valid & Vfpts) == 0 || m->fpts[0] != 1){
153
			r = seterror(m, Eproto);
154
			goto buggery;
155
		}
156
 
157
		Bterm(m->bp);
158
		m->pageno++;
159
		argv++;
160
	}
161
okexit:
162
	xonoff(m, 0);
163
	return Eok;
164
 
165
buggery:
166
	xonoff(m, 0);
167
	Bterm(m->bp);
168
	command(m, "AT+FK");
169
	response(m, 5);
170
	return r;
171
}