]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/fax/fax2receive.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / fax / fax2receive.c
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 }