Monday, February 23, 2026

Chromaprint for fingerprinting audio

I'm continuing to develop a VOLTS framework for functional testing of VoIP systems. And one of the problems it tries to catch is a no-media issue, which is greatly detected via sox. But better is actually to know that what is sent/received on audio is correct. And sox is really not a good option here.

Luckily, there is a tool called fpcalc, which is part of a chromaprint/AcoustID project, which is actually aiming for this. In other words - fingerprinting audio files. Only thing here - it's not really for for a short files, so better to have long (10-15 seconds) audio samples.

fpcalc was really easy to integrate into VOLTS, so now you can check not only if audio is present, but also if the audio is correct.

More info can be found on the project page and the VOLTS documentation.

Happy testing! 

Tuesday, February 10, 2026

Notes about using $var(...) in Kamailio

Everyone using Kamailio knows that $var() is a tricky beast. If you are not resetting it at the beginning of a script, you might get interesting effects later, or trying to use it with async statements is also not a good idea.

One of the things that tends to be overlooked is that now $null is implemented, despite its description in the documentation.

TL;DR: there is no $null, just a "0" (zero) value.

But one more thing is that an empty string is also not an empty string, but "0". So having  a statement like

uac_replace_from("$var(name)", "...");

will give you actually "0" in a CallerID name if you made something like

$var(name) = "";

before. Tricky beast as is. 

P.S.: To add, $vn(...) will also threat empty string as $null, but in this case will do even worse making From header like

From: <null> <sip:....> 

which is just a malformed header.

Monday, January 26, 2026

Compiling rtpengine 13.5.x on RHEL/Alma/Rocky 9

rtpengine having Debian as a target platform. But sometimes you need Red Hat-based distros.

So, voici how to compile and install rtpengine version mr13.5.1.3 (and I guess all 13.5.x branch) on a plain RHEL 9 system:

Enable Required Repositories

sudo dnf -y install epel-release
sudo dnf -y update


Install Development Tools

sudo dnf -y groupinstall "Development Tools"
sudo dnf -y groupinstall "RPM Development Tools"


Install Build Dependencies

sudo dnf -y install \
    gcc \
    make \
    pkgconfig \
    redhat-rpm-config \
    glib2-devel \
    libcurl-devel \
    openssl-devel \
    pcre-devel \
    zlib-devel \
    hiredis-devel \
    systemd-devel \
    libpcap-devel \
    libevent-devel \
    json-glib-devel \
    gperf \
    perl-IPC-Cmd \
    perl-podlators \
    libatomic \
    ncurses-devel \
    xmlrpc-c-devel \
    iptables-devel \
    iptables-nft \
    libmnl-devel \
    libnftnl-devel \
    pandoc \
    wget \
    git \
    libtiff-devel \
    libjpeg-turbo-devel \
    libsndfile-devel \
    libxml2-devel \
    autoconf \
    automake \
    libtool \
    mosquitto-devel \
    libwebsockets-devel \
    opus-devel \
    libjwt-devel

Install FFmpeg

sudo dnf -y install ffmpeg-free-devel

Note: you can use ffmpeg-devel from RPM-Fusion repo

Install MariaDB Development Files

sudo dnf -y install mariadb-devel mariadb-connector-c-devel

Create mysqlclient.pc symlink (rtpengine looks for this)


sudo ln -sf /usr/lib64/pkgconfig/mariadb.pc /usr/lib64/pkgconfig/mysqlclient.pc

Install Kernel Development Packages (for kernel module)

sudo dnf -y install kernel-devel kernel-headers elfutils-libelf-devel

Create Stub libiptc.pc File

RHEL 9 doesn't provide libiptc via pkg-config. Create a stub file:

sudo tee /usr/lib64/pkgconfig/libiptc.pc << 'EOF'
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64
includedir=${prefix}/include

Name: libiptc
Description: Stub libiptc for RHEL 9 (iptables chain management disabled)
Version: 1.8.9
Cflags:
Libs:
EOF

Verify it works

pkg-config --exists libiptc && echo "libiptc.pc created successfully"

Build and Install spandsp from FreeSWITCH Fork

The standard spandsp package doesn't work correctly on RHEL 9. Use the FreeSWITCH fork:

cd /usr/src
sudo git clone https://github.com/freeswitch/spandsp.git
cd spandsp
sudo ./bootstrap.sh
sudo ./configure --prefix=/usr
sudo make -j$(nproc)
sudo make install
sudo ldconfig

Build rtpengine and it's components

cd /usr/src
sudo wget -O rtpengine-mr13.5.1.3.tar.gz \
    https://github.com/sipwise/rtpengine/archive/refs/tags/mr13.5.1.3.tar.gz
sudo tar xzf rtpengine-mr13.5.1.3.tar.gz
sudo mv rtpengine-mr13.5.1.3 rtpengine
cd rtpengine


Build rtpengine Daemon

cd /usr/src/rtpengine/daemon
sudo make RTPENGINE_VERSION=mr13.5.1.3 -j$(nproc) with_iptables_option=no


Build Recording Daemon

cd /usr/src/rtpengine/recording-daemon
sudo make RTPENGINE_VERSION=mr13.5.1.3 -j$(nproc) with_iptables_option=no


Build Kernel Module (Optional)

cd /usr/src/rtpengine/kernel-module
KERNEL_VERSION=$(uname -r)
sudo make RTPENGINE_VERSION=mr13.5.1.3 KSRC=/usr/src/kernels/$KERNEL_VERSION
sudo make install
sudo depmod -a


Install rtpengine

cd /usr/src/rtpengine/daemon
sudo make install with_iptables_option=no

cd /usr/src/rtpengine/recording-daemon
sudo make install with_iptables_option=no


Create rtpengine User and Directories

sudo useradd -r -s /sbin/nologin rtpengine

sudo mkdir -p /var/run/rtpengine
sudo mkdir -p /var/spool/rtpengine
sudo mkdir -p /etc/rtpengine

sudo chown rtpengine:rtpengine /var/run/rtpengine /var/spool/rtpengine


Systemd integration

sudo tee /etc/rtpengine/rtpengine.conf << 'EOF'
[rtpengine]
table = -1
interface = eth0
listen-ng = 127.0.0.1:2223
port-min = 10000
port-max = 20000
log-level = 6
log-facility = daemon
foreground = false
pidfile = /var/run/rtpengine/rtpengine.pid
EOF

sudo tee /etc/systemd/system/rtpengine.service << 'EOF'
[Unit]
Description=RTPEngine Media Proxy
After=network.target

[Service]
Type=forking
PIDFile=/var/run/rtpengine/rtpengine.pid
ExecStart=/usr/bin/rtpengine --config-file=/etc/rtpengine/rtpengine.conf --pidfile=/var/run/rtpengine/rtpengine.pid
ExecStop=/bin/kill -TERM $MAINPID
Restart=on-failure
User=root
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload


Configure Firewall (if applicable)

sudo firewall-cmd --permanent --add-port=10000-20000/udp
sudo firewall-cmd --permanent --add-port=2223/udp
sudo firewall-cmd --reload


Load Kernel Module (if built)

sudo modprobe xt_RTPENGINE

Verify it's loaded
lsmod | grep xt_RTPENGINE

To load on boot, create a modules-load.d file
echo "xt_RTPENGINE" | sudo tee /etc/modules-load.d/rtpengine.conf

Start rtpengine

sudo systemctl enable rtpengine
sudo systemctl start rtpengine
sudo systemctl status rtpengine
rtpengine --version


Verification

ss -ulnp | grep 2223

Test with rtpengine-ctl (if available)
echo "list totals" | nc -u 127.0.0.1 222