VoIP via SIP with Qt

5 years have passed since my last SIP integration project. Qt jumped from 5.4.1 to 5.13.0, PJSIP from 2.4 to 2.8 and the Android NDK from revision 10 to 19. Time for an update, I'd say!

Requirements

  1. PJSIP 2.8
  2. Debian 9
  3. Qt 5.12+ for Android
  4. Android NDK r19c

Since my focus in 2014 was the Android platform, I first tried to compile the old sample project with the newest Qt and Android compiler which resulted in a lot of undefined references.

A quick look in the Qt documentation for Android revealed the reason: From Qt 5.12 on, the android framework is shipped with clang compilers instead of GCC.

Therefore I saw 2 possible solutions:

  1. Downgrade Qt and use GCC
  2. Try to upgrade all and use Clang

Surely being up-to-date and making use of the new and updated functionalities of recent Qt and PJSIP versions is priority.

While taking a look at the PJSIP docs and bug-tracker it seemed to be non-compatible with newer NDK versions and Clang, luckily this concern was unnecessary...

Compilation of PJSIP 2.8 for Android

The compilation of PJSIP for Anroid on a Debian 9 machine was quite straightforward:

  1. Get the latest PJSIP repo

svn checkout https://svn.pjsip.org/repos/pjproject/trunk

  1. Get the latest Android NDK

wget https://dl.google.com/android/repository/android-ndk-r19c-linux-x86_64.zip

  1. Unzip the Android NDK

unzip android-ndk-r19c-linux-x86_64.zip

  1. Change directory to the PJSIP trunk

cd trunk

  1. Edit the config_site.h to enable Android compilation

nano pjlib/include/pj/config_site.h

add:

#define PJ_CONFIG_ANDROID 1
#include <pj/config_site_sample.h>
  1. Export the location of the Android NDK

export ANDROID_NDK_ROOT=~/android-ndk-r19c

  1. Start the configuration

./configure-android

  1. Build it!

make dep && make clean && make

Check below how it should look like:

Using PJSIP 2.8 for Android with Qt

After successful compilation of PJSIP 2.8 for the Android target platform, we need some kind of wrapper to actually use it with Qt and a proper linking of our libraries.

Let's start with linking: Open a new Qt Project and include the PJSIP header files - easy. The correct order on how to include the single libs is more complex, so straight forward here you go:

LIBS += -L$$PWD/pjproject-2.8/lib \
 #-lpjmedia-audiodev-armv7-unknown-linux-android \
 #-lpjmedia-videodev-armv7-unknown-linux-android \
 #-lpjsip-armv7-unknown-linux-android \
 -lpjsua2-armv7-unknown-linux-android \
 -lpjsua-armv7-unknown-linux-android \
 -lpjsip-simple-armv7-unknown-linux-android \
 #-lpjsdp-armv7-unknown-linux-android \
 -lpjmedia-armv7-unknown-linux-android \
 -lpjsip-armv7-unknown-linux-android \
 -lpjmedia-audiodev-armv7-unknown-linux-android \
 -lpjsip-ua-armv7-unknown-linux-android \
 -lpjnath-armv7-unknown-linux-android \
 -lpjmedia-codec-armv7-unknown-linux-android \
 -lpj-armv7-unknown-linux-android \
 -lpjmedia-armv7-unknown-linux-android \
 -lilbccodec-armv7-unknown-linux-android \
 -lgsmcodec-armv7-unknown-linux-android \
 -lspeex-armv7-unknown-linux-android \
 -lresample-armv7-unknown-linux-android \
 -lsrtp-armv7-unknown-linux-android \
 -lpj-armv7-unknown-linux-android \
 -lpjlib-util-armv7-unknown-linux-android \
 -lwebrtc-armv7-unknown-linux-android
 #-lg7221codec-armv7-unknown-linux-android \

Once correctly included, it's necessary to write wrapping functions.

The most important structs and functions did not change since my old project, so you might use it as a very basic reference after updating the libs and it's pro file.

Due my research I stumbled across an awesome implementation of PJSIP for Qt in form of a fully fledged SDK called Risip made by Petref Saraci.

It appeared that he noticed my library a few years ago but wanted to extend it and Risip is the very good result. It was using PJSIP 2.7.1 and GCC, so I updated the Android part of it to use the above mentioned versions and compiler.

So in case you want to get the most easy start into VoIP with Qt, I currently recommend you to use Risip and contribute patches for upcoming versions to it, you can get it here:

RISIP

Once you have built your client or at least started with it, you might be interested in setting up the server side yourself to avoid expensive services.

I will explain how to build your own SIP server in the next blogpost, stay tuned! (smile)

Have fun,

  • Dominik