Contents |
Note: The following tutorial is adapted from a post by Alex Balashov on our now-deprecated blog (which the Evariste Workshop is meant to replace) in December 2007, revised slightly in December 2008 for some content.
I recently deployed Asterisk/IAXmodem/HylaFAX as a fairly high-volume fax-to-email gateway solution. In the process of so doing, I learned that there is a lot of good information out there -- in bits and pieces -- but not really a good, insightful tutorial to sum it all up conceptually to any degree of satisfying completeness, let alone up-front discussion of some theoretical and methodological questions, caveats, drawbacks and pitfalls that are useful in attempting a real-world deployment in a serious business environment.
It is my intent to provide something reaching in that direction here. I mean that in the most humble way possible; the open-source focused VoIP community could benefit from an involved synthesis of some of the relevant issues. By no means do I command the most comprehensive insights -- this is a new project for me, and that's why I'm eager to share what I've learned. Corrections, additions, questions and comments are absolutely welcome - please post comments or drop me a line!
This article does presume some familiarity with Asterisk and IP telephony on a technical level.
By the way, I have seen that packaged, integrated Asterisk GUI solutions such as Trixbox and FreePBX can take care of a lot of this for you automatically. If you like that, by all means, stick with it. Personally, I am one of those Asterisk enthusiasts that prefers the level of control and flexibility that comes with rolling one's own installation from scratch, writing the configuration manually, and so on. Ironically, I've found that it keeps things pretty simple. I've seen the immensely complicated and metadata-rich configs that FreePBX & co. put out; colour me several shades of not impressed. Too hard to figure out, modify, customise, or otherwise access the inner workings. But if you don't really want to roll your own solution, this article is probably not for you.
If you already know everything about your wants and needs in this area and are just looking for a tutorial on the technical nitty gritty, skip this section.
Believe it or not, much that goes in business these days still relies on analog facsmile technology, especially where signed paperwork, contracts, and financial documents bearing some measure of legally certifiable authenticity are required. If you are in business, chances are that you have a fax machine.
Fax-to-email functionality entails setting up an electronic interface that mimics the behaviour of a conventional fax machine in order to send and receive faxes from conventional fax machines. (If you are primarily receiving documents from electronic / digital sources, chances are you should be using e-mail or FTP for this.) The fax transmission is then converted to an electronic format (such as Adobe PDF) and automatically e-mailed as an attachment to the correct recipient.
This type of interface technology -- often known and branded as "electronic fax" or "e-fax" -- is about moving forward and embracing the migration to computer-based telephony1 while looking backward in acknowledgment that analog fax is likely to be around for some time yet. Until we come up with better, universal, integrated and legally/regulatorily viable ways of digitally "signing" documents at the very least, and possibly beyond that simply for reasons of lopsided technological development and acceptance, as part of the all-around division of labour in the so-called global economy.
If you are a provider of retail or wholesale end-subscriber telecommunications services, unified messaging, or play in the PSTN origination and termination space, etc. the reasons for why you may want to consider this option are fairly obvious, and in all likelyhood you already provide this service to your clients in some fashion.
For a consumer of these services, the question is almost entirely economic. You may already be a customer of one of the numerous services that pioneered this type of product some years ago, such as uReach or quite a few others. It is also a big hit with enhanced service providers participating in the "unified messaging" space (e-mail + voicemail + fax + anything else delivered to one messaging portal). If you have some type of "e-fax" service and are happy with it, the rule is the same as with other mission-critical services on which your business depends that are outside your core competency and competitive advantage: stick with it. It works well, does the job, and frees you from all the financial and technical headaches of figuring out and maintaining it yourself.
For my client, volume and ROI was the central element of this polemic. The company had a large number of employees with fax numbers, but only a small percentage of them routinely received faxes. However, the posture of the business model dictated that pretty much all of them needed to have fax numbers in principle. Also, the bulk of the employees were very low-ROI, specifically as far as that portion of their productivity that benefits from fax usage is concerned. Within the context of fax expenditures as such, marginal product of labour was incredibly, vastly lower than marginal cost. On top of that, the client had already deployed an Asterisk-based IP telephony system internally and had a large amount of PRI circuits with plenty of spare channel capacity that could be leveraged to bring fax services in-house and save money. The cost justification was clearly there.
Of course, you might benefit from this solution whether or not you share my client's particular cost structure and ROI dilemma. Surely you've seen what happens in, for example, a busy sales organisation when large crowds of employees assemble around a shared fax machine to wait for and collect their transmissions, whose sources are queuing behind a perenially "busy" fax line? You could be losing more than an hour a day of potential employee productivity on this waiting game, not to mention countless additional opportunities. With the right combination of technical capital, business need and fax volume, you may be better off not outsourcing your fax services, but even if you are, definitely invest in individual fax-to-email services one way or another! Keep your employees at their desks, your paper and toner costs low, and your faxes coming in quickly, expediently and simultaneously.
If fax is used in the course of your daily business operations to any significant degree whatsoever, you don't have time or money for the opportunity costs of doing things the old way.
In order to swing your own fax interface, you need more than just an analog telephony interface. You need something that can emulate a fax machine's DSP (Digital Signal Processor), which is essentially the same sort of DSP as in a modem. Some fax interface devices accomplish this in hardware DSP chips, the most obvious being a conventional fax machine. But it is also possible to emulate this functionality purely in software. That's the IAXmodem part of this equation. IAXmodem uses an open-source library called SpanDSP to perform its magic.
IAXmodem interfaces with Asterisk using IAX (Inter-Asterisk eXchange), a VoIP signaling and trunking protocol developed entirely in connection with Asterisk and primarily for the purpose of getting calls from one Asterisk PBX to another. It could have used SIP, or whatever -- it just happens to use IAX, and thus, by that virtue, also happens to require Asterisk to front it when interfacing with (decidedly non-IAX) PSTN call endpoints. I suppose if you have IAX trunking to a PSTN origination provider (which some offer) it is theoretically possible to use IAXmodem without Asterisk, but I wouldn't recommend it because IAXmodem by itself is pretty dumb, and does one thing. Plus, it has no measures to compensate for QoS issues such as jitter buffers for unevenly spaced media streams. From a call control standpoint, it is much wiser to pass calls through Asterisk.
IAXmodem itself is just a dumb DSP. To process and convert received fax data from whatever DSP source, you need actual fax software; that's HylaFAX.
You may have picked up on the fact that IAXmodem uses VoIP to provide the link between Asterisk and the actual modem DSP emulation component.
Much has been said and much has been made of the perils of running analog fax traffic encapsulated in a packetised form over an IP network, and not without reason. It generally doesn't work well. Fax terminals are extremely sensitive to the effects of delay and jitter on the encoded analog data; even slight packet loss or out-of-sequence errors in the IP leg of the transport can produce protocol errors that will cause a fax transmission to fail, or show up tragically garbled. The overall impact of the fundamental unreliability of IP -- especially over the Internet -- is much greater on fax traffic than it is on subjective perceptions of voice quality.
In order to get analog pass-thru on fax data to work, you need to use a clear-channel PCM codec whose accommodation of the analog spectrum equals the full extent of the 3.1 KHz analog bandwidth on standard analog voice lines. This means ITU-T G.711 with either μ-law (North American) or A-law (European) companding. But even then, it is generally impossible to run this traffic reliability over the Internet; too much data simply gets lost, or arrives in a manner inconsistent with the tight jitter requirements for successful pass-thru. This is the problem T.38 is intended to solve; it packetises fax data in ways more consistent with the way Internet applications usually transmit data, rather than attempting to graft high-throughput real-time voice data with extremely low packetisation durations onto an infrastructure whose QoS is not inherently designed to handle it well at present. Then, two T.30 (traditional analog fax) terminals can interface with each other over a more reliable data transport conduit that is entirely transparent to them.
Fortunately, moving fax data in an analog pass-thru format over a LAN -- not the greater Internet -- is generally reliable. It does depend on how your LAN is designed and what kind of contention exists on it. If you're moving a whole, whole lot of data across your LAN without any VoIP-oriented QoS precedence measures in place, it may still be problematic. But in general, it is possible. The IAXmodem FAQ has the following to offer:
As this relates to the setup being discussed here, you do not have to move the fax data over an IP network at all if you don't want to. You can set up HylaFAX, IAXmodem and Asterisk on a server that has analog lines (PRI or POTS) running into it, and thus take the fax traffic in unmitigated analog form directly at the source.
The setup I deployed does decompose this assembly and frame it over an IP data plane: The client had PRIs running into Asterisk boxes with Sangoma T1 cards. These media gateways then forward the call via SIP (using G.711μ-law for the RTP) to an internal fax server on the LAN that runs Asterisk, IAXmodem and HylaFAX. Asterisk receives those calls and forwards them onto IAXmodem using IAX. This has not given us any problems. Just make sure that the you are using G.711; if you use G.729 or some other high-compression codec, the acoustic characteristics of the voice signal are mangled in ways that humans do not necessarily find objectionable, but faxes do, thus breaking the fax transmission entirely -- as it reconstructs digital data from analog sound data over a larger bandwidth and sample complexity than is necessary for subjectively acceptable human speech.
Also, do note that there is an analog interface to the PSTN somewhere on our LAN here. If you are getting your PSTN origination entirely via SIP handoff, your success may vary. If it is over the Internet, chances are it won't work at all. If you are colocated with a telco or have a dedicated point-to-point IP link to your provider, perhaps it will be okay; it just depends.
I do recommend that you run the Asterisk instance that terminates the fax calls and funnels them into IAXmodem on the same machine. But it is not strictly necessary; in fact, the reason we forward the calls via SIP internally is more for unrelated engineering reasons. We could have just as well set up IAXmodem on one machine, and had the modems register as IAX peers right on the media gateways, and I am confident it would have worked fine, especially with the jitter buffer enabled. If you have experiences to the contrary, feel free to share.
This type of setup is, much like VoIP products in general, very telephone number-intensive, but especially so because the direct fax number dialed is pretty much your only destination criterion for routing calls to particular users. Unless you plan to route faxes to particular users based on caller ID or some other common call data addressable from within HylaFAX, you're pretty much going to have order direct fax numbers for every user. Luckily, despite heavy numbering space utilisation, getting a block of DIDs for this purpose from your carrier is not particularly expensive.
The more important point is that you need to have a way to get faxes coming through the door to particular users' mailboxes, and the direct fax number dialed is the best way to do it. This ability to transmit the number dialed by the far end into the application is known in telco terminology as DNIS (Dialed Number Information Service), which has its roots in legacy terminology that covers making DID (Direct Inward Dial) work with business PBXs by transmitting the number dialed from the telco switch as a separate item of signaling data. (Think about it -- how else does a telephone endpoint receiving a call inherently "know" what number a user dialed to reach it? Traditional telephone switching was purely a matter of cross-connecting DS0 signals.)
I cannot give an exhaustive tutorial on every aspect of setting up Asterisk for this task. If you do not know how to use Asterisk, learn to use it first, and this article will serve you better. There are plenty of resources online and offline to get you started, plus a resourceful, helpful and abundant user community to answer your questions.
You need to get your fax-bound calls into an Asterisk instance using one of the methods mentioned above, or some other method. This will be our departure point. In my case, this is really simple; on our media gateways, we have a dial plan that forwards DID ranges associated we've chosen to allocate for fax to the internal fax server via SIP:
;;; Context for calls coming in from PSTN.
[from-pstn]
exten => 8885551212,1,Goto(from-pstn-fax,fax,1)
...
; Fax routing.
[from-pstn-fax]
exten => fax,1,Dial(SIP/${DNID}@Fax,15,r)
exten => fax,n,Busy()
exten => fax,n,Hangup()
Notice that we supply the ${DNID} (Dialed Number ID) as the extension to reach at the fax server SIP trunk ('Fax'). This is because we have a dedicated dial plan ruleset for fax, with an extension called 'fax', so if we sent ${EXTEN}, its value would be 'fax', which is not particularly useful to the fax server as it provides no DNIS. But we might as well have just done:
exten => 8885551212,1,Dial(SIP/${EXTEN}@Fax,15,r)
Purely a matter of style.
Because our fax server only accepts fax calls, we just accept any number inward in the dial plan there:
[from-sip-external]
exten => _.,1,Dial(IAX2/FaxDSP0/${EXTEN},15,r)
exten => _.,2,Dial(IAX2/FaxDSP1/${EXTEN},15,r)
exten => _.,3,Dial(IAX2/FaxDSP2/${EXTEN},15,r)
exten => _.,4,Dial(IAX2/FaxDSP3/${EXTEN},15,r)
exten => _.,5,Dial(IAX2/FaxDSP4/${EXTEN},15,r)
exten => _.,6,Dial(IAX2/FaxDSP5/${EXTEN},15,r)
exten => _.,7,Dial(IAX2/FaxDSP6/${EXTEN},15,r)
exten => _.,8,Dial(IAX2/FaxDSP7/${EXTEN},15,r)
exten => _.,9,Dial(IAX2/FaxDSP8/${EXTEN},15,r)
exten => _.,10,Dial(IAX2/FaxDSP9/${EXTEN},15,r)
exten => _.,11,Dial(IAX2/FaxDSP10/${EXTEN},15,r)
exten => _.,12,Dial(IAX2/FaxDSP11/${EXTEN},15,r)
exten => _.,13,Dial(IAX2/FaxDSP12/${EXTEN},15,r)
exten => _.,14,Dial(IAX2/FaxDSP13/${EXTEN},15,r)
exten => _.,15,Dial(IAX2/FaxDSP14/${EXTEN},15,r)
exten => _.,16,Dial(IAX2/FaxDSP15/${EXTEN},15,r)
exten => _.,17,Dial(IAX2/FaxDSP16/${EXTEN},15,r)
exten => _.,18,Dial(IAX2/FaxDSP17/${EXTEN},15,r)
exten => _.,19,Dial(IAX2/FaxDSP18/${EXTEN},15,r)
exten => _.,20,Dial(IAX2/FaxDSP19/${EXTEN},15,r)
exten => _.,n,Congestion()
exten => _.,n,Hangup
The 'FaxDSPX[X]' destinations are registered IAX peers provided by IAXmodem. We have twenty inward fax channels (distinct IAXmodem entities) configured separately. As you can see above, we just cycle through them like a rollover hunt group; if the first fax DSP is busy, we go on the next, and so on. Remember that the Dial() application returns the execution scope from the context if the call is successful and does not continue to execute subsequent priorities.
Download IAXmodem and compile it, or install a package if your distribution supplies one. IAXmodem comes with the SpanDSP library.
Next, you need to decide how many "modems" you want to configure. We configured 20 in our case. Despite the high-volume fax environment, the need for more than five or so is not in evidence, but your oversubscription ratios may vary significantly. The considerations relevant to computing power and system dimensioning notwithstanding, I know of no theoretical limit to the amount of virtual IAXmodems one can configure, so if you expect to need three PRIs worth of capacity, have at it.
IAXmodems are defined in /etc/iaxmodem/ttyIAXy, where 'y' is the number of the serial device. They can start at 0 and are numbered upward, e.g. ttyIAX0 through ttyIAX20. The file is plain text and contains a stanza like so:
device /dev/ttyIAX0 owner uucp:uucp mode 660 port 4570 refresh 60 server 66.1.1.1 peername FaxDSP0 secret FaxDSP0 cidname Evariste Systems cidnumber 6789540670 codec ulaw
Each IAXmodem you configure creates a self-contained serial device (used by HylaFAX the same way a real serial port would be, by way of the same low-level serial I/O APIs) and a distinct registered IAX peer. This means that if you plan to have more than one IAXmodem, the IAX peers need to be registered from unique UDP ports in order to be uniquely reachable. So, if you define more than one ttyIAX, make sure to give them unique port numbers. I just started numbering mine one above the standard IAX port (4569) at 4570, 4571, 4572, and so on.
Also, the 'cidnumber' and others above are for outbound purposes and should not particularly concern you.
Now you need to create dedicated IAXmodem 'listeners' on each of these serial devices; this is what provides for something actually picking up when it gets a call. The listener daemons are started by running:
iaxmodem ttyIAXnn
The easiest way to ensure a listener is always running on each IAXmodem "port" is to put them in '/etc/inittab' as parts of a runlevel:
i0:2345:respawn:/usr/sbin/iaxmodem ttyIAX0 i1:2345:respawn:/usr/sbin/iaxmodem ttyIAX1 i2:2345:respawn:/usr/sbin/iaxmodem ttyIAX2 i3:2345:respawn:/usr/sbin/iaxmodem ttyIAX3 i4:2345:respawn:/usr/sbin/iaxmodem ttyIAX4 i5:2345:respawn:/usr/sbin/iaxmodem ttyIAX5 i6:2345:respawn:/usr/sbin/iaxmodem ttyIAX6 i7:2345:respawn:/usr/sbin/iaxmodem ttyIAX7 i8:2345:respawn:/usr/sbin/iaxmodem ttyIAX8 i9:2345:respawn:/usr/sbin/iaxmodem ttyIAX9 i10:2345:respawn:/usr/sbin/iaxmodem ttyIAX10 i11:2345:respawn:/usr/sbin/iaxmodem ttyIAX11 i12:2345:respawn:/usr/sbin/iaxmodem ttyIAX12 i13:2345:respawn:/usr/sbin/iaxmodem ttyIAX13 i14:2345:respawn:/usr/sbin/iaxmodem ttyIAX14 i15:2345:respawn:/usr/sbin/iaxmodem ttyIAX15 i16:2345:respawn:/usr/sbin/iaxmodem ttyIAX16 i17:2345:respawn:/usr/sbin/iaxmodem ttyIAX17 i18:2345:respawn:/usr/sbin/iaxmodem ttyIAX18 i19:2345:respawn:/usr/sbin/iaxmodem ttyIAX19
NOTE: Resist any temptation to give the process IDs names longer than three characters. When I had then named iax0, iax1, ... instead of ia0, ia1, ... not all of the iaxmodem processes would start. I am not sure why. Something with the way init(1) works, I suppose.
Restart init:
init q
The IAXmodem end of the setup is now complete. Remember that each IAXmodem listener is an IAX peer, and will try to register with Asterisk on the standard IAX port (4569). You will need to provide IAX peer definitions for each unique IAXmodem in '/etc/asterisk/iax.conf':
;;; ;;; IAX2 config for fax trunking to SpanDSP/IAXmodem/HylaFAX. ;;; [general] bindport = 4569 ; Port to bind to (IAX is 4569) bindaddr = 0.0.0.0 ; Address to bind to (all addresses on machine) disallow=all allow=ulaw allow=alaw mailboxdetail=yes iaxcompat=yes jitterbuffer=yes [FaxDSP0] type=friend username=FaxDSP0 secret=FaxDSP0 host=127.0.0.1 port=4570 disallow=all allow=ulaw qualify=yes [FaxDSP1] type=friend username=FaxDSP1 secret=FaxDSP1 host=127.0.0.1 port=4571 disallow=all allow=ulaw qualify=yes [ ... and so on ...]
You should now be able to dial into a fax DID and hear something resembling a modem pick up on the far end. If something seems amiss, verify that your dial plan is working correctly by running the Asterisk CLI and turning verbosity to high:
asterisk -r set verbose 60
Then try dial a fax number, and see what transpires:
-- Executing Dial("SIP/66.1.1.1-b77103a0", "IAX2/FaxDSP0/h|15|r") in new stack -- Called FaxDSP0/h
-- Call accepted by 127.0.0.1 (format ulaw)
-- Format for call is ulaw
-- IAX2/FaxDSP0-9 is ringing
-- IAX2/FaxDSP0-9 answered SIP/10.2.2.68-b77103a0
If IAXmodem is not working correctly, you may see something like:
-- Executing Dial("SIP/66.1.1.1-b77057f0", "IAX2/FaxDSP0/8885551212|15|r") in new stack
-- Called FaxDSP0/8885551212 -- IAX2/FaxDSP0-62 is circuit-busy
-- Hungup 'IAX2/FaxDSP0-62'
== Everyone is busy/congested at this time (1:0/1/0)
You can debug by disabling the 'iaxmodem' spawning for the current runlevel in '/etc/inittab' temporarily and run 'iaxmodem' on the terminal manually against a particular IAXmodem port (the first one in your dial plan hunting scheme):
iaxmodem ttyIAX0
If you are not sure whether the IAX registration against Asterisk is completing successfully, you can connect to the Asterisk CLI:
asterisk -r
And issue the command 'iax2 show peers':
fax*CLI> iax2 show peers Name/Username Host Mask Port Status FaxDSP19/FaxDSP 127.0.0.1 (S) 255.255.255.255 4589 OK (3 ms) FaxDSP18/FaxDSP 127.0.0.1 (S) 255.255.255.255 4588 OK (3 ms) FaxDSP17/FaxDSP 127.0.0.1 (S) 255.255.255.255 4587 OK (1 ms) FaxDSP16/FaxDSP 127.0.0.1 (S) 255.255.255.255 4586 OK (3 ms) FaxDSP15/FaxDSP 127.0.0.1 (S) 255.255.255.255 4585 OK (2 ms) FaxDSP14/FaxDSP 127.0.0.1 (S) 255.255.255.255 4584 OK (1 ms) FaxDSP13/FaxDSP 127.0.0.1 (S) 255.255.255.255 4583 OK (3 ms) FaxDSP12/FaxDSP 127.0.0.1 (S) 255.255.255.255 4582 OK (3 ms) FaxDSP11/FaxDSP 127.0.0.1 (S) 255.255.255.255 4581 OK (3 ms) FaxDSP10/FaxDSP 127.0.0.1 (S) 255.255.255.255 4580 OK (3 ms)
If you're really stuck, try turning on IAX debugging:
iax2 debug
This can give some hints:
Rx-Frame Retry[ No] -- OSeqno: 000 ISeqno: 000 Type: IAX Subclass: REGREQ Timestamp: 00003ms SCall: 06029 DCall: 00000 [10.2.2.63:4570] USERNAME : FaxDSP0 REFRESH : 60
If you place a call in, you can also verify that an IAXmodem DSP picked up by doing:
fax*CLI> show channels Channel Location State Application(Data)IAX2/FaxDSP0-3 (None) Up Bridged Call(SIP/66.1.1.1-b77 SIP/10.2.2.68-b77057 8885551212@from-sip- Up Dial(IAX2/FaxDSP0/8885551212|1 2 active channels 1 active call
HylaFAX is a complicated software package that can do many different things entirely outside the scope of this tutorial. However, if you're just wanting to push out faxes from it via e-mail, it should be relatively simple, as the stock package comes with decent pre-built configurations for dialing rules and so on.
Install HylaFAX, either from source or from a package. Start the services to make sure they all work out of the box:
[root@fax ~]# /etc/init.d/hylafax start Starting HylaFAX queue manager (faxq): [ OK ] Starting HylaFAX server (hfaxd): [ OK ] Restarting HylaFAX modem manager (faxgetty): [ OK ]
Next, you will need to put up HylaFAX's 'faxgetty' listeners on the IAXmodems. Back to '/etc/inittab/':
m0:2345:respawn:/usr/sbin/faxgetty ttyIAX0 m1:2345:respawn:/usr/sbin/faxgetty ttyIAX1 m2:2345:respawn:/usr/sbin/faxgetty ttyIAX2 m3:2345:respawn:/usr/sbin/faxgetty ttyIAX3 m4:2345:respawn:/usr/sbin/faxgetty ttyIAX4 m5:2345:respawn:/usr/sbin/faxgetty ttyIAX5 m6:2345:respawn:/usr/sbin/faxgetty ttyIAX6 m7:2345:respawn:/usr/sbin/faxgetty ttyIAX7 m8:2345:respawn:/usr/sbin/faxgetty ttyIAX8 m0:2345:respawn:/usr/sbin/faxgetty ttyIAX9 m10:2345:respawn:/usr/sbin/faxgetty ttyIAX10 m11:2345:respawn:/usr/sbin/faxgetty ttyIAX11 m12:2345:respawn:/usr/sbin/faxgetty ttyIAX12 m13:2345:respawn:/usr/sbin/faxgetty ttyIAX13 m14:2345:respawn:/usr/sbin/faxgetty ttyIAX14 m15:2345:respawn:/usr/sbin/faxgetty ttyIAX15 m16:2345:respawn:/usr/sbin/faxgetty ttyIAX16 m17:2345:respawn:/usr/sbin/faxgetty ttyIAX17 m18:2345:respawn:/usr/sbin/faxgetty ttyIAX18 m19:2345:respawn:/usr/sbin/faxgetty ttyIAX19
Restart init:
init q
Verify that faxgetty is in fact running:
[root@fax ~]# ps aux | grep faxgetty uucp 21847 0.0 0.0 5400 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX15 uucp 21848 0.0 0.0 5696 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX7 uucp 21851 0.0 0.0 4472 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX6 uucp 21852 0.0 0.0 6076 1636 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX5 uucp 21853 0.0 0.0 5792 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX16 uucp 21854 0.0 0.0 6360 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX3 uucp 21855 0.0 0.0 5368 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX17 uucp 21856 0.0 0.0 5024 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX2 uucp 21857 0.0 0.0 6236 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX18 uucp 21858 0.0 0.0 4480 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX14 uucp 21859 0.0 0.0 5376 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX1 uucp 21860 0.0 0.0 6288 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX4 uucp 21861 0.0 0.0 4736 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX19 uucp 21862 0.0 0.0 4712 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX0 uucp 21863 0.0 0.0 5664 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX13 uucp 21864 0.0 0.0 5804 1636 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX11 uucp 21865 0.0 0.0 5176 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX12 uucp 21866 0.0 0.0 6268 1636 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX8 uucp 21867 0.0 0.0 5728 1632 ? Ss 18:54 0:00 /usr/sbin/faxgetty ttyIAX10 root 21874 0.0 0.0 4492 648 pts/3 S+ 18:56 0:00 grep faxgetty
There are only two things you should need to modify. One is the inward fax distribution script. It's called 'FaxDispatch'. Where it lives is somewhat installation/distribution-dependent. On our CentOS fax server, it is in '/var/spool/hylafax/etc/'.
This is a bash shell script at heart, and controls HylaFAX's behaviour by setting two environment variables:
# By default, e-mail unroutable faxes to the secretary. SENDTO=secretary@faxes-receivable.evaristesys.com; # In PDF format. FILETYPE=pdf;
This script is passed numerous environment variables by HylaFAX (which invokes it internally) as well. Some of these ($SENDER, $CIDNUMBER, etc.) are mentioned in the comments in the stock file that is distributed with the package. However, if you are planning on routing by DNIS, you should know that the dialed number is passed to HylaFAX in this particular setup as $CALLID4. Not $CALLID, but $CALLID4. See the man page for faxrcvd(1) if you care.
Most information out there entreats you do something like this:
case "$CALLID4" in
8885551212)
# All toll-free faxes.
SENDTO=bob@evaristesys.com;
FILETYPE=pdf;;
*)
# All others.
SENDTO=employee@evaristesys.com;
FILETYPE=pdf;;
esac
But remember that this is a shell script, so you can build all sorts of outboard logic into it. In our case, we have a script that dips the employee database and automatically figures out which e-mail address to route the fax to:
DEST_EMAIL=$(/usr/bin/perl /usr/local/fax_route_dip/fax_route_dip.pl $CALLID4)
echo "Routing to: $DEST_EMAIL ($CALLID4)" >> /tmp/hylafax_routing.dbg.out
if [ $DEST_EMAIL == "NIL" ];
then
SENDTO=Faxmaster@evaristesys.com;
FILETYPE=pdf
else
SENDTO=$DEST_EMAIL
FILETYPE=pdf
fi
You also need to create configuration files in the same 'etc' directory for every IAXmodem listener that contain basic fax and modem-related configuration parameters. For the most part, these are fairly unimportant, but they need to be there. The files are called 'config.ttyIAXnn', e.g. config.ttyIAX0:
[root@fax etc]# more config.ttyIAX0 CountryCode: 1 AreaCode: 800 FAXNumber: +1.800.555.1212 LongDistancePrefix: 1 InternationalPrefix: 011 DialStringRules: etc/dialrules ServerTracing: 0xFFF SessionTracing: 0xFFF RecvFileMode: 0600 LogFileMode: 0600 DeviceMode: 0600 RingsBeforeAnswer: 1 SpeakerVolume: off GettyArgs: "-h %l dx_%s" LocalIdentifier: "IAXmodem0" TagLineFont: etc/lutRS18.pcf TagLineFormat: "From %%l|%c|Page %%P of %%T" MaxRecvPages: 200 # # # Modem-related stuff: should reflect modem command interface # and hardware connection/cabling (e.g. flow control). # ModemType: Class1 # use this to supply a hint# # Enabling this will use the hfaxd-protocol to set Caller*ID # #ModemSetOriginCmd: AT+VSID="%s","%d" # # If "glare" during initialization becomes a problem then take # the modem off-hook during initialization, and then place it # back on-hook when done. # #ModemResetCmds: "ATH1nAT+VCID=1" # enables CallID display #ModemReadyCmds: ATH0 Class1AdaptRecvCmd: AT+FAR=1 Class1TMConnectDelay: 400 # counteract quick CONNECT response # # If you have trouble with V.17 receiving or sending, # you may want to enable one of these, respectively. # #Class1RMQueryCmd: "!24,48,72,96" # enable this to disable V.17 receiving #Class1TMQueryCmd: "!24,48,72,96" # enable this to disable V.17 sending # # You'll likely want Caller*ID display (also displays DID) enabled. # ModemResetCmds: AT+VCID=1 # enables CallID display # # The pty does not support changing parity. # PagerTTYParity: none # # If you are "missing" Caller*ID data on some calls (but not all) # and if you do not have adequate glare protection you may want to # not answer based on RINGs, but rather enable the CallIDAnswerLength # for NDID, disable AT+VCID=1 and do this: # #RingsBeforeAnswer: 0 #ModemRingResponse: AT+VRID=1 # Uncomment DATE and TIME if you really want them, but you probably don't. #CallIDPattern: "DATE=" #CallIDPattern: "TIME=" CallIDPattern: "NMBR=" CallIDPattern: "NAME=" CallIDPattern: "ANID=" #CallIDPattern: "USER=" # username provided by call #CallIDPattern: "PASS=" # password provided by call #CallIDPattern: "CDID=" # DID context in call CallIDPattern: "NDID=" #CallIDAnswerLength: 4
And that's pretty much it. Now restart HylaFAX:
/etc/init.d/hylafax restart
And that should be all there is to it.
Of course, you will need to make sure you have a properly configured MTA (Mail Transfer Agent) running on the local server that can relay this mail outbound.
Happy trails!
NOTE: As of release 1.4, Asterisk has patches for native fax applications based on SpanDSP. If they work well, they should allow you to take IAXmodem and HylaFAX out of the equation. Also check out astfax for the e-mail integration portion. However, I've been told anecdotally by a number of Asterisk users that they do not work well and that the HylaFAX approach remains the most robust and stable.