Dave Horner's Website - Yet another perspective on things...
Home Tech Talk Unix/Linux/BSD/etc Asterisk faxing - Setup a complete faxing solution!
182 guests
Rough Hits : 2924347
moon and stars
how did u find my site?

which seems more true?

Premature optimization is the root of all evil (or at least most of it) in programming. -- Donald Knuth
$$e = \sum_{n=0}^\infty \frac{1}{n!}$$

Asterisk faxing - Setup a complete faxing solution!

Saturday, 26 March 2005 10:38

Faxing within Asterisk

Faxing with Asterisk can be problematic.  Right now all (Oct-2005) most Asterisk hardware doesn't support faxing directly.  So, you have to actually implement a soft fax modem.  Asterisk uses spandsp for implementing the actual modem.

I'm not writing to document how to actually use the fax applications within Asterisk.  For that look at Faxing With Asterisk I think it does a pretty good job of detailing how to use it.

However, I would like to comment on how to preprocess the tiffs that you want to send.  Many times you've got tiffs that aren't fax compliant.  I created a quick perl script that concats multiple tiff files together and makes sure they are fax compliant.  In fact, much of this code was developed by looking at how HylaFax preprocessed their tiffs.

Of course you'll want to modify this script for your own purposes it.  It requires perl, tiffcp, ghostscript, tiff2ps, and the Asterisk::Outgoing module for perl. 

Again, this script is used to insure that the tiffs you want to send are fax compliant.  It creates a temporary tiff for sending and creates a call file for Asterisk to process the fax file.

# Author: David A horner (DAH) http://dave.thehorners.com
# License: Public Domain
use Getopt::Std;
use Asterisk::Outgoing;
require File::Temp;
use File::Temp ();
use strict;
# handle args
my %opts;
getopts('a:l:p:r:u:', \%opts );
my $faxnumber=shift(@ARGV);
usage('Missing faxnumber') unless $faxnumber;
print "Fax number: $faxnumber\n";
#my $tmpp=pop(@ARGV);
#push(@ARGV, "/tmp/fax.tif");
#push(@ARGV, $tmpp);
usage('You must have at least one tiff file to send') unless $ARGV[0];
print "Sending fax files:\n";
foreach (@ARGV) {
   print "$_\n";
my $tmpfile = new File::Temp(UNLINK => 0, SUFFIX => ".tfax");
my $faxfile = new File::Temp(UNLINK => 0, SUFFIX => ".fax");
print "Filename is $tmpfile\n";
#-c g3:2d:fill
print "Running: tiffcp -i -c g3:1d:fill -f lsb2msb -r 9999 @ARGV $tmpfile\n";
###system("tiffcp -c g3:2d:fill -f lsb2msb -s @ARGV $tmpfile");
system("tiffcp -i -c g3:1d:fill -f lsb2msb -r 9999 @ARGV $tmpfile");
print "DONE WITH TIFFCP!\n";
my $vres=98;
my $hres=203.29;
my $paper='letter';
print "RUNNING: /usr/bin/tiff2ps -a $tmpfile | /usr/bin/gs -q -sDEVICE=tiffg3 -dNOPAUSE -dSAFER=true -sPAPERSIZE=$paper -dFIXEDMEDIA -r".$hres."x".$vres." \"-sOutputFile=$faxfile\"  -\n";
system("/usr/bin/tiff2ps -a  $tmpfile | /usr/bin/gs -q -sDEVICE=tiffg3 -dNOPAUSE -dSAFER=true -sPAPERSIZE=$paper -dFIXEDMEDIA -r".$hres."x".$vres." \"-sOutputFile=$faxfile\"  -") ;
print "DONE WITH GS!\n";
#usage('Missing faxnumber') unless $opts{'r'};
#usage('pages of the tiff file')  unless $opts{'l'};
my $out = new Asterisk::Outgoing;
foreach my $var (keys %{$out->{OUTVARS}}) {
   print "$var: " . $out->{OUTVARS}{$var} . "\n";
sub usage {
    print "\n!! ", @_, " !!\n";
    print <<USAGE;
Usage: $0 [options] <fax-number> <page(s) in g3-format>
    exit 1;

In the future I'll post some other scripts for processing faxes when they come in.  These scripts save off the tiff and email the user with the tiff that came in.
Now these scripts assume that you've already installed the app_rxfax and app_txfax that are included with the spandsp.

You should add a file named "faxextensions" to your /etc/asterisk/ directory and include this file in your asterisk extensions.
; Author: David A horner (DAH) http://dave.thehorners.com
; License: Public Domain
; (#include <extensions/fax>)
; Recieve faxes and email em!
; Make sure that /usr/local/sbin/mailfax exists and works!
; If you want fax detection(asterisk to put faxes into the fax ext)
; Edit zapata.conf and add faxdetect=incoming,outgoing,or both
; Used for debuging
; exten => s,1,rxfax(/path_to_test_tiff/incoming.tif)
; To define email address, use following in asterisk console
; *CLI> database put extensionemail companyname 
  This e-mail address is being protected from spambots. You need JavaScript enabled to view it
; Check if the email is correct by using
; *CLI> database show
; Macro for recieving faxes
exten => s,1,SetVar(FAXFILE=/var/spool/asterisk/faxes/${UNIQUEID}.tif)
exten => s,2,DBGet(EMAILADDR=extensionemail/${ARG1})
exten => s,3,rxfax(${FAXFILE})
exten => s,103,SetVar(EMAILADDR=
  This e-mail address is being protected from spambots. You need JavaScript enabled to view it
exten => s,104,Goto(3)
exten => h,1,System(/usr/local/sbin/mailfax ${FAXFILE} ${EMAILADDR} "${CALLERIDNUM} ${CALLERIDNAME}")
exten => h,2,Hangup
exten => i,1,Hangup     ;invalid event
exten => t,1,Hangup     ;timeout event
exten => s,1,Macro(faxreceive,pbxsolutions)
include => faxsend

Here is the mailfax script that I wrote to process the actual tiff fax file and email it. The script requires mime-construct as well as tiff2ps (for pdf emails).
# Author: David A horner (DAH) http://dave.thehorners.com
# License: Public Domain
  This e-mail address is being protected from spambots. You need JavaScript enabled to view it
BODY="Attached is your fax.  Thank you for using FAXSERVERNAME!"
if [ "${#@}" -ne "3" ]; then
  echo "$0 tifpath emailaddress faxsentfrom"
  echo "  tifpath - path of tif to send"
  echo "  emailaddress - email address's of recipients"
  echo "  faxsentfrom - fax sender, put in subject line"
if [ -f $FAXFILE ]; then
  # Send file as plain tiff
  mime-construct --to $RECIPIENT --subject "Fax from $FAXSENDER" \
    --header "From: \"$FROMNAME\" <$FROMADDR>$nl" \
    --string "$BODY"\
    --attachment fax.tif --type application/tiff --file $FAXFILE
  # Send file as a pdf
#  tiff2ps -2eaz -w 8.5 -h 11 $FAXFILE | ps2pdf - | \
#  tiff2ps -2eaz $FAXFILE | ps2pdf - | \
  tiff2ps -2eaz -w 8.5 -h 11 $FAXFILE | ps2pdf - $PDFFILE
  mime-construct --to $RECIPIENT --subject "Fax from $FAXSENDER" \
    --header "From: \"$FROMNAME\" <$FROMADDR>$nl" \
    --string "$BODY"\
    --attachment fax.pdf --type application/pdf --file $PDFFILE
  mime-construct --to $RECIPIENT --subject "Fax error from $FAXSENDER" \
    --header "From: \"$FROMNAME\" <$FROMADDR>$nl" \
    --string "Fax not recieved correctly!"
Note: This script does not delete the resulting tif and pdf files.  You can add an rm to the script yourself... or simply create a cron job to delete files that are older than X days.

To use these script you now simply create a context like so:
#include <faxextensions>
exten => XXXXXXX,1,Goto(faxlinecontext,100,1)
exten => XXXXXXX,2,Congestion
exten => 100,1,Macro(faxreceive,companyname)
include => faxsend

Also just for easy access, here is a call file for sending a fax:
Channel: Zap/g1/XXXXXXXXXX
Callerid: "faxing" <XXXXXXXXXX>
MaxRetries: 0
Application: txfax
Data: /var/spool/asterisk/faxes/sometiff.tif|caller
Context: default
Extension: s
RetryTime: 60
WaitTime: 60

Until Asterisk supports T.38 relay of fax you'll want to do uncompressed ulaw between you and your PSTN connection.  In fact, I wouldn't even try it without a direct PSTN connection, all my testing showed bad results when trying to do VOIP faxing.

I've yet to try it...but here is a script to do email to fax conversions.  This is software for doing a email to fax gateway that accepts both tiff and pdf.

Another software solution that looks good is AsterFax
Last Updated on Sunday, 06 December 2009 14:36