January 2010

You are currently browsing the monthly archive for January 2010.

Along with playing around with Tropo to test out VoIP applications where sipsorcery’s signalling only design is insufficient I have also occasionally fired up an Asterisk EC2 instance (thanks to Voxilla for bundling up an Asterisk EC2 AMI to make things easy). Each time I would customise the Asterisk dialplan to test out whatever it was and then take the instance down a few hours later. The great thing about sipsorcery is that it saves me having to configure SIP accounts or providers on the Asterisk system. I’d always thought it would be great if someone else did all the grunt work for me and offered Pay As You Go hosted Asterisk instances and saved me even the small amount of time I spent bringing my own instance up. There are lots of hosting companies out there that will host Asterisk instances but the key for me is the Pay As You Go piece, I might only want to test something out once every three months and I’m not interested in paying a monthly charge.

That’s why I’ve been somewhat interested in Cloudvox’s offering. It’s the first time I’ve seen hosted cheap hosted Asterisk instances. It’s great that they provide free “Hacker” accounts so you can at least make sure it’s not a snake oil product. Above that the cheapest plan is $6/month and calls at $0.06 per minute. Even though I’m not a fan of the monthly charge $6 is pretty cheap and it looks like you can switch back to the Hacker account easily if you know your account is not going to be in use for a while. The $0.06 per minute is not so appealing and it’s still a little bit fuzzy to me whether SIP-to-SIP calls are billable or not, apparently they are but I found that it depends on how they are dialled as to whether they show up on my account as billable or not (note I’m not trying to find ways around the cloudvox billing rather I’m trying to work out if SIP-to-SIP calls are free).

Cloudvox have two APIs for building applications although for some reason they have included SIP+RTP in the HTTP vs AGI comparison which doesn’t really make any sense and must be awfully confusing to developer new to VoIP. The HTTP API is very basic but is the easiest to get up and running with. I found it counterintuitive to begin with but that’s because I was so used to the concept of dialplans, VoiceXML and Asterisk that I was thinking of it as a way of simply loading the Asterisk dialplan whereas the approach is for the Cloudvox Asterisk servers to receive a call, send a HTTP request for a small number of Asterisk commands to a web server somewhere, execute those commands and return the result via another HTTP request, it makes perfect sense to me now. An example of an ideal task for the HTTP API is one the same I mentioned in the Tropo Transfer post about a user dialling into sipsorcery, somehow entering a number and then dialling that number out through one of their providers. The HTTP API would be perfect for getting Asterisk to play a prompt, collect some digits and then return them to sipsorcery via a HTTP request.

The second API revolves around the Asterisk Gateway Interface. Again I got somewhat confused this time by the fact that the emphasis is put on some pre-canned AGI servers like Adhearsion or the Asterisk::AGI Perl module. My confusion arose from thinking I needed to somehow connect to an AGI server Cloudvox had somewhere or that there was some special configuration on Cloudvox’s end that only allowed it to work with specific AGI servers. In the end the situation was again a lot simpler and Cloudvox don’t care what the AGI server is and all the examples and configuration guides are targetted at the common ones on the assumption, most likely correct as well, that most people will use one of them. Once that light bulb went off for me I dusted off my own C# AGI server, written many years ago, and had calls coming into it from the Cloudvox Asterisk servers in no time at all.

I’ve checked the very rudimentary C# AGI code into the sipsorcery code base, I had to strip out all the business logic so it’s really bare bones, it’s called SIPSorcery.Asterisk.FastAGI and is in the sipsorcery-servers directory. I don’t know when the next time I’ll get fired up to do anything else with it but it’s there as a reference should any other C# developers be interested. Generally I get all excited about integrating with new VoIP platforms but once i can play the monkey sounds or equivalent I consider the integration proven until something else crops up.

Updated 22 Jan 2001 due to sipsorcery call manager service again being made available on an HTTP URL since there’s a problem with Tropo recognizing the sipsorcery SSL certificate. Note the service is still available on HTTPS as well as HTTP. Also it’s no longer necessary to use the workaround to get SIP headers in a Tropo dialplan. Calls can be forwarded directly to sip.tropo.com.

Updated 12 Apr 2010 due to sipsorcery call manager service migration to HTTPS.

Tropo is a hosted voice application platform that I and a number of other sipsorcery users have messed around with at various stages. At this point I would say Tropo is definitely the pick of the bunch from the voice application platforms I have tested out and some of the stuff that can be done in a couple of lines of script, such as speech recognition or text-to-speech, is pretty amazing.

One glaring ommission for me and again other sipsorcery users has been the lack of an elegant way to transfer calls away off the Tropo servers. Here’s a few posts from the Tropo Forums about transfers:

  • Call and Transfer (from jack9901)
  • transfer API
  • And I posted the same query regarding blind transfers at some point as well but it must have been cleaned out

The usage pattern a lot of people are after is to dial into the Tropo platform, do some processing, such as ask the user to enter a number, and then transfer the call back to a different system to do some different processing, such as forward the call to a 3rd party SIP provider. Tropo does support attended transfers but that has two big shortcomings:

  • 1. Because Tropo will ultimately be charging by the minute having their servers bridge the whole call after any application processing is done is an unneccessary expense,
  • 2. Adding an extra media server into the call path always introduces call quality concerns. Even if Tropo’s systems and network connections are the best in the World it’s extra latency on the call that’s not needed.

After the recent work I did to support transfers on the sipsorcery servers I started thinking about the Tropo problem again and realised there was a nice elegant solution. Instead of initiating the SIP transfer from Tropo I could get Tropo to send a HTTPS request to sipsorcery and have it do the transfer instead. So that’s what I’ve spent the last few days doing and the good news is it works perfectly (at least for me).

The steps are:

  • Create a new dialplan on your sipsorcery account called transfer, this is the dialplan the call will end up in when it comes back from Tropo,
  • In your sipsorcery diaplan set the From header user to something that can be used to uniquely identify the call:

        when /^232$/ then sys.Dial("999142xxx@sip.tropo.com")
    

    An old example of a sipsorcery dialplan is shown below. The difference between the two is that when sip.tropo.com is used instead of sip-noproxy.voxeo.net there is no way to access the SIP headers within a Tropo dialplan and a “hack” of setting the From header user is needed.

        when /^232$/ then sys.Dial("999142xxx@sip.tropo.com[fu=uniqueidxxx]")
    

    The From header user can be accessed in the Tropo system with $currentCall.callerID $currentCall.getHeader(“x-sbc-call-id”),

  • In your Tropo application the blind transfer needs to be initiated using a HTTPS request a Ruby example I’ve used is:
    require 'java'
    
    answer()
    say "hello world"
    log "Call-ID=" + $currentCall.getHeader("x-sbc-call-id")
    svcURL = "http://www.sipsorcery.com/callmanager.svc/blindtransfer?user=username&callid=#{$currentCall.getHeader("x-sbc-call-id")}&destination=hold";
    url= java.net.URL.new svcURL
    conn = url.openConnection
    log "javaURL created"
    stm = conn.getInputStream
    transferResult = org.apache.commons.io.IOUtils.toString(stm)
    log transferResult
    say "http://202.6.74.107:8060/triplej.mp3" # Play some audio while transfer is being carried out.
    

    An old Tropo example, which will NOT work due to the call manager service no longer being provided on an HTTP URL, is shown below.

    require 'net/http'
    
    answer()
    say "hello world"
    transferResult = Net::HTTP.get_response(URI.parse("http://sipsorcery.com/callmanager.svc/blindtransfer?user=username&callid=#{$currentCall.callerID}&destination=1234")).body
    log transferResult
    say "http://202.6.74.107:8060/triplej.mp3" # Play some audio while transfer is being carried out.
    

    The new blindtransfer web service method takes three parameters:

    • user must be your sipsorcery username,
    • callid is used to identify the call leg that’s being transferred out of the call. Tropo doesn’t seem to provide much access to the incoming call headers so I’ve tailored the sipsorcery end to be able to look up the call leg based on the From header URI user. That’s why it needs to be set to something reasonably unique in your sipsorcery dialplan,
    • destination this is the value that will end up in the sipsorcery transfer dialplan as req.URI.User.

For once the whole thing is easier than it sounds and I think for those people already familiar with sipsorcery and Tropo it will be an easy job to use the new mechanism. The great thing about it is that there is now an elegant way to solve the challenge of allowing a user to dial in and enter or say their number and then dial that number out through a different provider.

Upate: There’s a bit of confusion around what needs to happen to take advantage of this latest fix.

  • 1. NO changes need to be made to SIP accounts or the SIP account a particular ATA/Phone is using,
  • 2. A change does need to be made to the registration contact being used for a provider IF it’s used for Google Voice callbacks AND the contact username is NOT the same as the web login username.

As people quickly discovered the new redundant sipsorcery deployment did not play happily with matching callbacks on Google Voice calls. The reason is that Google Voice calls from sipsorcery are not a SIP call at all but instead are initated with a HTTP request to Google Voice which generates a callback to a 3rd party SIP provider such as Gizmo (via SIP) or SIPGate (via PSTN) which if the provider is configured correctly forwards the call back to sipsorcery. If that all goes smoothly the sipsorcery server will receive the call and attempt to match it up to the SIP call that initiated the whole thing. Messy, yes; complicated, yes; one big hack, yes; since Google Voice don’t currently provide a public SIP gateway this mechanism is the only way to use Google Voice with sipsorcery, not that that’s a major goal of the project but it seemed like an interesting challenge at the time.

Anyway the introduction of a dual server deployment at sipsorcery meant that the forwarded call from the 3rd party SIP provider could now arrive at either server. That’s not an issue for pure SIP calls and the sipsorcery application servers are smart enough to know which proxy to use when forwarding to registered SIP accounts. However it is an issue when waiting for the Google Voice callback since the originating SIP call exists on a single specific server and if the forwarded callback does not arrive at the same server they won’t be matched up and more than likely the forwarded call will get rejected or cause a different phone to ring.

I have now put in a workaround (hack to a hack to a hack sort of thing) that will allow the callbacks to be correctly matched up. The caveat is that the forwarded call from the 3rd party SIP provider MUST be to the username of the owning account that is it can’t be to any old sipsorcery SIP account it MUST be a SIP account that has the same name as the username that’s used to login to the web site.

The new mechanism relies on telling the sipsorcery SIP proxies, that sit in front of the application servers, that the next call for a specific username should be directed to a specific application server. The reason the SIP account must be the exact same as the owning username is that the SIP proxies don’t have time to go looking things up in the database, they are designed to get the SIP packets to and from the other SIP servers as quickly as possible and introducing database checks would slow them down dramatically.

So the mechanism isn’t perfect but then again the original sipsorcery Google Voice call approach is not a beacon of purity either. Hopefully it should be enough to get people by.

With the SQL Azure migration complete and the second sipsorcery application server similarly bedded down now is a good time to provide the configuration options for SIP clients to avail of the new redundancy measures.

The quick steps to take to configure your SIP client are:

1. Do nothing.

In the majority of cases there will be nothing at all needed on the client side to allow it to failover between the two sipsorcery SIP servers. The sipsorcery SRV records are now configured for both sipsorcery.com and sip.sipsorcery.com (using either is exactly the same, I typically use just sipsorcery.com because it’s less typing).

For the failover mechanism to work a SIP client MUST support SRV records (RFC 3263: Session Initiation Protocol (SIP): Locating SIP Servers to be official about it). It’s also necessary that one of the two hostnames mentioned above, I’ll repeat them because they are critically important sipsorcery.com or sip.sipsorcery.com, are used and NOT an IP address or the hostname of one of the individual SIP servers.

There are still a few minor issues I am working on sorting out such as matching up GoogleVoice callbacks, which can now arrive at either of the two SIP servers, and fixing the event logging for the Silverlight console so that it gets the events from both server rather than just a single one. Apart from those issues the new sipsorcery deployment is working very well and given that it took 5 or so months of development work to make the changes to allow a multi-server deployment not to mention the work on Amazon’s SimpleDB that ended up not being used I am so far pretty happy with the way things are running.

The single point of failure in the sipsorcery system is now the Microsoft SQL Azure database platform. SQL Azure has a monthly SLA of SLA of 99.9% which would translate to 43.2 minutes of downtime in a 30 day month. That’s actually a pretty low level of reliability for a telecoms type service where five nines (26 seconds per month) is typically the bare minimum and six nines (2.6 seconds per month) is desired but hopefully the SQL Azure service will exceed expectations. Incidentally there has been an outage already in January, on the 17th between 0503 UTC and 0519 UTC the sipsorcery applications were able to read but not write to the SQL Azure database so that’s 16 minutes of the 44.6 minutes (January has 31 days so the SLA allows an extra 1.4 minutes of downtime) used up.

The data migration to SQL Azure has been completed and the sipsorcery.com web site is now available. The migration went very smoothly but if anyone notices any issues please post on the Forums. The MySQL database has been switched off, although it will be left in situ for the time being, and the sipsorcery.com service is now running between the Amazon EC2 and Microsoft Azure clouds.

I will be migrating the sipsorcery.com database from its current MySQL instance to an SQL Azure database between 0000 and 0400 UTC on 13 Jan 2010. During that time the sipsorcery.com web service will be unavailable and updates to SIP accounts, SIP providers and dialplans will not be possible.

I will post a a notification on this blog once the migration is complete.

I plan to turn off the sipwizard.net server in the next couple of days. It has served it’s purpose of verifying a multi-server deployment and of SQL Azure integration. If anyone wants to preserve any information they have in the sipwizard system please do so within the next 24 hours (by midnight Monday 11 Jan 2010 UTC).

I have now also updated the sipsorcery system to the latest version of software which brings it up to the same state as the sipwizard system. There were a few little hiccups on the update which can be seen on the sipsorcery status graph at around Saturday 9 Jan 2010 2300 UTC. The software update also means transfers are now working, at least for the phones I have tested with, on sipsorcery.com. The key point with to be aware of with sipsorcery’s handling of transfers is that blind transfers are passed through to the user agents to deal with and how different user agents handle them will vary especially if the user agent is a SIP Provider’s PBX server. Attended transfers, where the original call is put on hold and a new call dialled, are handled on the sipsorcery server and their behaviour should be a lot more predictable.

The sipsorcery system is hopefully now close to a point where it will be able to operate with redundant servers which will alleviate the outages the service has had due to the Amazon EC2 instance failing. The plan is to migrate to an SQL Azure database in the next couple of days and if all goes well with it a second sipsorcery server will be brought online shortly thereafter.

Upon waking in his Lermoos chalet ready for a day’s skiing Chad was devastated to discover that a blizzard had closed the slopes and that even venturing outside would be extremely hazardous.

After waking Trixy, Brandon and Penelope to relay the bad news the group consensus was that the day should be spent watching back-to-back Bridget Jones movies. Luckily the chalet was fitted out with the latest in SIP based media players TV and helpfully had its SIP number on the top.

Chad immediately jumped on his mobile and dialled into his Netflix account (Netflix having seen the light and installed a SIP server plus allowed access from outside the US). Chad got through to the Netflix IVR.

Chad (huffily): “Bridget Jones.”

IVR: “There are two movies available with Bridget Jones in the title.”

Chad (even more huffily): “Both you stupid machine.”

IVR: “Say play or press 0 to start the streaming the movie”.

Not wanting to watch the movies on his mobile and thereby deprive his companions of such a pleasurable experience Chad pressed the transfer button on his phone and keyed in chalet1@lermoos.at.

IVR: “Do you wish to transfer control and media to the destination device? Press 1 for media only or 2 for both.”

Chad completely exasperated at talking to such a poorly programmed IVR presses 1.

A few seconds later the touchscreen TV comes to life and informs the viewers that a certain Chad would like to play a movie. Chad touches the TV to accept the call and shouts “Play” at his phone, no sooner having cuddled up to Trixy then the first frame of the all time classic jumps to life on the TV screen.

Just in case anyone ends up reading this post hoping for an answer to the radio/podcast question in the title, unfortunately it’s not here. It may be possible, and I’m sure one day it will be, but apart from setting up a media server, which is what sipsorcery is all about avoiding, I don’t know how to do it.

Playing around with publicly accessible media services that can be used with sipsorcery is something I always find interesting and have been doing since the mysipswitch days. I’ve blogged about a previous unsuccessful effort to use a hosted VXML service. I got motivated to write this blog entry after reading a post on the mysipswitch forums by gabbar.singh Free stuffs. The post contains a link to a site called Polinez which purports to assign a dedicated US landline number to arbitrary podcast URLs and thereby make them accessible to any PSTN phone. In turn using a SIP Provider or GoogleVoice to call the US landline number makes the podcasts accessible from a SIP phone. I tested it out with a triplej (Australian radio station) free music podcast and while a number of +16414533901 was allocated when calling it I get either a seemingly random podcast or an unavailable message.

Following the experience with Polinez I did a bit of a hunt around for any other way to connect a phone to a podcast along with any free music on hold or other types of streaming services that would work with a phone. Not that suprisingly I didn’t find that many, the web browser is the predominant access mechanism for streams these days and the phone is largely ignored. It’s a shame because there are times when accessing media via a phone, be it hard of soft, is preferrable and even superior to a web browser. Flash media, as used by Amazon’s Cloudfront and YouTube, are great examples of incredibly convenient ways to stream media but with no way to easily access it from a phone :(.

The best I can come up with at the moment are a few numbers that provide streaming on hold music. Like the SIP Application Servers if anyone knows of any others I’d love to hear about them.

  • sip:305@blueface.ie music on hold from Blue Face’s Asterisk server,
  • sip:music@iptel.org fado of Anamar provided by iptel,
  • sip:early_music@iptel.org same as above but this time as early media,

Update 23 Jan 2010 I was mucking around with Tropo to see about getting Blind Transfers working when I spotted that it’s possible to playback mp3’s directly from a Tropo application, something I’d missed before. I know my favourite radio station triplej has a live mp3 feed so that got me wondering whether I would finally have an easy way to play live radio on my IP phone?! The Tropo app required is amazingly only two lines:

answer
say "http://202.6.74.107:8060/triplej.mp3"

My initial test calls failed which made me think that the Tropo server was not able to play mp3 streams and instead needed to fully download and mp3 files it needed to play. I posted a query on the Tropo forums just in case I was missing something. A Tropo staffer responded almost instantaneously that playing mp3 streams was supported and that he was able to connect to the triplej stream without any problems. I tried another few times and after about 4 or 5 calls had success! I am still only able to get the occassional call to connect to the triplej stream but I think that’s the streaming servers’s issue not Tropo’s as I have the same problem trying to connect from Windows Media Player. The reliability aside that’s the first time I’ve been able to listen to a live radio stream on my phone without having to come up with a custom solution involving Asterisk or the LIVE555 Streaming Media Server, AMAZING!

Over the last week – in between New Years Eve and a sipsorcery.com crash – I’ve been doing some work on supporting SIP transfers aka REFER requests. I’ve been able to get transfers working between the Bria Softphone and Zoiper Communicator. I didn’t want to disrupt sipsorcery.com so soon after the recent outage so at the moment the update that supports transfers is only available on the sipwizard.net server. Transfers are supported on sipsorcery.com.

Only attended transfers are handled by the sipwizard server as it does not make sense for blind transfers to be processed by a signalling only SIP application server instead blind transfer requests are passed through to the user agent at the other end of the call to process as they see fit.
Both attended and blind transfers are supported. With blind transfers a dial string option can be used to determine whether to process the transfer on the sipsorcery server or to pass it through to the user agent on the other end of the call. Attended transfers are always processed on the server since the user agent on the other end of the call will not know anything about the dialogue being replaced.

There are some additional dial string options that can control the processing of REFER requests. One thing to be cautious of is blind transfers where a malicious called party could send a blind transfer to a premium rate number or such. There are different ways that could be handled: in theory user agents should ask for confirmation before accepting a blind transfer, apart from that I may change have changed the software so that blind transfers are disabled by default and only passed through if explicitly configured on a call by call basis. Of course premium number ranges could also be blocked within the dialplan but there would always be the possibility that a destination had been missed or some other attack was possible.

The new dial string parameter is tr (which stands for transfer). The values it can have are:

  • n for no transfers allowed in which case all REFER requests will be rejected. This is the default value and does not need to be set.
  • p for pass through in which case all blind transfer requests will be forwarded to the user agent on the other end of the dialogue. Attended transfers will still be processed on the sipwizard server.
  • c for place call. Attended transfers will be processed by server, blind transfers will intiate a new call on server and then do an attended transfer. For a blind transfer the Refer-To URI will be sent to a dialplan with a name of transfer, if it doesn’t exist the transfer will fail.

If anyone is using SIP transfers I’d be interested to know whether it works for them through sipwizard.net. I’m currently away from my Polycom and Cisco IP Phones and plan on doing some more testing with them next week.

# To explicitly block all transfer attempts. This is the default operation if there is no tr dial string option.
sys.Dial("1234@provider[tr=n]")

# To process blind transfers in a transfer dialplan.
sys.Dial("1234@provider[tr=c]")

# To pass through transfer requests to the user agent.
sys.Dial("aaron@local[tr=p]")