Skip to content

Building

You'll need Linux (glibc or musl: Alpine builds and passes the same tests), CMake (3.16 or later), a C++17 compiler (Clang where it is installed, GCC otherwise: below; and a C compiler for the Asterisk and FreeSWITCH modules), and git. No OpenSSL is needed: libre's crypto (the digests for SIP's authentication, AES for SRTP) is Mbed TLS's, fetched and built with it (below).

cmake -B build
cmake --build build

The build takes Clang (clang, clang++, or the newest clang-<n>) when it is installed and nothing else chose the compiler, with GCC's C++ library (libstdc++) and binutils as Clang uses them on Linux. CC=gcc CXX=g++, -DCMAKE_C_COMPILER=... or -DDMODEM_PREFER_CLANG=OFF take GCC instead, and an existing build directory keeps the compiler it was configured with. Both are tested; CI builds with Clang.

With libasound2-dev (ALSA), dmodemd can also drive a softmodem's codec (-a), and with libusb-1.0-0-dev a Smart Link SmartUSB56, a pico-serial Line stick, a pico-serial WB stick (a bare pair, the wideband mode) or an Agere USB 2.0 soft modem (--usb, docs/hardware.md).

This builds build/dmodemd/dmodemd, build/dmodemd/libdmodem.a, build/dmodemd/libdmodem_sip.a and, when Asterisk's headers are installed, build/asterisk/codec_clearmode.so (RFC 4040's CLEARMODE for ISDN data calls; app_dmodem.so too with -DDMODEM_APP_DMODEM=ON, for your own Asterisk only: LICENSING.md), and when FreeSWITCH is installed (its freeswitch.pc), build/freeswitch/mod_dmodem.so. cmake --install build installs them.

The Dockerfile builds the same on Alpine Linux (musl) and makes a small image with dmodemd, dmodem-ari and libdmodem: docker build -t dmodem ., then docker run --rm -it --network host -e SIP_LOGIN=user:password@domain dmodem. --build-arg TESTS=ON also builds the tests and runs the offline ones while building.

dmodemd's SIP is libre (baresip's re, BSD-3-Clause), which is not part of this repository. CMake uses an installed one (pkg-config libre, 4.12 or later); without one it clones the pinned release (v4.12.0) once and builds it in the build directory, a static library. -DDMODEM_LIBRE=system requires an installed libre, -DDMODEM_LIBRE=fetch always builds the pinned one, and -DDMODEM_LIBRE_TAG=... picks another release. The SDP, RTP (G.711) and UDPTL are dmodemd's own. That libre is built on Mbed TLS (its pinned release, v3.6.7, fetched and built the same way, linked statically): libre needs a few digests and AES from it, not TLS, so only those end up in dmodemd. libre has no AES of its own on Mbed TLS; D-Modem's patch, cmake/libre-mbedtls-aes.patch, adds it, for SRTP. -DDMODEM_CRYPTO=openssl builds libre on the system's OpenSSL (libssl-dev) instead.

libdmodem_sip.a is the modem on a SIP line as a library (frontend/dmodemd/sip_modem.h): the modem core with its SIP user agent, its DTE any descriptor (a pty, or one end of a socket pair), run in a thread of the program's own and stopped from another; dmodemd is a pty in front of it. It cross compiles: with a CMake toolchain file (the Android NDK's, say: -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-26) libre and Mbed TLS are fetched and built with the same toolchain; a system without /etc/resolv.conf (Android) gives the DNS servers in sip::Config. The tree also builds as another CMake project's subdirectory.

Windows

dmodemd also builds for Windows (7 and later) as a single static dmodemd.exe: with MSVC on Windows (cmake -G Ninja in a Developer Command Prompt), or from Linux with MinGW-w64 (-DCMAKE_TOOLCHAIN_FILE=platforms/windows/mingw-w64.cmake) or clang-cl against MSVC's libraries (platforms/windows/clang-cl.cmake). Its DTE is a COM port (--com COM5, one end of a com0com pair), a named pipe (--pipe, --pipe-connect: a virtual machine's COM port, so a guest can dial out through it), D-Modem's own virtual modem driver (--driver auto: a UMDF driver that Windows lists as a modem, for dial-up networking and fax programs through Unimodem, with a UMDF 1 build for Windows 7 and 8; not yet tried on Windows itself) or a TCP connection (--tcp, by default 127.0.0.1:2323). The USB modems (--usb: the SmartUSB56, the pico-serial Line and the Agere modem, on WinUSB) work there too; the PBX modules and the ALSA line are Linux-only. See docs/windows.md.

macOS

dmodemd also builds for macOS 11 and later, on Apple silicon and Intel (-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" for one universal binary), with Apple's command line tools and CMake alone: libre, Mbed TLS and libusb are fetched and built with it. It is the Linux modem with its pty and the USB modems (--usb, through libusb's IOKit backend); the ALSA line is not built. It has not been built on a Mac yet: the CI job is ready for when the repository's CI has runners again. See docs/macos.md.

Haiku

dmodemd also builds for Haiku (x86_64), BeOS's open successor: on Haiku itself (pkgman install cmake ninja git pkgconfig libusb_devel, then cmake -B build), or from Linux with Clang and a sysroot of Haiku's own packages (python3 platforms/haiku/haiku_sysroot.py ~/haiku-sysroot, then -DCMAKE_TOOLCHAIN_FILE=platforms/haiku/haiku.cmake -DHAIKU_SYSROOT=$HOME/haiku-sysroot). It is the Linux modem with its pty and the USB modems (--usb, through HaikuPorts' libusb); the ALSA line and the PBX modules are not built. The cross build is checked with warnings as errors, but it has not run on Haiku itself yet. See docs/haiku.md.

Tests: ctest --test-dir build -L quick runs the fast ones (a few seconds; GoogleTest programs, with the system's libgtest-dev or a copy fetched while configuring); -L spandsp (with libspandsp-dev) and -L smartlink are longer. The interop tests run the modem against other soft modems (docs/interop.md); -L smartlink against Smart Link's original binary-only i386 DSP library (dsp/test/smartlink/dsplibs.o), kept only as a test peer; they need a 32-bit build environment (-m32 with Clang or GCC, and 32-bit libraries: Debian-based systems can install g++-multilib) and are skipped without one. See docs/testing.md.