linux-fax-stack/README.md
2024-08-04 22:30:45 +02:00

330 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Linux Fax Stack Setup (HylaFax & SIP)
Linux Fax Stack using Hylafax and t38modem.
***THIS GUIDE IS WIP***
This guide was created using information from the opalvoid wiki (http://wiki.opalvoip.org/index.php?n=Main.HomePage)
## Softwarestack
### ptlib
(legacy) library for doing a little bit of everything.
### Opal
Voice codec used by e.g. mumble.
### t38modem
Emulates a serial modem from SIP connetion
### Hylafax
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
For Debian 12, we´ll only install dependencies which are hard requirements.
For this guide we'll use ptlib 2.18.6 and opal 3.18.6.
#### Installing Requirements
First we'll need some packages
```bash
apt-get install build-essential git wget pkg-config libssl-dev libsrtp2-dev -y
```
#### 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/
- t38mdem (4.6.2) https://github.com/hehol/t38modem/releases/tag/4.6.2
#### ptlib
```bash
./configure
make
make install
```
#### opal
```bash
./configure
make -j5
make runtest
make install
```
#### t38modem
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
```bash
git clone https://github.com/hehol/t38modem
cd t38modem
make
```
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
cp t38modem /bin/t38modem
``'
### 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**
- Don't use `libavformat-dev` -> Compile error in Opal
- Configure script needs `pkg-config` to be installed to find ptlib install
- On SourceForge downloads `.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 pkg-config
```
- 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
- 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
```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/`
## Using t38modem (requires systemd)
```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
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>"
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"
```
- 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
## TODO
- **TODO: Test on Debian / RockPi / RaspberryPi**
- **TODO: Test on Eventphone Infra**
- **TODO: Package t38modem with service files and config**