home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / bts314b4 / rcvfax.c < prev    next >
C/C++ Source or Header  |  1994-01-08  |  10KB  |  571 lines

  1. #define SERIAL  1
  2. #define CONSOLE 2
  3.  
  4. #define RTS_ON  Offgibit(~0x08)
  5.  
  6. #define NOCARRIERTO 30
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <time.h>
  11. #include <stdlib.h>
  12. #include <tos.h>
  13. #include <ext.h>
  14.  
  15. #include "bink.h"
  16. #include "com_st.h"
  17. #include "externs.h"
  18. #include "msgs.h"
  19.  
  20. #include "faxascii.h"
  21.  
  22. #define BLOCKSIZE     0x1000L
  23. #define HEADERSIZE    0x10
  24. #define RINGTIMEOUT 18
  25.  
  26. typedef struct
  27. {
  28.     char title[6];
  29.     int version, reserved, page_wid, page_cnt, coding;
  30. } zyxel_header;
  31.  
  32. zyxel_header m_head;
  33.  
  34. void build_tables(void);
  35.  
  36. int carrier;
  37. byte *rec_block;
  38. char ans[82];
  39.  
  40. char curr_fn[PATH_MAX];
  41. struct date datum;
  42. struct time zeit;
  43.  
  44. char disc_ans[]={"DISCONNECT"};
  45. int  pages;
  46. char disco_response[80], gpr[40];
  47. char con_str[80];
  48. byte lead_0[256], trail_0[256];
  49.  
  50. void send_command(char cmd[])
  51. {
  52.     /* Cauxout */
  53.     
  54.     while(Bconstat(SERIAL)) Bconin(SERIAL);
  55.  
  56.     while(*cmd) Bconout(SERIAL,*cmd++);
  57.  
  58.     Bconout(SERIAL,ASC_CR);
  59. }
  60.  
  61. int get_response_quick(char *ans, int to)
  62. {
  63.     int i, rv, fertig, c;
  64.     time_t start;
  65.  
  66.     fertig=FALSE;
  67.     i=0;
  68.     start=time(NULL);
  69.  
  70.     while(!fertig)
  71.     {
  72.         if(Bconstat(SERIAL))
  73.         {
  74.             c=(char) Bconin(SERIAL);
  75.             if( ((c==0x0A)&(i>=2)) || (i>=70) )
  76.             {
  77.                 rv=fertig=TRUE;
  78.                 ans[i]=0;
  79.             }
  80.             else
  81.             {
  82.                 if( (c>=0x20) )
  83.                     ans[i++]=c;
  84.             }
  85.         }
  86.         else if ((time(NULL)-start)>to)
  87.         {
  88.             fertig=TRUE;
  89.             strcpy(ans,"timeout");
  90.             status_line(msgtxt[M_FAX_DEBUG], ans);
  91.             rv=FALSE;
  92.         }
  93.     }
  94.  
  95.     return rv;
  96. }
  97.  
  98. int get_response_quick_ltd(char *ans, int to)
  99. {
  100.     int i, rv, fertig, c;
  101.     time_t start;
  102.  
  103.     fertig=FALSE;
  104.     i=0;
  105.     start=time(NULL);
  106.  
  107.     while(!fertig)
  108.     {
  109.         if(Bconstat(SERIAL))
  110.         {
  111.             c=(char) Bconin(SERIAL);
  112.             if( ((c==0x0A)&(i>=2)) || (i>=40) )
  113.             {
  114.                 rv=fertig=TRUE;
  115.                 ans[i]=0;
  116.             }
  117.             else
  118.             {
  119.                 if( (c>=0x20) )
  120.                     ans[i++]=c;
  121.             }
  122.         }
  123.         else if ((time(NULL)-start)>to)
  124.         {
  125.             fertig=TRUE;
  126.             strcpy(ans,"timeout");
  127.             status_line(msgtxt[M_FAX_DEBUG], ans);
  128.             rv=FALSE;
  129.         }
  130.     }
  131.  
  132.     return rv;
  133. }
  134.  
  135. /* get response, return answer */
  136. int get_resp_ra(char *ans, int to)
  137. {
  138.     int i, rv, fertig, c;
  139.     time_t start;
  140.  
  141.     fertig=FALSE;
  142.     i=0;
  143.     start=time(NULL);
  144.  
  145.     while(!fertig)
  146.     {
  147.         if(Bconstat(SERIAL))
  148.         {
  149.             c=(char) Bconin(SERIAL);
  150.             if( ((c==0x0A)&(i>=2)) || (i>=70) )
  151.             {
  152.                 rv=fertig=TRUE;
  153.                 ans[i]=0;
  154.             }
  155.             else
  156.             {
  157.                 if( (c>=0x20) ) ans[i++]=c;
  158.             }
  159.         }
  160.         else if ((time(NULL)-start)>to)
  161.         {
  162.             fertig=TRUE;
  163.             strcpy(ans,"timeout");
  164.             status_line(msgtxt[M_FAX_DEBUG], ans);
  165.             rv=FALSE;
  166.         }
  167.     }
  168.  
  169.     return rv;
  170. }
  171.  
  172. void test_for_rec_fax_file(void)
  173. {
  174.     int f;
  175.   
  176.     if((f=open(curr_fn,O_RDONLY))>0)
  177.     {
  178.         close(f);
  179.         curr_fn[strlen(curr_fn)-1]='x';
  180.     }
  181. }
  182.  
  183. void make_next_name(void)
  184. {
  185.     char pfn[15];
  186.  
  187.     getdate(&datum);
  188.     gettime(&zeit);
  189.     sprintf(pfn,"FR%02d%02d%02d.F%02d",
  190.             datum.da_mon, datum.da_day, zeit.ti_hour, zeit.ti_min);
  191.     strcpy(curr_fn,fax_inbound);
  192.     strcat(curr_fn,pfn);
  193.     test_for_rec_fax_file();
  194. }
  195.  
  196. /*
  197. long get_con(void)
  198. {
  199.     carrier= ((*mfp_reg_ptr & 0x02)==0);
  200.     return 0;
  201. }
  202. */
  203.  
  204. void receive(int f)
  205. {
  206.     int not_stopped=TRUE;
  207.     byte *lz, c;
  208.     int key, disc_ptr=0;
  209.     int zeros=0, eolns=0, eleven0=FALSE, carrier_da=TRUE;
  210.     size_t count=0;
  211.     time_t noca_time;
  212.  
  213.     noca_time=time(NULL);
  214.     lz=rec_block;
  215.  
  216.     while(not_stopped)
  217.     {
  218.         if(Bconstat(SERIAL))
  219.         {
  220.             c=*lz++=(byte) Bconin(SERIAL);
  221.             count++;
  222.             
  223.             if (count==BLOCKSIZE)
  224.             {
  225.                 write(f,rec_block,count);
  226.                 count=0;
  227.                 lz=rec_block;
  228.             }
  229.  
  230.             if(disc_ans[disc_ptr]==c)
  231.             {
  232.                 disc_ptr++;
  233.                 
  234.                 if(disc_ptr==10) /* DISCONNECT */
  235.                 {
  236.                   not_stopped=FALSE;
  237.                 }
  238.             }
  239.             else
  240.                 disc_ptr=0;
  241.  
  242.             if( zeros+lead_0[c]>=11 )
  243.                 eleven0=TRUE;
  244.             else
  245.             {
  246.                 if(c)
  247.                 {
  248.                     zeros=trail_0[c];
  249.                     eolns=0;
  250.                 }
  251.                 else
  252.                     zeros+=trail_0[c];
  253.             }
  254.             
  255.             if( (eleven0) && c)
  256.             {
  257.                 eleven0=FALSE;
  258.                 eolns++;
  259.                 zeros=trail_0[c];
  260.                 if(eolns>5)
  261.                 {
  262.                     status_line(msgtxt[M_FAX_RESULT], pages);
  263.                     pages++;
  264.                     eolns=0;
  265.                     
  266.                     if (count) /* gute Zeit den Puffer zu leeren */
  267.                     {
  268.                         write(f,rec_block,count);
  269.                         count=0;
  270.                         lz=rec_block;
  271.                     }
  272.                     
  273.                     carrier_da=TRUE;    /* zur Sicherheit */
  274.                     
  275.                     /* sind noch ein paar Bytes da? */
  276.                     while(Bconstat(SERIAL))
  277.                     {
  278.                         c=*lz++=(byte) Bconin(SERIAL);
  279.                     }
  280.  
  281.                     /* Nächste Seite mit DC2 anfordern 
  282.                     Bconout(SERIAL, ASC_DC2);
  283.                     get_response_quick_ltd(con_str, 4);
  284.                     if(!strchr(con_str,'/'))
  285.                     {
  286.                         Bconout(SERIAL, ASC_DC2);
  287.                         get_response_quick_ltd(con_str, 4);
  288.                     }
  289.                     */
  290.                 }/* ENDIF eop detected   */
  291.             }/* end: mal wieder ein EOL  */
  292.         } /* END es sind Bytes abzuholen */
  293.         else if(Bconstat(CONSOLE))
  294.         {
  295.             key=(int)Bconin(CONSOLE);
  296.             if(key=='h')
  297.             {
  298.                 Bconout(SERIAL, ASC_CAN);
  299.                 delay(5);
  300.                 send_command("ATH");  /* Aufhaengen */
  301.                 not_stopped=FALSE;
  302.             }
  303.         }
  304.         else /* sonst nix zu tun */
  305.         {
  306.             carrier = CARRIER;
  307.             /*Supexec(get_con);*/ /* setzt carrier true/false */
  308.             if(carrier)
  309.             {
  310.                 noca_time=time(NULL);
  311.                 carrier_da=TRUE;    
  312.                 /* kann das immer noch schiefgehen ??? */
  313.             }
  314.             else
  315.             {
  316.                 if(carrier_da)
  317.                 {
  318.                     carrier_da=FALSE;
  319.                     noca_time=time(NULL);
  320.                 }
  321.                 else
  322.                     if( (time(NULL)-noca_time)>NOCARRIERTO )
  323.                         not_stopped=FALSE;
  324.             }
  325.         }
  326.     } /* ende der receive-loop */
  327.  
  328.     /* DISCONNECT oder Carrier ist weg */
  329.     if(count>12)
  330.         count-=12;
  331.     else
  332.         count=0;
  333.  
  334.     if (count) /* Rest rausschreiben */
  335.     {
  336.         write(f,rec_block,count);
  337.     }
  338.  
  339.     get_resp_ra(disco_response, 2); /* rest of disconnect String */
  340.  
  341.     get_resp_ra(gpr, 3);            /* No carrier */
  342.  
  343.     status_line(msgtxt[M_FAX_RESULT], pages);
  344. }
  345.  
  346. void fill_header(void)
  347. {
  348.     int resolution, coding, rec_wid;
  349.     char *pos;
  350.  
  351.     strcpy(m_head.title,"ZyXEL");
  352.     m_head.version = 2;
  353.     m_head.reserved= 0;
  354.  
  355.     pos=memchr(con_str,'V',40);
  356.     if (pos)
  357.     {
  358.         pos++;             /* String is: VnTnRnLnCnPxxxxxxx... */
  359.         resolution=*pos++ & 0x01; /* vertical resolution */
  360.         pos++;             /* skip "T" */
  361.         coding=*pos++ & 0x01;       /* coding */
  362.         pos++;             /* skip "R" */
  363.         rec_wid=*pos++ & 0x03;    /* recording width */
  364.         switch(rec_wid)
  365.         {
  366.             case 1:
  367.                 m_head.page_wid=2048;
  368.                 break;
  369.                 
  370.             case 2:
  371.                 m_head.page_wid=2432;
  372.                 break;
  373.                 
  374.             case 0:
  375.             default:
  376.                 m_head.page_wid=1728;
  377.                 break;
  378.         }
  379.     }
  380.     else
  381.     {
  382.         m_head.page_wid=1728;
  383.         resolution=0;
  384.         coding=0;
  385.     }
  386.  
  387.     m_head.page_cnt= pages;
  388.     m_head.coding  = resolution | (coding<<1);
  389. }
  390.  
  391. void write_header(int out_f)
  392. {
  393.     int i;
  394.     byte *out_ptr;
  395.  
  396.     out_ptr=rec_block;
  397.  
  398.     for(i=0; i<6; i++)
  399.     {
  400.         *out_ptr++=m_head.title[i];
  401.     }
  402.  
  403.     *out_ptr++ = m_head.version & 0xFF;
  404.     *out_ptr++ = (m_head.version >> 8);
  405.     *out_ptr++ = m_head.reserved & 0xFF;
  406.     *out_ptr++ = m_head.reserved >> 8;
  407.     *out_ptr++ = m_head.page_wid & 0xFF;
  408.     *out_ptr++ = m_head.page_wid >> 8;
  409.     *out_ptr++ = m_head.page_cnt & 0xFF;
  410.     *out_ptr++ = m_head.page_cnt >> 8;
  411.     *out_ptr++ = m_head.coding & 0xFF;
  412.     *out_ptr++ = m_head.coding >> 8;
  413.  
  414.     write(out_f,rec_block,HEADERSIZE);
  415. }
  416.  
  417. int receive_fax(int out_file)
  418. {
  419.     int aborted=FALSE, faxconnect, nocarr;
  420.  
  421.     /* Faxconnect hat der Mailer schon festgestellt */
  422.     carrier = CARRIER;
  423.     /*Supexec(get_con);*/
  424.     faxconnect=carrier;
  425.     RTS_ON;
  426.     
  427.     if(Bconstat(SERIAL))
  428.     {
  429.         get_response_quick_ltd(con_str, 4);    /* und abholen */
  430.         status_line(msgtxt[M_FAX_DEBUG], con_str);
  431.     }
  432.     
  433.     if(faxconnect)
  434.     {
  435.         nocarr=TRUE;        /* hier verkehrt herum setzen */
  436.                             /* den "Rest" des Connect-Strings anfordern */
  437.  
  438. /*
  439.         Bconout(SERIAL, ASC_DC2);
  440.         get_response_quick_ltd(con_str, 4);
  441.         if(!strchr(con_str,'/'))
  442.         {
  443.             status_line(msgtxt[M_FAX_NOTZYXEL]);
  444.             faxconnect=FALSE;
  445.         }
  446. */
  447.     }
  448.     else
  449.     {
  450.         status_line(msgtxt[M_FAX_CLOST]);
  451.         nocarr=TRUE;
  452.         faxconnect=FALSE;
  453.     }
  454.  
  455.     if(!faxconnect && !nocarr) /* try it again */
  456.     {
  457.         get_response_quick(con_str, 4);
  458.         status_line(msgtxt[M_FAX_DEBUG], con_str);
  459.         faxconnect=!strncmp(con_str,"CONNECT FAX",11L);
  460.         nocarr=!(strncmp(con_str,"NO CARRIER",10));
  461.     }
  462.     
  463.     if(!faxconnect && !nocarr) /* and again */
  464.     {
  465.         get_response_quick(con_str, 4);
  466.         status_line(msgtxt[M_FAX_DEBUG], con_str);
  467.         faxconnect=!strncmp(con_str,"CONNECT FAX",11L);
  468.     }
  469.  
  470.     if(faxconnect)
  471.     {
  472.         pages=1;
  473.         
  474.         fill_header();
  475.         write_header(out_file); /* reserve space for header update */
  476.         receive(out_file);
  477.         /*hang_up();*/
  478.         fill_header();
  479.         
  480.         if(lseek(out_file, 0L, SEEK_SET))
  481.         {
  482.             status_line(msgtxt[M_FAX_UPDATEF]);
  483.         }
  484.         else
  485.             write_header(out_file);
  486.     }
  487.     else
  488.     {
  489.         status_line(msgtxt[M_FAX_NOCONNECT]);
  490.         aborted=TRUE;
  491.     }
  492.     
  493.     return aborted;
  494. }
  495.  
  496. int create_and_get(void)
  497. {
  498.     int rv=0, rec_fax_file;
  499.  
  500.     make_next_name();
  501.  
  502.     status_line(msgtxt[M_FAX_TRYING], curr_fn);  
  503.     
  504.     if( (rec_fax_file=open(curr_fn,O_WRONLY|O_TRUNC|O_CREAT)) > 0 )
  505.     {
  506.         rv=receive_fax(rec_fax_file);
  507.         close(rec_fax_file);
  508.         if(rv) remove(curr_fn);
  509.     }
  510.     else
  511.     {
  512.         status_line(msgtxt[M_FAX_CREATERROR]);
  513.         rv=-1;
  514.     }
  515.     
  516.     return rv;
  517. }
  518.  
  519. int fax_recieve( void )
  520. {
  521.     int mrv;
  522.   
  523.     mrv=0;
  524.  
  525.     build_tables();
  526.     
  527.     if( (rec_block=(byte *)malloc(BLOCKSIZE))==NULL)
  528.     { 
  529.         status_line(msgtxt[M_FAX_RAMERROR]);
  530.         return 0;
  531.     }
  532.  
  533.     status_line(msgtxt[M_FAX_STARTED]);
  534.     
  535.     create_and_get();
  536.  
  537.     status_line(msgtxt[M_FAX_STOPPED]);
  538.      
  539.     free(rec_block);
  540.     return mrv;
  541. }
  542.  
  543. /***************  Standard routines **************************************/
  544. void build_tables( void )
  545. {
  546.     int i, j, l0, t0;
  547.  
  548.     /* ist halt noch ne Initialisierung */  
  549.     /* mfp_reg_ptr=(byte *) 0xFFFA01L; */
  550.  
  551.     for(i=0;i<256;i++)
  552.     {
  553.         l0=t0=0;
  554.         
  555.         for(j=0;j<8;j++)
  556.             if( !(i & (0x80 >> j)))
  557.                 t0++;
  558.             else
  559.                 break;
  560.                 
  561.         for(j=0;j<8;j++)
  562.             if( !(i & (0x01 << j)))
  563.                 l0++;
  564.             else
  565.                 break;
  566.         
  567.         lead_0[i]=l0;
  568.         trail_0[i]=t0;
  569.     }
  570. }
  571.