2024-08-01 12:18:31 +00:00
# Linux Fax Stack Setup (HylaFax & SIP)
2024-08-04 20:25:33 +00:00
Linux Fax Stack using Hylafax and t38modem.
2024-08-01 12:18:31 +00:00
2024-08-04 20:25:33 +00:00
***THIS GUIDE IS WIP***
2024-08-01 12:18:31 +00:00
2024-08-16 10:15:10 +00:00
This guide was created using information from the opalvoid wiki (http://wiki.opalvoip.org/index.php?n=Main.HomePage).
Please do not follow this guide blindly.
Some used Opal versions are marked as being infected with malware by SourceForge.
**We are strongly discouraging, that you are using these versions.**
2024-08-01 12:18:31 +00:00
2024-08-12 12:49:10 +00:00
## Software stack
2024-08-04 20:25:33 +00:00
### ptlib
(legacy) library for doing a little bit of everything.
### Opal
2024-08-26 08:25:09 +00:00
Voice codec
2024-08-04 20:25:33 +00:00
### t38modem
2024-08-12 12:49:10 +00:00
Emulates a serial modem from SIP connection
2024-08-04 20:25:33 +00:00
2024-08-12 12:49:10 +00:00
### HylaFax
2024-08-04 20:25:33 +00:00
Enterprise grade software, managing physical and emulated modems.
Has some problems: https://github.com/lexbailey/compilerfax/blob/main/hylafax_is_broken
## Operating Systems
Unfortunately this software stack uses a lot of legacy software. Because of this, this guide was only tested on specific software versions
### Debian 12 Bookworm
2024-08-12 12:58:08 +00:00
For Debian 12, we'll only install dependencies which are hard requirements.
2024-08-04 20:25:33 +00:00
For this guide we'll use ptlib 2.18.6 and opal 3.18.6.
2024-11-10 22:59:05 +00:00
WARNING: Hylafax will get stuck during the modem probing process.
2024-08-04 20:25:33 +00:00
#### Installing Requirements
First we'll need some packages
```bash
2024-08-12 11:44:52 +00:00
apt-get install build-essential git wget pkg-config libssl-dev libsrtp2-dev libspandsp-dev -y
2024-08-04 20:25:33 +00:00
```
#### Download sourcecode
Versions:
- libpt (2.18.6) https://sourceforge.net/projects/opalvoip/files/v3.18 Cygni/Stable 6/
- opal (3.18.6) https://sourceforge.net/projects/opalvoip/files/v3.18 Cygni/Stable 6/
2024-08-16 10:15:10 +00:00
- t38modem (4.6.2) https://github.com/hehol/t38modem/releases/tag/4.6.2
2024-08-04 20:25:33 +00:00
#### ptlib
```bash
./configure
make
make install
2024-08-04 20:30:45 +00:00
```
2024-08-01 12:18:31 +00:00
2024-08-04 20:25:33 +00:00
#### opal
```bash
./configure
2024-08-26 08:25:09 +00:00
make
2024-08-04 20:25:33 +00:00
make runtest
make install
2024-08-04 20:30:45 +00:00
```
2024-08-04 20:25:33 +00:00
#### t38modem
2024-08-12 12:58:08 +00:00
If you are getting an error about `-1` not being able to be casted to a `long unsigned int` due to `-Wnarrowing` inside `dle.cxx` , you can add `-Wno-narrowing` after the `CPPFLAGS` in the Makefile to disable this error
2024-08-04 20:25:33 +00:00
2024-08-04 20:30:45 +00:00
```bash
2024-08-04 20:25:33 +00:00
git clone https://github.com/hehol/t38modem
cd t38modem
make
2024-08-04 20:30:45 +00:00
```
2024-08-01 12:18:31 +00:00
2024-08-04 20:25:33 +00:00
If running the t38modem executable, you should run these commands
```bash
cp /usr/local/lib/libpt.so.2.18.6 /lib
cp /usr/local/lib/libopal.so.3.18.6 /lib
```
To install t38modem run
```bash
2024-08-05 22:16:55 +00:00
cp ./t38modem /usr/local/bin
2024-08-04 20:32:30 +00:00
```
2024-08-04 20:25:33 +00:00
### Ubuntu 20.04 LTS
Was tested on Ubuntu 20.04 LTS VM (VirtualBox, LXC?)
You can relies heavily on http://wiki.opalvoip.org/index.php?n=Main.HomePage
Versions:
- libpt (2.18.6) https://sourceforge.net/projects/opalvoip/files/v3.18 Cygni/Stable 6/
- opal (3.18.6) https://sourceforge.net/projects/opalvoip/files/v3.18 Cygni/Stable 6/
- t38mdem (4.6.2) https://github.com/hehol/t38modem/releases/tag/4.6.2
Follow http://wiki.opalvoip.org/index.php?n=Main.BuildingPTLibUnix and http://wiki.opalvoip.org/index.php?n=Main.HomePage **but**
2024-08-01 12:18:31 +00:00
- Don't use `libavformat-dev` -> Compile error in Opal
2024-08-04 20:25:33 +00:00
- Configure script needs `pkg-config` to be installed to find ptlib install
- On SourceForge downloads `.tar.bz2` files for *nix
2024-08-01 12:18:31 +00:00
2024-08-04 20:25:33 +00:00
#### Build PTLib
2024-08-01 12:18:31 +00:00
- Version 2.18.6
- Dependency of Opal, bundled with Opal source code (SourceForge)
- http://wiki.opalvoip.org/index.php?n=Main.BuildingPTLibUnix
- **TODO: Remove dependencies, most of them are optional**
```bash
sudo apt install \
2024-08-01 16:21:40 +00:00
g++ git make autoconf libpcap-dev libexpat1-dev libssl-dev libsasl2-dev libldap2-dev \
2024-08-01 12:18:31 +00:00
unixodbc-dev liblua5.3-dev libv8-dev libncurses-dev libsdl2-dev \
2024-08-04 20:25:33 +00:00
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev pkg-config
2024-08-01 12:18:31 +00:00
```
- PTLib will be installed in the `/usr/local` tree -> set `PKG_CONFIG_PATH` to be findable (compile time)
- Set `LD_LIBRARY_PATH` to find PTLib at compile and run time
- Set `PTLIBPLUGINDIR` (compile and run time)
- (To compile as static library: `./configure --disable-shared` )
```bash
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig # compile time
export LD_LIBRARY_PATH=/usr/local/lib # compile and run time
export PTLIBPLUGINDIR=/usr/local/lib/ptlib-x.y.z # compile and run time
cd ptlib-x.y.z/
./configure
make
sudo make install
```
2024-08-04 20:25:33 +00:00
#### Build Opal
2024-08-01 12:18:31 +00:00
- Version 3.18.6
- http://wiki.opalvoip.org/index.php?n=Main.BuildingOpalUnix
2024-08-01 16:21:40 +00:00
- Dont use `libavcodec-dev` -> Compile error
2024-08-01 12:18:31 +00:00
- **TODO: Remove dependencies, most of them are optional**
```bash
sudo apt install \
2024-08-01 16:21:40 +00:00
libsrtp2-dev libgsm1-dev libspeex-dev libopus-dev libx264-dev \
2024-08-01 12:18:31 +00:00
libvpx-dev libtheora-dev libspandsp-dev dahdi
```
- (To compile as static library: `./configure --disable-shared` )
```bash
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig # compile time
export LD_LIBRARY_PATH=/usr/local/lib # compile and run time
export PTLIBPLUGINDIR=/usr/local/lib/ptlib-x.y.z:/usr/local/lib/opal-a.b.c # compile and run time
cd opal-a.b.c/
./configure
make
sudo make install
```
2024-08-04 20:25:33 +00:00
#### t38modem
2024-08-01 12:18:31 +00:00
- https://github.com/hehol/t38modem, Version 4.6.2
2024-08-04 20:25:33 +00:00
- https://github.com/T38Modem/t38modem could also be used, but seems to be not as maintained
- If you are getting error about `-1` not being able to be casted to a `long unsigned int` due to `-Wnarrowing` inside `dle.cxx` , you can add `-Wno-narrowing` after the `CPPFLAGS` in the Makefile to disable this error
2024-08-01 12:18:31 +00:00
```bash
cd t38modem-x.y.z/
make
sudo cp ./t38modem /usr/local/bin
```
- t38modem can only find Opal if `LD_LIBRARY_PATH` and `PTLIBPLUGINDIR` are environment variables to the program
2024-08-05 22:16:55 +00:00
< hr / >
## Configuring t38modem
### Init script
2024-08-01 12:18:31 +00:00
2024-08-16 10:15:10 +00:00
- To automatically start t38modem, you need to create Systemd services
2024-08-01 16:21:40 +00:00
- script is adapted from https://web.archive.org/web/20111231021042/https://www.foriamroot.org/hylafax-6-0-debian-or-ubuntu-t38modem-1-0-asterisk-1-6/
2024-08-01 12:18:31 +00:00
2024-08-05 22:16:55 +00:00
First we'll create the configuration directory under `/etc` using `sudo mkdir -p /etc/t38modem/bin/` .
Then create a file named `/etc/t38modem/bin/run` using the following content.
It will be the script to manage the current status of t38modem.
2024-08-01 12:18:31 +00:00
```bash
#!/bin/bash
2024-08-01 16:21:40 +00:00
# /etc/t38modem/bin/run
2024-08-01 12:18:31 +00:00
export LD_LIBRARY_PATH=/usr/local/lib
2024-08-12 12:50:42 +00:00
export PTLIBPLUGINDIR=/usr/local/lib/ptlib-2.18.6:/usr/local/lib/opal-3.18.6 # Adjust lib versions!
if [ -z "${1}" ]; then
>& 2 echo "Config file path not set! Aborting..."
exit 1
fi
. "${1}"
command="t38modem --ptty +/dev/ttyT38-${T38MODEM_PTTY_ID} --sip-proxy ${T38MODEM_SIP_USERNAME}:${T38MODEM_SIP_PASSWORD}@${T38MODEM_SIP_SERVER} --sip-register ${T38MODEM_SIP_USERNAME}@${T38MODEM_SIP_SERVER},${T38MODEM_SIP_PASSWORD} --sip-listen udp\$:5060 --stun ${T38MODEM_STUN_SERVER} --route t38:.*=sip:< dn > @${T38MODEM_SIP_SERVER} --route sip:.*=t38:< dn > "
if [ "$T38MODEM_DISABLE_T38" = true ]; then
command="${command} --disable-t38-mode --audio"
fi
exec $command
2024-08-01 12:18:31 +00:00
```
2024-08-05 22:16:55 +00:00
And then we'll have to make it executable like this.
2024-08-01 12:18:31 +00:00
```bash
2024-08-01 16:21:40 +00:00
sudo chmod +x /etc/t38modem/bin/run
2024-08-01 12:18:31 +00:00
```
2024-08-05 22:16:55 +00:00
#### Quick script overview
2024-08-12 12:50:42 +00:00
- Using this script, it is possible to start t38modem with a config file as an argument
2024-08-01 12:18:31 +00:00
- `-t` enables debugging
- More `t` 's is deeper debugging (e.g. `-tttt` )
- If t38modem says it was able to create the virtual modem but `/dev/ttyT38-1` is not available, you do not have sufficient permissions
2024-08-12 12:50:42 +00:00
- Configuration is specified in `/etc/t38modem/config/XX`
2024-08-01 12:18:31 +00:00
2024-08-05 22:16:55 +00:00
### Create the configuration file
2024-08-12 12:50:42 +00:00
Create a file using the following contents at `/etc/t38modem/config/XX` .
2024-08-16 10:15:10 +00:00
Replace `XX` with the modem number.
2024-08-05 22:16:55 +00:00
2024-08-01 12:18:31 +00:00
```bash
2024-08-12 12:50:42 +00:00
T38MODEM_PTTY_ID="XX" # /dev/ttyT38-XX
2024-08-01 12:18:31 +00:00
T38MODEM_SIP_USERNAME="USERNAME"
T38MODEM_SIP_PASSWORD="PASSWORD"
T38MODEM_SIP_SERVER="voip.example.com"
2024-08-12 12:50:42 +00:00
T38MODEM_STUN_SERVER="stun.example.com:1234"
T38MODEM_DISABLE_T38=false # enable if your SIP server prefers G.711
2024-08-01 12:18:31 +00:00
```
2024-08-05 22:16:55 +00:00
You should give only root access to the config.
2024-08-01 12:18:31 +00:00
```bash
2024-08-12 12:50:42 +00:00
sudo chown root:root -R /etc/t38modem/config/
sudo chmod 700 -R /etc/t38modem/config/
2024-08-01 12:18:31 +00:00
```
2024-08-05 22:16:55 +00:00
### Testing your setup
2024-08-12 12:50:42 +00:00
- You can now communicate with your modem `/dev/ttyT38-XX` , just as if it was a real Hayes compatible modem (https://www.computerhope.com/atcom.htm)
2024-08-01 12:18:31 +00:00
- Test using minicom, configure it to point to our modem. Each command is initiated by a Return
- Dial a number:
- Get the attention of the modem: `at` -> `OK`
2024-08-05 22:16:55 +00:00
- Dial: `atd[NUMBER]` , replace '[NUMBER]' using the number, you want to call
2024-08-01 12:18:31 +00:00
- If all works correctly you should be able to answer the phone and hear a single beep
- Answer a call:
- Get the attention of the modem: `at` -> `OK`
- *Call the number of your modem*
- -> `RING`
- Answer the call: `ata` -> `CONNECT`
- You should now hear your modem "talking" to you
2024-11-10 22:59:05 +00:00
- ATH means hang up
2024-08-01 12:18:31 +00:00
- Pitfalls:
- If you are already connected to your SIP server it may not give proper response codes. My provider returns `500 Internal Server Error`
- Test the command before running the init script!
2024-08-12 11:44:52 +00:00
- Do not try to used `ATO` to switch to a data connection, t38modem will return `ERROR` .
Thats hardcoded in `pmodeme.cxx` in `void ModemEngineBody::HandleCmdRest(PString &resp)` .
Dont let that hodld you back.
2024-08-01 12:18:31 +00:00
### systemd service
2024-08-12 12:50:42 +00:00
If you want to run a fax server, you can create a systemd service template to let your emulated fax modem start automatically on system boot.
To do this you have to copy paste the following into `/etc/systemd/system/t38modem@.service` .
2024-08-01 12:18:31 +00:00
```toml
2024-08-12 12:50:42 +00:00
# /etc/systemd/system/t38modem@.service
2024-08-01 12:18:31 +00:00
[Unit]
Description=t38modem
2024-08-01 16:21:40 +00:00
After=network-online.target
Wants=network-online.target
2024-08-12 12:50:42 +00:00
AssertPathExists=/etc/t38modem/config/%i
2024-08-01 12:18:31 +00:00
[Service]
Type=simple
2024-08-01 16:21:40 +00:00
Restart=always
2024-08-12 12:50:42 +00:00
ExecStart=/etc/t38modem/bin/run /etc/t38modem/config/%i
2024-08-01 12:18:31 +00:00
[Install]
WantedBy=multi-user.target
```
2024-08-12 12:50:42 +00:00
Enable and start the service for your config file (`/etc/t38modem/config/XX`) using the following commands:
2024-08-01 12:18:31 +00:00
```bash
sudo systemctl daemon-reload
2024-08-12 12:50:42 +00:00
sudo systemctl enable t38modem@XX.service
sudo systemctl start t38modem@XX.service
2024-08-01 12:18:31 +00:00
```
< hr / >
2024-08-01 19:39:29 +00:00
## Install HylaFax
2024-08-12 12:49:10 +00:00
These instructions were tested using Hylafax version 6
2024-08-01 16:21:40 +00:00
- `sudo apt install hylafax-server`
- Set Postfix Configuration to **Local only** in dpkg-reconfigure menu
2024-08-12 12:49:10 +00:00
## Configure HylaFax
2024-08-01 16:21:40 +00:00
- Run `sudo faxsetup`
- Add new modem
2024-08-12 12:50:42 +00:00
- Enter correct modem port (`ttyT38-XX`)
2024-08-12 12:49:10 +00:00
- Enter dialing configuration (see Dial Rules for Eventphone EPVPN)
2024-08-01 16:21:40 +00:00
- Accept default configuration for everything else
- It should automatically detect it to be a `T38FAX` modem
2024-08-01 19:39:29 +00:00
- Look at `man sendfax` to send faxes
- `fgetty` (the service to receive faxes) should be enabled automatically
- Bugs:
2024-08-01 20:15:31 +00:00
- If you get some protocol errors, just let HylaFax do its thing.
2024-08-01 19:39:29 +00:00
Fax over SIP is not stable at all in my experience
2024-08-12 12:50:42 +00:00
- If your call is cleared because it `Could not find common media capabilities` t38modem may not have been able to load PTLib or Opal. Check your library paths!
2024-08-01 19:39:29 +00:00
2024-08-12 12:49:10 +00:00
### Cron
2024-08-01 19:39:29 +00:00
- Alias your fax admin account as `FaxMaster` (`/etc/aliases`)
```bash
# /etc/aliases
# [...]
# HylaFax
FaxMaster: $USER # replace with fax admin account
```
- Add standard tasks to crontab file: `crontab -e`
```bash
0 * * * * /usr/sbin/faxqclean
25 23 * * * sh /usr/sbin/faxcron | mail FaxMaster
```
2024-08-01 16:21:40 +00:00
2024-08-12 12:49:10 +00:00
### Dial Rules for Eventphone EPVPN
If you want to use Eventhone EPVPN, you can apply the following dial settings onto your modems.
You can find the config at `/etc/hylafax/config.ttyT38-1` .
In this case `ttyT38-1` is the modem block device.
2024-08-12 10:49:24 +00:00
```
2024-08-12 12:50:42 +00:00
# /etc/hylafax/config.ttyXX
2024-08-12 10:49:24 +00:00
CountryCode: 1
AreaCode: 999
```
2024-08-12 11:20:05 +00:00
2024-08-16 10:15:10 +00:00
## Apply configuration
If HylaFax doesn't receive or send faxes, you can try restarting it.
This can be done using
```bash
sudo /etc/init.d/hylafax stop
sudo /etc/init.d/hylafax start
```
2024-08-12 12:49:10 +00:00
## FaxDispatch
- https://legacy.hylafax.org/content/Advanced_Permissions_with_6.0
# TODO
2024-08-04 20:25:33 +00:00
- **TODO: Test on Debian / RockPi / RaspberryPi**
- **TODO: Test on Eventphone Infra**
- **TODO: Package t38modem with service files and config**