ref: 7420dc6adab03f28020243d71a3372cda15cacbc
dir: /sys/src/cmd/fax/fax2receive.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "modem.h" static char buf[102400]; static int page(Modem *m, char *spool) { int count, r; char c; /* * Start data reception. We should receive CONNECT in response * to +FDR, then data reception starts when we send DC2. */ m->valid &= ~(Vfhng|Vfet|Vfpts); if(command(m, "AT+FDR") != Eok) return Esys; switch(response(m, 30)){ case Rconnect: m->phase = 'C'; if((r = createfaxfile(m, spool)) != Eok) return r; if((r = putmchar(m, "\022")) != Eok) return r; break; case Rhangup: return Eok; default: return seterror(m, Eattn); } /* * Receive data. */ verbose("starting page %d", m->pageno); count = 0; while((r = getmchar(m, &c, 6)) == Eok){ if(c == '\020'){ if((r = getmchar(m, &c, 3)) != Eok) break; if(c == '\003') break; if(c != '\020'){ verbose("B%2.2ux", c); continue; } } buf[count++] = c; if(count >= sizeof(buf)){ if(write(m->pagefd, buf, count) < 0){ close(m->pagefd); return seterror(m, Esys); } count = 0; } } verbose("page %d done, count %d", m->pageno, count); if(count && write(m->pagefd, buf, count) < 0){ close(m->pagefd); return seterror(m, Esys); } if(r != Eok) return r; /* * Wait for either OK or ERROR. */ switch(r = response(m, 20)){ case Rok: case Rrerror: return Eok; default: verbose("page: response %d", r); return Eproto; } } static int receive(Modem *m, char *spool) { int r; loop: switch(r = page(m, spool)){ case Eok: /* * Check we have a valid page reponse. */ if((m->valid & Vfhng) == 0 && (m->valid & (Vfet|Vfpts)) != (Vfet|Vfpts)){ verbose("receive: invalid page reponse: #%4.4ux", m->valid); return seterror(m, Eproto); } /* * Was the page successfully received? * If not, try again. */ if((m->valid & Vfpts) && m->fpts[0] != 1) goto loop; /* * Another page of the same document, a new document * or no more pages. * If no more pages we still have to get the FHNG, so * the code is just the same as if there was another * page. */ if(m->valid & Vfet){ switch(m->fet){ case 0: /* another page */ case 2: /* no more pages */ m->pageno++; goto loop; case 1: /* new document */ /* * Bug: currently no way to run the * fax-received process for this, so it * just stays queued. */ faxrlog(m, Eok); m->pageno = 1; m->time = time(0); m->pid = getpid(); goto loop; } verbose("receive: invalid FET: %d", m->fet); return seterror(m, Eproto); } /* * All done or hangup error. * On error remove all pages in the current document. * Yik. */ if(m->valid & Vfhng){ if(m->fhng == 0) return Eok; verbose("receive: FHNG: %d", m->fhng); /* for(r = 1; r <= m->pageno; r++){ char pageid[128]; setpageid(pageid, spool, m->time, m->pid, r); remove(pageid); } */ return seterror(m, Eattn); } /*FALLTHROUGH*/ default: return r; } } int faxreceive(Modem *m, char *spool) { int r; verbose("faxdaemon"); if((r = initfaxmodem(m)) != Eok) return r; /* * assume that the phone has been answered and * we have received +FCON */ m->pageno = 1; m->time = time(0); m->pid = getpid(); fcon(m); /* * I wish I knew how to set the default parameters on the * MT1432 modem (+FIP in Class 2.0). */ return receive(m, spool); }