Archive for the ‘voip’ Category

Why does Asterisk consume 100% CPU?

Wednesday, May 6th, 2009

I don’t know :)

But people has asked me this a couple of times lately and my answer is always “I don’t know”. However ps can give you more information about it. In fact, this works for any application you have and you want to debug why is going crazy.

First, check which thread (Asterisk is a multi threaded application) is going crazy.

# ps -LlFm -p `pidof asterisk`

That should show you the % of CPU being used by each Asterisk thread in the column named “C”, then write down the LWP colum value for the thread you are interested on. (LWP is a light weight process number, roughly speaking, the thread id). Now that you have the thread id, you need to know what that thread is doing.

# pstack `pidof asterisk` > /tmp/asterisk.stack.txt

That will cause the asterisk process to dump the stack state to the /tmp/asterisk.stack.txt file. If you don’t have the pstack command google for it, I think in CentOS is as easy as yum install pstack.

Then open the file and search for the LWP that you just wrote down. Hopefully you will find some hints that let you know how to avoid it or at least a lot more information to post in bugs.digium.com

UPDATE:
One of the guys who asked this question later told me what he found:

Thread 10 (Thread 0x41d8f940 (LWP 3406)):
#0 0x00000033ce2ca436 in poll () from /lib64/libc.so.6
#1 0x00000000004933c0 in ast_io_wait ()
#2 0x00002aaabd9510cd in network_thread ()
#3 0x00000000004f8b2c in dummy_start ()
#4 0x00000033cee06367 in start_thread () from /lib64/libpthread.so.0
#5 0x00000033ce2d2f7d in clone () from /lib64/libc.so.6

A quick grep -rI “network_thread” in the Asterisk source code reveals this function belongs to chan_iax.c, disabling chan_iax.so in modules.conf is a good workaround to his problem, however further debugging would be needed to determine why the monitor thread is looping like that.

Cluecon 2009

Tuesday, May 5th, 2009

I will be speaking at ClueCon this year. The talk will be about writing FreeSwitch modules and how the development process compares to writing modules for Asterisk in terms of APIs. If you are interested in learning how to write modules for Asterisk and/or Freeswitch, this is your chance!

The full schedule is still being prepared so be sure to check the site later when it’s done.

I could not decide which banner to use here, so I decided to put 3 I really liked :) … if you use any open source telephony application, support developers by attending or at least putting one of these banners on your site.

From the ClueCon site:
ClueCon – is an annual 3-Day Telephony User and Developer Conference bringing together the entire spectrum of Telephony from TDM circuits to VoIP and everything in between. The presentations and discussions will cover several open source telephony applications such as Asterisk/Callweaver, OpenSIPS/Kamailio (formerly OpenSER), Bayonne, YATE and FreeSWITCH. Other great projects that will be discussed include OPAL and Woomera.

More funny banners at: http://files.freeswitch.org/cluecon_2009/

MFC-R2 support in Asterisk trunk

Tuesday, March 17th, 2009

I am glad to announce that MFC-R2 support has been merged into Asterisk trunk. Today I just got an e-mail from Russell, the team lead of the Asterisk development team confirming the merge and that the upcoming version Asterisk 1.6.2 will be the first one having built-in support for this signalling.

More details in the following commit: http://lists.digium.com/pipermail/asterisk-commits/2009-March/031735.html

I want to thank all the people that supported the development of OpenR2 with code, testing and build infrastructure. Particularly thanks to:

Neocenter, company located at México, Distrito Federal, that supported the development of OpenR2 from the very beginning, even when I myself was not even sure it could work. Thanks Octavio, Pop and Alejandro.

Sangoma Technologies For their sponsorship during all this time.

Digium Inc for creating Asterisk.

Alexandre Alencar for all his contributions to the project in different areas.

There is obviously more people that has contributed, you all know who you are :)

G729A and G723.1 support for FreeSwitch

Sunday, February 8th, 2009

The past weekend I spent some time writing a module for the FreeSwitch project in order to support the G729A codec in it. This codec is patent encumbered, however, my target was not to do this in software, but just create the software interface for FreeSwitch to talk with a PCI card manufactured by Digium that does the transcoding for G729A and G723.1 .

This is the data sheet for the TC400B board. The programming interfaces to access the encoders and decoders is not documented (or at least I could not find any documentation), but it’s enough to have available the source code for the module in Asterisk that uses that very same board.

This board expose its available encoders to the DAHDI / Zaptel core driver, which in turn exposes all transcoders registered by the boards through the Linux filesystem in /dev/dahdi/transcode or /dev/zap/transcode, depending on whether you have Zaptel or DAHDI drivers.

Here I want to explain the few interfaces required to use this board.

The first thing you usually want to do is verify that there is encoders and decoders available. This is done through an ioctl to request the information about the availability of these transcoders.

        struct dahdi_transcoder_info info = {0};

        fd = open("/dev/dahdi/transcode", O_RDWR);
        if (fd < 0) {

                fprintf(stderr, "Failed to open dahdi transcode device\n");
                exit(1);
        }
        for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) {

                printf("Found transcoder '%s', numchannels = %d, dstfmts = %d, srcfmts = %d.\n", info.name,
                                info.numchannels, info.dstfmts, info.srcfmts);
        }

        close(fd);

The driver will let you know the number of encoders, decoders and the source and destiny formats. The formats masks can be found in /usr/include/dahdi/kernel.h. In future versions that may change, I discussed this with one of the DAHDI developers, since I think that this should be in dahdi/user.h and not in kernel.h given that is a user space interface.

Once you know which transcoders are available you can request an encoder or decoder, or both.

        int encoder_fd, decoder_fd;

        struct dahdi_transcoder_formats g729_encoder;
        struct dahdi_transcoder_formats g729_decoder;

        g729_encoder.srcfmt = DAHDI_FORMAT_ULAW;

        g729_encoder.dstfmt = DAHDI_FORMAT_G729A;

        g729_decoder.srcfmt = DAHDI_FORMAT_G729A;

        g729_decoder.dstfmt = DAHDI_FORMAT_ULAW;

        encoder_fd = open("/dev/dahdi/transcode", O_RDWR);

        if (encoder_fd < 0) {
                printf("Failed to open transcode device\n");
                exit(1);
        }
        if (ioctl(fd, DAHDI_TC_ALLOCATE, &g729_encoder)) {

                printf("Failed to allocate encoder\n");
                close(encoder_fd);
                exit(1);
        }

        decoder_fd = open("/dev/dahdi/transcode", O_RDWR);
        if (decoder_fd < 0) {

                printf("Failed to open transcode device\n");
                exit(1);
        }
        if (ioctl(fd, DAHDI_TC_ALLOCATE, &g729_decoder)) {

                printf("Failed to allocate decoder\n");
                close(fd);
                exit(1);
        }

Finally, once allocated, you just have to write chunks of ulaw data and read chunks of decoded g729 data and viceversa. You can choose whether the device will accept ulaw or alaw to g729 or g723 manipulating the srcfmt and dstfmt members of dahdi_transcoder_formats. Just remember that ulaw or alaw encoded data requires 8 times more bytes than g729 encoded data, therefore if you write a frame of 20ms of alaw (160 bytes for a sampling rate of 8000hz) you will read just 20 bytes of g729 encoded data, of course, the same apply when you decode a g729 frame or for g723 (for which alaw and ulaw requires 12 times more space).

The module is available here under the MPL license. Also, the module was just commited to trunk yesterday in the Freeswitch SVN repository. I want to thank to Voiceway for sponsoring the module and Neocenter for providing the hardware to test it.

New astunicall release

Sunday, November 30th, 2008

I just released a new astunicall package and chan_unicall driver for Asterisk 1.6, you can get it as usual from:

http://www.moythreads.com/astunicall/downloads/

Heading to Brazil

Saturday, November 29th, 2008

I will be speaking this Thursday in the morning at IPComm 2008 in São Paulo, Brazil. The presentation will be about the development I have been doing for Asterisk with OpenR2. This is great news for me, most users and contributors of OpenR2 are located in Brazil. If you happen to live in that area, hope to see you there!

IPComm 2008

ztloop with CAS support

Sunday, November 23rd, 2008

During some time I had the idea that it should be possible to test the user space software that deals with E1/T1 lines (Asterisk, FreeSwitch, OpenR2) without any hardware at all, that way I could work off-line in my laptop (when I am on-line I usually have access to some server with an E1 card on it). Yesterday I googled a bit about it and found the ztloop kernel module, developed by the company DruidSoftware. It’s a very simple module, based on the ztdummy module, but is not part of the zaptel package, so you have to download it, and patch the Makefile to compile it.

The module works by registering 4 zaptel spans. The first 2 are connected, by software, in loop. Which means anything you write to channel 1 (span 1) it will be available for reading in channel 32 (span 2). It does this by soft-wiring the tx and rx buffers of each span channel and registering a timer callback with the kernel, which will call it at a 1024Hz rate (just like ztdummy) and calling zt_transmit() and zt_receive() from within this callback (since there is no E1/T1 hardware interrupts, this timer is required).

The other 2 spans are for line tapping. All channels in span 3 tap span 1 and span 4 taps span 2. If you open a channel in span 3 you will be able to eavesdrop the data over the corresponding channel in span 1 (this tapping functionality can also be accomplished by zaptel pseudo devices, that is the way ztmonitor works).

The number of loop and tapping spans is configurable passing parameters to the kernel module.

Even though this module works fine for PRI lines, until today, it did not work for MFC/R2 lines, because it was lacking CAS support. After reading for some time Zaptel drivers code it started to make sense and I added a few lines of code required to loop R2 lines.

I basically added the span handler (a function pointer in the zt_span structure) to handle the transmission of CAS bits. This handler is called each time some process from user space calls ioclt(fd, ZT_SETTXBITS), most drivers would talk to the E1/T1 hardware to ask it to change the bits position, but, what I did is to call zt_rbsbits() function in the span that I know this span is looped to, that way the other span will “see” the bits and wake up any user space process that is waiting on bits changes.

It’s kind of cool that now I can test my Asterisk MFC/R2 development in my laptop w/o needing any hardware at all :-)

The source code for this modified ztloop kernel module can be found here: http://www.moythreads.com/ztloop.c. I will send the patch to the DruidSoftware guys to see if they include it in their next release.

Back from Astricon

Friday, October 17th, 2008

I got back from Astricon 3 weeks ago. It was good to meet some people I only had talk with on IRC or IM.

Here is my presentation: OpenR2 – MFC/R2 Free of headaches or your money back. My presentation explains how and why I started the OpenR2 project and how it can help to ease the MFC/R2 signaling support for Asterisk.

In other news tomorrow is my last day working for IBM. I started at IBM 2 years ago and I have learned how it is to work in such a big company, good things (salary, stability, no pressure), bad things (bureaucracy, slow development etc). Of course, being such a big company this may not be truth for all areas and will definitely vary among countries and development teams.

Having said that, it was quite difficult to me take the decision of leaving, but I was starting to enter in my comfort zone. It’s time to move, and more importantly, move to a job where I can learn new exciting technologies and I can work in telephony and open source communications that is what I like the most.

This Monday I will start working for Sangoma Technologies. It’s definitely not as big as IBM, but I think the company is at a sweet spot between a small and a big company. This also means soon I will be moving to Toronto. Let’s see how it goes …

Ah, btw, I also got married this week :)

I’ll be speaking in Phoenix at Astricon

Thursday, July 31st, 2008

So, not quite, Astricon will be in Glendale AZ, 9 miles northwest from Phoenix downtown. The conference will be from September 23 – 25 and I’ll be speaking about the support for MFC/R2 I am adding to Asterisk, hope to see you there!

MFC/R2 branches for Asterisk 1.2 and 1.4

Saturday, July 5th, 2008

I just created 2 branches for MFC/R2 support in chan_zap for Asterisk 1.2 and 1.4, this branches replaced the patches and .tar.gz I previously published, is much easier to keep them up-to-date this way. If you still need the patches you can easily get them using svn diff.

Let’s say you need a patch against Asterisk 1.4.21.1

svn diff  http://svn.digium.com/svn/asterisk/tags/1.4.21.1 \
http://svn.digium.com/svn/asterisk/team/moy/mfcr2-1.4 > asterisk-openr2-1.4.21.1.patch

That will create a patch to transform Asterisk 1.4.21.1 version into an OpenR2-enabled version. However this has other side-effect, changes that may have nothing to do with openr2 can be introduced. I therefore recommend using my branches directly.