Book Image

FreeSWITCH 1.0.6

Book Image

FreeSWITCH 1.0.6

Overview of this book

FreeSWITCH is an open source telephony platform designed to facilitate the creation of voice and chat-driven products scaling from a soft-phone to a PBX and even up to an enterprise-class soft-switch. It is always exciting to design and build your own telephony system to suit your needs, but the task is time consuming and involves a lot of technical skills.This book comes to your rescue, helping you to set up a telephony system fast and easily using FreeSWITCH. It will take you from being a novice to creating a fully-functional telephony system of your own. It is rich with practical examples and will give you all of the information and skills needed to implement your own PBX system.The book begins by introducing the architecture and working of FreeSWITCH before detailing how to plan a telephone system and moving on to the installation, configuration, and management of a feature-packed PBX. You will learn about maintaining a user directory, XML dial plan and advanced dial plan concepts, call routing, and the extremely powerful Event Socket. You will finally learn about the online community and history of FreeSWITCH.
Table of Contents (18 chapters)
FreeSWITCH 1.0.6
Credits
About the Authors
About the Reviewer
Preface
The History Of FreeSWITCH
Index

Appendix B. The History Of FreeSWITCH

In order to properly explain the origin of FreeSWITCH we have to go back to the time before we even had the idea to write it. The VoIP revolution really began to take shape at the turn of the century with the creation of both the Asterisk PBX and OpenH323. Both of these pioneering software packages enabled many developers to have access to VoIP resources without paying for a costly commercial solution. This led to many new innovations in both projects, and the rapid spread of the evidence that true usability of IP telephony did indeed exist.

I first got involved in the industry in 2002, when my company at the time was selling outsourced technical support and we needed a way to manage the calls and send the traffic to an off-site location. We were using a commercial solution but it was costly to deploy and had very over-priced per-seat charges on top of that. I had done a lot of work with open source applications such as Apache and MySQL in my past duties as a web hosting platform architect so I decided to do some research on the existence of any open source telephony applications. Enter Asterisk.

When I first downloaded Asterisk, I was amazed. I got some analog telephone cards to use with it and here I was at my house, with a dial tone on a phone that was plugged into the back of my Linux PC. Wow! That's crazy... It wasn't long before I started immersing myself in the code, trying to figure out how it worked. I learned quickly that it was possible to extend this software to do other things based on loadable dynamic modules just like Apache. I started digging around and worked up a few test modules. This was better than ever. Now I was not only making my phone talk to this PC, I was making it execute my own code when I dialed a certain number.

I played around with a few ideas and then the thought dawned on me. Hey! I really like Perl and this telephone stuff is pretty cool too. What if I try to combine them? I looked into the documentation on embedding Perl into a C application and before I knew it I had app_perl.so, a loadable module for Asterisk that would allow me to execute Perl code of my choice when a call was routed to my module. It wasn't perfect and I started to learn quickly about the challenge of embedding Perl in a multi-threaded application, but it was at least an awesome proof of concept and quite the accomplishment for a few days of tinkering.

As time progressed, I was drawn deeper into the Asterisk online community. After playing with the code for a few weeks, I began working on some call-center solutions using Asterisk as the telephony engine and some homegrown web applications as a frontend. Along the way, I encountered some bugs in Asterisk, so I submitted them to the issue tracker for inclusion to the development branch. The more this process repeated, the deeper my involvement in the project grew, and I began creating improvements to the software as well as just sporadic fixes to bugs. By 2004, I was actually fixing bugs that other people reported as well as my own. It was the least I felt I could do for having a free solution to all of my problems. If my problems would actually be solved, still remained to be seen.

When I was testing my application, I would make many calls to the system and watch for the web page to update, control the queues and watch the stats build up. However, one thing I was not paying attention to was the number of simultaneous calls and the call volume itself. I was really only making a call or two at a time, and I was not really fully testing my application. When I put it into production for the first time, it was also the first time I ever saw what happened when multi-threaded software had an irresolvable conflict in the locking contention, better known as a dead lock. I was quite familiar with the segmentation fault, as I had encountered many of those along the way when I was working on my own modules, but I was surprised to also see a rise in the number of inexplicable random ones happening only some of the time.

A segmentation fault is a violation that an application commits where it makes inappropriate access to memory by destroying the same memory more than once or accessing memory addresses that are out of bounds or do not exist. You will run into them a lot in C programming, since you have lower-level access to the operating system and there is nothing to protect you from making errors besides your own discipline. I don't give up easily, which you could consider a curse or a blessing, so when I started to encounter some problems, I was prepared to get to the bottom of it. I spent countless hours studying the output from the GNU debugger and trying to simulate the traffic that caused my problems. After a little trial and error, we find success! I managed to duplicate the crash in my test lab using a load generator. I even managed to figure out where the problem was and fixed it! That was a great feeling that lasted right up until later that afternoon, when I learned there was another new problem with similar symptoms somewhere else in the code.

I managed to slowly back out the features in my application that increased the likelihood of a deadlock or segmentation fault, but I could not completely eliminate all of the problems. I eventually discovered that the app_queue module was causing most of my grief which was not the best news considering that was the module I was using the most in my call-center application. Some of the changes I wanted to make were too intrusive for inclusion in the main code distribution so I ended up using my own copy of the code so I could continue to update the rest of Asterisk. This kept things stable, but only stable enough to seek another solution.

By this time I had written a fairly large amount of features into Asterisk and was really starting to have some big ideas for new functionality. I created a new concept called "function variables" allowing modules to expose an interface that could be expanded from the dial plan (if you read the rest of this book that idea may sound familiar). I still was wrestling with the queue problems, so I got together with another Asterisk community member and started brainstorming on a new ACD queue module for Asterisk called mod_icd.

ICD stood for Intelligent Call Distribution, a play on the acronym ACD meaning Automatic Call Distribution. We had identified all of the shortcomings of the app_queue module with regards to functionality and we had a common interest in making a more stable module that would not cause countless crashes and deadlocks. We had a working prototype and a lot of work to do. We used state machines and higher-level memory management abstractions with data pools and several other inspiring concepts that we felt were lacking in the standard Asterisk. The problem was, I think we over-engineered the module too much, almost as if we were trying to edge out the entire Asterisk core, which was of course not completely possible being only a loadable module within that core.

We never quite finished mod_icd. It was late 2004 and my opportunities with call-center solutions lay smashed on the rocks, washed away by the unforgiving seas of segmentation faults and deadlocks. We started focusing more on other telephony services that did not involve queuing. I developed a new offering of toll-free termination and fax-to-e-mail services. Using several new features I added to the mainline Asterisk and some of my less-popular modules that were not approved, I built a cluster of seven Asterisk boxes and connected them to a large telecom circuit. This deployment of Asterisk was not problem-free but, on the bright side, if some of the machines crashed there was more to take its place while we restarted them.

At this point I had accumulated several new ideas, some tested, some not, some that were going to require some major changes to Asterisk. My team, Brian West, Michael Jerris and I were donating a lot of time to the Asterisk project. We helped maintain the issue tracker. We fixed bugs and helped out every week by hosting a developer's conference call. We even hosted a mirror of the code on our site. We were very involved yet some of our new ideas were causing some political turmoil in the Asterisk community, as there was an unnecessary competition among the various developers. Every contributor to Asterisk must sign a form stating that all the code you write, that may be included in the Asterisk code base, will automatically have a royaltyfree license for Digium, the owner of Asterisk, to do what it pleases with your code. This was so they could sell the unrestricted licensing to would-be buyers for a high price. Not exactly the spirit of open source but that's another story. I think this alienation caused some strife between the volunteer developers like myself and the developers who were hired outright by Digium to work on Asterisk.

Even with the tension, we were dedicated to the project and really wanted to see it succeed. We were having those regular weekly conference calls and they were really starting to help get the developers motivated. We decided that we should have a live in-person meeting so we could all share our knowledge of telephony and hang out for a few days. We had no idea what we were doing, but we decided to do it anyway and call it ClueCon. Having a clue meant you knew what you were doing, so ClueCon was a conference to help everyone to "get a clue". I do acknowledge, I just said we did not know what were doing either, so there was a bit of irony that people with no clue would start a clue con. However, that turned out to be more of a blessing than a problem and the clue we were referring to was in regards to telephony not to running conferences.

Therefore, with several months until the first ClueCon, in the spring of 2005, we had one of our usual weekly conference calls and began talking particularly in detail about several shortcomings of Asterisk. This is not uncommon, because our primary goal was to identify the problems and convert them into solutions. There was, at the time, a fairly large unruly crowd who was tired of the endless problems they were experiencing with Asterisk. Many of them joined this weekly call, hoping to persuade us to look at one of their issues. The more I thought about it, the bigger the task seemed to unravel some of the big architectural problems that were plaguing us. Many concepts were monolithic in nature and would not scale. Many features had several users dependant on them and changing them with a goal of improvement could lead to regressions in functionality. It just seemed like some of the problems could only be solved with a sledgehammer, yanking out some older code and doing some serious rewrites to some of the deeper recesses of the core code. This did not seem very viable since it would render Asterisk unusable for months if not a year or more. That's when I had the idea, let's make a 2.0!

It was not the worst idea; I knew it would be challenging but, hey, I thought we could start a new code base alongside the old one, so we could tear out the parts of the code that caused the most problems and replace them while still maintaining the original code for the users who depended on something that worked. I was pretty excited about the idea and equally shocked when the project leader reacted to my suggestion of the idea, and he appeared was equally shocked that I would even suggest such a thing so, in short, we did not make an Asterisk 2.0. Here I was, with a ton of ideas and a clear mind on exactly what I did and did not like about Asterisk with nowhere to write them down.

I gazed at that empty text-editor buffer open in an empty directory for an hour. I knew what I wanted to do, but it was hard to bring it to words. I never could find the words until I added in several oddly arranged punctuation around them. Those were not your everyday words, they were symbol names and variable declarations. I was writing C code. In a few days, I drafted up a basic application in C, tying together some of my favorite tools from my past experience in programming. I had the Apache Portable Runtime or APR library, the Perl language, and a few other packages. I built a core and a loadable module structure, a few helper functions to use memory pools and I had a simple command-line prompt that would allow you to type help if you wanted to see a sarcastic comment about there being no help for you, and exit to shut the application down. I made a sample module that would let you telnet to a specific TCP port and have it echo back everything you typed and a very basic state machine. I called it Choir. I thought of my idea as a series of parts working together to make one unified voice like a choir. After that initial coding session, I put it down for a while. ClueCon was coming and I did not want to rush things as I still thought that there was much to consider.

August of 2005 was the first annual ClueCon conference. We had several open source VoIP project leaders including Craig Southeren, one of the authors of OpenH323 and Mark Spencer, creator of Asterisk and the same person who did not like my Asterisk 2.0 idea. However, it was awesome to get these guys in the same room. We filled the day with presentations, with discussions going back and forth, and we really got everyone thinking. It was a huge success and I left the conference energized and ready to work on my Choir code again. However, I didn't. Instead I talked it through on our conference call for months while trying to keep my struggling Asterisk based platform afloat. It was fall now and the turmoil in the Asterisk community finally erupted into a rebellion. A large percentage of the community forked Asterisk into a new application called OpenPBX.

I totally understood why they did it, and I supported them the best I could. I donated all of the code I had written for Asterisk, for them to do what they pleased. I helped when I had a chance, but could never fully get involved with the effort because I still had the same problem—I saw a need to really tear everything down to the basic level and the founders of the new project were mostly interested in fixing specific pressing issues that were not being addressed in a timely manner by the Asterisk core team. We still had the conference calls, but mostly nobody would show up from the Asterisk project because they were not happy with the idea of cavorting with the rebels. I apologized one day because I could not try to solve any problem in OpenPBX that would not boil down to totally gutting everything and writing a new core. That's when someone asked me, "How long do you think it would take to get your new code to make a call?" Like Mr. Owl from the tootsie pop commercials, I had no idea so I decided to find out. A-one, a-two, a-three weeks (give or take).

The first module that actually produced sound was called mod_woomera; it was an endpoint module using the Woomera protocol written by Craig Southeren, the same person I had just met at ClueCon. I made a similar module for Asterisk and it was a simple protocol and required no codecs or anything fancy. The idea was that it would take the complexity out of H323 and allow applications to use it via this simple protocol that could be easily integrated into VoIP applications, so it seemed like a great place to start. As I started to work, I realized that I needed more elements in my basic core and slowly started to bring the code together to a point where I could make a call to the Woomera-powered H323 listener process and get activity in my Pandora code. Yes, I renamed it to Pandora because nobody liked the name Choir. I joyously listened to the Alan Parsons Project hit Sirius stream into my speakers from my application for the first time. This was even more exciting than the first time I made Asterisk work because I actually wrote this code myself from scratch and it was doing something.

Now I was getting somewhere; I figured out how to make two channels bridge, then how to support some other protocols and do a few basic things beyond a sarcastic help message and an exit routine. The idea came and went to dub this code OpenPBX 2 and finally when I had enough with naming arguments, I decided once and for all what I wanted to call the application: FreeSWITCH. I finally had a name I knew I was going to stick with and some working code, and a lot of ambition. I put my head down and just began coding. There was work to be done everywhere. It was too overwhelming to think about it really. I just kept plowing through the code and by the time I reached January of 2006, I had enough to share with the public. We opened up our code repository to developers asking them to register for a developer account to gain access to the code as a way to make sure only those who were serious would bother to complete the registration process. We had some people checking it out and providing feedback and we really started to feel like we had a real project.

We had a module to bridge calls, one to play sounds, a few codecs, some examples of Dialplan modules, and a few other things. Oh and did I mention it worked on Windows too?

Our original site is still preserved, though none of the links are active: http://www.freeswitch.org/old_index.html.

Somewhere along the way from all that planning, we actually produced code that could run on Windows as well as Linux and Mac OSX. My original team mates, Michael and Brian were there from the beginning and Mike, having a lot of experience in Windows, made sure we could compile and run the code in MSVC. It was a struggle at first, but after having to correct tons of compiler errors on many occasions, I began to learn how to code in a way that would be friendly on most platforms on the first try. Time started to fly and before I knew it, it was ClueCon time again. That year I gave my first presentation on FreeSWITCH demonstrating the core design and fundamentals that are outlined in the opening chapter of this book. We saw far exciting modules, such as an endpoint module that can communicate with Google Talk. My presentation featured a live demonstration of several thousand calls being set up and torn down by our mod_exosip SIP module. It was a nice demo, but we still weren't happy.

Exosip was a SIP library that was really nothing more than a helper library to Osip, an open source SIP library that provided most of the functionality. The Exosip made it a bit easier to get an endpoint moving and we decided to use it but we encountered several mishaps with it and I started to feel that same sinking feeling I had when I was trying to get Asterisk working, so we started looking for a replacement. It didn't help that there was potential licensing conflicts because Exosip claimed to be GPL despite the fact that its parent library was LGPL (which, in my opinion, is a much more reasonable license). As we chose MPL for our project, it was forbidden by the GPL to allow GPL'd code to be included in an MPL app. License debates are fun and a good way to get people excited but that was not the time for one.

We searched the land of open source far and wide, for both a new SIP stack and an RTP stack to use in FreeSWITCH since there was quite the high demand for SIP functionality. We auditioned several libraries for both roles and we ended trying at least five different stacks for both protocols. I never found an RTP stack that satisfied me, so I wrote my own. I was not foolish enough to try the same thing with SIP. Having a front row seat to the mess caused by Asterisk trying to write a SIP stack from scratch and the failure with Exosip in my rear-view window, I continued to search for a SIP stack until I found Sofia-SIP, a SIP stack written by Nokia. We built a functional mod sofia to test things out and we were highly impressed. We continued to polish the module until we reached the point where we could drop mod_exosip and use mod_sofia as our primary SIP endpoint module. This was only the beginning really, as I still find myself adding code to mod_sofia on a regular basis to this day. SIP is a complicated and frightening protocol that brings many unpleasant thoughts to mind even saying its name , but now is not the time for that conversation.

We gave another presentation on FreeSWITCH at ClueCon 2007, this time with a new SIP module and a lot more code. Now we also had OpenZAP, a TDM library to connect FreeSWITCH to telephone hardware. I experienced the joy of making the very same cards I got working on Asterisk so long ago, to work with FreeSWITCH as well. We had announced that soon we would be releasing the 1.0 edition of FreeSWITCH. Anyone who read our original homepage that I posted earlier might notice we announced that an official release was "coming soon" way back then. This was announced in January of 2006 and we were trying desperately to make things the way we wanted them ever since. We really wanted to focus on making a stable core before all else and we were making real progress, but we still were not ready to release 1.0.

By spring of 2008 we had stable SIP, we had the event socket to remotely control FreeSWITCH, we had a module to interface with our API commands over http, we had XML curl and a nice big list of features. We finally decided it was the right time for a release, so we bit the bullet and released FreeSWITCH 1.0 Phoenix. I chose Phoenix as the release name because I felt that all of our hard work was born from the ashes of our previous failures and though it had been used by a lot of others, including NASA who was launching the Phoenix to Mars at the same exact time, I think it was the appropriate title.

ClueCon 2008 featured the announcement that 1.0 had been finally released earlier that year in late May. Several presentations also related to FreeSWITCH as well as the other open source projects such as Asterisk who had produced a 1.6 release that year. We spent the next entire year focusing on wideband audio support and other advanced features such as on-the-fly re-sampling of unlike audio streams. We added many new SIP features like presence indications and other fancy things beyond simple call setup and a follow-up 1.0.1 release.

In 2009, we released 1.0.2 to 1.0.4 versions and presented FreeSWITCH again at the fifth annual ClueCon. Some of our early innovations matched up with reality by that time, as we were able to demonstrate Polycom phones using high-definition audio on their new Siren codec as well as support for the Skype protocol as an endpoint module. The FreeSWITCH presentation was an overview of the things you probably didn't realize you could do unless you learn to think fourth-dimensionally, as Doc Emmitt Brown from Back To The Future and I both like to put it. We have some similarities to Asterisk in behavior, but we also have an entirely new paradigm that opens the door to some incredible things you can do with just a PC and a telephone.

As the new decade begins we are still working hard on making stable code and building new features into FreeSWITCH. We will soon be releasing 1.0.5, and we have a long list of new ideas to work on as well as a wonderful online community who supports us and contributes code, feedback, and much more on a regular basis. ClueCon MMX (2010) is scheduled to take place in the first week of August; we hope to see you all there and I hope you have managed to learn a little bit more about FreeSWITCH and why I decided to start typing those first few characters in that empty text-editor.