linux-fax-stack/README.md
2024-08-01 22:15:31 +02:00

262 lines
7.3 KiB
Markdown

# Linux Fax Stack Setup (HylaFax & SIP)
- ***This guide is WIP***
- Ubuntu 20.04 LTS VM (VirtualBox, LXC?)
- **TODO: Test on Debian / RockPi / RaspberryPi**
- **TODO: Test on Eventphone Infra**
<hr/>
## Setup t38modem
- **TODO: Package t38modem with service files and config**
## Opal
- http://wiki.opalvoip.org/index.php?n=Main.HomePage
- Don't use `libavformat-dev` -> Compile error in Opal
- https://sourceforge.net/projects/opalvoip/files/
- Version 3.18.6
- **TODO: Test out other versions**
- `.tar.bz2` files for *nix
### Build PTLib
- 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 \
g++ git make autoconf libpcap-dev libexpat1-dev libssl-dev libsasl2-dev libldap2-dev \
unixodbc-dev liblua5.3-dev libv8-dev libncurses-dev libsdl2-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
```
- 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
```
### Build Opal
- Version 3.18.6
- http://wiki.opalvoip.org/index.php?n=Main.BuildingOpalUnix
- Dont use `libavcodec-dev` -> Compile error
- **TODO: Remove dependencies, most of them are optional**
```bash
sudo apt install \
libsrtp2-dev libgsm1-dev libspeex-dev libopus-dev libx264-dev \
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
```
## t38modem
- https://github.com/hehol/t38modem, Version 4.6.2
- Could also use https://github.com/T38Modem/t38modem, 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` to the `CPPFLAGS` in the Makefile to disable this error
```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
### Init script
- To automatically start t38modem, you need to create Systemd services, as well as start and stop scripts
- 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/
- `sudo mkdir -p /etc/t38modem/bin/`
```bash
#!/bin/bash
# /etc/t38modem/bin/run
export LD_LIBRARY_PATH=/usr/local/lib
export PTLIBPLUGINDIR=/usr/local/lib/ptlib-x.y.z:/usr/local/lib/opal-a.b.c # Adjust lib versions!
case "$1" in
start)
. /etc/t38modem/config
# defines
# - T38MODEM_SIP_USERNAME
# - T38MODEM_SIP_PASSWORD
# - T38MODEM_SIP_SERVER
# - T38MODEM_STUN
if [ -z ${T38MODEM_STUN+x} ]; then
$STUN="--stun ${T38MODEM_STUN}"
else
$STUN=""
fi
COMMAND="t38modem -u T38modem --ptty +/dev/ttyT38-1 --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 --route t38:.*=sip:<dn>@${T38MODEM_SIP_SERVER} --route sip:.*=t38:<dn> ${STUN}"
echo "${COMMAND}"
exec $COMMAND > /dev/null 2>&1 &
PID=$!
echo "Starting t38modem with pid $PID (pidfile /run/t38modem.pid)"
echo $PID > /run/t38modem.pid
;;
stop)
if [ ! -f "/run/t38modem.pid" ]; then
echo "t38modem is not running! (/run/t38modem.pid does not exist)"
exit 1
fi
echo -n "Stopping t38modem pid: "
PID=`cat /run/t38modem.pid`
kill -9 $PID
rm /run/t38modem.pid
echo "${PID} Done"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
;;
esac
exit 0
```
```bash
sudo chmod +x /etc/t38modem/bin/run
```
- `-t` enables debugging
- More `t`'s is deeper debugging (e.g. `-tttt`)
- You can of course run the t38modem command without this init script
- If t38modem says it was able to create the virtual modem but `/dev/ttyT38-1` is not available, you do not have sufficient permissions
- Configuration is specified in `/etc/t38modem/config`
```bash
# /etc/t38modem/config
T38MODEM_SIP_USERNAME="USERNAME"
T38MODEM_SIP_PASSWORD="PASSWORD"
T38MODEM_SIP_SERVER="voip.example.com"
# T38MODEM_STUN="stun.example.com" # optional
```
- Give only root access to the config
```bash
sudo chown root:root /etc/t38modem/config
sudo chmod 700 /etc/t38modem/config
```
- You can now communicate with your modem `/dev/ttyT38-1` , just as if it was a real Hayes compatible modem (https://www.computerhope.com/atcom.htm)
- 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`
- Dial: `atd0123456789`
- 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
- 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!
### systemd service
```toml
# /etc/systemd/system/t38modem.service
[Unit]
Description=t38modem
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/etc/t38modem/bin/run start
ExecStop=/etc/t38modem/bin/run stop
PIDFile=/run/t38modem.pid
KillMode=none
Restart=always
[Install]
WantedBy=multi-user.target
```
- Enable the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable t38modem.service
sudo systemctl start t38modem.service
```
<hr/>
## Install HylaFax
- Version 6
- `sudo apt install hylafax-server`
- Set Postfix Configuration to **Local only** in dpkg-reconfigure menu
- Run `sudo faxsetup`
- Add new modem
- Enter correct modem port (`ttyT38-1`)
- Enter dialing configuration
- Accept default configuration for everything else
- It should automatically detect it to be a `T38FAX` modem
- Look at `man sendfax` to send faxes
- `fgetty` (the service to receive faxes) should be enabled automatically
- Bugs:
- If you get some protocol errors, just let HylaFax do its thing.
Fax over SIP is not stable at all in my experience
## Cron
- 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
```
## FaxDispatch
- https://legacy.hylafax.org/content/Advanced_Permissions_with_6.0