Back from Brazil and already in Canada

I got back from IPComm in Brazil 2 weeks ago. It was great meeting several OpenR2 users and even people who has contributed code. One of the cool things of this conference was that Jim Van Meggelen, one of the authors of “Asterisk – The future of telephony” wrote a white paper about OpenR2 installation with Sangoma boards, the white paper was translated to Portuguese in order to have hard copies distributed at the show, but, here are the links for the soft copies:

http://www.sangoma.com/data/docs/MFCR2_and_Sangoma_English.pdf

http://www.sangoma.com/data/docs/MFCR2_and_Sangoma_Portuguese.pdf

I expect the OpenR2 Brazilian community to keep growing even more now that the first release is about to be done.

Enough about Brazil. Let’s talk a bit about Canada. Just a few days after getting back to Mรƒยฉxico from Brazil, I moved to Toronto, Canada in order to start working at Sangoma’s offices. What a change!, just yesterday we had a snow storm, just check this out:

Ontario Snow Storm

But, aside of the weather, everything else is great. We got a nice apartment about 2 blocks from the CN Tower and the cable guy just came a few minutes ago to install internet, tv and phone, and look this:

Finally a decent internet connection. As if that was not enough for Christmas gift (for me anyway), Sangoma gave everyone in the engineering department a very nice Christmas present: An Acer Aspire One, ain’t that cool?

So, past Thursday was my first day working at Sangoma’s offices and I must say I think I’m gonna enjoy my work like never before. No stupid meetings anymore, just technical meetings discussing relevant aspects of development. Management reports just don’t exist, we briefly speak to our manager once in a while, who happens to *really* know how to architect and write programs and in fact is one of the biggest code producers in the company, not a guy who can’t code and is promoted to a management position.

In conclusion, Sangoma rulez ๐Ÿ™‚

Posted in life, openr2 | 2 Comments

New astunicall release

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/

Posted in asterisk | 1 Comment

Heading to Brazil

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

Posted in asterisk, openr2 | Leave a comment

OpenR2 Release Candidate 2

I just released the release candidate 2 for openr2. A couple of minor bug fixes were made and I expect this release candidate to be the last one before finally releasing openr2 1.0.0

The code is available in google code:
http://code.google.com/p/openr2/downloads/list

Posted in openr2 | Leave a comment

ztloop with CAS support

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.

Posted in asterisk, freeswitch | 7 Comments

Back from Astricon

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 ๐Ÿ™‚

Posted in asterisk, boring | Leave a comment

I’ll be speaking in Phoenix at Astricon

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!

Posted in asterisk | Leave a comment

MFC/R2 branches for Asterisk 1.2 and 1.4

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.

Posted in asterisk | Leave a comment

OpenR2 back-ported to Asterisk 1.4 and 1.2

I just back-ported the support for MFC/R2 signaling using the OpenR2 library to Asterisk 1.4 and 1.2, go and get it while is still hot!

http://www.libopenr2.org/

I also updated the site to use TextMotion, a new web publishing software (aka CMS), works pretty well, kudos to the TextMotion devs.

Posted in asterisk | Leave a comment

A Tale of Two Bugs

It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the age of bug-hunting!

Recently I fixed 2 bugs, yeah, I know I spent a lot of time fixing bugs but this 2 were quite interesting to me, not because of the bugs itself, but rather because of some stuff I learned in the process like the implementation of variadic functions and how the C++ compiler optimizes certain stuff unveiling odd bugs.

Bug 1

Let’s analyze the first one, it was a bug I had with some Unicall R2 installation in 64 bits. The problem was simple, as soon as I loaded chan_unicall.so Asterisk crashed ๐Ÿ™‚

After running Asterisk with gdb I found the crash happened inside libc function strlen that was being called by uc_log(), the Unicall logging function. As most logging C functions, uc_log is a variadic function. uc_log does not do any complicated stuff, is mostly just a wrapper to vsnprintf and the variable arguments were just passed on to vsnprintf and there the crash was occurring, so, how can one see the arguments a variadic function receives using gdb? First, one must know how variadic functions are implemented by the compiler and platform you are working on.

Most common implementation of variadic functions in C is just to define va_list as an unsigned char* pointing to the last argument of the function and each call to va_arg() retrieves the next chunk of memory of the specified size and increment va_list to point to the start of the next argument, therefore, displaying arguments is just matter of printing the memory area after the last argument. However, AMD64 has a different implementation, va_list is an array of 1 structure with members:

.gp_offset
.fp_offset
.overflow_arg_area
.reg_save_area

gp_offset is how many bytes after reg_save_area the first argument is. To print the first variable argument that we know is an “int” we do:

(gdb) p *(int *)(((char *)arg_ptr[0].reg_save_area)+arg_ptr[0].gp_offset)

however, gp_offset will be only incremented after calling va_arg() macro, if you want to see more arguments you must increment reg_save_area by the number of bytes you know arguments take, in the case of uc_log, initial value of gp_offset is 24, probably because it receive 3 fixed arguments (8 bytes * 3). So, the first variable argument starts at .reg_save_area + 24, the second at .reg_save_area + 32 (we’re in a 64 bit machine).

So, what about .fp_offset and .overflow_arg_area?, well, it seems .reg_save_area is quite limited (possibly limited by the number of the processor registers) and you can never go beyond .gp_offset == 40, therefore that will only work for up to 6 arguments (including the fixed ones). .overflow_arg_area is used for any subsequent argument and .fp_offset is the pointer to the next argument on that memory area. Well, that’s enough, let’s get straight to the point, the crash was caused because unicall.h include the following prototype:

extern const char *uc_statet2str(int state);

That function returned the value passed to uc_log(…., uc_state2str()) … so what’s the issue? well, read once again the prototype and how uc_log used it. Is not a typo here in my blog, the prototype really is uc_statet2str, and the function call is uc_state2str, indeed there is a typo in the header file causing the compiler to default to the return value “int” and not const char* when compiling libmfcr2, for 64 bit platform there is 4 bytes of difference between char* and int causing a crash due to invalid memory read.

Bug 2

This one is easier to explain with a chunk of code, can you tell what’s wrong with it and what possible outputs will have when running it as “./test t”?


#include <stdio.h>
#include <string.h>

#define SIZE 100

int main(int argc, char *argv[])
{

        char *bufptr = NULL;
        if (argc == 2) {

                char inblock_buff[SIZE];
                bufptr = inblock_buff;
                strcpy(bufptr, "some buffer");
        }

        printf("buffer: %s\n", bufptr);
        if (argc == 2 && argv[1][0] == 't') {

                char otherbuff[SIZE];
                otherbuff[0] = 0;
        }

        printf("buffer: %s\n", bufptr);
        return 0;
}

Indeed, the output will depend on how you compile it and even probably will depend on the compiler implementation? The thing is, that if you compile this code in Linux with gcc 4.1.2 as gcc -O2 bug.c -o bug, and then run it as ./bug t

The output is:

buffer: some buffer
buffer: some buffer

But, compiling without optimizations gcc -O0 bug.c -o bug the output is:

buffer: some buffer
buffer:

When the second if() block is optimized-out the value of the block variable inblock_buff is not overwritten and therefore bufptr remains pointing to “some buffer” and the code seems to “work”, but when -O0 the second if() block is not optimized and the bug arise, bufptr will point to char 0 printing nothing. In my particular case this buffer was the input of the keyboard of a 5250 session, hence, in some cases the keyboard input was just ignored.

Posted in C/C++, linux | Comments Off on A Tale of Two Bugs