The Raspberry Pi as a SIP Client with PJSIP

I know, most people have no need to call a phone line to endlessly listen to an announcement or, even better, music. However, in my line of work I sometimes do. Over the years I’ve helped myself out with calling the time service that repeats giving me the current time endlessly. But it’s a kludge and I always wanted to have my own system. Finally, I had some time to fill the gap and the result is a Raspberry Pi connected via SIP to the telephone system that endlessly plays music when I call its phone number.

In a previous post I described how I connected a SIP software client on my notebook to my fixed line network operator’s IMS. Have a look there for the details. After finding out how that worked the next logical step was to see if I could repeat this with a command line SIP client, preferably on a Raspberry Pi that would allow me to play and audio file. SIP doesn’t seem to be the most popular protocol in open source so the number of projects that I could use as a basis were limited. After researching for a while I gave PJSIP a try as it is the basis for quite a number of SIP software products.

Compiling the Software

Getting the command line pjsip user agent (client) to work on a Raspberry Pi was not quite straight forward as the software is only available as source code and has to be compiled on the target system. While this is usually straight forward these days I had quite a number of problems with this one. There are a number of articles that describe the process but each one failed for me at some point. I finally managed to get the source compiled on a Raspberry Pi by combining the wisdom contained in the following articles:

The good thing is that after compilation, the resulting directory can be copied and pasted to other Raspberry Pis without installing anything else except for a virtual sound card driver as described below. I’ve tried on a Raspberry Pi 1, 2 and 3 and it works on all of them.

A Virtual Microphone

The only thing the PJSIP requires is that a sound card supporting a microphone and a driver for it is installed. A few years ago I bought a USB sound card for a few Euros for a Raspberry Pi project that was automatically recognized by the Raspbian OS. I used it again for this project and PJSIP recognized it without the need to install anything. The second option I tried was to use a dummy microphone sound card driver that is already part of Raspbian. It can be loaded as a kernel module manually or automatically during the boot process as follows:

# manual
sudo modprobe snd-dummy

# put the driver name (snd-dummy) in /etc/modules 
# for auto-load during boot.
sudo nano -w /etc/modules

This worked well for me and I could thus put the USB sound card back into my Volumio system.

Auto-answering Calls

And here’s my command line for starting pjsip as a SIP user agent that automatically accepts incoming calls and endlessly plays the music from a .wav file:

cd ~/pjproject-2.1.0/pjsip-apps/bin

#HOME
./pjsua-armv7l-unknown-linux-gnu --play-file ~/s32.wav --local-port=5061 --auto-answer 200 --auto-play --auto-loop --max-calls 5 --config-file ./pjsip.cfg

Note: I had to use a non-standard local port (5061) as ‘pjsua’ would fail starting without the option claiming the standard port (5060) could not be opened. Whatever… From the ‘change directory’ instruction above you might have noticed that I haven’t used the latest version of the project, which was 2.6 at the time of this writing. I got it working with this version so I saw no need to try again with a newer one.

The command line instruction uses a configuration file that only contains the following parameters:

--id sip:martin-pi@fritz.box
--registrar sip:192.168.99.1
--realm fritz.box
--username martin-pi
--password very-secret-password

A quick look at the parameters shows that I didn’t make the Pi connect directly to the fixed line IMS system but rather to the SIP server on my home router instead. That probably made a lot of things a lot simpler, saved me a number of configuration options and leaves room for further adventures on a rainy day.

Limited Audio File Length

One limitation I noticed is that the length of the music in the .wav file should not be longer than about 2 minutes 20 seconds. Anything longer and pjsua would start breaking up the voice path after that time. I tried several different .wav encodings when converting an MP3 file with VLC and also different input files but the result was always the same: The music plays fine for the first 2 minutes and 20 seconds and then starts breaking up. With 2 minute sound files, however, the music plays endlessly. Just what I wanted!

Making PJSIP Run In The Background With Screen

One more thing I needed was for PJSIP to run in the background and to let me exit the terminal. For other programs I would use “nohup” and “&” for the purpose. PJSIP would complain that no terminal was available when doing this and stopped running. I thus used ‘screen’, a screen manger and terminal emulator / multiplexer that simulates several terminals in a single terminal window and lets the user attach and detach from the ‘real virtual’ terminal without stopping its own terminals (yes, ‘real virtual’ is kind of contradicting). Here are some useful ‘screen’ commands for this purpose:

  • CTRL-A followed by a “c” opens a new terminal and sends pjsipua virtually to the background without it stopping
  • CTRL-A + ” (quote!) shows a list of virtual terminals
  • “screen -r” reattaches to the still running instance after exiting the shell or SSH session.

PJSIP is not resource hungry at all so it runs well even on the first generation Raspberry Pi. The source code also offers APIs for Python and other operating systems so there’s lots of fun for many rainy days ahead!