[sipp] type=friend context=internal host=192.168.1.20 port=6000 user=sipp canreinvite=no disallow=all allow=ulaw
uCasteriskIntroductionuCasterisk (you-see-Asterisk) is a set of scripts, makefiles and patches to build Asterisk for uClinux. The target is the Blackfin BF533 STAMP board, although it should be portable to other uClinux platforms. uCasterisk in one part of a project to build a completely open telephony platform. Both the hardware and the software are freely available under the GPL. Asterisk Port to uClinuxThe uCasterisk port was derived from the OpenWRT port of Asterisk developed by Brian Capouch, and uses a similar set of scripts derived from the cross compilation tool Buildroot. There are several ports of Asterisk to embedded hardware (for example OpenWRT and Gumstix). These ports run in a regular Linux environment on embedded hardware that supports a Memory Management Unit (MMU). The difference with uCasterisk is that it runs in a uClinux environment, i.e. on embedded processors without a MMU. This opens up the use of Asterisk on a variety of other processors; e.g. the Blackfin which has some nice features like DSP capability, low cost, and ease of interfacing to hardware. At the time I performed the initial port in Sep 2005, the main challenge with the port was that uClinux didn't support shared libraries (at least not in the way regular Linux does) and Asterisk uses LOTs of shared libraries. I worked around this using GNU libtool (which can emulate shared libraries) and some patches to the Asterisk .so loader. The result is that all of the shared libraries are statically linked but Asterisk is tricked into thinking they are .so's. Not quite as good as the real thing (e.g. you need to shut down uCasterisk to add/remove a module), but it seems to work fine. Since that time uClinux has added regular shared lib support so the shared library hack is now no longer necessary, and porting new versions of Asterisk to uClinux has become a little easier. Despite the static linking, the footprint on the Blackfin is still fairly small, e.g. my current build is about 2.4M for Asterisk which includes a bunch of shared libs (without any sound files). I have also written about porting multithreaded apps to uClinux here.
SIPp TestingTo test uCasterisk I have been using SIPp. The information in this section might also be useful to other Asterisk newbies who would like to use SIPp for testing, as it took me a few hours to work out how to configure Asterisk and SIPp. I actually found this really interesting as I hit a few memory management issues related to the differences between Linux and uClinux. This meant I had to research how memory management works for multi-threaded apps on uClinux. For the interest of others I have written a short article on my blog to explain the techniques I used.
Initially I found that uCasterisk would fall over after a few hundred SIP calls, often crashing uClinux. However after gaining some understanding of uClinux memory management, and upgrading the Blackfin uClinux kernel to 2005R4 RC2, it is now much more stable, for example a recent test on a BF533 STAMP executed 500,000 SIP calls over a 12 hour period. Initially, uCasterisk was configured to use 2MByte of physical memory per call, so after about 15 simultaneous calls I tended to run out of memory. Each simultaneous call causes a new thread to be spawned, and each thread was allocated its own 2MByte stack. I spent a few days researching stack allocation on uClinux and wrote a small library to measure the amount of stack actually used, which is described here. This allowed me to fine-tune the amount of stack required and minimise the use of physical memory. Sometime I would like to research the memory usage further to see if this can be improved, but as a first pass it is sufficient for my needs (SOHO IP-PBX with say 4 FXO ports). I suspect with some tweaking and extra memory a T1-span could be handled by the Blackfin. Test 1 - 0.5s calls to exercise SIP and thread creationThe test configuration is:
Here is the sip.conf file I used. Declaring the host IP allows SIPp to make calls without needing to register: [sipp] type=friend context=internal host=192.168.1.20 port=6000 user=sipp canreinvite=no disallow=all allow=ulaw This is the extension logic from extensions.conf: [internal] ; dummy extension just for testing exten => 2005,1,Answer exten => 2005,2,Wait(2) exten => 2005,3,Hangup And this is the SIPp command line I use on the Linux box used to generate calls (bf533 is the hostname of my BF533 STAMP board). ./sipp -sn uac -d 500 -s 2005 bf533 -l 10 Results:
Test 2 - 10s calls to exercise RTP audioThe test configuration is:
The configuration is similar to Test 1 above except the following entry has been added to extensions.conf: [internal] . <snip> . ; reach standard asterisk demo exten => 2000,1,Goto(demo,s,1) This is the SIPp command line I use on the Linux box used to generate calls (bf537 is the hostname of my BF537 STAMP board). ./sipp -sn uac -d 10000 -s 2000 bf537 -l 10 -mp 5606 Results:
CodecsThe Blackfin is a powerful DSP processor and is capable of running multiple speech codecs in real time. In May 2006 I worked with Jean-Marc Valin from the Speex project to reduce the MIPs required for Speex encoding from 40 to around 23. The techniques used to optimise Speex are discussed here. Also in May 2006 I developed an optimised port of GSM for the Blackfin, which is discussed here. Here is the translation matrix for uCasterisk 0.1.4 running on a BF537 STAMP: *CLI> show translation Translation times between formats (in milliseconds) Source Format (Rows) Destination Format(Columns) g723 gsm ulaw alaw g726 adpcm slin lpc10 g729 speex ilbc g723 - - - - - - - - - - - gsm - - 4 4 - 7 3 - - 38 - ulaw - 9 - 1 - 5 1 - - 36 - alaw - 9 1 - - 5 1 - - 36 - g726 - - - - - - - - - - - adpcm - 12 5 5 - - 4 - - 39 - slin - 8 1 1 - 4 - - - 35 - lpc10 - - - - - - - - - - - g729 - - - - - - - - - - - speex - 19 12 12 - 15 11 - - - - ilbc - - - - - - - - - - - *CLI> This demonstrates the capability of the Blackfin for serious DSP work. It is feasible to run several codecs in real time, for example supporting 4-10 compressed VOIP calls. There are commercial versions of G729 are available for the Blackfin, they run in about 22 MIPs (i.e. 10-20 channels could run in real time). DownloadScreen Shot== Parsing '/etc/asterisk/iaxprov.conf': Found -- Loaded provisioning template 'default' [chan_sip.so] => (Session Initiation Protocol (SIP)) == Parsing '/etc/asterisk/sip.conf': Found == SIP Listening on 0.0.0.0:5060 == Using TOS bits 0 == Registered channel type 'SIP' (Session Initiation Protocol (SIP)) == Registered application 'SIPDtmfMode' == Parsing '/etc/asterisk/enum.conf': Found == Parsing '/etc/asterisk/extconfig.conf': Found == Parsing '/etc/asterisk/logger.conf': Found Asterisk Event Logger restarted == Parsing '/etc/asterisk/manager.conf': Found == Parsing '/etc/asterisk/enum.conf': Found == Parsing '/etc/asterisk/rtp.conf': Found == RTP Allocating from port range 10000 -> 20000 Asterisk Ready. *CLI> stop now Beginning asterisk shutdown.... Executing last minute cleanups Asterisk cleanly ending (0). root:/var/tmp> uname -r 2.6.12.1-BFIN-2005R3 root:/var/tmp> HowTo Build uCasterisk
Sample Conf FilesSample conf files are stored in packages/asterisk/files on the host, and /etc/asterisk on the target. These are standard Asterisk conf files with the following configurations added at the end of each file: sip.conf: An IpDialog SIP Phone 2 (SIP protocol) iax.conf: An iaxComm Windows softphone (IAX2 protocol) extensions.conf: 2003: The iaxComm soft phone 2004: The SIP phone 2005: A dummy phone that answers, waits one second and hangs up
HowTo Install uCasterisk BinaryI have generated binaries for those who would like to test uCasterisk on their STAMP board without any compiling. The binary is a complete Linux image - all you need to do is download to your target using tftp and boot. It makes trying out uCasterisk on your STAMP very easy.
Modifying uCasteriskThe make files can automatically generate patches against the standard asterisk and zaptel tar balls. Perform your edits in the build-bfin-uclinux/asterisk-1.0.9 or build-bfin-uclinux/zaptel-1.0.9.1 directory. Then type: make asterisk-make-patches to generate the patch files, which are stored in the package directory. Renamed Asterisk filesIn channels sub-dir iax2-parser.c was renamed iax2_parser.c, and iax2-provision.c was renamed iax2_provision.c to support the static linking using libtool (it's a long story). This messes up the patching, as diff thinks these files are new. Oops. Also, in the zaptel package I renamed zaptel.c to zaptel1.c as I couldn't work out how to build a kernel module from two source files when one of them had the same name as the output .ko file. I am sure there is a better way to do this. Can anyone please tell me how? Blackfin ConfigurationYou need the following configuration to build uCasterisk: Toolchain
uClinux-dist
U-boot I am currently using the 2005R4 RC2 kernel and the December 2005 release of u-boot. If you use an earlier version of u-boot your kernel will not boot correctly. Expect Expect is installed to automate downloading to the target. If you do not have expect installed you will not be able to use the download scripts. On my host: [david@solomon uCasterisk-0.1.4]$ expect -v expect version 5.42.1
Other uClinux ArchitecturesThese lines in uCasterisk-x.y/.config: BR2_ARCH="bfin-uclinux" BR2_TOOLCHAIN_DIR="/opt/uClinux/bfin-uclinux/bin" define the architecture. I would be interested to know if uCasterisk works on other architectures. The Build Process and Directory OrganisationHere is a short description of each directory. For more information on Buildroot check out the Buildroot site.
The build process works like this:
TO-DO ListIf you are interested in working on this project, here are some interesting tasks in rough order of importance:
|