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
static char buf[102400];
8
 
9
static int
10
page(Modem *m, char *spool)
11
{
12
	int count, r;
13
	char c;
14
 
15
	/*
16
	 * Start data reception. We should receive CONNECT in response
17
	 * to +FDR, then data reception starts when we send DC2.
18
	 */
19
	m->valid &= ~(Vfhng|Vfet|Vfpts);
20
	if(command(m, "AT+FDR") != Eok)
21
		return Esys;
22
 
23
	switch(response(m, 30)){
24
 
25
	case Rconnect:
26
		m->phase = 'C';
27
		if((r = createfaxfile(m, spool)) != Eok)
28
			return r;
29
		if((r = putmchar(m, "\022")) != Eok)
30
			return r;
31
		break;
32
 
33
	case Rhangup:
34
		return Eok;
35
 
36
	default:
37
		return seterror(m, Eattn);
38
	}
39
 
40
	/*
41
	 * Receive data.
42
	 */
43
	verbose("starting page %d", m->pageno);
44
	count = 0;
45
	while((r = getmchar(m, &c, 6)) == Eok){
46
		if(c == '\020'){
47
			if((r = getmchar(m, &c, 3)) != Eok)
48
				break;
49
			if(c == '\003')
50
				break;
51
			if(c != '\020'){
52
				verbose("B%2.2ux", c);
53
				continue;
54
			}
55
		}
56
		buf[count++] = c;
57
		if(count >= sizeof(buf)){
58
			if(write(m->pagefd, buf, count) < 0){
59
				close(m->pagefd);
60
				return seterror(m, Esys);
61
			}
62
			count = 0;
63
		}	
64
	}
65
	verbose("page %d done, count %d", m->pageno, count);
66
	if(count && write(m->pagefd, buf, count) < 0){
67
		close(m->pagefd);
68
		return seterror(m, Esys);
69
	}
70
	if(r != Eok)
71
		return r;
72
 
73
	/*
74
	 * Wait for either OK or ERROR.
75
	 */
76
	switch(r = response(m, 20)){
77
 
78
	case Rok:
79
	case Rrerror:
80
		return Eok;
81
 
82
	default:
83
		verbose("page: response %d", r);
84
		return Eproto;
85
	}
86
}
87
 
88
static int
89
receive(Modem *m, char *spool)
90
{
91
	int r;
92
 
93
   loop:
94
	switch(r = page(m, spool)){
95
 
96
	case Eok:
97
		/*
98
		 * Check we have a valid page reponse.
99
		 */
100
		if((m->valid & Vfhng) == 0 && (m->valid & (Vfet|Vfpts)) != (Vfet|Vfpts)){
101
			verbose("receive: invalid page reponse: #%4.4ux", m->valid);
102
			return seterror(m, Eproto);
103
		}
104
 
105
		/*
106
		 * Was the page successfully received?
107
		 * If not, try again.
108
		 */
109
		if((m->valid & Vfpts) && m->fpts[0] != 1)
110
			goto loop;
111
 
112
		/*
113
		 * Another page of the same document, a new document
114
		 * or no more pages.
115
		 * If no more pages we still have to get the FHNG, so
116
		 * the code is just the same as if there was another
117
		 * page.
118
		 */
119
		if(m->valid & Vfet){
120
			switch(m->fet){
121
 
122
			case 0:				/* another page */
123
			case 2:				/* no more pages */
124
				m->pageno++;
125
				goto loop;
126
 
127
			case 1:				/* new document */
128
				/*
129
				 * Bug: currently no way to run the
130
				 * fax-received process for this, so it
131
				 * just stays queued.
132
				 */
133
				faxrlog(m, Eok);
134
				m->pageno = 1;
135
				m->time = time(0);
136
				m->pid = getpid();
137
				goto loop;
138
			}
139
 
140
			verbose("receive: invalid FET: %d", m->fet);
141
			return seterror(m, Eproto);
142
		}
143
 
144
		/*
145
		 * All done or hangup error.
146
		 * On error remove all pages in the current document.
147
		 * Yik.
148
		 */
149
		if(m->valid & Vfhng){
150
			if(m->fhng == 0)
151
				return Eok;
152
			verbose("receive: FHNG: %d", m->fhng);
153
			/*
154
			for(r = 1; r <= m->pageno; r++){
155
				char pageid[128];
156
 
157
				setpageid(pageid, spool, m->time, m->pid, r);
158
				remove(pageid);
159
			}
160
			 */
161
			return seterror(m, Eattn);
162
		}
163
		/*FALLTHROUGH*/
164
 
165
	default:
166
		return r;
167
	}
168
}
169
 
170
int
171
faxreceive(Modem *m, char *spool)
172
{
173
	int r;
174
 
175
	verbose("faxdaemon");
176
	if((r = initfaxmodem(m)) != Eok)
177
		return r;
178
 
179
	/*
180
	 *  assume that the phone has been answered and
181
	 *  we have received +FCON
182
	 */
183
	m->pageno = 1;
184
	m->time = time(0);
185
	m->pid = getpid();
186
	fcon(m);
187
 
188
	/*
189
	 * I wish I knew how to set the default parameters on the
190
	 * MT1432 modem (+FIP in Class 2.0).
191
	 */
192
	return receive(m, spool);
193
}