Mod fax

From FreeSWITCH Wiki

Jump to: navigation, search

Contents

Status

We are finishing mod_fax. It requires full field testing now.

Its important that you create the config XML file since the spool directory for faxes can be configured only there.

Things to be done:

  • Fire out an event on every fax received/sent.
  • Fire out an event on every page fax received/sent.
  • T.38 support.

Comment by Marcelo Coraça de Freitas(ogro) Also, mod_fax require you use a G.711 (PCMA/PCMU) codec or it won't work. If you are using txfax for sending and rxfax for receiving, remember to use the same codec in both ends.

Installation and configuration

  • Enable mod_fax in modules.conf and recompile.
  • Make sure to copy and edit fax.conf.xml into your appropriate autoload directory.
  • Enable mod_fax in Modules.conf.xml.

If you receive 'No targets specified and no makefile found' when making mod_fax, then spandsp is probably not configured.

  • Ensure that you have libtiff development files installed.
    • For Debian/Ubuntu you can type
Type This
apt-get install libtiff4-dev


  • For CentOS 5.x
Type This
yum install libtiff-devel


Type This
cd libs/spandsp
./configure --prefix=/usr/local/freeswitch
cd ../../
make


Informational Tip

If you get a complaint about TIFF library, try the following:

make tiff-reconf

 


Now it should make mod_fax

Invoking the app from the XML dialplan

You can invoke the rxfax application and use the data option to pass it the TIFF file name. If you do not pass any information in the data option mod_fax will create the file name for you and place the received fax into your spool directory.

(This section need to be completed)

For receiving a fax

<extension name="test_rxfax_stream">
       <condition field="destination_number" expression="^\*90012$">
               <action application="answer" />
               <action application="playback" data="silence_stream://2000"/>
               <action application="rxfax" data="//my_directory//rxfax.tiff"/>
               <action application="hangup"/>
       </condition>
</extension>

If you want each fax have a unique name you can use this variation:

   <extension name="fax_receive">
     <condition field="destination_number" expression="^9978$">
       <action application="answer" />
       <action application="playback" data="silence_stream://2000"/>
       <action application="rxfax" data="/tmp/FAX-${uuid}.tif"/>
       <action application="hangup"/>
     </condition>
   </extension>


For transmitting a fax

A PDF file can be converted to TIFF format using ImageMagick, here is an example:

convert -density 204x98 -resize 1728x1186 -monochrome -compress Fax txfax.pdf txfax.tiff

For a better Quality, you can use Ghostscript for PDF/PS files, here is an example:

gs -q -sDEVICE=tiffg3 -r204x98 -dNOPAUSE -sOutputFile=txfax.tiff -- txfax.pdf

NOTE: Ghostscript wont put your document in the correct orientation... not really a problem when sending to a remote paper machine, but it nice to have it correctly when receiving a fax on a computer. ImageMagick put the correct orientation BUT the quality is FAR from the quality of Ghostscript.

You can transmit a Fax using the following dialplan:

<extension name="test_txfax_stream">
       <condition field="destination_number" expression="^\*90012$">
               <action application="txfax" data="txfax.tiff"/>
               <action application="hangup"/>
       </condition>

</extension>

Invoking the app from the CLI

For transmitting a fax

In the CLI, for sending a fax via profile external using gateway 10.10.10.10 and fax machine number 100, you'll have to use this.

originate sofia/external/100@10.10.10.10 &txfax(/path_to_fax_file)

Or to specify the gateway to use:

originate sofia/gateway/<gateway name>/<phone number> &txfax(/path_to_fax_file)

fax2mail: Emailing the fax upon receipt

  • In recent versions of FreeSWITCH, the dialplan ends once rxfax completes, api_hangup_hook executes the script in this case.
    • This dialplan also illustrates some possible regex's for specific UA's that only have dedicated fax's attached so they send they fax as an email attachment to the online fax service.
<include>
  <extension name="outbound_fax">
    <condition field="caller_id_number" expression="^(100[23])$"/>
    <condition field="destination_number" expression="^(1\d{10})$">
      <action application="set" data="api_hangup_hook=system ${base_dir}/scripts/emailfax.sh $1 /tmp/${uuid}.rxfax.tiff"/>    
      <action application="answer"/>
      <action application="playback" data="silence_stream://2000"/>
      <action application="rxfax" data="/tmp/${uuid}.rxfax.tiff"/>
      <action application="hangup"/>
    </condition>
  </extension>
</include>
  • Uuencode is no longer well supported or as good a format as mime. Using mutt to send the attachments solves this but presents some configuration hurdles to format the email. This solution presents a way to deal with every such case. Edit the paths and domain to match your fax service. Create the ${base_dir}/scripts/emailfax.sh file as follows:
#!/bin/bash
#
# $1 is email alias (The dialed #)
# $2 is filename
 
mutt -n -f /dev/null -F /opt/freeswitch/scripts/muttrc -a $2 -s "Fax to $1@myfax.com" $1@myfax.com < /dev/null
  • Now create the muttrc file. This configuration allows the sending of mail without a local mailbox which the user running freeswitch probably doesn't have (you can add more config to tune the headers of your email as needed):
set from = 'alias@DOMAIN'
set realname = 'YOUR ORG NAME'
set folder = /dev/null

Here is another example, using a python script called process-rxfax.py, via Dialplan XML:

<extension name="test_rxfax_python"/>
       <condition field="destination_number" expression="^\*90012$">
               <action application="set" data="recipient=YOU@YOURDOMAINHERE.com"/> 
               <action application="python" data="process-rxfax"/> 
               <action application="hangup"/>
       </condition>
</extension>

This python script gets put into your FreeSWITCH's mod_python path, and will launch mod_fax to receive the fax and then convert it to a PDF and email it. The script requires that you have the ps2pdf utility (from ghostscript) and tiff2ps installed. In FreeBSD these are in Ports and are also available under most Linux distributions via package management (apt-get, yum, rpm etc). This python script also requires a working mod_python and mod_fax installation. More information here.

mail2fax: Faxing a received mail

There are several pieces:

The script email2fax may look like this:

#!/bin/sh

set -e

PATH=/usr/local/bin:/usr/bin:/bin

TMPMAIL=/tmp/email2fax.$$.txt
TMPPDF=/tmp/email2fax.$$.pdf
TMPFAX=/tmp/email2fax.$$.tiff
DEST='sofia/external/100@10.10.10.10'

cat > $TMPMAIL
cat $TMPMAIL | email2pdf --header=/tmp/header.html - $TMPPDF

#rm $TMPMAIL

gs -q -sDEVICE=tiffg3 -r204x98 -dNOPAUSE -sOutputFile=$TMPFAX -- $TMPPDF 2> /dev/null
#convert -density 204x98 -resize 1728x1186 -monochrome -compress Fax $TMPPDF $TMPFAX

#rm $TMPPDF

chmod o+r $TMPFAX

/opt/freeswitch/bin/fs_cli \
 --execute="originate {fax_verbose=true}$DEST &txfax($TMPFAX)"

#rm $TMPFAX
exit 1

Configuring the app

App can be controlled globally using fax.conf.xml

<configuration name="fax.conf" description="FAX application configuration">
   <settings>
       <param name="use-ecm"       value="true"/>
       <param name="verbose"       value="true"/>
       <param name="disable-v17"   value="false"/>
       <param name="ident"         value="SpanDSP Fax Ident"/>
       <param name="header"        value="SpanDSP Fax Header"/>
       <param name="spool-dir"     value="/tmp"/>
       <param name="file-prefix"   value="faxrx"/>
   </settings>
</configuration>

Controlling the app

You can set the following channel's variables to control the behavior of the mod application:

  • fax_force_caller - Force to act as caller or receiver; Mode: Tx=1 or Rx=0
  • fax_ident
  • fax_header
  • fax_start_page - Saved document will start at specified page
  • fax_end_page - Saved document will end at specified page
  • fax_prefix
  • fax_use_ecm - Forces the use of ECM if globally disabled, on a per call basis
  • fax_disable_v17 - Disable V17 modem that is: use lower speed modems (lower speeds are auto-negotiated with the remote party and cannot be forced. That's a work that the spandsp modem handles on its own.)
  • fax_verbose - Be verbose when printing logs (per call basis)

Checking the results

Rx/Tx fax will set the following channel variables when it terminates:

  • fax_success - 0 on error, 1 on success;
  • fax_result_code - 0 on error otherwise >= 1;
  • fax_result_text - fax error string, provide info where an error has happened;
  • fax_ecm_used - "on" or "off";
  • fax_local_station_id
  • fax_remote_station_id
  • fax_document_transferred_pages
  • fax_document_total_pages
  • fax_image_resolution - XxY
  • fax_image_size
  • fax_bad_rows
  • fax_transfer_rate - speed expressed in bauds (bit per seconds) like 14.400, 9.600, etc.;
  • fax_v17_disabled - 0/1
  • fax_ecm_requested - 0/1
  • fax_filename

Error result codes

When receiving a "Fax processing not successful", you should also receive one of the following result codes:

  • 2 - Timed out waiting for initial communication.
  • 3 - Timed out waiting for the first message.
  • 5 - The HDLC carrier did not stop in a timely manner.
  • 11 - Far end cannot receive at the resolution of the image.
  • 12 - Far end cannot receive at the size of image.
  • 13 - Unexpected message received.
  • 14 - Received bad response to DCS or training.
  • 17 - Received a DCN while waiting for a DIS.
  • 18 - Invalid response after sending a page.
  • 20 - Received no response to DCS or TCF.
  • 21 - No response after sending a page.
  • 37 - Unexpected DCN while waiting for EOM, EOP or MPS.
  • 41 - TIFF/F file cannot be opened.
  • 43 - TIFF/F format is not compatible.
  • 48 - Disconnected after permitted retries.
  • 49 - The call dropped prematurely.

***Please help complete the list***

Tests

  • Linksys PAP2T via SIP with G.711 - sending to RxFax is OK.
  • Asterisk + spandsp - asterisk has problem with CNG so you need to patch mod_fax.c at the moment and comment out the "continue" under the CNG detection - this is a temporary hack just to do tests until mod_fax is finished - I was able to receive a 120 pages fax without problems.
  • Receiving faxes with a single port FXO (*cough* clone *cough*) works. I've only tried a couple of 1 page faxes but they were received successfully. Great work!
  • FreeSWITCH originating the fax via txfax, sending to rxfax on another channel on the same FreeSWITCH works with no issues, even when multiple faxes are being processed at the same time. Was able to put a load on FreeSWITCH by originating a bunch of test faxes from fs_cli, and they all went through properly. Codec = uLaw/G.711 8000
  • Receiving from analog fax machines connected to PSTN, routed via SIP trunk to FreeSWITCH seems to work very reliably. Tests done with SIP trunks from an OpenSER server with PRIs connected to it directly, so little to no VoIP latency is occurring. Received faxes from several senders via this method of 1-10 pages at various resolutions from different fax machines/lines of various quality with no rejections yet. Also tested receiving from FaxZero.com (free web faxing gateway) and it has worked several times.
  • Fax abilities vary among SIP providers. I have been able to receive, but not send faxes over FlowRoute. I have been able to successfully send faxes using ViaTalk. - hinmanjp

Have fun with fax, Antonio Gallo (AGX)

Personal tools
Community
Support FreeSWITCH