Asterisk faxing - Setup a complete faxing solution!
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.
#!/usr/bin/perl # 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; $out->setvariable("Channel","ZAP/G1/$faxnumber"); $out->setvariable("MaxRetries","30"); $out->setvariable("WaitTime","100"); $out->setvariable("Application","txfax"); $out->setvariable("Data","$tmpfile|caller"); foreach my $var (keys %{$out->{OUTVARS}}) { print "$var: " . $out->{OUTVARS}{$var} . "\n"; } $out->create_outgoing; print "DONE WITH OUTGOING!\n"; exit; sub usage { print "\n!! ", @_, " !!\n"; print <<USAGE; Usage: $0 [options] <fax-number> <page(s) in g3-format> USAGE 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 [macro-faxreceive] 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) [faxsend] 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 [incomingfax] 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).
#!/bin/sh # Author: David A horner (DAH) http://dave.thehorners.com # License: Public Domain FAXFILE=$1 FILENAME=${FAXFILE:0:${#FAXFILE}-4} PDFFILE=${FILENAME}".pdf" RECIPIENT=$2 FAXSENDER=$3 FROMADDR= This e-mail address is being protected from spambots. You need JavaScript enabled to view it FROMNAME="FAXSERVERNAME Faxserver" 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" exit fi 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 else mime-construct --to $RECIPIENT --subject "Fax error from $FAXSENDER" \ --header "From: \"$FROMNAME\" <$FROMADDR>$nl" \ --string "Fax not recieved correctly!" fiNote: 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> ;Faxline exten => XXXXXXX,1,Goto(faxlinecontext,100,1) exten => XXXXXXX,2,Congestion [faxlinecontext] 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.
-----
Update
-----
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.
email2fax
Another software solution that looks good is AsterFax