Creating a Fax Server Using Asterisk (an Open Source PBX)
As part of building FaxDroid a fax server was required to perform the actual transmission of fax. The responsibility of the fax server is to convert a file into a facsimile (fax) and transmit that over phone lines (and vice versa). To do this 3 things are needed:
- A VOIP carrier
- A programmable private branch exchange (PBX)
- A means to convert a file into sound waves for fax transmission and vice versa.
For the VOIP carrier I used Twilio. For the programmable PBX I used Asterisk. Asterisk itself has a fax module which using spandsp is able to convert files to fax messages and vice versa.
From a high level architecture this is how asterisk fit into the overall design of FaxDroid:
The end user interacts with the FaxDroid through the UI. The UI makes REST API calls to the back end which in turn is integrated with Asterisk. When the Asterisk server receives a fax request, (using the PJSIP channel driver) a call is initiated with the destination fax machine. The call is routed through Twilio (the carrier for FaxDroid). Once the call is established the actual fax is transmitted using the fax module. For incoming faxes similar operations are performed in reverse.
In the following sections I explain in more details how the Asterisk server is integrated with FaxDroid
Outgoing Faxes
Outgoing faxes start when the user initiates a fax request from the UI. This then sends an API request to the back end. The back end first stores the document to transmit in an S3 bucket. It then performs some business logic to determine if it is possible to send out the fax (i.e. enough credits exist in the customers account). Once it is determined that the fax can be sent out it instructs asterisk to originate a channel to the destination fax device. At this point a call is made towards the destination and Asterisk waits for the other end to answer. The call is made using the PJSIP channel driver which in turn in connects to the SIP trunks provided by Twilio. If FaxDroid was unable to originate the call (i.e. the number is invalid or the line is busy) it notifies the user of the failure.
Once a channel has been opened to the destination fax device the call is transferred to the send_fax dialplan. Dial plans (https://wiki.asterisk.org/wiki/display/AST/Dialplan) are essentially a way to program asterisk to act in specific ways. Quote from the Asterisk website itself “The dialplan is essentially a scripting language specific to Asterisk and one of the primary ways of instructing Asterisk on how to behave”.
The dial plan uses the Fax Module provided by Asterisk to initiate the fax. The Fax Module requires Spandsp to be installed on the servers (https://www.soft-switch.org/). Spandsp is an open source tool that converts TIFF files to sound waves and vice versa. The Fax Module reads our TIFF file from S3, converts it to sound waves and transmits them over the SIP connection that was previously established.
During the full duration of the connection FaxDroid is listening on status updates. Several things could happen:
- The other end prematurely hangs up.
- There is a failure in delivery.
- The fax is successfully delivered.
FaxDroid handles each of these cases separately and notifies the user of the delivery status.
Incoming Faxes
FaxDroid also accepts incoming faxes. Incoming faxes originate from the peers device. SIP trunks have been setup in Twilio to accept incoming connections and transfer these calls to the Asterisk server. Once the channel is established the call is routed to the receive_fax dialplan. The dial plan first makes an API request to the back end server to determine whether or not to continue with the call or to hangup. FaxDroid performs some business logic at this point to determine whether or not to accept the incoming call. For example it checks if the user has enough credits in their account to receive more faxes.
In case the incoming call is accepted, the receive Fax Module converts the incoming sound waves into a TIFF file. The file is then stored in S3 and a REST call is made to FaxDroid to indicate the fax has been received. It is at this point that the user can view the file in their dashboard.
Skills
Asterisk, Twilio, SIP Trunks
Description
Built a fax server using Asterisk (an open source PBX)
Skills:
- Asterisk
- Twilio
- SIP Trunks