home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / fax / ps250 / ps250_util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  12.4 KB  |  630 lines

  1. /* ps250_util.c: utility routines for Panasonic 250 fax machine */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/fax/ps250/RCS/ps250_util.c,v 6.0 1991/12/18 20:07:26 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/fax/ps250/RCS/ps250_util.c,v 6.0 1991/12/18 20:07:26 jpo Rel $
  9.  *
  10.  * $Log: ps250_util.c,v $
  11.  * Revision 6.0  1991/12/18  20:07:26  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15. #include    "util.h"
  16. #include    "retcode.h"
  17. #include    "qmgr.h"
  18. #include    "IOB-types.h"
  19. #include     <sys/stat.h>
  20. #include    <sys/termios.h>
  21. #ifdef SYS5        /* Can't use isode/sys.file.h due to termios.h */
  22. #include     <fcntl.h>
  23. #else
  24. #include     <sys/file.h>
  25. #endif
  26. #include    "../faxgeneric.h"
  27. #include     "ps250.h"
  28.  
  29. static int set_softcar();
  30. static void set_hardcar();
  31.  
  32. Trans    trans;
  33.  
  34. /*
  35.  *    Open and initialise fax device
  36.  */
  37.  
  38. openPsModem(psm)
  39. PsModem    *psm;
  40. {
  41.     static struct    termios tios;
  42.  
  43.     if ((psm->fd = open (psm->devName, O_RDWR, 0)) == NOTOK) {
  44.         PP_SLOG (LLOG_EXCEPTIONS,
  45.              psm->devName,
  46.              ("unable to open fax device"));
  47.         sprintf(psm->errBuf,
  48.             "Unable to open fax device '%s'",
  49.             psm->devName);
  50.         return NOTOK;
  51.     }
  52.     
  53.     /* initialise line parameters */
  54. /*    (void) ioctl (psm->fd, TIOCEXCL, 0); */
  55.     tios.c_iflag = 0;
  56.     tios.c_oflag = 0;
  57.     tios.c_cflag = B19200 | CS8 | CREAD | CSTOPB | PARENB | 
  58.         PARODD | CRTSCTS | HUPCL;
  59.     tios.c_lflag = 0;
  60.     tios.c_cc[VMIN] = 1;
  61.     if (ioctl (psm->fd, TCSETS, &tios) == NOTOK) {
  62.         PP_SLOG(LLOG_EXCEPTIONS, psm->devName,
  63.             ("ioctl failed"));
  64.         (void) close (psm->fd);
  65.         sprintf(psm->errBuf,
  66.             "Unable to initialise line parameters");
  67.         return NOTOK;
  68.     }
  69.     sleep(1);
  70.     if (psm->softcar == TRUE)
  71.         return set_softcar(psm);
  72.     return OK;
  73. }
  74.  
  75. /*
  76.  *    Close fax device
  77.  */
  78.  
  79. closePsModem (psm)
  80. PsModem    *psm;
  81. {
  82.     int val = TIOCM_DSR|TIOCM_DTR;
  83.  
  84.     if (psm->softcar == TRUE)
  85.         set_hardcar(psm);
  86.     (void) ioctl (psm->fd, TIOCMBIC, &val);
  87.     return close (psm->fd);
  88. }
  89.  
  90. /*
  91.  *    Initial fax device for Xmit
  92.  */
  93.  
  94. dialPsModem(psm, telno)
  95. PsModem    *psm;
  96. char    *telno;
  97. {
  98.         
  99.     trans.src_type = FAX_TYPE_MH;
  100.     trans.src_addr = FAX_MODE_PC;
  101.     trans.dst_type = FAX_TYPE_MH;
  102.     trans.param1 = psm->resolution;
  103.     trans.param2 = FAX_PARAM2_G3 | FAX_PARAM2_OTI_TOP |
  104.                 FAX_PARAM2_OTI_BOT | FAX_PARAM2_ECMON;
  105.  
  106.     if (psm->polled == TRUE)
  107.         trans.param2 |= FAX_PARAM2_POLLED;
  108.  
  109.     if (atoi(telno) == 0 && telno[0] != '+') {
  110.         PP_NOTICE(("printing fax locally"));
  111.         trans.telno[0] = 0;
  112.         trans.dst_addr = FAX_MODE_PRINTER;
  113.     } else {
  114.         PP_NOTICE(("faxing to %s",
  115.                telno));
  116.         strcpy(trans.telno, telno);
  117.         trans.dst_addr = FAX_MODE_REMOTE;
  118.     } 
  119.  
  120.     trans.remid[0] = 0;
  121.  
  122.     if (fax_trans_and_check (psm, &trans, FALSE) != OK)
  123.         return RP_MECH;
  124.     return OK;
  125. }
  126.  
  127. /*
  128.  *    Initial fax device for Listen
  129.  */
  130.  
  131. ps_init_listen(psm)
  132. PsModem    *psm;
  133. {
  134.         
  135.     trans.src_type = FAX_TYPE_MH;
  136.     trans.src_addr = (psm->scanner) ? FAX_MODE_SCANNER : FAX_MODE_REMOTE;
  137.     trans.dst_type = FAX_TYPE_MH;
  138.     trans.dst_addr = FAX_MODE_PC;
  139.     trans.param1 = psm->resolution;
  140.     trans.param2 = FAX_PARAM2_G3 | FAX_PARAM2_OTI_TOP |
  141.                 FAX_PARAM2_OTI_BOT | FAX_PARAM2_ECMON;
  142.  
  143.     if (psm->polled == TRUE)
  144.         trans.param2 |= FAX_PARAM2_POLLED;
  145.  
  146.     trans.telno[0] = 0;
  147.     trans.remid[0] = 0;
  148.  
  149.     if (fax_trans_and_check (psm, &trans, TRUE) != OK)
  150.         return RP_MECH;
  151.     return OK;
  152. }
  153.  
  154. /*
  155.  *    software carrier detect switching routines
  156.  */
  157.  
  158. static int set_softcar (psm)
  159. PsModem    *psm;
  160. {
  161.     int    softcar;
  162.     
  163.     if (psm->softcar != TRUE)
  164.         return OK;
  165.  
  166.     if (ioctl (psm->fd, TIOCGSOFTCAR, &softcar) == -1) {
  167.         PP_SLOG (LLOG_EXCEPTIONS, psm->devName,
  168.              ("ioctl(TIOCGSOFTCAR) failed"));
  169.         sprintf(psm->errBuf,
  170.             "ioctl(TIOCGSOFTCAR) failed");
  171.         return NOTOK;
  172.     }
  173.  
  174.     if (softcar == 0) {
  175.         /* need to switch on softcar */
  176.         softcar = 1;
  177.         if (ioctl (psm->fd, TIOCSSOFTCAR, &softcar) == -1) {
  178.             PP_SLOG(LLOG_EXCEPTIONS, psm->devName,
  179.                 ("ioctl(TIOCSSOFTCAR) failed"));
  180.             sprintf(psm->errBuf,
  181.                 "ioctl(TIOCSSOFTCAR) failed");
  182.             return NOTOK;
  183.         }
  184.     }
  185.     return OK;
  186. }
  187.  
  188. static void set_hardcar(psm)
  189. PsModem    *psm;
  190. {
  191.     int    softcar;
  192.     
  193.     if (psm->softcar != TRUE)
  194.         return;
  195.     
  196.     if (ioctl (psm->fd, TIOCGSOFTCAR, &softcar) == -1) {
  197.         PP_SLOG(LLOG_EXCEPTIONS, psm->devName,
  198.             ("ioctl(TIOCGSOFTCAR) failed"));
  199.         return;
  200.     }
  201.     
  202.     if (softcar == 1) {
  203.         /* need to switch off softcar */
  204.         softcar = 0;
  205.         if (ioctl (psm->fd, TIOCSSOFTCAR, &softcar) == -1)
  206.             PP_SLOG(LLOG_EXCEPTIONS, psm->devName,
  207.                 ("ioctl(TIOCSSOFTCAR) failed"));
  208.     }
  209. }
  210.  
  211. /*
  212.  *    Abort a fax
  213.  */
  214.  
  215. abortPsModem (psm)
  216. PsModem    *psm;
  217. {
  218.     Stat1    st1;
  219.     fax_sendstop(psm->fd);
  220.     fax_getstat1(psm->fd, &st1);
  221. }
  222.  
  223. /*
  224.  * wait for end of transmission
  225.  */
  226.  
  227. eomPsModem(psm)
  228. PsModem    *psm;
  229. {
  230.     Stat1    st1;
  231.     int    cont = TRUE;
  232.     while (cont == TRUE) {
  233.         if (fax_sendenq1(psm->fd) == NOTOK) {
  234.             sprintf(psm->errBuf,
  235.                 "sendenq1 failed");
  236.             PP_LOG(LLOG_EXCEPTIONS,
  237.                    ("%s", psm->errBuf));
  238.             return NOTOK;
  239.         }
  240.         cont = FALSE;
  241.         switch (fax_getresp(psm->fd, &st1)) {
  242.             case RESP_STAT1:
  243.             switch (get_job_info(st1.job_info)) {
  244.                 case JOB_NORM_END:
  245.                 break;
  246.                 case JOB_FAULT_JOB_END:
  247.                 case JOB_LINE_DISC:
  248.                 sprintf(psm->errBuf,
  249.                     "bad termination from fax");
  250.                 abortPsModem(psm);
  251.                 return NOTOK;
  252.                 case JOB_IN:
  253.                 cont = TRUE;
  254.                 break;
  255.                 default:
  256.                 sprintf(psm->errBuf,
  257.                     "unknown termination from fax %o",
  258.                     st1.job_info);
  259.                 PP_LOG(LLOG_EXCEPTIONS,
  260.                        ("%s", psm->errBuf));
  261.                 return NOTOK;
  262.             }
  263.             default:
  264.             break;
  265.         }
  266.         if (cont == TRUE)
  267.             sleep(1);
  268.     }
  269.     return OK;
  270. }
  271.  
  272. /*
  273.  *    Initialise modem for fax transmission
  274.  */
  275.  
  276. static int reinit_fax (fd, trans, src_type, dst_type, param1)
  277. int    fd;
  278. Trans    *trans;
  279. char    src_type;
  280. char    dst_type;
  281. int    param1;
  282. {
  283.     if (src_type != trans->src_type
  284.         || dst_type != trans -> dst_type
  285.         || param1 != trans -> param1) {
  286.         /* have to change type */
  287.         trans->src_type = src_type;
  288.         trans->dst_type = dst_type;
  289.         trans -> param1 = param1;
  290.         
  291.         if (fax_move_and_check(fd, trans) == NOTOK) 
  292.             return NOTOK;
  293.     }
  294.     return OK;
  295. }
  296.  
  297. psModemG3init (psm)
  298. PsModem    *psm;
  299. {
  300.     if (reinit_fax(psm->fd, &trans,
  301.                FAX_TYPE_MH, FAX_TYPE_MH, psm->resolution) != OK) {
  302.         sprintf(psm->errBuf,
  303.             "initialise failed");
  304.         PP_LOG(LLOG_EXCEPTIONS,
  305.                ("%s", psm->errBuf));
  306.         return NOTOK;
  307.     }
  308.     return OK;
  309. }
  310.  
  311. /*
  312.  *    Initialise modem for ia5 transmission
  313.  */
  314.  
  315. psModemIA5init (psm)
  316. PsModem    *psm;
  317. {
  318.     if (reinit_fax(psm->fd, &trans,
  319.                FAX_TYPE_ASCII, FAX_TYPE_RASTER, 
  320.                psm->resolution) != OK) {
  321.         sprintf(psm->errBuf,
  322.             "initialise failed");
  323.         PP_LOG(LLOG_EXCEPTIONS,
  324.                ("%s", psm->errBuf));
  325.         return NOTOK;
  326.     }
  327.     return OK;
  328. }
  329.     
  330. /*
  331.  *    Send page of bits to fax modem
  332.  */
  333.  
  334. extern int num_sent;
  335.  
  336. sendPsModem (psm, str, len, last)
  337. PsModem    *psm;
  338. char    *str;
  339. int    len;
  340. int    last;
  341. {
  342.     char    *ix;
  343.     int    sendflag, sendlen;
  344.     
  345.     sendflag = sendlen = num_sent = 0;
  346.     ix = str;
  347.     while (ix - str < len && sendflag == 0) {
  348.         sendlen = ((ix + MAXDATASIZ) > (str + len)) ?
  349.             len - (ix - str) : MAXDATASIZ;
  350.         if (ix - str + sendlen >= len) {
  351.             /* last bit of page */
  352.             if (last)
  353.                 sendflag = FAX_WRITE_EOF | FAX_WRITE_EOP;
  354.             else
  355.                 sendflag = FAX_WRITE_EOP;
  356.         } else
  357.             sendflag = 0;
  358.         if (fax_write_and_check (psm, ix, 
  359.                      sendlen, sendflag) != OK) {
  360.             sprintf(psm->errBuf,
  361.                 "fax_write_and_check failed");
  362.             PP_LOG(LLOG_EXCEPTIONS,
  363.                    ("%s", psm->errBuf));
  364.             return NOTOK;
  365.         }
  366.         if (sendflag) {
  367.             if (last)
  368.                 PP_LOG(LLOG_NOTICE,
  369.                        ("EOF (%d sent)", num_sent));
  370.             else
  371.                 PP_LOG(LLOG_NOTICE,
  372.                        ("EOP (%d sent)", num_sent));
  373.         }
  374.         ix += sendlen;
  375.     }
  376.     return OK;
  377. }
  378.  
  379. /*
  380.  *    Send file of IA5 to fax modem
  381.  */
  382.  
  383. sendPsModemIA5 (psm, fp, last)
  384. PsModem    *psm;
  385. FILE    *fp;
  386. int    last;
  387. {
  388.     int    n, numLines, LinesPerA4 = 24*3;
  389.     char    buf[250];
  390.  
  391.     numLines = 0;
  392.  
  393.     while (fgets (buf, sizeof(buf), fp) != NULLCP) {
  394.         if (feof(fp))
  395.             break;
  396.         n = strlen(buf);
  397.         if (n < sizeof(buf)) {
  398.             buf[n++] = '\r';
  399.             if (n < sizeof(buf))
  400.                 buf[n++] = '\0';
  401.             n = strlen(buf);
  402.         }
  403.         if (fax_write_and_check (psm, buf, n,
  404.                      (++numLines == LinesPerA4) ? FAX_WRITE_EOP : 0) != OK) {
  405.             sprintf(psm->errBuf,
  406.                 "fax_write_and_check failed");
  407.             PP_LOG(LLOG_EXCEPTIONS,
  408.                    ("%s", psm->errBuf));
  409.             return NOTOK;
  410.         }
  411.         if (numLines == LinesPerA4) numLines = 0;
  412.     }
  413.     /* fillout last page */
  414.     n = 0;
  415.     while (numLines++ < LinesPerA4) {
  416.         buf[n++] = '\n';
  417.         buf[n++] = '\r';
  418.     }
  419.     if (n == 0)
  420.         buf[n++] = ' ';
  421.     buf[n] = '\0';
  422.     if (fax_write_and_check (psm, buf, n,
  423.                  (last) ? (FAX_WRITE_EOP | FAX_WRITE_EOF) : FAX_WRITE_EOP) != OK) {
  424.         sprintf(psm->errBuf,
  425.             "fax_write_and_check failed");
  426.         PP_LOG(LLOG_EXCEPTIONS,
  427.                ("%s", psm->errBuf));
  428.         return NOTOK;
  429.     }
  430.     return OK;
  431. }
  432.  
  433. /*   */
  434.  
  435. /* loop waiting for inbound fax */
  436. ps_wait_for_fax (psm)
  437. PsModem    *psm;
  438. {
  439.     Stat1    st1;
  440.     int    cont = TRUE;
  441.  
  442.     do {
  443.         if (fax_sendenq1(psm->fd) == NOTOK) {
  444.             sprintf(psm->errBuf,
  445.                 "sendenq1 failed");
  446.             PP_LOG(LLOG_EXCEPTIONS,
  447.                    ("%s", psm->errBuf));
  448.             return NOTOK;
  449.         }
  450.         
  451.         if (fax_getresp (psm->fd, &st1) == NOTOK) {
  452.             sprintf(psm->errBuf,
  453.                 "bad response from fax");
  454.             PP_LOG(LLOG_EXCEPTIONS,
  455.                    ("%s", psm->errBuf));
  456.             return NOTOK;
  457.         }
  458.  
  459.         if (st1.ring_in == RING_IN) {
  460.             psm->scanner = FALSE;
  461.             cont = FALSE;
  462.         } else if ((st1.scan_stat & SCAN_DOC_SCAN) == SCAN_DOC_SCAN) {
  463.             psm->scanner = TRUE;
  464.             cont = FALSE;
  465.         }
  466.         
  467.         if (cont == TRUE)
  468.             sleep(1);
  469.     } while (cont == TRUE);
  470.     return OK;
  471. }
  472.  
  473. /*   */
  474.  
  475. /* loop waiting for inbound data */
  476. ps_wait_for_data (psm)
  477. PsModem    *psm;
  478. {
  479.     Stat1    st1;
  480.  
  481.     if (fax_getresp (psm->fd, &st1) == NOTOK) {
  482.         sprintf(psm->errBuf,
  483.             "bad response from fax");
  484.         PP_LOG(LLOG_EXCEPTIONS,
  485.                ("%s", psm->errBuf));
  486.         return NOTOK;
  487.     }
  488.     
  489.     while (get_job_info(st1.job_info) != JOB_DATA_AVAIL) {
  490.         sleep (1);
  491.         
  492.         if (fax_sendenq1(psm->fd) == NOTOK) {
  493.             sprintf(psm->errBuf,
  494.                 "sendenq1 failed");
  495.             PP_LOG(LLOG_EXCEPTIONS,
  496.                    ("%s", psm->errBuf));
  497.             return NOTOK;
  498.         }
  499.         
  500.  
  501.         if (fax_getresp (psm->fd, &st1) == NOTOK) {
  502.             sprintf(psm->errBuf,
  503.                 "bad response from fax");
  504.             PP_LOG(LLOG_EXCEPTIONS,
  505.                    ("%s", psm->errBuf));
  506.             return NOTOK;
  507.         }
  508.     }
  509.  
  510.     return OK;
  511. }
  512.         
  513. /*   */
  514. /* receive data from fax */
  515.  
  516. rcvPsModem(psm, pg3fax)
  517. PsModem    *psm;
  518. struct type_IOB_G3FacsimileBodyPart    **pg3fax;
  519. {
  520.     struct type_IOB_G3FacsimileBodyPart *ret = (struct type_IOB_G3FacsimileBodyPart *) 
  521.         calloc (1, sizeof (struct type_IOB_G3FacsimileBodyPart));
  522.     struct type_IOB_G3FacsimileData    *ix, *t = NULL;
  523.     int    retval, last;
  524.  
  525.     ret -> parameters = (struct type_IOB_G3FacsimileParameters *)
  526.         calloc(1, sizeof(struct type_IOB_G3FacsimileParameters));
  527.     ret -> parameters -> optionals =
  528.         opt_IOB_G3FacsimileParameters_number__of__pages;
  529.     
  530.     do {
  531.         if ((retval = rcvPsPage(psm, &ix, &last)) != OK)
  532.             return retval;
  533.         if (ret->data == NULL)
  534.             ret -> data = t = ix;
  535.         else {
  536.             t -> next = ix;
  537.             t = ix;
  538.         }
  539.         ret -> parameters -> number__of__pages++;
  540.     } while (last != TRUE);
  541.     *pg3fax = ret;
  542.     return retval;
  543. }
  544.  
  545. /*   */
  546. /* receive page from fax */
  547.  
  548. static void add_to_strb(pstr, ptotal, plus, len)
  549. char    **pstr;
  550. int    *ptotal;
  551. char    *plus;
  552. int    len;
  553. {
  554.     char    *ret;
  555.  
  556.     if (*pstr == NULLCP)
  557.         ret = malloc(len * sizeof(char));
  558.     else
  559.         ret = realloc(*pstr, (len+(*ptotal)) * sizeof(char));
  560.     
  561.     bcopy (plus, (ret + (*ptotal)), len);
  562.     *ptotal += len;
  563.     *pstr = ret;
  564. }
  565.  
  566. rcvPsPage(psm, pdata, plast)
  567. PsModem    *psm;
  568. struct type_IOB_G3FacsimileData **pdata;
  569. int    *plast;
  570. {
  571.     Stat1    st1;
  572.     Data    data;
  573.     int    cont, total;
  574.     char    *str = NULLCP;
  575.  
  576.     *pdata = (struct type_IOB_G3FacsimileData *) NULL;
  577.     *plast = FALSE;
  578.     cont = TRUE;
  579.     total = 0;
  580.  
  581.     do {
  582.         if (fax_read_and_check(psm, &data) == NOTOK)
  583.             return NOTOK;
  584.         reverse_strb(data.data, data.datalen);
  585.         add_to_strb(&str, &total, data.data, data.datalen);
  586.         if (data.docEnd)
  587.             *plast = TRUE;
  588.         if (data.pageEnd)
  589.             cont = FALSE;
  590.         if (cont == TRUE) {
  591.             if (fax_sendenq1(psm->fd) == NOTOK) {
  592.                 sprintf(psm->errBuf,
  593.                     "sendenq1 failed");
  594.                 PP_LOG(LLOG_EXCEPTIONS,
  595.                        ("%s", psm->errBuf));
  596.                 if (str != NULLCP) free(str);
  597.                 return NOTOK;
  598.             }
  599.             if (fax_getresp (psm->fd, &st1) == NOTOK) {
  600.                 sprintf(psm->errBuf,
  601.                     "Bad response from fax");
  602.                 PP_LOG(LLOG_EXCEPTIONS,
  603.                        ("%s", psm->errBuf));
  604.                 if (str != NULLCP) free(str);
  605.                 return NOTOK;
  606.             }
  607.             if (get_job_info(st1.job_info) != JOB_DATA_AVAIL) {
  608.                 sprintf(psm->errBuf,
  609.                     "No data waiting to be read");
  610.                 PP_LOG(LLOG_EXCEPTIONS,
  611.                        ("%s", psm->errBuf));
  612.                 if (str != NULLCP) free(str);
  613.                 return NOTOK;
  614.             }
  615.         }
  616.     } while (cont == TRUE);
  617.     
  618.     if (str != NULLCP) {
  619.         *pdata = (struct type_IOB_G3FacsimileData *) 
  620.             malloc(sizeof(struct type_IOB_G3FacsimileData));
  621.         (*pdata) -> element_IOB_0 = 
  622.             strb2bitstr (str, (total * BITSPERBYTE), 
  623.                      PE_CLASS_UNIV,
  624.                      PE_PRIM_BITS);
  625.         (*pdata) -> next = NULL;
  626.         free (str);
  627.     }
  628.     return OK;
  629. }
  630.