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
page(Modem * m,char * spool)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
receive(Modem * m,char * spool)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
faxreceive(Modem * m,char * spool)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 }
194