HylaFax
About
Hylafax is "The world's most advanced open source fax server".
Click here to expand Table of Contents
- 1 Download
- 2 Dependencies
- 3 Installation
- 4 mod_spandsp
- 5 Configuration
- 6 Stop/ Start Hylafax
- 7 Minicom testing for CallerID
- 8 Incoming
- 8.1 Dialplan
- 8.2 ESL
- 8.3 File name based on UUID
- 9 Outgoing
- 10 Logs
- 11 Modem devices permissions issue
Download
Dependencies
apt-get update
apt-get install libtiff4-dev
Installation
cd hylafax-version
./configure (uses default values)
make
make install (must be root or equivalent)
mod_spandsp
The recommended way to integrate HylaFax with FreeSWITCH is to use emulated soft modem via mod\_spandsp
. Edit conf/autoload\_configs/spandsp.conf.xml
to include the following
<modem-settings>
<param name="total-modems" value="30"/>
</modem-settings>
After reloading mod_spandsp on fs_cli
fs> reload mod_spandsp
You will see new soft modems being created with relevant pointers to modem devices.
# ls -l /dev/FS*
lrwxrwxrwx 1 root root 10 2012-05-31 18:31 /dev/FS0 -> /dev/pts/4
lrwxrwxrwx 1 root root 10 2012-05-31 18:31 /dev/FS1 -> /dev/pts/5
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS10 -> /dev/pts/14
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS11 -> /dev/pts/15
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS12 -> /dev/pts/16
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS13 -> /dev/pts/17
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS14 -> /dev/pts/18
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS15 -> /dev/pts/19
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS16 -> /dev/pts/20
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS17 -> /dev/pts/21
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS18 -> /dev/pts/22
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS19 -> /dev/pts/23
lrwxrwxrwx 1 root root 10 2012-05-31 18:31 /dev/FS2 -> /dev/pts/6
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS20 -> /dev/pts/24
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS21 -> /dev/pts/25
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS22 -> /dev/pts/26
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS23 -> /dev/pts/27
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS24 -> /dev/pts/28
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS25 -> /dev/pts/29
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS26 -> /dev/pts/30
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS27 -> /dev/pts/31
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS28 -> /dev/pts/32
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS29 -> /dev/pts/33
lrwxrwxrwx 1 root root 10 2012-05-31 18:31 /dev/FS3 -> /dev/pts/7
lrwxrwxrwx 1 root root 10 2012-05-31 18:31 /dev/FS4 -> /dev/pts/8
lrwxrwxrwx 1 root root 10 2012-05-31 18:31 /dev/FS5 -> /dev/pts/9
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS6 -> /dev/pts/10
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS7 -> /dev/pts/11
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS8 -> /dev/pts/12
lrwxrwxrwx 1 root root 11 2012-05-31 18:31 /dev/FS9 -> /dev/pts/13
To test if the newly created soft modems are okay and respond to AT commands, you can find their support class by using cu command.
# apt-get install cu
# cu -l FS0
Connected
at+fclass=?
0,1,1.0
OK
Configuration
faxsetup (with default settings)
faxaddmodem FS0
faxaddmodem FS1
.
.
.
faxaddmodem FS29
Edit /etc/rc.local to start hfaxd, faxq and faxgetty at boot
# Starting the HylaFAX hfaxd and faxq Daemons at Boot.
/usr/local/sbin/hylafax start
# Starting faxgetty for incoming Fax
m0:2345:respawn:/usr/local/sbin/faxgetty FS0
m1:2345:respawn:/usr/local/sbin/faxgetty FS1
m2:2345:respawn:/usr/local/sbin/faxgetty FS2
m3:2345:respawn:/usr/local/sbin/faxgetty FS3
m4:2345:respawn:/usr/local/sbin/faxgetty FS4
m5:2345:respawn:/usr/local/sbin/faxgetty FS5
m6:2345:respawn:/usr/local/sbin/faxgetty FS6
m7:2345:respawn:/usr/local/sbin/faxgetty FS7
m8:2345:respawn:/usr/local/sbin/faxgetty FS8
m9:2345:respawn:/usr/local/sbin/faxgetty FS9
m10:2345:respawn:/usr/local/sbin/faxgetty FS10
m11:2345:respawn:/usr/local/sbin/faxgetty FS11
m12:2345:respawn:/usr/local/sbin/faxgetty FS12
m13:2345:respawn:/usr/local/sbin/faxgetty FS13
m14:2345:respawn:/usr/local/sbin/faxgetty FS14
m15:2345:respawn:/usr/local/sbin/faxgetty FS15
m16:2345:respawn:/usr/local/sbin/faxgetty FS16
m17:2345:respawn:/usr/local/sbin/faxgetty FS17
m18:2345:respawn:/usr/local/sbin/faxgetty FS18
m19:2345:respawn:/usr/local/sbin/faxgetty FS19
m20:2345:respawn:/usr/local/sbin/faxgetty FS20
m21:2345:respawn:/usr/local/sbin/faxgetty FS21
m22:2345:respawn:/usr/local/sbin/faxgetty FS22
m23:2345:respawn:/usr/local/sbin/faxgetty FS23
m24:2345:respawn:/usr/local/sbin/faxgetty FS24
m25:2345:respawn:/usr/local/sbin/faxgetty FS25
m26:2345:respawn:/usr/local/sbin/faxgetty FS26
m27:2345:respawn:/usr/local/sbin/faxgetty FS27
m28:2345:respawn:/usr/local/sbin/faxgetty FS28
m29:2345:respawn:/usr/local/sbin/faxgetty FS29
The directories are located in
/var/spool/hylafax
Configuration files for individual soft modems created by mod\_spandsp
are in /var/spool/hylafax/etc/config.FS\*
Stop/ Start Hylafax
To start/stop hfaxd, the HylaFax Daemon and faxq, the HylaFax queue manager.
/etc/init.d/hylafax {stop|start|restart}
Minicom testing for CallerID
Use minicom on the tty (instead of faxgetty). And then do the following:
ATZ
AT+VCID=1
ATI
ATI3
And then send a call to that modem. Check what the CallerID display says.
Incoming
For incoming Fax sessions, the call should be bridged to modem/x/y where x is the slot and y is the dialed number. Use a to get the next available slot and number.
Dialplan
Edit the dialplan conf/dialplan/default.xml to include the following snippet or similar commands over ESL.
<extension name="fax_receive">
<condition field="destination_number" expression="^(.*)$">
<action application="answer" />
<action application="playback" data="silence_stream://2000"/>
<action application="bridge" data="modem/a/a"/>
<action application="hangup"/>
</condition>
</extension>
ESL
#!/usr/bin/env python
import SocketServer
from ESL import *
class ESLRequestHandler(SocketServer.BaseRequestHandler ):
def setup(self):
print self.client_address, 'connected!'
fd = self.request.fileno()
print fd
con = ESLconnection(fd)
print "Connected: "
print con.connected()
if con.connected():
info = con.getInfo()
uuid = info.getHeader("unique-id")
print uuid
con.execute("answer", "", uuid)
con.executeAsync("bridge", "modem/1/a/a", uuid)
#server host is a tuple ('host', port)
server = SocketServer.ThreadingTCPServer(('localhost', 8888), ESLRequestHandler)
server.serve_forever()
File name based on UUID
Bridge call to modem/1/a/uuid, where uuid is a variable with value equal to the uuid of the call
Edit /var/spool/hylafax/etc/config.FS0, config.FS1 etc to include the following
RingsBeforeAnswer: 2 (you probably already have this configured, but check)
ModemResetCmds: AT+VCID=1
CallIDPattern: "NMBR="
CallIDPattern: "NDID="
Restart faxgetty. Then in your bin/faxrcvd $CALLID1 will refer to the CallerID, and $CALLID2 will refer to the DID. Edit bin/faxrcvd to include the following
DID=$CALLID1
UUID=`echo $CALLID2 | cut -d "/" -f 2-`
NEWFILE=$UUID
mv -f $FILE $NEWFILE
Outgoing
Use sendfax for putting your outgoing Faxes in the queue.
sendfax -n -vv -d <destination_number> <filename.ps>
Edit the dialplan to include a bridge to the called number.
<extension name="fax_transmit">
<condition field="destination_number" expression="^(.*)$">
<action application="bridge" data="freetdm/1/a/$1"/>
<action application="hangup"/>
</condition>
</extension>
Logs
The log files with detailed message transaction between modem and hylafax are in directory /var/spool/hylafax/log
The transfer status of each received or sent fax is stored in /var/spool/hylafax/etc/xferfaxlog
in tab separated format with the following parameters
date - The date and time of the transaction in the format MM/DD/YY HH:MM , where MM is the numeric month, DD the numeric day, YY the last two digits of the year, and HH:MM is the time in 24-hour format.
commid - The communication identifier for the call.
modem - The device identifier for the modem that was used to do the send or receive.
jobid - The job number for outbound calls.
jobtag - The client-specified job tag for outbound calls.
fax.tif - The associated recvq fax TIFF file for the event.
sender - The sender/receiver’s electronic mailing address (facsimile receptions are always attributed to the ‘‘fax’’ user).
dest-number - The phone number dialed for outgoing calls.
TSI - The Transmitter Subscriber Identification string (as received) for incoming calls.
CSI - The Caller Subscriber Identification string of the remote machine (as reported) for outgoing calls.
local-number - The local phone number on which the data was received.
params - The negotiated facsimile session parameters used for transferring data encoded as described below.
#pages - The total number of pages transferred.
jobtime - The duration of the session; in the format HH:MM:SS . This time includes setup overhead and any time spent cleaning up after a call.
conntime - The time spent on the phone; in the format HH:MM:SS . This should be the time used by the Telco/PTT (see https://freeswitch.org/confluence/display/FREESWITCH/Glossary#Glossary-Telco) to calculate usage charges.
reason - A string that indicates if any problem occurred during the session.
CIDName - The received CIDName value for the session.
CIDNumber - The received CIDNumber value for the session.
owner - The login name of the job owner.
dcs - The T.30 DCS string that was used in the facsimile communication.
Modem devices permissions issue
If running FS as a non-root user, mod\_spandsp
will fail when trying to create the /dev/FS
devices (the /dev/pts
are a non issue). The solution for this is to edit conf/autoload\_configs/spandsp.conf.xml
to include the undocumented "directory" parameter:
<modem-settings>
<param name="total-modems" value="30"/>
<param name="directory" value="/dev/FS"/>
</modem-settings>
Then modify the init.d script of FS to include the creation of /dev/FS
and its correct permission and ownership settings.
In the SET section
FS_USER=freeswitch
FS_GROUP=freeswitch
FS_DEVDIR=/dev/FS
inside do_start()
# Create /dev/FS for mod_spandsp soft modems
if [ $FS_DEVDIR ] ; then
mkdir $FS_DEVDIR
chown $FS_USER:$FS_GROUP $FS_DEVDIR
chmod -R 0775 $FS_DEVDIR
fi