SipX Android Build Environment

From SipXtapi

Jump to: navigation, search

Contents

General notes

The Android port is largely done. If you would like to help test additional features on Android, or have any questions regarding it please contact Dan Petrie: dpetrie AT SIPez DOT com

When sipX development was started in 1998 initial design was to use it as the fast path/real-time part of an embedded system solution. The real-time critical parts (SIP stack, media processing subsystem and call processing) were built using C++ while the GUI and high level application logic were built in Java. This should sound familiar to those who know the Android architecture. sipX architecture along with its extensive set of features and well-known easy-to-use API makes it an ideal SIP based VoIP solution for the Android platform. sipXtapi becomes the API that gets exposed through JNI to allow feature rich Java based VoIP applications to be built for Android.

Setting up Android Development Environment

Note: these instructions have changed. We recently move to NDK r3 from NDK r2 (AKA 1.6).

We have taken the approach of wrapping sipX in JNI to call C++ code from Android's Java application framework. The Java application framework SDK can be reviewed and downloaded. The Android JNI toolkit is called NDK.

  1. Download the NDK for your platform
  2. Follow the NDK install procedure and be sure to run <ndk>/build/host-setup.sh
  3. You will likely want to install the Android SDK, Eclipse and the Android plugin ADT for Eclipse as well see installation instructions

Create a New Android Project

The following instructions assume that you are using the Eclipse development environment for building your Android application. It is possible to do this without using Eclipse, but you are on your own. These instructions assume that you have installed Android NDK r3 and SDK component for Android 2.0.1 or 2.1 and the Android plugin for Eclipse.

Note: If you are adding sipX to an existing project, your project MUST be in the apps directory below the NDK root (e.g. <NDK>/apps/mySipXApp/project where the "project" directory contains the AndroidManifest.xml, assets, gen, res, src directories).

  • From eclipse create a new android project
File->New->Android Project
  • In the "New Android Project" dialog that pops up enter the name of your project (e.g. mySipxApp):
Project name: mySipXApp 
  • Uncheck: the "use default location" checkbox
  • Click the "Browse..." button and navigate to the apps directory under the NDK root directory (<NDK>). Then create a new directoy using the "New Folder" button and name it the same as your project. Then create another new directory call "project" under the prior new project.
Browse...
Navigate to <NDK>/apps
New Folder
Name of new folder: mySipxApp
Create
Name of new folder: project
Location: <NDK>/apps/myNewApp/project
Open 
  • Check the "Build Target" of Android 2.0.1 or 2.1
Build Target: Android 2.0.1
  • Fill in the other properties in the "New Android Project
Application Name: mySipxApp
Package Name: com.example.com
Create Activity: MySipxActivity
Min SDK Version: 6
  • Click "Finish"
Finish

Check out sipX, install pcre and settup NDK make files

  • Check out sipX from subversion or make a link in your project directory for the sipX JNI code:
cd <NDK>/apps/mySipxApps/project
svn checkout https://scm.sipfoundry.org/rep/sipX/main jni
      OR
ln -s <your_sipX_root> jni
  • Manually create the sipX build stamp source files. Note: this MUST be run from the sipX root directory (jni).

(TODO: need to put this in the Android makefiles)

cd <NDK>/apps/mySipxApps/project/jni
./scripts/makeBuildTimestamps.sh
  • Get PCRE 7.8 and unpack sources to <NDK>/apps/mySipxApps/project/jni/libpcre/ directory (NOT to <NDK>/apps/mySipxApps/project/jni/libpcre/pcre-7.8/).
cd <NDK>/apps/mySipxApps/project/jni
wget http://downloads.sourceforge.net/project/pcre/pcre/7.8/pcre-7.8.tar.gz?use_mirror=voxel
tar -zxvf pcre-7.8.tar.gz
mv pcre-7.8 libpcre
  • Copy or link the android NDK make file for pcre into the libpcre directory:
cd <NDK>/apps/mySipxApps/project/jni/libpcre
ln -s ../scripts/pcre_Android.mk Android.mk
  • Copy or link the android NDK application make file to the project root directory
cd <NDK>/apps/mySipxApps
ln -s project/jni/scripts/Application.mk .
  • Copy or link the SPEEX android makefile
cd project/jni/sipXmediaLib/contrib/libspeex
ln -s ../android/speex/Android.mk .
  • Copy or link following two libs (which are part of Android core, but not part of NDK) to build output directory so Android build system can find them:
cd <NDK>/out/apps/mySipxApps
ln -s ../../../apps/mySipxApps/project/jni/sipXmediaLib/contrib/android/android_2_0_libs/libmedia.so .
ln -s ../../../apps/mySipxApps/project/jni/sipXmediaLib/contrib/android/android_2_0_libs/libutils.so .
ln -s ../../../apps/mySipxApps/project/jni/sipXmediaLib/contrib/android/android_2_0_libs/libcutils.so .
  • Edit <NDK>/apps/sipX-jni-test/project/jni/sipXtackLib/Android.mk so that ANDROID_CORE_PATH points to the Android 1.6 source code. This path should contain the directory bionic and its source code. This is hopefully a temporary thing. For now you need to download the Android source (see http://source.android.com/download for instructions). If you like, you can limit the git to only download bionic.

Build sipX and pcre libraries for Android NDK

You should now be setup to build pcre and the sipX libraries for use in your application vi NDK. Previously you should have setup and followed the instructions for the installation of NDK and per those instructions run <ndk>/build/host-setup.sh. Ideally you should have built at least one of the sample NDK projects and run it in the emulator or a real Android phone to test that your NDK, SDK and Eclipse environment are all set up properly and working.

  • In a command line shell run the make file for building the sipX and pcre libraries for Android NDK. You MUST do this from the NDK root directory.
cd <NDK>
make APP=mySipxApp
  • You should see something like:
Android NDK: Building for application 'mySipxApp'    
Compile thumb  : pcre <= apps/myNewApp/project/jni/libpcre/pcre_compile.c
Compile thumb  : pcre <= apps/myNewApp/project/jni/libpcre/pcre_config.c
Compile thumb  : pcre <= apps/myNewApp/project/jni/libpcre/pcre_dfa_exec.c
Compile thumb  : pcre <= apps/myNewApp/project/jni/libpcre/pcre_exec.c
Compile thumb  : pcre <= apps/myNewApp/project/jni/libpcre/pcre_fullinfo.c
...
Compile++ thumb: sipXsdp <= apps/myNewApp/project/jni/sipXsdpLib/src/sdp/SdpCodec.cpp
Compile++ thumb: sipXsdp <= apps/myNewApp/project/jni/sipXsdpLib/src/sdp/SdpDefaultCodecFactory.cpp
Compile++ thumb: sipXsdp <= apps/myNewApp/project/jni/sipXsdpLib/src/sdp/SdpMediaLine.cpp
In file included from apps/myNewApp/project/jni/sipXsdpLib/include/sdp/SdpMediaLine.h:28,
                from apps/myNewApp/project/jni/sipXsdpLib/src/sdp/SdpMediaLine.cpp:16:
apps/myNewApp/project/jni/sipXsdpLib/include/sdp/Sdp.h:20:20: warning: iostream: No such file or directory
SharedLibrary  : libsipXsdp.so
Install        : libsipXsdp.so => apps/myNewApp/project/libs/armeabi

Running Unit Tests

The unit test executables get built after the libraries and are put into (using our myNewApp example) <NDK>/apps/myNewApp/project/libs/armeabi. The unit test executable for the sipXportLib for Android is called sipxportunit. The instructions below show one way to install this binary. This is a bit of a hack, but its the best we have figured out so far. Ideally it would be nice if we could get Eclipse to package up the binaries and install them with the application, but we have not figure out how to do that yet. So these instructions manually push the binaries into the application install.

The instructions assume the following:

project name: myNewApp
application name: com.example.myNewApp
  • Install your application on your Android emulator or device. We do not really need to run the application, we are just going to use its library directory as a place to hold the binaries.
  • Push the unittest onto your Android emulator or device using adb. adb comes with the Android SDK and can be found in the <SDK/tools/adb directory. This example shows the path to the unittest from your <NDK> directory.
adb push apps/myNewApp/project/libs/armeabi/sipxportunit /data/data/com.example.myNewApp/lib/sipxportunit
  • Change the permissions on the executable so that you can run it.
adb shell chmod 777 /data/data/com.example.myNewApp/lib/sipxportunit
  • Run the binary on your emulator or device.
adb shell /data/data/com.example.myNewApp/lib/sipxportunit
  • You should see output to the screen something like:
[TEST]: UtlIntTests::testConstructor
[TEST]: UtlIntTests::testCompareTo
[TEST]: UtlIntTests::testCompareTo_NonInt
[TEST]: UtlIntTests::testEquals
...

Running Unit Tests in gdb on Android Device

These instructions are thanks to [1]

  • Download and extract gdb for android
wget http://ortegaalfredo.googlepages.com/android-gdb-6.8.tar.bz2
    or
curl http://ortegaalfredo.googlepages.com/android-gdb-6.8.tar.bz2 > android-gdb-6.8.tar.bz2
tar -jxvf android-gdb-6.8.tar.bz2
  • Push gdb onto your Android device or emulator
adb push android-gdb-6.8/dgb /data/bin/dgb
  • Run a shell on your android emulator or device
tools/adb shell
  • Set the shell path for gdb
# export SHELL=/system/bin/sh
  • Start gdb for for the unit test that you want to run
# /data/bin/gdb /data/data/com.example.myNewApp/lib/sipxportunit
  • You should see something like the following
dlopen failed on 'libthread_db.so.1' - libthread_db.so.1: cannot open shared object file: No such file or directory
GDB will not be able to debug pthreads.
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-none-linux-gnueabi"...
(no debugging symbols found)
  • Run the unit test
(gdb) run
  • If you want symbols (by default release code is built), you will need to edit <NDK>/apps/mySipxApps/Application.mk and set:
APP_OPTIM        := debug
  • The sipX portable unit test framework by default catches SEGVs and FPEs and then skips to the next unit test in an attempt to run all the way through the suite. If you would like it to terminate so that it gets caught by gdb you will want to disable the signal catcher in the unit test framework. You can do this by editing sipXportLib/src/test/sipxportunit/SipxPortUnitTestEnvironment.cpp and uncommenting:
#define DONT_CATCH_SIGNALS

Still in progress

We are making calls on Android!!! There is still more testing, debugging to do and a lot more JNI to write. However we can place & receive calls, hold, unhold, answer, reject, forward, hangup calls.

We are still working on the following:

  • DONE!! replacement for the CPPUNIT unit test framework (CPPUNIT requires RTTI and C++ exceptions which are not supported on Android).
  • Mostly DONE!! Getting all of our unit tests to pass. Over 1,030,000 test points are passing on Android. Yes ONE MILLION!
  • DONE!! Replacing the istream/ostream/fstream dependencies in mediaLib (no istream/ostream/fstream on Android).
  • DONE!! Developing the audio device drivers for sipXmedia that will work on Android. DONE!!
  • Performance optimization to be able to run many call leg conferences on Android
  • Developing JNI intefaces for sipXtapi

If you would like to help please send us a note: dpetrie AT SIPez DOT com

Further reading

  • A useful description of Android framework layout can be found here.
  • To get better idea about how Android's internals are structured, I advice you to watch this excellent introduction: Anatomy & Physiology of an Android. It's said there that "Android is not Linux", and I tend to say that's true. Many things you expect to see in Linux are missing here or replaced with own implementations. So, go watch this presentation or you'll find yourself totally lost.
Personal tools