Friday, June 17, 2011

Timers in Python

Often in computer programs there would be a requirement to execute a function/task after certain time has passed. And some times this task could be a repetitive one, that needs to be executed again and again after certain interval has elapsed. A simple example is, in VoIP applications a phone is required to send a voice packet every 20 milliseconds. In GUI application a clock needs to be displayed in which updates it self every second displaying time elapsed or current time. For all such cases a timer is best suited tool.

Python standard library provides a Timer class that is capable of executing task in single shot mode. However, thats a very basic functionality that a timer could provide. The external GUI and Network frameworks of python provide extensive timers with fancy provisions. I'll provide a list of timer APIs provided by vairous python libraries that I've come across.
  • after method of Tkinter librarie's mainwindow (ships with standard library on windows, again minimal functionality one) 
  • wx.Timer , wx.CallLater , wx.PyTimer these are various timers provided by wxPython library. The CallLater and PyTimer are convenience functions built on top of wx.Timer 
  • QTimer is PySide's (PyQt) version of timer functionality. Its neat with various helper functions.
  • callLater , LoopingCall are the timer APIs provided by the network swiss army knife of python - Twisted library.
Every asynchronous program comes with a main loop. Which dispatches the events (mouse, keyboard or network events) to target functions. The cardinal rule of such programs is not to block this main loop. Suppose if you block the main loop by calling long running function in your program, the main loop will no longer get a chance to dispatch any pending events until this long running function returns. time.sleep(100) in a function's body would certainly block whole program until those 100 seconds elapse. As a side effect, the program will freeze at that point. If its a GUI program it will no longer respond to user inputs and if its network program it will no longer read underlying sockets until this time.sleep returns. To avoid such awkward situation almost every frame work that comes with a main loop makes a provision for executing tasks at desired time with the help of timer functions. Timer tools are neat and useful. An in depth explanation of the way they are implemented and the problems that they solve will be the subject another post soon.

Saturday, June 4, 2011

Pitfalls to avoid while using mod_xml_curl of FreeSWITCH

xml_curl is a great module of FreeSWITCH that simplifies user management (configuration management) . This module allows FreeSWITCH to fetch account details from a different server running HTTP service. The basic info  of what is xml_curl and how to use it can be found on this wiki page of FS  .

Now to the subject matter of this post. Current version of FS sofia profile can be paralyzed severely, if xml_curl is not carefully configured. If a request sent by xml_curl originated out of REGISTER request of some UA is never replied (situations that can trigger this is network issue or a bug in web service ),  and connection is kept open like that. Any subsequent REGISTER requests sent by SIP UAs will not be replied back by mod_sofia, thus causing a situation where new SIP UAs can no longer register. To avoid this there is a timeout option in xml_curl's config file. 

<param name="timeout" value="10"/>

With this option in place it will safe guard FS sofia profile in question from becoming unresponsive. Also, it would be a good practice to use some sort of timeout functionality making sure that connection made by FS is not blocked indefinitely by web app.
The reason this happens is because of the underlying sofia library  used by FS handles only one REGISTER request at a time. Anthony has some plans on enhancing this situation by making xml_curl not to come in way of sofia profiles working.

Another tip is to use cacheable='true' attribute of user xml returned by web service. This will make FS to maintain a local cache of the account details. The details will stay in cache until cleared. This means that FS won't be hitting your web app for every REGISTER request that hoards of SIP UAs are sending, it will ask only once upon first request. The subsequent requests will be looked up from cache.

Monday, January 24, 2011

PySide and the GUI world of Python

For desktop GUI development Python has a long list of options that one can choose from . Here are more popular ones (Tkinter, wxPython, PyQt, PyGTK) and many other infamous ones. Of all these libraries, PyQt a Python binding for Qt has wonderful docs and consitent API rich widget classes. This is mostly due to the licensing model that Qt and PyQt used. These libraries have made very good use of dual licensing, which helped their development. The people behind the libraries got paid thus they made sure that the crossplat-form experience is smooth , API is consistent and docs good.

But, even with all these goodies, it hasn't seen a great use in opensource consulting arena because of the high price and viral GPL license. After Nokia's acquistion of Qt situation has changed. Nokia released Qt under less restrictive license (LGPL ) . Which helped many devs looking for this day to go and embrace it. But on python side things were same quite for some time even after Nokia's acquisition of Qt. When Nokia and PyQt's Riverbank has failed to reach an agreement. Nokia has decided go ahead with making its own Python bidings, called PySide. Last october PySide has made a windows version release. With the PySide project really picking up, it will help more wide spread use of Qt. Nokia being hardware company has very little to loose by opening up Qt to public with less restrictive license. The very same step that Trolltech and Riverbank has restrained from doing because Qt is their bread and butter ! Nokia's decision has nice side effect that now all the python and opensource devs have a wonderful GUI library at their dispose. The sad thing being that Riverbank's PyQt libs will take a hit from the rise of PySide.

Wednesday, December 29, 2010

Inbound,Outbound EventSocket connections the beginner's confusion

For FreeSWITCH beginners and programmers coming from Asterisk world, these two terms Inbound,Outbound are very confusing. For developers who are familiar with Asterisk this is in short
  • Inbound = AMI
  • Outbound = FastAGI
For new comers -  Inbound EventSocket connection can be used for controlling FreeSWITCH as a whole, can get information on any existing channel. We need to make these connections with FreeSWITCH from an external program.

Outbound connections are generally tied up with a single channel, these connections are created by FreeSWITCH, whenever a socket (FastAGI in asterisk) application is encountered in dialplan. Generally meant to execute action on a single channel only and receiving events pertaining to that channel. 

However, FreeSWITCH is very flexible and this behavior can easily be changed as we can choose which Events our program can subscribe to.  'myevents' command to FreeSWITCH will tie the socket connection to a particular channel. And event command will make the socket connections to receive all FreeSWITCH wide events related to every live channel in FreeSWITCH.


These are named so by looking at them from a FreeSWITCH prespective. EventSocket connections that FreeSWITCH accepts are inbound to it and connections that FreeSWITCH makes to an external socket server is outbound to it.

Saturday, December 18, 2010

FreeSWITCH EventSocket header length

Python's email package is very useful for parsing and generating email messages. The messaging format used, is defined in RFC822 and RFC2822. This similar format is also used for many other protocols ( the one that I work with most often is SIP). FreeSWITCH also uses similar messaging format for communicating with applications over it's EventSocket interface.

The default python implementation adheres to line length recommendations specified in RFC2822  2.1.1 section so it wraps any header line beyond the length of 78 characters. However, this is bad for FreeSWITCH 1.0.6 as it ignores the wrapped part of the line. One good example is executing play_and_get_digits from EventSocket as it has more number of arguments the argument line length often exceeds 78 chars when all the argument values are provided. And, FreeSWITCH silently ignores the wrapped part of the arguments. To avoid this, you can override the as_string() method of email.message.Message and set maxheaderlen=0 in email.generator.Generator() used by Message class. That will disable the line wrapping and your FreeSWITCH applications will work as expected.

Wednesday, December 15, 2010

Use of return_ring_ready originate variable in FreeSWITCH

FreeSWITCH has easy API to originate calls. And this origination can be customized to great extent to meet various needs. By default the originate API command of FreeSWITCH will return only when the media starts flowing in like in the following situations
  • '183 Session in progress'  early media
  • '200 OK' when the call is answered. 
Different SIP providers have switches that behave differently when it comes to sending back session information. They may send '200 OK ' directly without any 180 codes. Or they may send fake ring back, by immediately sending '180 Ringing' back to FreeSWITCH. As mentioned above originate command only returns a result when origination is failed or when media starts flowing in. Now, if you want to make originate command to return when FreeSWITCH sees '180 Ringing' other end ringing thats when return_ring_ready variable comes in handy. You just need to set this to true during origination so FreeSWITCH returns immediately when it sees 180 saying that origination is successful.

Why this is important ? There might be situations where you are using a outbound socket application to connect back to the originated call when it succeeds.
originate sofia/gateway/someprovider/919246461929 &socket(127.0.0.1:8082 async full)

By default socket application only gets called when originate returns and originate won't return until it sees 183 or 200.

originate {return_ring_ready=true}sofia/gateway/someprovider/919246461929 &socket(127.0.0.1:8082 async full)
If you execute the above command originate will return immediately and executes the outbound socket connection when it sees '180 Ringing' .  This behavior allows you to read the channel information in outbound socket before the call is answered and also will allow you to catch CHANNEL_ANSWER event fired by FreeSWITCH when the other end answers the call(you can start playing your IVR at this point). In the default behavior you can you cannot capture CHANNEL_ANSWER if your SIP provider is sending signaling 200 after 180.  As originate only return after it sees '200 OK'  by the time your outbound socket gets invoked its too late to capture CHANNEL_ANSWER event. However, return_ring_ready is not required to achieve this if the provider is sending 183 before 200. Most of the SIP providers do send at least one 18X variant signal. So, its safe to have return_ring_ready set to true if you want outbound socket to be invoked before the channel is answered.

Wednesday, October 20, 2010

Asterisk Vs FreeSWITCH - Channel Tracking UniqueID

If you have ever used Asterisk's AMI (Asterisk Manager Interface ). You will know the pain of tracking a particular channel, especially when its getting originated or being bridged with some other channel. There is no easy way to do that cause in asterisk the Unique ID of a channel keeps changing over its life span. New Unique IDs are created through out a channel's lifespan when originated one Unique ID and when linked with other channel again a new Unique ID etc etc. All this gives jitters to programmer, and this kind of behaviour clearly shows some design mistakes in Asterisk.


Asterisk uses unix timestamp appended by an incremental counter as a channel's uniqueid.

A sample unique id of a channel used by asterisk - 1268129694.0

This post is not about talking down Asterisk or any thing. Asterisk is a great milestone in opensource telephony evolution.

That brings us to next beast in the evolution FreeSWITCH. FreeSWITCH is built by a person (Anthony Minessale II ) who has great understanding of Asterisk. So, he made sure that the short comings of Asterisk are addressed in a proper way. EventSocket interface of FreeSWITCH is more powerful and hooks into almost every aspect of FreeSWITCH. EventSocket is one single protocol for call control and switch control instead of two different protocols that Asterisk has FastAGI and AMI.

FreeSWITCH tracks calls in a real neat way by hooking them up with UUIDs. Each leg or channel in FreeSWITCH is identified by a single UUID through out its lifespan. Which makes it a breeze for the programmer to deal with call events and control the calls. FreeSWITCH also allows you to specify your own UUID for a call leg while originating, that way you are given absolute control of what goes on with a leg.

Before I end the post, here is a sample unique id of a channel used by FreeSWITCH - 60a3c6de-dc73-11df-9c62-00238b1dd454