FaxSend.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:38k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: FaxSend.c++,v 1.18 2008/01/12 20:00:18 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1990-1996 Sam Leffler
  4.  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
  5.  * HylaFAX is a trademark of Silicon Graphics
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. #include <errno.h>
  27. #include "Sys.h"
  28. #include "Dispatcher.h"
  29. #include "tiffio.h"
  30. #include "FaxServer.h"
  31. #include "FaxMachineInfo.h"
  32. #include "FaxRecvInfo.h"
  33. #include "FaxAcctInfo.h"
  34. #include "faxApp.h" // XXX
  35. #include "UUCPLock.h"
  36. #include "t.30.h"
  37. #include "config.h"
  38. #define BATCH_FIRST 1
  39. #define BATCH_LAST  2
  40. /*
  41.  * FAX Server Transmission Protocol.
  42.  */
  43. void
  44. FaxServer::sendFax(FaxRequest& fax, FaxMachineInfo& clientInfo, FaxAcctInfo& ai, u_int& batched, bool usedf)
  45. {
  46.     useDF = usedf;
  47.     u_int prevPages = fax.npages;
  48.     if (!(batched & BATCH_FIRST) || lockModem()) {
  49.         if (batched & BATCH_FIRST)
  50. {
  51.     beginSession(fax.number);
  52.     batchid = getCommID();
  53. } else
  54. {
  55.     if (! batchLogs)
  56.     {
  57. beginSession(fax.number);
  58. batchid.append("," | getCommID());
  59. traceServer("SESSION BATCH %s", (const char*) batchid);
  60.     }
  61.         }
  62. fax.commid = getCommID(); // set by beginSession
  63. traceServer("SEND FAX: JOB %s DEST %s COMMID %s DEVICE '%s' FROM '%s <%s>' USER %s"
  64.     , (const char*) fax.jobid
  65.     , (const char*) fax.external
  66.     , (const char*) fax.commid
  67.     , (const char*) getModemDevice()
  68.     , (const char*) fax.sender
  69.     , (const char*) fax.mailaddr
  70.     , (const char*) fax.owner
  71. );
  72. /* Dispatcher already did setupModem() */
  73. changeState(SENDING);
  74. IOHandler* handler =
  75.     Dispatcher::instance().handler(
  76. getModemFd(), Dispatcher::ReadMask);
  77. if (handler)
  78.     Dispatcher::instance().unlink(getModemFd());
  79. setServerStatus("Sending job " | fax.jobid);
  80. /*
  81.  * Construct the phone number to dial by applying the
  82.  * dialing rules to the user-specified dialing string.
  83.  */
  84. sendFax(fax, clientInfo, prepareDialString(fax.number), batched);
  85. if ((batched & BATCH_LAST) || (fax.status != send_done)) {
  86.     /*
  87.      * Because some modems are impossible to safely hangup in the
  88.      * event of a problem, we force a close on the device so that
  89.      * the modem will see DTR go down and (hopefully) clean up any
  90.      * bad state its in.  We then wait a couple of seconds before
  91.      * trying to setup the modem again so that it can have some
  92.      * time to settle.  We want a handle on the modem so that we
  93.      * can be prepared to answer incoming phone calls.
  94.      */
  95.     discardModem(true);
  96.     changeState(MODEMWAIT, 5);
  97.     unlockModem();
  98.     endSession();
  99. } else if(! batchLogs)
  100. {
  101.     traceServer("SESSION BATCH CONTINUES");
  102.     endSession();
  103. }
  104.     } else {
  105. if (state != LOCKWAIT)
  106.     sendFailed(fax, send_retry,
  107. "Can not lock modem device", 2*pollLockWait);
  108. if (state != SENDING && state != ANSWERING && state != RECEIVING)
  109.     changeState(LOCKWAIT, pollLockWait);
  110.     }
  111.     /*
  112.      * Record transmit accounting information for caller.
  113.      *
  114.      * As the encoded parameters is limited to 32 bits and DCS does
  115.      * not contain V.34-Fax speeds we use both.
  116.      */
  117.     ai.npages = fax.npages - prevPages; // count of pages transmitted
  118.     ai.params = clientParams.encode(); // encoded negotiated parameters
  119.     clientParams.asciiEncode(ai.faxdcs); // DCS signal
  120.     fax.sigrate = clientParams.bitRateName(); // (last) signalling rate used
  121.     fax.df = clientParams.dataFormatName(); // negotiated data format
  122. }
  123. void
  124. FaxServer::sendFailed(FaxRequest& fax, FaxSendStatus stat, const char* notice, u_int tts)
  125. {
  126.     fax.status = stat;
  127.     fax.notice = notice;
  128.     /*
  129.      * When requeued for the default interval (called with 3 args),
  130.      * don't adjust the time-to-send field so that the spooler
  131.      * will set it according to the default algorithm that 
  132.      * uses the command-line parameter or requeueOther and a random jitter.
  133.      */
  134.     if (tts != 0)
  135. fax.tts = Sys::now() + tts;
  136.     traceServer("SEND FAILED: JOB %s DEST %s ERR %s"
  137. , (const char*) fax.jobid
  138. , (const char*) fax.external
  139. , (const char*) notice
  140.     );
  141. }
  142. /*
  143.  * Send the specified TIFF files to the FAX
  144.  * agent at the given phone number.
  145.  */
  146. void
  147. FaxServer::sendFax(FaxRequest& fax, FaxMachineInfo& clientInfo, const fxStr& number, u_int& batched)
  148. {
  149.     connTime = 0; // indicate no connection
  150.     fxStr notice;
  151.     /*
  152.      * Calculate initial page-related session parameters so
  153.      * that braindead Class 2 modems which ignore AT+FIS can constrain
  154.      * the modem with AT+FCC before dialing the telephone, and so that
  155.      * Class 1.0 modems know to not enable V.34 support if ECM is not
  156.      * being used.  Hopefully this doesn't interfere with batched faxes.
  157.      */
  158.     clientParams.decodePage(fax.pagehandling);
  159.     /*
  160.      * So we want to restrict DF selection to those masked in fax.desireddf
  161.      */
  162.     clientParams.df = fxmin(modem->getBestDataFormat(), (u_int)fax.desireddf);
  163.     clientParams.br = fxmin(modem->getBestSignallingRate(), (u_int) fax.desiredbr);
  164.     clientParams.ec = (modem->supportsECM() ? fax.desiredec : EC_DISABLE);
  165.     clientParams.st = fxmax(modem->getBestScanlineTime(), (u_int) fax.desiredst);
  166.     clientParams.bf = BF_DISABLE;
  167.     /*
  168.      * Force the modem into the appropriate class
  169.      * used to send facsimile.  We do this before
  170.      * doing any fax-specific operations such as
  171.      * requesting polling.
  172.      */
  173.     if ((batched & BATCH_FIRST) &&
  174. !modem->faxService(!clientInfo.getHasV34Trouble() && clientParams.ec != EC_DISABLE && clientParams.br > BR_14400,
  175.     !clientInfo.getHasV17Trouble() && clientParams.br > BR_9600)) {
  176. sendFailed(fax, send_failed, "Unable to configure modem for fax use");
  177. return;
  178.     }
  179.     /*
  180.      * Check if this job includes a poll request, and
  181.      * if it does, inform the modem in case it needs to
  182.      * do something to get back status about whether or
  183.      * not documents are available for retrieval.
  184.      */
  185.     if (fax.findItem(FaxRequest::send_poll) != fx_invalidArrayIndex &&
  186. !modem->requestToPoll(notice)) {
  187. sendFailed(fax, send_failed, notice);
  188. return;
  189.     }
  190.     if (!modem->sendSetup(fax, clientParams, notice)) {
  191. sendFailed(fax, send_failed, notice);
  192. return;
  193.     }
  194.     if (tiff2faxCmd.length() && (class2RTFCC || softRTFCC)) {
  195. /*
  196.  * Here we enable "intelligent" RTFCC format selection by 
  197.  * determining the effectiveness of 2-D encoding.  We take all 
  198.  * fax items and convert them to both MH (1-D) and MMR (2-D).  
  199.  * Then we can sum up the data sizes and later make a decision 
  200.  * based on receiver support for which compression format will 
  201.  * be optimal.
  202.  */
  203. formatSize[0] = formatSize[1] = 0;
  204. const char* argv[7];
  205. argv[0] = (const char*) tiff2faxCmd;
  206. argv[1] = "-S";
  207. argv[3] = "-o";
  208. argv[6] = NULL;
  209. char pidstr[6];
  210. snprintf(pidstr, sizeof(pidstr), "%u", (u_int) getpid());
  211. fxStr newfile, ext, opt;
  212. struct stat sb;
  213. for (u_int i = 0, n = fax.items.length(); i < n; i++) {
  214.     if (fax.items[i].op == FaxRequest::send_fax) {
  215. argv[5] = (const char*) fax.items[i].item;
  216. for (u_short j = 0; j < 2; j++) {
  217.     switch (j) {
  218. case 0: opt = "-1"; ext = ".MH."; break;
  219. case 1: opt = "-3"; ext = ".MMR."; break;
  220.     }
  221.     argv[2] = (const char*) opt;
  222.     newfile = fax.items[i].item;
  223.     newfile.append(ext);
  224.     newfile.append(pidstr);
  225.     argv[4] = (const char*) newfile;
  226.     pid_t pid = fork();
  227.     switch (pid) {
  228. case 0:
  229.     Sys::execv((const char*) tiff2faxCmd, (char* const*) argv);
  230.     sleep(1); // XXX give parent time
  231.     _exit(127);
  232. case -1:
  233.     break;
  234. default:
  235.     Sys::waitpid(pid);
  236.     break;
  237.     }
  238.     if (Sys::stat(newfile, sb) < 0) {
  239. logError("Could not create %s, result: %s", (const char*) newfile, strerror(errno));
  240. break;
  241.     }
  242.     formatSize[j] += sb.st_size;
  243.     /*
  244.      * In theory we could leave these files around for other faxsend processes
  245.      * (if we didn't use the pid in the filename) or to use instead of performing 
  246.      * RTFCC.  But CPU is usually cheap, and for now it's easier to just delete 
  247.      * these here rather than having to keep track of cleaning up elsewhere.
  248.      */
  249.     Sys::unlink((const char*) newfile);
  250. }
  251.     }
  252. }
  253. if (formatSize[0] < formatSize[1])
  254.     traceProtocol("1-D encoding outperforms 2-D by %d%%. Prefer MH format.", 
  255. (formatSize[1]-formatSize[0])*100/formatSize[1]);
  256.     }
  257.     fax.notice = "";
  258.     notifyCallPlaced(fax);
  259.     CallStatus callstat;
  260.     if (batched & BATCH_FIRST)
  261. callstat = modem->dial(number, fax.faxnumber, notice);
  262.     else
  263. callstat = ClassModem::OK;
  264.     if (callstat == ClassModem::OK)
  265. connTime = Sys::now(); // connection start time
  266.     (void) abortRequested(); // check for user abort
  267.     if (callstat == ClassModem::OK && !abortCall) {
  268. /*
  269.  * Call reached a fax machine.  Check remote's
  270.  * capabilities against those required by the
  271.  * job and setup for transmission.
  272.  */
  273. fax.ndials = 0; // consec. failed dial attempts
  274. fax.tottries++; // total answered calls
  275. fax.totdials++; // total attempted calls
  276. clientInfo.setCalledBefore(true);
  277. clientInfo.setDialFailures(0);
  278. modem->sendBegin();
  279. bool remoteHasDoc = false;
  280. notifyConnected(fax);
  281. FaxSendStatus status = modem->getPrologue(
  282.     clientCapabilities, remoteHasDoc, notice, batched);
  283. if (status != send_ok) {
  284.     sendFailed(fax, status, notice, requeueProto);
  285. } else {
  286.     // CSI
  287.     fxStr csi("<UNSPECIFIED>");
  288.     (void) modem->getSendCSI(csi);
  289.     clientInfo.setCSI(csi); // record remote CSI
  290.     fax.csi = csi; // store in queue file also for notify
  291.     // NSF
  292.     NSF nsf;
  293.     (void) modem->getSendNSF(nsf);
  294.     clientInfo.setNSF(nsf.getHexNsf()); // record remote NSF
  295.     fax.nsf = fxStr::format("Equipment:%s %s:Station:%s", nsf.getVendor(), nsf.getModel(), nsf.getStationId());
  296.     // DIS
  297.     fxStr clientdis;
  298.     clientCapabilities.asciiEncode(clientdis);
  299.     clientInfo.setDIS(clientdis);
  300.     // modem used
  301.     fax.modemused = getModemDeviceID(); // store in queue file also for notify
  302.     if (!sendClientCapabilitiesOK(fax, clientInfo, notice)) {
  303. // NB: mark job completed 'cuz there's no way recover
  304. sendFailed(fax, send_failed, notice);
  305.     } else {
  306. modem->sendSetupPhaseB(fax.passwd, fax.subaddr);
  307. /*
  308.  * Group 3 protocol forces any sends to precede any polling.
  309.  */
  310. fax.status = send_failed;
  311. bool dosetup = true;
  312. while (fax.items.length() > 0) { // send operations
  313.     u_int i = fax.findItem(FaxRequest::send_fax);
  314.     if (i == fx_invalidArrayIndex)
  315. break;
  316.     FaxItem& freq = fax.items[i];
  317.     traceProtocol("SEND file "%s"", (const char*) freq.item);
  318.     fileStart = pageStart = Sys::now();
  319.     if (!sendFaxPhaseB(fax, freq, clientInfo, batched, dosetup)) {
  320. /*
  321.  * Prevent repeated batching errors.
  322.  */
  323. if (fax.status == send_batchfail) {
  324.     fax.status = send_retry;
  325.     clientInfo.setSupportsBatching(false);
  326.     batched |= BATCH_LAST;
  327. }
  328. /*
  329.  * Prevent repeated V.34 errors.
  330.  */ 
  331. if (fax.status == send_v34fail) {
  332.     fax.status = send_retry;
  333.     clientInfo.setHasV34Trouble(true);
  334. }
  335. /*
  336.  * Prevent repeated V.17 errors.
  337.  */ 
  338. if (fax.status == send_v17fail) {
  339.     fax.status = send_retry;
  340.     clientInfo.setHasV17Trouble(true);
  341. }
  342. /*
  343.  * On protocol errors retry more quickly
  344.  * (there's no reason to wait is there?).
  345.  */
  346. if (fax.status == send_retry ||
  347.   fax.status == send_reformat)
  348.     fax.tts = time(0) + requeueProto;
  349. break;
  350.     }
  351.     /*
  352.      * The file was delivered, notify the server.
  353.      * Note that a side effect of the notification
  354.      * is that this file is deleted from the set of
  355.      * files to send (so that it's not sent again
  356.      * if the job is requeued).  This is why we call
  357.      * find again at the top of the loop
  358.      */
  359.     notifyDocumentSent(fax, i);
  360.     dosetup = false;
  361. }
  362. fax.nocountcover = modem->getNoCountCoverPages(); // update it
  363. if ((fax.status == send_done || dosetup) &&
  364.       fax.findItem(FaxRequest::send_poll) != fx_invalidArrayIndex)
  365.     sendPoll(fax, remoteHasDoc);
  366.     }
  367. }
  368. if ((batched & BATCH_LAST) || (fax.status != send_done))
  369.     modem->sendEnd();
  370. if (fax.status != send_done) {
  371.     clientInfo.setSendFailures(clientInfo.getSendFailures()+1);
  372.     clientInfo.setLastSendFailure(fax.notice);
  373. } else
  374.     clientInfo.setSendFailures(0);
  375.     } else if (!abortCall) {
  376. /*
  377.  * Analyze the call status codes and selectively decide if the
  378.  * job should be retried.  We try to avoid the situations where
  379.  * we might be calling the wrong number so that we don't end up
  380.  * harrassing someone w/ repeated calls.
  381.  */
  382. fax.ndials++; // number of consecutive failed calls
  383. fax.totdials++; // total attempted calls
  384. switch (callstat) {
  385. case ClassModem::NOFCON: // carrier seen, but handshake failed
  386.     clientInfo.setCalledBefore(true);
  387.     /* fall thru... */
  388. case ClassModem::DATACONN: // data connection established
  389. case ClassModem::NOCARRIER: // no carrier detected on remote side
  390. case ClassModem::BUSY: // busy signal
  391. case ClassModem::NOANSWER: // no answer or ring back
  392.     if (!clientInfo.getCalledBefore() && fax.ndials > retryMAX[callstat])
  393. sendFailed(fax, send_failed, notice);
  394.     else if (fax.retrytime != 0)
  395. sendFailed(fax, send_retry, notice, fax.retrytime);
  396.     else
  397. sendFailed(fax, send_retry, notice, requeueTTS[callstat]);
  398.     break;
  399. case ClassModem::NODIALTONE: // no local dialtone, possibly unplugged
  400. case ClassModem::ERROR: // modem might just need to be reset
  401. case ClassModem::FAILURE: // modem returned something unexpected
  402.     if (!clientInfo.getCalledBefore() && fax.ndials > retryMAX[callstat])
  403. sendFailed(fax, send_failed, notice);
  404.     else
  405. sendFailed(fax, send_retry, notice, requeueTTS[callstat]);
  406.     break;
  407. case ClassModem::OK: // call was aborted by user
  408.     break;
  409. }
  410. if (callstat != ClassModem::OK) {
  411.     clientInfo.setDialFailures(clientInfo.getDialFailures()+1);
  412.     clientInfo.setLastDialFailure(fax.notice);
  413. }
  414.     }
  415.     if (abortCall)
  416. sendFailed(fax, send_retry, "Call aborted by user");
  417.     else if (fax.status == send_retry) {
  418. if (fax.totdials == fax.maxdials) {
  419.     notice = fax.notice | "; too many attempts to dial";
  420.     sendFailed(fax, send_failed, notice);
  421. } else if (fax.tottries == fax.maxtries) {
  422.     notice = fax.notice | "; too many attempts to send";
  423.     sendFailed(fax, send_failed, notice);
  424. }
  425.     }
  426.     if ((batched & BATCH_LAST) || (fax.status != send_done)) {
  427. /*
  428.  * Cleanup after the call.  If we have new information on
  429.  * the client's remote capabilities, the machine info
  430.  * database will be updated when the instance is destroyed.
  431.  *
  432.  * We wait a second to prevent any hangup signal from 
  433.  * precluding the complete reception of the last-sent
  434.  * audio.
  435.  */
  436. sleep(1);
  437. modem->hangup();
  438.     }
  439.     /*
  440.      * This may not be exact--the line may already have been
  441.      * dropped--but it should be close enough unless the modem
  442.      * gets wedged and the hangup work times out.  Also be
  443.      * sure to register a non-zero amount of connect time so
  444.      * that folks doing accounting can adjust charge-back costs
  445.      * to reflect any minimum connect time tarrifs imposted by
  446.      * their PTT (e.g. calls < 1 minute are rounded up to 1 min.)
  447.      */
  448.     if (connTime) {
  449. connTime = Sys::now() - connTime;
  450. if (connTime == 0)
  451.     connTime++;
  452.     }
  453. }
  454. /*
  455.  * Process a polling request.
  456.  */
  457. void
  458. FaxServer::sendPoll(FaxRequest& fax, bool remoteHasDoc)
  459. {
  460.     u_int ix = fax.findItem(FaxRequest::send_poll);
  461.     if (ix == fx_invalidArrayIndex) {
  462. fax.notice = "polling operation not done because of internal failure";
  463. traceServer("internal muckup, lost polling request");
  464. // NB: job is marked done
  465.     } else if (!remoteHasDoc) {
  466. fax.notice = "remote has no document to poll";
  467. traceServer("REJECT: " | fax.notice);
  468. // override to force status about polling failure
  469. if (fax.notify == FaxRequest::no_notice)
  470.     fax.notify = FaxRequest::when_done;
  471.     } else {
  472. FaxItem& freq = fax.items[ix];
  473. FaxRecvInfoArray docs;
  474. fax.status = (pollFaxPhaseB(freq.addr, freq.item, docs, fax.notice) ?
  475.     send_done : send_retry);
  476. for (u_int j = 0; j < docs.length(); j++) {
  477.     FaxRecvInfo& ri = docs[j];
  478.     if (ri.npages > 0) {
  479. Sys::chmod(ri.qfile, recvFileMode);
  480. notifyPollRecvd(fax, ri);
  481.     } else {
  482. traceServer("POLL: empty file "%s" deleted",
  483.     (const char*) ri.qfile);
  484. Sys::unlink(ri.qfile);
  485.     }
  486. }
  487. if (fax.status == send_done)
  488.     notifyPollDone(fax, ix);
  489.     }
  490. }
  491. /*
  492.  * Phase B of Group 3 protocol.
  493.  */
  494. bool
  495. FaxServer::sendFaxPhaseB(FaxRequest& fax, FaxItem& freq, FaxMachineInfo& clientInfo, u_int batched, bool dosetup)
  496. {
  497.     TIFF* tif = TIFFOpen(freq.item, "r");
  498.     if (tif && (freq.dirnum == 0 || TIFFSetDirectory(tif, freq.dirnum))) {
  499. if (dosetup) {
  500.     // set up DCS according to file characteristics
  501.     fax.status = sendSetupParams(tif, clientParams, clientInfo, fax.notice);
  502. }
  503. if (fax.status == send_ok) {
  504.     /*
  505.      * Count pages sent and advance dirnum so that if we
  506.      * terminate prematurely we'll only transmit what's left
  507.      * in the current document/file.  Also, if nothing is
  508.      * sent, bump the counter on the number of times we've
  509.      * attempted to send the current page.  We don't try
  510.      * more than 3 times--to avoid looping.
  511.      */
  512.     u_int prevPages = fax.npages;
  513.     fax.status = modem->sendPhaseB(tif, clientParams, clientInfo,
  514. fax.pagehandling, fax.notice, batched);
  515.     if (fax.status == send_v17fail && fax.notice == "") {
  516. // non-fatal V.17 incompatibility
  517. clientInfo.setHasV17Trouble(true);
  518. fax.status = send_ok;
  519.     }
  520.     if (fax.npages == prevPages) {
  521. fax.ntries++;
  522. if (fax.ntries > 2) {
  523.     if (fax.notice != "")
  524. fax.notice.append("; ");
  525.     fax.notice.append(
  526. "Giving up after 3 attempts to send same page");
  527.     traceServer("SEND: %s "%s", dirnum %d",
  528. (const char*) fax.notice, (const char*) freq.item, freq.dirnum);
  529.     fax.status = send_failed;
  530. }
  531.     } else {
  532. freq.dirnum += fax.npages - prevPages;
  533. fax.ntries = 0;
  534.     }
  535. }
  536.     } else {
  537. fax.notice = tif ? "Can not set directory in document file" :
  538.    "Can not open document file";
  539. traceServer("SEND: %s "%s", dirnum %d",
  540.     (const char*) fax.notice, (const char*) freq.item, freq.dirnum);
  541.     }
  542.     if (tif)
  543. TIFFClose(tif);
  544.     return (fax.status == send_ok);
  545. }
  546. /*
  547.  * Check client's capabilities (DIS) against those of the
  548.  * modem and select the parameters that are best for us.
  549.  */
  550. bool
  551. FaxServer::sendClientCapabilitiesOK(FaxRequest& fax, FaxMachineInfo& clientInfo, fxStr& emsg)
  552. {
  553.     /*
  554.      * Select signalling rate and minimum scanline time
  555.      * for the duration of the session.  These are not
  556.      * changed once they are set here.
  557.      */
  558.     clientInfo.setMaxSignallingRate(clientCapabilities.br);
  559.     int signallingRate =
  560. modem->selectSignallingRate(
  561.     fxmin(clientInfo.getMaxSignallingRate(), fax.desiredbr));
  562.     if (signallingRate == -1) {
  563. emsg = "Modem does not support negotiated signalling rate {E400}";
  564. return (false);
  565.     }
  566.     clientParams.br = signallingRate;
  567.     if (clientInfo.getHasV17Trouble() && (clientParams.br == BR_14400 || clientParams.br == BR_12000)) clientParams.br = BR_9600;
  568.     clientInfo.setMinScanlineTime(clientCapabilities.st);
  569.     int minScanlineTime =
  570. modem->selectScanlineTime(
  571.     fxmax(clientInfo.getMinScanlineTime(), fax.desiredst));
  572.     if (minScanlineTime == -1) {
  573. emsg = "Modem does not support negotiated min scanline time {E401}";
  574. return (false);
  575.     }
  576.     clientParams.st = minScanlineTime;
  577.     /*
  578.      * Use optional Error Correction Mode (ECM) if the
  579.      * peer implements and our modem is also capable.
  580.      */
  581.     if ((clientCapabilities.ec != EC_DISABLE) && modem->supportsECM() && fax.desiredec) {
  582. /*
  583.  * 1) The receiver expresses a preference one type of T.30-A ECM. In nearly 
  584.  *    all circumstances 256-bit is the default.
  585.  * 2) We allow the fax job also to express a preference for one type or the 
  586.  *    other to be used.  Our default is also 256-bit.
  587.  * 3) We allow the Class 1 modem to specify a preference between them.  Again,
  588.  *    the default it 256-bit.
  589.  * 4) Although T.30-C advises us to honor remote preferences (although 
  590.  *    discussing a different ECM type than these) the receiver is required to 
  591.  *    support both if either are supported at all.
  592.  *
  593.  * So, to respond to all of these preferences we basically say that if any
  594.  * of these preferences indicate 64-bit then use 64-bit.  Otherwise, use
  595.  * 256-bit.
  596.  */
  597. if (!modem->supportsECM(EC_ENABLE256) || clientCapabilities.ec != EC_ENABLE256 || fax.desiredec != EC_ENABLE256)
  598.     clientParams.ec = EC_ENABLE64;
  599. else
  600.     clientParams.ec = EC_ENABLE256;
  601.     } else
  602. clientParams.ec = EC_DISABLE;
  603.     clientParams.bf = BF_DISABLE;
  604.     /*
  605.      * Record the remote machine's capabilities for use below in
  606.      * selecting tranfer parameters for each page sent.  The info
  607.      * constructed here is also recorded in a private database for
  608.      * use in pre-formatting documents sent in future conversations.
  609.      */
  610.     clientInfo.setSupportsVRes(clientCapabilities.vr);
  611.     clientInfo.setSupports2DEncoding(clientCapabilities.df & BIT(DF_2DMR));
  612.     clientInfo.setSupportsMMR(clientCapabilities.df & BIT(DF_2DMMR));
  613.     clientInfo.setMaxPageWidthInPixels(clientCapabilities.pageWidth());
  614.     clientInfo.setMaxPageLengthInMM(clientCapabilities.pageLength());
  615.     traceProtocol("REMOTE best rate %s", clientCapabilities.bitRateName());
  616.     traceProtocol("REMOTE max %s", clientCapabilities.pageWidthName());
  617.     traceProtocol("REMOTE max %s", clientCapabilities.pageLengthName());
  618.     traceProtocol("REMOTE best vres %s", clientCapabilities.bestVerticalResName());
  619.     traceProtocol("REMOTE format support: %s", (const char*) clientCapabilities.dataFormatsName());
  620.     if (clientCapabilities.ec != EC_DISABLE)
  621. traceProtocol("REMOTE supports %s", clientCapabilities.ecmName());
  622.     traceProtocol("REMOTE best %s", clientCapabilities.scanlineTimeName());
  623. #ifdef notdef
  624.     // NB: don't say anything since it confuses the naive
  625.     traceProtocol("REMOTE %s PostScript transfer",
  626. clientInfo.getSupportsPostScript() ? "supports" : "does not support");
  627. #endif
  628.     traceProtocol("USE %s", clientParams.bitRateName());
  629.     if (clientParams.ec != EC_DISABLE) traceProtocol("USE error correction mode");
  630.     return (true);
  631. }
  632. /*
  633.  * Select session parameters according to the info
  634.  * in the TIFF file.  We setup the encoding scheme,
  635.  * page width & length, and vertical-resolution
  636.  * parameters.  If the remote machine is incapable
  637.  * of handling the image, we bail out.
  638.  *
  639.  * Note that we shouldn't be rejecting too many files
  640.  * because we cache the capabilities of the remote machine
  641.  * and use this to image the facsimile.  This work is
  642.  * mainly done to optimize transmission and to reject
  643.  * anything that might sneak by.
  644.  */
  645. FaxSendStatus
  646. FaxServer::sendSetupParams1(TIFF* tif,
  647.     Class2Params& params, const FaxMachineInfo& clientInfo, fxStr& emsg)
  648. {
  649.     uint16 compression;
  650.     (void) TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
  651.     if (compression != COMPRESSION_CCITTFAX3 && compression != COMPRESSION_CCITTFAX4) {
  652. emsg = fxStr::format("Document is not in a Group 3 or Group 4 compatible"
  653.     " format (compression %u) {E402}", compression);
  654. return (send_failed);
  655.     }
  656.     // XXX perhaps should verify samples and bits/sample???
  657.     uint32 g3opts;
  658.     if (!TIFFGetField(tif, TIFFTAG_GROUP3OPTIONS, &g3opts))
  659. g3opts = 0;
  660.     /*
  661.      * JPEG sending disabled for now
  662.      */
  663.     params.jp = 0;
  664.     /*
  665.      * RTFCC lets us ignore our file data format, but our data
  666.      * format may be based upon a requested data format, and without
  667.      * re-reading the q file, we won't know if the data format was
  668.      * requested.  So, RTFCC defeats requested data formatting. :-(
  669.      */
  670.     if (class2RTFCC || softRTFCC) {
  671. /*
  672.  * Determine the "maximum" compression.
  673.  *
  674.  * params.df prior to here represents how faxq formatted the image.
  675.  * clientCapabilities.df represents what formats the remote supports.
  676.  *
  677.  * Ignore what faxq did and send with the "highest" (monochrome) 
  678.  * compression that both the modem and the remote supports.
  679.  */
  680. if (useDF) {
  681.     /*
  682.      * The job has been restricted to a specific data format per
  683.      * JobControls or something similar - that value is now 
  684.      * found in clientParams.df.
  685.      */
  686.     params.df = fxmin(clientParams.df, params.df);
  687. } else {
  688.     params.df = 0;
  689.     u_int bits = clientCapabilities.df;
  690.     bits &= BIT(DF_JBIG+1)-1; // cap at JBIG, only deal with monochrome
  691.     while (bits) { // puts params.df to the "best" support by the remote
  692. bits >>= 1;
  693. if (bits) params.df++;
  694.     }
  695. }
  696. // Class 2 RTFCC doesn't support JBIG
  697. if (params.df == DF_JBIG && (!modem->supportsJBIG() || (params.ec == EC_DISABLE) || class2RTFCC))
  698. params.df = DF_2DMMR;
  699. // even if RTFCC supported uncompressed mode (and it doesn't)
  700. // it's likely that the remote was incorrect in telling us it does
  701. if (params.df == DF_2DMRUNCOMP) params.df = DF_2DMR;
  702. // don't let RTFCC cause problems with restricted modems...
  703. if (params.df == DF_2DMMR && (!modem->supportsMMR() || (params.ec == EC_DISABLE) || !(clientCapabilities.df & BIT(DF_2DMMR))))
  704. params.df = DF_2DMR;
  705. if (params.df == DF_2DMR && (!modem->supports2D() || !(clientCapabilities.df & BIT(DF_2DMR))))
  706. params.df = DF_1DMH;
  707. if (tiff2faxCmd.length() && formatSize[0] != 0 && formatSize[0] != 0 && formatSize[0] != 0) {
  708.     /*
  709.      * T.4 and T.6 compress poorly when there are frequent alternations between
  710.      * black and white (i.e. a dithered photograph).  Thus, in some cases the
  711.      * "highest" compression may actually be MH.  Since MH support is requisite 
  712.      * we can switch "down" to it freely.
  713.      *
  714.      * If MH is tighter than MMR then it would be extremely unlikely that MH would
  715.      * not also be tighter than MR.  So we don't consider dropping from MMR to MR.
  716.      *
  717.      * JBIG will virtually always outcompress any other format, so we don't consider
  718.      * another format when we can use JBIG.
  719.      */
  720.     if ((params.df == DF_2DMMR || params.df == DF_2DMR) && formatSize[0] < formatSize[1]) 
  721. params.df = DF_1DMH;
  722. }
  723.     } else {
  724. if (compression == COMPRESSION_CCITTFAX4) {
  725.     if (!clientInfo.getSupportsMMR()) {
  726. emsg = "Document was encoded with 2DMMR, but client does not support this data format {E403}";
  727. return (send_reformat);
  728.     }
  729.     if (!modem->supportsMMR()) {
  730. emsg = "Document was encoded with 2DMMR, but modem does not support this data format {E404}";
  731. return (send_reformat);
  732.     }
  733.     if (params.ec == EC_DISABLE) {
  734. emsg = "Document was encoded with 2DMMR, but ECM is not being used. {E405}";
  735. return (send_reformat);
  736.     }
  737.     params.df = DF_2DMMR;
  738. } else if (g3opts & GROUP3OPT_2DENCODING) {
  739.     if (!clientInfo.getSupports2DEncoding()) {
  740. emsg = "Document was encoded with 2DMR, but client does not support this data format {E406}";
  741. return (send_reformat);
  742.     }
  743.     if (!modem->supports2D()) {
  744. emsg = "Document was encoded with 2DMR, but modem does not support this data format {E407}";
  745. return (send_reformat);
  746.     }
  747.     params.df = DF_2DMR;
  748. } else
  749.     params.df = DF_1DMH;
  750.     }
  751.     /*
  752.      * Try to deduce the resolution of the image
  753.      * image.  This can be problematical for arbitrary TIFF
  754.      * images 'cuz vendors sometimes don't give the units.
  755.      * We, however, can depend on the info in images that
  756.      * we generate 'cuz we're careful to include valid info.
  757.      */
  758.     float yres;
  759.     if (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres)) {
  760. short resunit = RESUNIT_INCH; // TIFF spec default
  761. (void) TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
  762. if (resunit == RESUNIT_INCH)
  763.     yres /= 25.4;
  764. if (resunit == RESUNIT_NONE)
  765.     yres /= 720.0; // postscript units ?
  766.     } else {
  767. /*
  768.  * No vertical resolution is specified, try
  769.  * to deduce one from the image length.
  770.  */
  771. u_long l;
  772. TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &l);
  773. yres = (l < 1450 ? 3.85 : 7.7); // B4 at 98 lpi is ~1400 lines
  774.     }
  775.     float xres;
  776.     if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres)) {
  777. short resunit = RESUNIT_INCH; // TIFF spec default
  778. (void) TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
  779. if (resunit == RESUNIT_INCH)
  780.     xres /= 25.4;
  781. if (resunit == RESUNIT_NONE)
  782.     xres /= 720.0; // postscript units ?
  783.     } else {
  784. /*
  785.  * No horizontal resolution is specified, try
  786.  * to deduce one from the image width.
  787.  */
  788. u_long l;
  789. TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &l);
  790. xres = (l < 1729 ? 8 : 16); // R8 = 8 l/mm, R16 = 16 l/mm
  791.     }
  792.     if (yres >= 15.) {
  793. if (xres > 10) {
  794.     if (!(clientInfo.getSupportsVRes() & VR_R16)) {
  795. emsg = fxStr::format("Hyperfine resolution document is not supported"
  796.     " by client, image resolution %g x %g lines/mm {E408}", xres, yres);
  797. return (send_reformat);
  798.     }
  799.     if (!modem->supportsVRes(20)) { // "20" is coded for R16
  800. emsg = fxStr::format("Hyperfine resolution document is not supported"
  801.     " by modem, image resolution %g x %g lines/mm {E409}", xres, yres);
  802. return (send_reformat);
  803.     }
  804. params.vr = VR_R16;
  805. } else {
  806.     if (!((clientInfo.getSupportsVRes() & VR_R8) || (clientInfo.getSupportsVRes() & VR_200X400))) {
  807. emsg = fxStr::format("Superfine resolution document is not supported"
  808.     " by client, image resolution %g lines/mm {E410}", yres);
  809. return (send_reformat);
  810.     }
  811.     if (!modem->supportsVRes(yres)) {
  812. emsg = fxStr::format("Superfine resolution document is not supported"
  813.     " by modem, image resolution %g lines/mm {E411}", yres);
  814. return (send_reformat);
  815.     }
  816. if (clientInfo.getSupportsVRes() & VR_R8) params.vr = VR_R8;
  817. else params.vr = VR_200X400;
  818. }
  819.     } else if (yres >= 10.) {
  820. if (!(clientInfo.getSupportsVRes() & VR_300X300)) {
  821.     emsg = fxStr::format("300x300 resolution document is not supported"
  822. " by client, image resolution %g lines/mm {E412}", yres);
  823.     return (send_reformat);
  824. }
  825. if (!modem->supportsVRes(yres)) {
  826.     emsg = fxStr::format("300x300 resolution document is not supported"
  827. " by modem, image resolution %g lines/mm {E413}", yres);
  828.     return (send_reformat);
  829. }
  830. params.vr = VR_300X300;
  831.     } else if (yres >= 7.) {
  832. if (!((clientInfo.getSupportsVRes() & VR_FINE) || (clientInfo.getSupportsVRes() & VR_200X200))) {
  833.     emsg = fxStr::format("High resolution document is not supported"
  834. " by client, image resolution %g lines/mm {E414}", yres);
  835.     return (send_reformat);
  836. }
  837. if (!modem->supportsVRes(yres)) {
  838.     emsg = fxStr::format("High resolution document is not supported"
  839. " by modem, image resolution %g lines/mm {E415}", yres);
  840.     return (send_reformat);
  841. }
  842. if (clientInfo.getSupportsVRes() & VR_FINE) params.vr = VR_FINE;
  843. else params.vr = VR_200X200;
  844.     } else
  845. params.vr = VR_NORMAL; // support required
  846.     /*
  847.      * Max page width depends on the resolution, so this must come after VR.
  848.      * maxPageWidth is stored in normal values, so we must compare against
  849.      * the corresponding normal resolution page width.
  850.      */
  851.     uint32 w;
  852.     (void) TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  853.     double rf = (params.vr == VR_R16 ? 2 : params.vr == VR_300X300 ? 1.5 : 1);
  854.     if (w > (clientInfo.getMaxPageWidthInPixels()*rf)) {
  855. emsg = fxStr::format("Client does not support document page width"
  856. ", max remote page width %g pixels, image width %lu pixels {E416}",
  857. (uint32) (clientInfo.getMaxPageWidthInPixels()*rf), w);
  858. return (send_reformat);
  859.     }
  860.     if (!modem->supportsPageWidth((u_int) w, params.vr)) {
  861. static const double widths[8] = {
  862.     1728, // 1728 in 215 mm line
  863.     2048, // 2048 in 255 mm line
  864.     2432, // 2432 in 303 mm line
  865.     1216, // 1216 in 151 mm line
  866.     864, // 864 in 107 mm line
  867.     0,
  868.     0,
  869.     0,
  870. };
  871. emsg = fxStr::format("Modem does not support document page width"
  872. ", max page width %g pixels, image width %lu pixels {E417}",
  873. widths[modem->getBestPageWidth()&7]*rf, w);
  874. return (send_reformat);
  875.     }
  876.     // NB: only common values
  877.     params.wd = ((uint32) (w/rf) <= 1728 ? WD_A4 : (uint32) (w/rf) <= 2048 ? WD_B4 : WD_A3);
  878.     /*
  879.      * Select page length according to the image size and
  880.      * vertical resolution.  Note that if the resolution
  881.      * info is bogus, we may select the wrong page size.
  882.      * Note also that we're a bit lenient in places here
  883.      * to take into account sloppy coding practice (e.g.
  884.      * using 200 dpi for high-res facsimile.
  885.      */
  886.     if (clientInfo.getMaxPageLengthInMM() != (u_short) -1 || !modem->supportsPageLength((u_int) -1)) {
  887. u_long h = 0;
  888. (void) TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  889. float len = h / yres; // page length in mm
  890. if ((int) len > clientInfo.getMaxPageLengthInMM()) {
  891.     emsg = fxStr::format("Client does not support document page length"
  892.   ", max remote page length %d mm"
  893.   ", image length %lu rows (%.2f mm) {E418}",
  894. clientInfo.getMaxPageLengthInMM(), h, len);
  895.     return (send_reformat);
  896. }
  897. if (!modem->supportsPageLength((u_int) len)) {
  898.     static const char* lengths[4] = {
  899. "297", // A4 paper
  900. "364", // B4 paper
  901. "<unlimited>", // unlimited
  902. "<undefined>", // US letter (used internally)
  903.     };
  904.     emsg = fxStr::format("Modem does not support document page length"
  905.   ", max page length %s mm"
  906.   ", image length %lu rows (%.2f mm) {E419}",
  907. lengths[modem->getBestPageLength()&3], h, len);
  908.     return (send_reformat);
  909. }
  910. // 330 is chosen 'cuz it's half way between A4 & B4 lengths
  911. params.ln = (len < 330 ? LN_A4 : LN_B4);
  912.     } else
  913. params.ln = LN_INF;
  914.     /*
  915.      * Scanline time varies depending on the remote capabilities,
  916.      * upon ECM usage, and upon the resolution.  The MS2 parameters
  917.      * are not available in DCS.
  918.      */
  919.     if (params.st == ST_40MS2) {
  920.         if (params.vr) params.st = ST_20MS;
  921.         else params.st = ST_40MS;
  922.     }
  923.     if (params.st == ST_20MS2) {
  924.         if (params.vr) params.st = ST_10MS;
  925.         else params.st = ST_20MS;
  926.     }
  927.     if (params.st == ST_10MS2) {
  928.         if (params.vr) params.st = ST_5MS;
  929.         else params.st = ST_10MS;
  930.     }
  931.     if (params.ec != EC_DISABLE) params.st = ST_0MS; // T.30 Table 2 Note 8 - ECM imposes 0ms/scanline
  932.     return (send_ok);
  933. }
  934. FaxSendStatus
  935. FaxServer::sendSetupParams(TIFF* tif, Class2Params& params, const FaxMachineInfo& clientInfo, fxStr& emsg)
  936. {
  937.     FaxSendStatus status = sendSetupParams1(tif, params, clientInfo, emsg);
  938.     if (status == send_ok) {
  939. traceProtocol("USE %s", params.pageWidthName());
  940. traceProtocol("USE %s", params.pageLengthName());
  941. traceProtocol("USE %s", params.verticalResName());
  942. traceProtocol("USE %s", params.dataFormatName());
  943. traceProtocol("USE %s", params.scanlineTimeName());
  944.     } else if (status == send_reformat) {
  945. traceServer(emsg);
  946.     } else if (status == send_failed) {
  947. traceServer("REJECT: " | emsg);
  948.     }
  949.     return (status);
  950. }
  951. /*
  952.  * Send Notification Support.
  953.  */
  954. void
  955. FaxServer::notifyPageSent(FaxRequest& req, const char*)
  956. {
  957.     time_t now = Sys::now();
  958.     req.npages++; // count transmitted page
  959.     if (req.nocountcover) {
  960. req.nocountcover--;
  961. req.skippedpages--;
  962.     }
  963.     /*
  964.      * If the system is busy then req.writeQFile may not return quickly.
  965.      * Thus we run it in a child process and move on.
  966.      */
  967.     pid_t pid = req.writeQFilePid;
  968.     req.writeQFilePid = fork();
  969.     switch (req.writeQFilePid) {
  970. case 0:
  971.     if (pid > 0) (void) Sys::waitpid(pid); // the calls to writeQFile must be sequenced serially
  972.     req.writeQFile(); // update q file for clients
  973.     traceProtocol("SEND FAX (%s): FROM %s TO %s (page %u of %u sent in %s)"
  974. , (const char*) req.commid
  975. , (const char*) req.mailaddr
  976. , (const char*) req.external
  977. , req.npages
  978. , req.totpages
  979. , fmtTime(now - pageStart)
  980.     );
  981.     sleep(1);               // XXX give parent time
  982.     exit(0);
  983. case -1:
  984.     logError("Can not fork for non-priority processing.");
  985.     req.writeQFile(); // update q file for clients
  986.     traceProtocol("SEND FAX (%s): FROM %s TO %s (page %u of %u sent in %s)"
  987. , (const char*) req.commid
  988. , (const char*) req.mailaddr
  989. , (const char*) req.external
  990. , req.npages
  991. , req.totpages
  992. , fmtTime(now - pageStart)
  993.     );
  994.     break;
  995. default:
  996.     Dispatcher::instance().startChild(req.writeQFilePid, this);
  997.     break;
  998.     }
  999.     pageStart = now; // for next page
  1000. }
  1001. /*
  1002.  * Handle notification that a document has been successfully
  1003.  * transmitted.  We remove the file from the request array so
  1004.  * that it's not resent if the job is requeued.
  1005.  *
  1006.  * NB: Proper operation of the reference counting scheme used
  1007.  *     to handle delayed-removal of the imaged documents requires
  1008.  *     that the central scheduler be notified when a document
  1009.  *     is transmitted (so that it can update its global table
  1010.  *     of document uses); this is normally done in the derived
  1011.  *     class by overriding this method.
  1012.  */
  1013. void
  1014. FaxServer::notifyDocumentSent(FaxRequest& req, u_int fi)
  1015. {
  1016.     const FaxItem& freq = req.items[fi];
  1017.     if (freq.op != FaxRequest::send_fax) {
  1018. logError("notifyDocumentSent called for non-TIFF file");
  1019. return;
  1020.     }
  1021.     traceProtocol("SEND FAX (%s): FROM %s TO %s (%s sent in %s)"
  1022. , (const char*) req.commid
  1023. , (const char*) req.mailaddr
  1024. , (const char*) req.external
  1025. , (const char*) freq.item
  1026. , fmtTime(getFileTransferTime())
  1027.     );
  1028.     logInfo("SEND FAX: JOB %s SENT in %s"
  1029. , (const char*) req.jobid
  1030. , fmtTime(getFileTransferTime())
  1031.     );
  1032.     // we must ensure that the previous writeQFiles have completed
  1033.     if (req.writeQFilePid > 0) (void) Sys::waitpid(req.writeQFilePid);
  1034.     if (freq.op == FaxRequest::send_fax)
  1035. req.renameSaved(fi);
  1036.     req.items.remove(fi);
  1037.     req.writeQFile();
  1038. }