Quantcast
Channel: CodeSection,代码区,Linux操作系统:Ubuntu_Centos_Debian - CodeSec
Viewing all articles
Browse latest Browse all 11063

Setting a VoIP SIP user agent with Embedded Linux

$
0
0

This is a guest post by Leonardo Graboski Veiga, working for Toradex.

Introduction

This article’s main goals are: to cross-compile the PJSIP libraries and the PJSUA API reference implementation; deploy it to the target system; give an overview about the SIP protocol; and explore the reference implementation features, regarding audio only. For this purpose, a Computer on Module (CoM) from Toradex was chosen in the following configuration: Colibri iMX6DL* + Colibri Evaluation Board . The evaluation board and CoM are displayed in Figures 1 and 2, respectively.


Setting a VoIP SIP user agent with Embedded Linux

Figure 1 Colibri Evaluation Board


Setting a VoIP SIP user agent with Embedded Linux

Figure 2 Colibri iMX6DL

VOIP or Voice over IP, is a term designed to refer to a set of methods and technologies targeted for the implementation of telephony services over the Internet. For the purpose of this article, the scope will be limited to the use of a reference implementation built upon the SIP communication handling protocol by means of the PJSIP libraries and PJSUA2 API. If you wish to gather more information about VOIP itself, there is a website that labels itself “A reference guide to all things VOIP” and it holds comprehensive information on the matter.

SIP is the Session Initiation Protocol a protocol used for signaling and handling communication sessions. This protocol is sometimes referred to as the de facto standard for VOIP implementations. It is an IETF (Internet Engineering Task Force) standard even though there are other options to SIP, such as IAX2 . SIP employs the RTP protocol for data transmission which itself is encapsulated in TCP or UDP and can be encrypted by using TLS.

PJSIP is a set of libraries that implements the SIP and related protocols such as RTP and STUN, among others in C language. Some of its advantages are that it is free, open source, and highly portable. It was started in 2005 and is still being maintained and improved with wide documentation and the advantage of having a high level API named PJSUA2 for easily building custom applications. The PJSUA2 even has an online book for its official documentation.

Cross-compilation

The first step to cross-compile the PJSIP libraries and the test/sample application is to have the toolchain set. To do it, we can follow the toolchain for hard float calling convention section of this article . Note that if you are willing to use your own cross-compilation toolchain, according to this PJSIP documentation, you are required to have the following GNU tools: GNU make (other make will not work), GNU binutils, and GNU gcc for the target.

If the basic rootfs provided by Linaro doesn’t have some ALSA headers and the library needed to compile PJSIP, we will download and compile these libraries from the ALSA project website . In this article, the alsa-lib version downloaded was 1.1.1. then we will install the headers and library to the Linaro rootfs.

Install the toolchain Linaro:

<br /> cd<br /> wget -c https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/arm-linux-gnueabihf/gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf.tar.xz<br /> tar xvf gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf.tar.xz<br /> ln -s gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf gcc-linaro<br />

cd

wget - c https : / / releases .linaro .org / components / toolchain / binaries / 5.2 - 2015.11 - 2 / arm - linux - gnueabihf / gcc - linaro - 5.2 - 2015.11 - 2 - x86_64_arm - linux - gnueabihf .tar .xz

tar xvf gcc - linaro - 5.2 - 2015.11 - 2 - x86_64_arm - linux - gnueabihf .tar .xz

ln - s gcc - linaro - 5.2 - 2015.11 - 2 - x86_64_arm - linux - gnueabihf gcc - linaro

Export the environment variables:

<br /> export ARCH=arm<br /> export PATH=~/gcc-linaro/bin/:$PATH<br /> export CROSS_COMPILE=arm-linux-gnueabihf-<br />

export ARCH = arm

export PATH = ~ / gcc - linaro / bin / : $PATH

export CROSS_COMPILE = arm - linux - gnueabihf -

Download and unpack the ALSA lib:

<br /> wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.1.1.tar.bz2<br /> tar xjvf alsa-lib-1.1.1.tar.bz2<br /> cd alsa-lib-1.1.1/<br />

wget ftp : / / ftp .alsa - project .org / pub / lib / alsa - lib - 1.1.1.tar.bz2

tar xjvf alsa - lib - 1.1.1.tar.bz2

cd alsa - lib - 1.1.1 /

Before compiling the ALSA lib source codes, it is necessary to run the autoconf script with the CFLAGS , LDFLAGS and prefix variables pointing to the rootfs from the Linaro toolchain:

<br /> ./configure host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc CFLAGS=”-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” LDFLAGS=”-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” prefix=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc/usr/<br />

1

. / configure host = arm - linux - gnueabihf CC = arm - linux - gnueabihf - gcc CFLAGS = “-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” LDFLAGS = “-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” prefix = / home / leonardo / gcc - linaro / arm - linux - gnueabihf / libc / usr /

Then just build and install. After the make command, the compilation will fail at some point; but it doesn’t matter because the headers and library we need will have been compiled.

<br /> make<br /> make install<br />

make

make install

Having the toolchain configured, it is time to download and extract the PJSIP source codes to the host machine and then go into the directory that holds the unpacked content. At the time this article was written, PJSIP version was 2.5.1.

<br /> cd<br /> wget http://www.pjsip.org/release/2.5.1/pjproject-2.5.1.tar.bz2<br /> tar xvjf pjproject-2.5.1.tar.bz2<br /> cd pjproject-2.5<br />

cd

wget http : / / www .pjsip .org / release / 2.5.1 / pjproject - 2.5.1.tar.bz2

tar xvjf pjproject - 2.5.1.tar.bz2

cd pjproject - 2.5

Before compiling the PJSIP source codes, it is necessary to run the autoconf script pointing to the previously modified rootfs from the Linaro toolchain. It is almost the same way we did to compile the ALSA libraries, except for the fact that the directory where we want the compiled libraries to be installed is a directory we will compress and deploy to the target machine.

<br /> ./configure host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc CFLAGS=”-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” LDFLAGS=”-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” prefix=/home/leonardo/deploy<br />

1

. / configure host = arm - linux - gnueabihf CC = arm - linux - gnueabihf - gcc CFLAGS = “-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” LDFLAGS = “-mfloat-abi=hard -mfpu=neon sysroot=/home/leonardo/gcc-linaro/arm-linux-gnueabihf/libc” prefix = / home / leonardo / deploy

Then we are able to compile the libraries and also copy the reference implementation executable to the installation folder:

<br /> make dep<br /> make<br /> make install<br /> cp pjsip-apps/bin/pjsua-arm-unknown-linux-gnueabihf ../deploy/<br /> cd ..<br />

make dep

make

make install

cp pjsip - apps / bin / pjsua - arm - unknown - linux - gnueabihf . . / deploy /

cd . .

The next steps are to compress the folder and copy it to the Colibri iMX6. To discover the iMX6 IP, you can issue the ifconfig command:

<br /> tar cjvf deploy.tar.bz2 deploy/<br /> scp deploy.tar.bz2 root@192.168.10.5<br />

tar cjvf deploy .tar .bz2 deploy /

scp deploy .tar .bz2 root @ 192.168.10.5

Finally, log into the Colibri iMX6:

<br /> cd<br /> tar xjvf deploy.tar.bz2<br /> mv pjsua-arm-unknown-linux-gnueabihf .<br /> cp -a deploy/. /usr/<br /> rm -r deploy<br />

cd

tar xjvf deploy .tar .bz2

mv pjsua - arm - unknown - linux - gnueabihf .

cp - a deploy / . / usr /

rm - r deploy

Now, we have the PJSIP deployed to the target although it isn’t necessary for our next steps, since we will be using a binary only, you may find it useful somehow while developing applications of your own. We are also ready to start using the reference implementation, but first, let’s check some other things.

Audio check and configuration

The PJSIP library uses ALSA (Advanced Linux Sound Architecture) resources, which is also the audio subsystem used by the Toradex embedded system BSPs. Before starting, make sure you plug a headphone/speakers and a microphone into the carrier board with the system powered-off, as illustrated in the Figure 3.


Setting a VoIP SIP user agent with Embedded Linux

Figure 3 Connecting the mic/headphones/speakers to the Evaluation Board

Then you can use the alsamixer application to adjust the audio options according to your system.

<br /> root@colibri-imx6:~# alsamixer<br />

1

root @ colibri - imx6 : ~ # alsamixer

The configuration used is illustrated in the Figure 4 and you should notice that adjusting the microphone’s amplification too loud can cause distortion, thus, it is good to experiment with the settings. Even adjusting the mic option to zero won’t mute your microphone; it just means there will be no amplification, or in other words 0dB gain. Another important point to notice is that if you force power-off the system, the configurations you made might be lost, therefore reboot or shutdown from the command line the first time you make your changes.

<br /> root@colibri-imx6:~# reboot<br /> or<br /> root@colibri-imx6:~# shutdown -h now<br />

root @ colibri - imx6 : ~ # reboot

or

root @ colibri - imx6 : ~ # shutdown -h now


Setting a VoIP SIP user agent with Embedded Linux

Figure 4 Alsamixer configuration (Click to Enlarge)

To test the audio input (microphone) and, subsequently the output (headphones/speakers), we will record some audio by using the arecord command and then play it by using the aplay command. Notice that for the arecord there are some options that we need to set: -V displays a VU meter so you have visual feedback whether your mic configuration is good or not; mono is passed since microphone is mono; -r is the sampling rate; -f is the format and -d is the duration in seconds. For more information regarding arecord, you can use the help option, or if you want to know more about audio on the Colibri iMX6, you can go to the Toradex developer related page .

<br /> root@colibri-imx6:~# arecord -V mono -r 8000 -f S16_LE -d 15 Capture8kHz.wav<br /> root@colibri-imx6:~# aplay Capture8kHz.wav<br />

root @ colibri - imx6 : ~ # arecord -V mono -r 8000 -f S16_LE -d 15 Capture8kHz.wav

root @ colibri - imx6 : ~ # aplay Capture8kHz.wav

If you can hear yourself well, we are ready to go ahead. Otherwise, check the connectors and the audio configuration.

SIP protocol overview

SIP is the session initiation protocol standardized by the IETF and used for VOIP and other types of multimedia sessions, such as messaging and video. It is text-based and uses the UTF-8 encoding, usually choosing UDP or TCP over port 5060 as a transport protocol. The information provided here about this protocol is mostly based on information provided here .

The protocol has methods defined in its RFC and method extensions defined in other RFCs. A few of them are:

ACK: used in some situations for handshake BYE: session hang up CANCEL: cancel an invite INVITE: add another user agent to a session SUBSCRIBE: request information about the status of a session NOTIFY: sent from time to time by the gateway, must be answered with 200 OK MESSAGE: used to allow and transport instant messages

There are also response codes, each with a specific meaning, that consist of 3 digit values:

1xx: provisional request received and still needs to process e.g. 100 trying, 180 ringing 2xx: success action successfully received and accepted e.g. 200 ok 3xx: redirection there is still some action needed to complete the request e.g. 300 multiple choices; 305 use proxy 4xx: client error server cannot process request or the client sent invalid e.g. 400 bad request; 404 not found 5xx: server error server cannot process a valid request e.g. 500 server internal error 6xx: global failure no server can fulfill the request e.g. 600 busy everywhere; 603 decline

It is important to notice that the SIP protocol doesn’t carry the audio information. Instead, it uses the RTP protocol encoded usually in UDP or TCP transport. For a better understanding, the Figure 5 explains how the transaction between two user agents is done for a simple call.


Setting a VoIP SIP user agent with Embedded Linux

Figure 5: Example of a simple SIP call between user agents

To make calls, a SIP URI is needed. It is a form of identifying a communication resource. A complete SIP URI has the format sip:user: [emailprotected] :port;uri-parameters?headers, but there are systems which can operate even with a SIP URI that provides only the host. PJSUA reference implementation

The PJSUA API reference implementation is a command-line based application which uses the PJSIP, PJMEDIA, and PJNATH libraries and implements a user agent, also known as softphone. Its source-code can be found here and is a useful starting point to developing your own solution. The full documentation regarding the use of the PJSUA application can be found here .

Before starting to test, find the IP address for both your embedded system and your PC/notebook. You must have both of them in the same LAN, because we are not worried about using a proxy server or anything like that, therefore our connection between devices will be made point-to-point.

<br /> eonardo@leonardo:~$ ifconfig<br /> root@colibri-imx6:~# ifconfig<br />

eonardo @ leonardo : ~ $ ifconfig

root @ colibri - imx6 : ~ # ifconfig

In this article, we will assume IP address 192.168.10.5 for the Colibri iMX6 and 192.168.10.1 for the PC. You also must have softphone software installed in your PC it can even be the same reference application, if you want to compile it for your machine this article will use the Linphone open-source softphone for Ubuntu 14.04 LTS . To start PJSUA in the embedded system use the following command. The PJSUA command line interface that you are expected to see is described in the Figure 6.

<br /> root@colibri-imx6:~# ./pjsua-arm-unknown-linux-gnueabihf<br />

1

root @ colibri - imx6 : ~ # ./pjsua-arm-unknown-linux-gnueabihf


Setting a VoIP SIP user agent with Embedded Linux

Figure 6: PJSUA command-line interface (Click to Enlarge)

To make a new call from the embedded system to the PC, type “m” and then enter the simplest SIP URI possible which consists of passing only t

Viewing all articles
Browse latest Browse all 11063

Trending Articles