fax2receive.c 3.4 KB

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