Faxing with CallWeaver

We need a table of contents here!

Fax support in CallWeaver

Capabilities

  • CallWeaver supports faxing with T.38 if the channel driver is SIP. It supports fax termination and gatewaying.
  • CallWeaver can gateway a fax from an ATA to the PSTN and vice versa if the whole media path is T.38
  • CallWeaver can send and receive a TIFF files as faxes over T.38 or a Zap channel with the TxFax (Transmit Fax) and RxFax (Receive Fax) applications.

Notes

  • Do not try to send fax over a compressing codec. Examples are GSM, ILBC, G.729 and others.
  • If your SIP gateway does not support T.38, 99% of the times Faxing over SIP will not work.
  • T.38 is a standard for sending fax in realtime.
  • T.37 uses an SMTP-like store and forward system.
  • When faxing for legal purposes T.38 is usually preferred so that the sender can get a receipt notification.
  • Please edit your sip.conf and uncomment t38udptlsupport. Many people have been complaining that T.38 was not working even when t38udptlsupport wasn’t enabled.

Receiving a fax

  • Make sure T.38 is enabled in sip.conf if you are going to use T.38.

You can receive a fax from a BRI/PRI/ISDN/PSTN Line and, enabling T.38, even from a SIP channel!

The basic dial plan syntax for receiving a fax follows:

[inbound]
exten => 800,1,Goto(faxin,s,1)

[faxin]
exten => s,1,Set(LOCALSTATIONID=Navynet.it FAX)
exten => s,n,Set(LOCALHEADERINFO=Navynet SRL is a solution provider for business)
exten => s,n,Set(FAXFILE=/tmp/${UNIQUEID}.tif)
exten => s,n,Set(FAXFILENOEXT=/tmp/${UNIQUEID})
exten => s,n,RxFAX(${FAXFILE},ecm)
exten => s,n,NoOp(RX: REMOTESTATIONID is ${REMOTESTATIONID})
exten => s,n,NoOp(RX: PHASEESTATUS is ${PHASEESTATUS})

The previous code makes CallWeaver jump into context [faxin]. Everything is handled by CallWeaver and at the end, if ${PHASEESTATUS} is 0, you’ll have a tiff file in your TMP directory. That’s your fax !!

For me only this code works fine with t.38 for receiving a fax AND it also calls the system function to handle the .tif. So here it comes:

[fax-incomming] 
exten => 1,1,Wait(1)
exten => 1,n,Answer()
exten => 1,n,Wait(1)
exten => 1,n,Set(CID=${CALLERID(num)})
exten => 1,n,SipT38SwitchOver()
exten => 1,n(s3),Set(FAXFILE=${UNIQUEID})
exten => 1,n,Set(FAXPATH=/tmp/)
exten => 1,n,Set(FAXPAGES=0)
exten => 1,n,RxFAX(${FAXPATH}${FAXFILE}.tif,ecm)
exten => 1,n,GotoIf,$["${FAXPAGES}" = "0"] ? s20
exten => 1,n(s7),NoOp(REMOTE="${REMOTESTATIONID}" PAGES=${FAXPAGES} BITRATE=${FAXBITRATE} RESOLUTION=${FAXRESOLUTION})
exten => 1,n,Set(OFAXPAGES=${FAXPAGES})
exten => 1,n,Set(FAXPAGES=0)
exten => 1,n,System(FAXFILE="${FAXFILE}" FAXPATH="${FAXPATH}" REMOTESTATIONID="${REMOTESTATIONID}" FAXPAGES="${OFAXPAGES}" FAXBITRATE="${FAXBITRATE}" FAXRESOLUTION="${FAXRESOLUTION}" FAXSENDER="${CID}" MYFAX="${MYFAX}" /SCRIPT_PATH_TO_HANDLE_TIF)
exten => 1,n,Wait,1
exten => 1,n,Playback(vm-msgsaved)
exten => 1,n,Wait,1
exten => 1,n,Goto(1,s3)

exten => 1,n(s20),Wait,1
exten => 1,n,Hangup

exten => h,1,GotoIf,$["${FAXPAGES}" = "0"] ? 3
exten => h,2,Goto(1,s7)
exten => h,3,NoOp

Transmitting a fax

  • Make sure T.38 is enabled in sip.conf if you are going to use T.38.

The T.38 switchover should be done by the receiving party.

Please examine this snippet of code:

[faxout]
exten => s,1,Set(LOCALSTATIONID=Navynet.it FAX)
exten => s,n,Set(LOCALHEADERINFO=Navynet SRL offre soluzioni VOIP per call center)
exten => s,n,Set(FAXFILE=/root/fax/test3_opbx_rulez.tif)
exten => s,n,TxFAX(${FAXFILE},caller,ecm)
exten => h,1,NoOp(TX: REMOTESTATIONID is ${REMOTESTATIONID})
exten => h,n,NoOp(TX: PHASEESTATUS is ${PHASEESTATUS})

This basically works the same way as RxFAX. The difference is that you need a TiffG4 image file to be sent…

[djr]: another difference is this: after TxFAX completes, it does not
hang up.  So the 'h' extension above should be 's', with priority 'n'.

How to invoke TxFAX

The simplest solution is : open an empty file and copy the following code into it.

Channel: SIP/YOURCHANNEL/05595995995995
CallerID: My Name <My Number>
MaxRetries: 0
WaitTime: 30

; you can set variables here too!!
; Setting the file name is let as an exercise to the reader.
Set: LOCALSTATIONID=inxs2
Set: LOCALHEADERINFO=CallWeaver Fax with T38 

;Please note. 
;Setting the T38CALL channel variable before actually originating the call, 
;skips the RTP part and starts T38 negotiation directly. Don't use unless
;you are dialing on a SIP channel.
; be aware that some gateway (cisco, for example) do not allow direct T38 negotiation.
;Set: T38CALL=1
;Fax detection and switchover should be done by the receving party. Setting
;the following variable will enable CallWeaver to send the invite for the initial switchover if 
;a fax CNG is detected. (useless since trunk 2585)
;Set: T38TXDETECT=something 

Context: faxout
Extension: s
priority: 1

of course, change the channel to what you need.

Chown that file to the callweaver user and MOVE (not cp but mv !!) that file to the callweaver outgoing spool dir.

Look for something like *opbxspooldir => /var/spool/callweaver in your CallWeaver config file (callweaver.conf) That is your outgoing spool dir.

As soon as you copy that file to the spool, CallWeaver will start sending the fax.

${PHASEESTATUS} =0 variable will report a successful transaction.

Please note. Setting the T38CALL channel variable before actually originating the call, skips the RTP part and starts T.38 negotiation directly.

If you are experiencing bad behaviour:
  • are you using mv instead of cp to put the call file in the outgoing spool?

How to generate TIFF G4 images suitable for Fax transmission

This code (requires ghostscript) will convert input_file.pdf to a suitable tiff image which can be used by app_TxFAX:

gs -q -dNOPAUSE -dBATCH -dSAFER \
    -sDEVICE=tiffg4 \
    -sOutputFile=fax_test.tif \
    -f input_file.pdf

Ghostscript is able to convert postscript files, jpeg or gif images to TIFF format for faxing.

T38Gateway

This is an application that will do bridging between T.38 and the PSTN.

It is still experimental and your milage may vary.

Using it in a dialplan is simple: it is similar to Dial(), you specify a dial string (eg. ZAP/1/3214567 or SIP/outgoing/3124567), and it will call that number and bridge the calls.

Some notes:
  • Do not Answer() the call before calling T38Gateway(), because the fax could fail in the time taken to dial the other number. Let T38Gateway answer the call for you.
  • If you’re using RxFAX on another CallWeaver machine to terminate T.38, sometimes the fax CNG is not detected and the T.38 switchover doesn’t take place, so faxing happens over (unreliable!) voice. As a workaround for now, use FaxDetect(4000) and SipT38SwitchOver in the fax context to force a T.38 switchover:
[sipfax]
exten => s,1,FaxDetect(4000)
exten => s,n,Hangup()
exten => fax,1,SipT38SwitchOver()
exten => fax,n,RxFAX(/tmp/fax.tiff)
exten => fax,n,Hangup()

Additional notes

Please report details of your experience to the mailing list. Add bugs you may find to the bug tracker. We are trying to improve Fax support.

Basic checklist if T.38 does not work

  • check if your router is not messing up with the SIP headers when CallWeaver is running on 5060, check your router compatibility or put the CallWeaver onto a port different then 5060
  • are you using the latest CallWeaver Trunk and the latest SpanDSP snapshot ?
  • is t38udptlsupport enabled in sip.conf ?

Troubleshooting

You need more information to troubleshoot t.38 issues. Use the following settings to see what is going on at various layers.

  • Add ,debug flag to TxFax
  • Open logger.conf in the CallWeaver config dir and uncomment the line beginning with “full => ”
  • Start CallWeaver and from the CLI type:
    • sip debug
    • udptl debug
    • rtp debug
    • set verbose 9
    • set debug 9
Preparing for the call, use tethereal or tshark or tcpdump to sniff the traffic and save it on a file. Those applications are quite complex but something like the following may work:
  • $application -i $ETH_IF -n host $REMOTE_HOST_CALLWEAVER_IS_TALKING_TOO -s65000 -w $FILENAME
where :
  • $application is tcpdump, tethereal or tshark
  • ETH_IF is the interface (if only one, you may skip it)
  • $REMOTE_…. is self explaining
  • $FILENAME the dump file

Now try the call and at the end, stop $application and save the dump file. Open the full log in CallWeaver dir, take the interesting parts out (if there other calls in the meanwhile, please try to tidy the log)

Put those 2 files somewhere and tell us where to grab them (you may even post those logs to the list if you cannot put those files online).

FAQ

  • Q: What does “Unregistered channel type ‘Fax’ ” mean when I issue stop now at the console? A: This is from chan_fax. it has nothing to do with T38. Do not load it if you don’t know what it’s for. We should really write a chan_fax wiki page.
  • Q: Do I have to do anything special in the /dev directory? What if I am using Udev? A: No
  • Q: How can I email faxes to specific recipients? A: It’s been explained before! Do a Google search or check voip-info.org
  • Q: Can a DID be both a fax number and a voice number? A: Use the FaxDetect application (show FaxDetect) to detect if it’s a fax or a voice call. A: Yes, but in order to detect whether the call is voice or fax, you need to Answer it first. After this, you can do detection of fax tones and route it to another place in the dialplan to receive the fax.
  • Q: What is udptl.conf for? It’s there to define some parameters of the UDPTL data that CallWeaver is going to generate.
  • Q: Which fax machines/ATAs are known to work with T.38 in CallWeaver? A: Please see the T38 Compatibility List A: The T38 Compatibility List has just been added (end of march 2007) so it doesn’t represent the full situation. Please help us maintain this list.
  • Q: I try to send a fax from ATA → CallWeaver → A non-SIP channel → Gateway → PSTN, but it doesn’t work. Why? A: Simply because the only channel in CallWeaver supporting T.38 is SIP. This means you will have to do SIP all the way. You can’t use Woomera, IAX2 etc in between unless they are on localhost. Your Gateway also needs to support T.38. Basically ALL EQUIPMENT YOUR FAX IS PASSING HAS TO SUPPORT T.38 FOR IT TO WORK

Credits

Steve Underwood (aka coppice) for spandsp !!