Tuesday, January 13, 2015

Getting ready for #signalconf

It's been a while since I last wrote in here... mainly because I've been working like crazy, but I'm expecting to start blogging on a regular basis at least until the Signal conference (the new version of the twilio conference).

The (first and) last conference I attended was the 2013 360|iDev one... and even if I ended up leaving the iOS world, I got something that changed my (professional) life from it... The conviction that (almost) everything is possible. I was already working with Twilio's APIs, I started playing with Asterisk, I started this blog, people started contacting me about it, I left the company I was working for and I'm proud to say that I'm working exclusively on stuff that I find interesting.

I went to that conference with very little experience on that particular technology, having only worked on an iOS app before, and without enough knowledge to really stand out from the crowd.

I'm in a very different situation for the Signal conference... I've worked with Twilio on several projects, using different technologies (Python and .NET both with websockets) and probably all what they offer. I have a good understanding of Asterisk and I'm eager to meet interesting people that can help me take my game to the next level (while I help them do the same)... but in two days, it's going to be crazy to really connect with so many people... that's why I feel I have to do something about it.

The thing that got me noticed in the virtual world is how I integrated Asterisk and Twilio before there was a single blog post around... so I'm going to try to build on it. Something that's missing in Twilio is the ability to have SIP phones register with it, so that developers can deal with SIP phones instead of regular landline or mobile phones. I'm guessing that's a feature that's coming (given that other companies already offer it and that Twilio has recently added SIP Trunking capabilities). Besides adding an option to work with existing SIP terminals, the cost of calling SIP phones is significantly lower than calling landlines or mobile phones around the world, so it only makes sense for them to integrate it into what they sell... but in the mean time, I'm going to do something about it!

In order to have SIP phones register, you need to have a PBX (Asterisk or Freeswitch)... and dealing with them is usually a headache for application developers, so I'm going to build an Open Source "Asterisk as a service" service. It will have a .NET RESTful backend that will handle the application logic and several Ubuntu servers with Asterisk that will take care of the communication with Twilio and the SIP phones. The code to handle the servers will be pure Python and the frontend will be an AngularJS application that will connect to the backend in the same way that the Ubuntu servers will.

I'm going to have it ready for the Signal conference and I expect it to be an effective way for me to show how I work and what I know. I will also put a big deal of effort in detailing what's missing and how things could be improved (I've never worked with a SIP proxy, and for it to be really scalable and redundant, the solution would need one. I don't think I'll have enough time to learn and tackle that down though).

I expect to keep on sharing my problems and solutions in here... what started as a way to give back has taken my by surprise... Here's to more surprises and to a great 2015!

See you there?

Wednesday, April 9, 2014

Installing Asterisk 12 on Ubuntu 12.04 with pjproject and SRTP

Today I had to install an Asterisk that could deal with WebRTC. I read on the Asterisk wiki that in order for it to work, it needs to be installed with pjproject and SRTP. Until today, I always used menuselect to choose what to install, but these two buddies are kind of different... they aren't selectable unless you install them before Asterisk.

As I couldn't find a guide with the steps to follow (took bits of information from different sources and figured some things by myself) here's what worked for me. I took a lot from
Asterisk 12 on a Raspberry Pi | MatthewJordan.net so thanks to Matthew ;) I also enjoyed how he shows what he's doing, so I'm copying that from there too.

Install the Asterisk dependencies and more stuff we're going to need (I'm also installing libbfd-dev b/c want to use BETTER_BACKTRACES)

gmc@blog:~$ sudo apt-get install build-essential libsqlite3-dev libxml2-dev libncurses5-dev libncursesw5-dev libiksemel-dev libssl-dev libeditline-dev libedit-dev curl libcurl4-gnutls-dev libjansson4 libjansson-dev libuuid1 uuid-dev libxslt1-dev liburiparser-dev liburiparser1 git autoconf libbfd-dev -y

Reading package lists... Done
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place


Install libsrtp

We first donwload and uncompress the files (thanks to Alexander Traud for pointing me out that libsrtp moved to github)
gmc@blog:~$ cd ~
gmc@blog:~$ git clone https://github.com/cisco/libsrtp.git
Cloning into 'libsrtp'...
remote: Reusing existing pack: 2037, done.
remote: Total 2037 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (2037/2037), 3.17 MiB | 1.30 MiB/s, done.
Resolving deltas: 100% (1249/1249), done.
Checking connectivity... done.
Then configure and make it!... I figured out the flags for ./configure by trial and error (at one point, Asterisk complained about the -fPIC flag, so I just added it)
gmc@blog:~$ cd libsrtp/
gmc@blog:~/libsrtp$ autoconf
gmc@blog:~/libsrtp$ ./configure CFLAGS=-fPIC --prefix=/usr

checking for ranlib... ranlib
checking for gcc... gcc
checking whether the C compiler works... yes
config.status: creating doc/Makefile
config.status: creating crypto/include/config.h

gmc@blog:~/libsrtp$ make

gcc -DHAVE_CONFIG_H -Icrypto/include -I./include -I./crypto/include  -fPIC -c srtp/srtp.c -o srtp/srtp.o
gcc -DHAVE_CONFIG_H -Icrypto/include -I./include -I./crypto/include  -fPIC -c crypto/cipher/cipher.c -o crypto/cipher/cipher.o
gcc -DHAVE_CONFIG_H -Icrypto/include -I./include -I./crypto/include  -fPIC -c crypto/cipher/null_cipher.c -o crypto/cipher/null_cipher.o
gcc -DHAVE_CONFIG_H -Icrypto/include -I./include -I./crypto/include  -fPIC -L. -o test/rtpw test/rtpw.c test/rtp.c libsrtp.a  -lsrtp
Build done. Please run 'make runtest' to run self tests.

I saw that there was a make runtest... it's pretty cool :) here's what you should see
gmc@blog:~/libsrtp$ make runtest

gcc -DHAVE_CONFIG_H -Icrypto/include -I./include -I./crypto/include  -fPIC -c crypto/math/math.c -o crypto/math/math.o
crypto/math/math.c: In function 'bitvector_print_hex':
crypto/math/math.c:854:5: warning: format not a string literal and no format arguments [-Wformat-security]
libsrtp test applications passed.
libcryptomodule test applications passed.
make[1]: Leaving directory `/home/test/srtp/crypto'

and then... just install it
gmc@blog:~/srtp$ sudo make install

/usr/bin/install -c -d /usr/include/srtp
/usr/bin/install -c -d /usr/lib
cp include/*.h /usr/include/srtp  
cp crypto/include/*.h /usr/include/srtp
if [ -f libsrtp.a ]; then cp libsrtp.a /usr/lib/; fi


Install pjproject

Clone the project from its git repo
gmc@blog:~/srtp$ cd ~
gmc@blog:~$ git clone https://github.com/asterisk/pjproject pjproject

Cloning into 'pjproject'...
remote: Reusing existing pack: 3636, done.
remote: Total 3636 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3636/3636), 7.76 MiB | 2.05 MiB/s, done.
Resolving deltas: 100% (1167/1167), done.

Configure and make it... again, after a few attempts, I got here
gmc@blog:~$ cd pjproject/
gmc@blog:~/pjproject$ ./configure --prefix=/usr --enable-shared --disable-sound --disable-resample --disable-video --disable-opencore-amr --with-external-srtp

checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
Further customizations can be put in:
  - 'user.mak'
  - 'pjlib/include/pj/config_site.h'
The next step now is to run 'make dep' and 'make'.

gmc@blog:~/pjproject$ make

for dir in pjlib/build pjlib-util/build pjnath/build third_party/build pjmedia/build pjsip/build pjsip-apps/build ; do \
  if make  -C $dir all; then \
      true; \
make[2]: Leaving directory `/home/test/pjproject/pjsip-apps/build'
make[1]: Leaving directory `/home/test/pjproject/pjsip-apps/build'

gmc@blog:~/pjproject$ sudo make install

mkdir -p /usr/lib/
sed -e "s!@PJ_LDLIBS@!-lpjsua -lpjsip-ua -lpjsip-simple -lpjsip -lpjmedia-codec -lpjmedia -lpjmedia-videodev -lpjmedia-audiodev -lpjmedia -lpjnath -lpjlib-util  -lgsmcodec -lspeex -lilbccodec -lg7221codec  -lsrtp -lpj -luuid -lm -lrt -lpthread  -lcrypto -lssl!" | \
sed -e "s!@PJ_INSTALL_CFLAGS@!-I/usr/include -DPJ_AUTOCONF=1 -O2 -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1 -fPIC!" > //usr/lib/pkgconfig/libpjproject.pc

That should be it! this is an extra step to verify that's correctly set up
gmc@blog:~/pjproject$ pkg-config --list-all | grep pjproject
libpjproject     libpjproject - Multimedia communication library

Done! pjproject is installed! just one more thing...

Install Asterisk

Download an uncompress...
gmc@blog:~/pjproject$ cd ~
gmc@blog:~$ wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-12-current.tar.gz

--2014-04-09 21:46:57--  http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-12-current.tar.gz
Resolving downloads.asterisk.org (downloads.asterisk.org)..., 2001:470:e0d4::ee
Connecting to downloads.asterisk.org (downloads.asterisk.org)||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 56483961 (54M) [application/x-gzip]
Saving to: `asterisk-12-current.tar.gz'
100%[========================================================================================================================>] 56,483,961  10.6M/s   in 5.9s    
2014-04-09 21:47:03 (9.10 MB/s) - `asterisk-12-current.tar.gz' saved [56483961/56483961]

gmc@blog:~$ tar -xzf asterisk-12-current.tar.gz
Configure and make menuselect...
gmc@blog:~$ cd asterisk*
gmc@blog:~/asterisk-12.1.1$ ./configure --with-pjproject --with-ssl --with-srtp

checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for gcc... gcc
configure: build-cpu:vendor:os: x86_64 : unknown : linux-gnu :
configure: host-cpu:vendor:os: x86_64 : unknown : linux-gnu :

gmc@blog:~/asterisk-12.1.1$ make menuselect
CC="cc" CXX="" LD="" AR="" RANLIB="" CFLAGS="" LDFLAGS="" make -C menuselect CONFIGURE_SILENT="--silent" cmenuselect
make[1]: Entering directory `/home/test/asterisk-12.1.1/menuselect'
gcc  -g -D_GNU_SOURCE -Wall   -c -o menuselect.o menuselect.c

This is where you can see, under Resource Modules, that we have the res_pjsip_* modules enabled and res_srtp enabled too... you can do changes and tune your Asterisk how you like and quit by hitting x (that's save and quit)... then, we only have to...
gmc@blog:~/asterisk-12.1.1$ make

Generating embedded module rules ...
   [CC] astcanary.c -> astcanary.o
   [LD] astcanary.o -> astcanary
 +--------- Asterisk Build Complete ---------+
 + Asterisk has successfully been built, and +
 + can be installed by running:              +
 +                                           +
 +                make install               +

gmc@blog:~/asterisk-12.1.1$ sudo make install

Installing modules from channels...
Installing modules from pbx...
 +---- Asterisk Installation Complete -------+
 +                                           +
 +                                           +
 + Asterisk has successfully been installed. +
 + If you would like to install the sample   +
 + configuration files (overwriting any      +
 + existing config files), run:              +
 +                                           +
 +                make samples               +
 +                                           +
 +-----------------  or ---------------------+
 +                                           +
 + You can go ahead and install the asterisk +
 + program documentation now or later run:   +
 +                                           +
 +               make progdocs               +
 +                                           +
 + **Note** This requires that you have      +
 + doxygen installed on your local system    +

If you're like me and want it to just set up the init.d scripts (so that a simple service asterisk start works) you can do
gmc@blog:~/asterisk-12.1.1$ sudo make config

 Adding system startup for /etc/init.d/asterisk ...
   /etc/rc0.d/K91asterisk -> ../init.d/asterisk
   /etc/rc1.d/K91asterisk -> ../init.d/asterisk
   /etc/rc6.d/K91asterisk -> ../init.d/asterisk
   /etc/rc2.d/S50asterisk -> ../init.d/asterisk
   /etc/rc3.d/S50asterisk -> ../init.d/asterisk
   /etc/rc4.d/S50asterisk -> ../init.d/asterisk
   /etc/rc5.d/S50asterisk -> ../init.d/asterisk

And if you're just getting started and want to see some samples...
gmc@blog:~/asterisk-12.1.1$ sudo make samples

Installing adsi config files...
/usr/bin/install -c -d "/etc/asterisk"
Installing configs/asterisk.adsi
Installing file phoneprov/polycom.xml
Installing file phoneprov/snom-mac.xml

And that's it! Congrats! You have what should be a WebRTC compatible Asterisk :)

Here are all the commands without their outputs so that you can run everything without copy/pasting one by one (and b/c I'm sure I'm going to do it again and don't want to remove the responses :P)
# dependencies
sudo apt-get install build-essential libsqlite3-dev libxml2-dev libncurses5-dev libncursesw5-dev libiksemel-dev libssl-dev libeditline-dev libedit-dev curl libcurl4-gnutls-dev libjansson4 libjansson-dev libuuid1 uuid-dev libxslt1-dev liburiparser-dev liburiparser1 git autoconf libbfd-dev -y

# srtp
cd ~
git clone https://github.com/cisco/libsrtp.git
cd libsrtp/
./configure CFLAGS=-fPIC --prefix=/usr

# check that the tests pass
make runtest

sudo make install

# pjproject
cd ~
git clone https://github.com/asterisk/pjproject pjproject
cd pjproject/
./configure --prefix=/usr --enable-shared --disable-sound --disable-resample --disable-video --disable-opencore-amr --with-external-srtp
sudo make install

# the following command should return
# libpjproject     libpjproject - Multimedia communication library
pkg-config --list-all | grep pjproject

# asterisk
cd ~
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-12-current.tar.gz
tar -xzf asterisk-12-current.tar.gz
cd asterisk*
./configure --with-pjproject --with-ssl --with-srtp

# after this command, you can select what you want on your Asterisk
make menuselect

sudo make install

# if you want the init.d scripts created
sudo make config

Saturday, March 22, 2014

Installing paramiko on Windows 8 64-bits witn MinGW

A few weeks ago, I recommended a friend Python as a great language to code... multiplatform and all that. He asked me about connecting to an SSH2 server and I told him that there were tons of libraries for everything, and that there def was one library for that.

I wasn't wrong... but when we met again, he told me he had a big headache installing any of them... I then decided to give the one that looked best (paramiko) and wow... things can go pretty nasty... but I'd like to think that's just b/c of the C part of the world.

I finally figured it out, and as it wasn't straightforward (much less pythonic) at all, I decided to write down my steps here... it may save a lot of hours to the next folk that wants to give it a try.

The (general) problem

paramiko can't be easily installed on windows because it uses pycrypto... which is a C library that deals with the encryption part.

The first approach

Their website has a link to a bunch of precopiled packages... so I gave that a try first. The right way of installing a package is by using easy_install. It did the set up, but when I tried to import the module, it failed with the message ImportError: DLL load failed: %1 is not a valid Win32 application. when its code imported winrandom.

On their site they also say that on some 64-bits systems winrandom just fails, and the only option is to manually compile it. Oh, what a luck.

Compiling it

Ok, if that's what it takes... let's try it out. Even if I have Visual Studio, I'd like to keep it out of the ecuation. This answer pointed me in the right direction, I had to do it with MinGW.

I had never used it before, but it's extremely straightforward. On the Instalation Manager, select the packages
  • mingw32-base
  • mingw32-gcc-gcc+
  • msys-base
We're also going to need another package that's not there. You should go to all packages and select mingw32-gmp (the dev one, triple check that you select that one).

Once those packages are selected, go to the Instalation menu and then to Apply Changes. After the setup, you should add c:\mingw\bin;c:\mingw\mingw32\bin;C:\MinGW\msys\1.0;c:\mingw\msys\1.0\bin;c:\mingw\msys\1.0\sbin to your path.

Now, to enter into the beautiful console, you just need to go to run (Windows + R) and write msys. If that doesn't open a console for you, there's probably something wrong with your path. Be sure to add it after what you already have there.

If you try pip install pycrypto you'll see it fails (and it's actually trying to use Visual Studio). You need to add a file named distutils.cfg inside C:\Python33\Lib\distutils (or whatever Python folder you're using). It should have
That will tell python to use mingw32 to compile whatever it needs to compile... and we're one step closer!

Unfortunately, doing pip install pycrypto also throws all types of errors again... at least, they're different :) The message is always error: unknown type name 'off64_t'... which I didn't have a clue of what it meant... but fortunately I found this answer on SO. As he said, it's brutal... time to modify the sys/types.h file :P

Let me save you a few minutes, the same thing happens with the off_t type. Open the file C:\MinGW\include\sys\types.h and search for off_t. You'll find something like
#ifndef _OFF_T_
#define _OFF_T_
typedef long _off_t;
#ifndef __STRICT_ANSI__
typedef _off_t off_t;
#endif /* __STRICT_ANSI__ */
#endif /* Not _OFF_T_ */

#ifndef _OFF64_T_
#define _OFF64_T_
typedef __int64 _off64_t;
#ifndef __STRICT_ANSI__
typedef __int64 off64_t;
#endif /* __STRICT_ANSI__ */
#endif /* ndef _OFF64_T */

The problem is that the compiler is setting the strict mode... but on the types.h file, if that mode is set, it doesn't add the off_t alias for the _off_t type (I couldn't care less about the strict mode... just want it to run!). In order to fix it, replace that code with
#ifndef _OFF_T_
#define _OFF_T_
typedef long _off_t;
typedef _off_t off_t;
#endif /* Not _OFF_T_ */

#ifndef _OFF64_T_
#define _OFF64_T_
typedef __int64 _off64_t;
typedef __int64 off64_t;
#endif /* ndef _OFF64_T */
And now... we're always declaring the aliases the pycrypto code uses... almost there! I'm using virtualenv, and if you have more than 1 project, you should too... but here, I'm going to just install it on the entire system to keep it simpler.

Soooo.... we're good to do pip install paramiko and it should work... voilá? nah, not so fast :P I ran my sample program and got ImportError: No module named 'winrandom' wonderful winrandom again...

This time the error was fixed by just copying C:\Python33\Lib\site-packages\Crypto\Random\OSRNG\winrandom.pyd into my project folder and now yeah, voilá!!!

I'm sure there's something missing on my python path or something... but I'd like to set it up just for Python 3.3... does anyone know what's the missing part? If you do, please let me know in the comments.

That's it! you should have paramiko working :) I'm not sure if it's the easiest one (I've seen a couple of wrappers, so my guess is that it isn't) or the fastest one, but I made it work on Windows!!!

You'll see that I mentioned a couple answers on SO... please go check them up and give them upvotes... it's extremely rewarding and those are guys that don't have lots of reputation, so it's triple cool that they're giving so great answers.

Good luck!!!!

A RESTful bridge to send and receive SMS using AT commands

I bought the Portech MV-372 to place free calls to both my and my wife's mobile phones. Despite some minor hiccups (like the web server not being 100% of the time available or stuff like that) it's been working fine.

One of the first things I wanted to do was having my twilio number forward text messages (SMS) to my mobile phone... but using the Portech (so that they're free). The problem with that is that the Portech uses AT Commands that are really something to deal with.

You need to open a telnet connection to the device and then issue the commands required to either verify if there are new texts or send a new one... there's no way to tell that a text arrived to the Portech other than by polling.

Oh, and I forgot... you can only have one concurrent telnet connection open... and that's not all... while there's a connection established, you can't place new calls. That's a lovely scenario to work on, right?


  1. Have a RESTful service that let me send and receive texts
  2. Have a RESTful service that lets me ask my carrier how much credit I have on my SIMs
I have recently started playing with python... so this is a perfect fit for my ODROID... connect once a minute to check if there were new texts to process and send the ones that were on the queue.

For the second goal my carrier (antel) exposes this through the SIM Applications... that means I had to dig into the STK AT Commands as well. The bright side, is that once I select the appropriate option what I get is just a regular text saying how much credit I have.

After just four days (what made me fall in love with python) I had something that worked. A bridge between the AT Commands and the beautiful REST world... I set up my logic on my windows server and have the bridge running locally on my odroid.

You can find the project on github. There are lots of things to do, but it gets the job done. Basically, when it's running behind nginx, it exposes a service for you to send texts and when a new text arrives it does a RESTful request to a url specified on config.py. In order to see which requests it does and what it expects, you should dig into the code... so it's not exactly ready for production but it has been pretty stable at home.

The setup is pretty raw right now, just an sql script for the database and the only documentation is on the code... but if there's people interested on it, I could see myself making it more user friendly ;)

If you happen to use it and have something to contribute, feel free to send pull requests.

Tuesday, January 14, 2014

Asterisk 12 on a Raspberry Pi... my experience

It's been a long trip since I started playing with Asterisk... I did a few more things than integrating Asterisk with Twilio.

After doing that, I compared flowroute with Anveo (which works great for outgoing calls, but had issues with an incoming number on Argentina... I wouldn't recommend them for that). I ended up using Anveo for most of my outgoing calls and it works just fine.

But, I wanted to be able to forward calls to my mobile phone (or my wife's) for free... ooor, as close to free as it gets. I then bought a Portech MV-372 on Ebay... yeah, that's probably the opposite to free... but once I got my hands on it, I bought 2 SIM cards... one of them can call me for free, the other can call my wife for free (as long as I put $5 on them every month).

I quickly realized that the NAS (a Synology DS112j) didn't have enough power to deal with the calls. I read that Asterisk needs a kernel with a clock interrupting at least at 1000 HZ. When I first read that, I didn't have a clue on what that meant... but then, I found this great post that explained it with an app that lets you figure out yours. The NAS had 96 HZ.

I then moved to a VPS... but that made calls originating on my home line to the Portech travel all the way to the US. That generated a delay that was totally unacceptable. I started to think that maybe there's a reason for everyone to run Asterisk servers locally... you can't beat a LAN.

Also, at that point, the friends from Asterisk released Asterisk 12... with a REST interface that really got me thinking...

My good friend Juan lent me his Raspberry Pi to try it out. I know there are some images around with Asterisk already installed, but I preferred to go ahead and cherry pick what would be installed. I followed the steps at this post and voilá... I won't say that the compilation was fast... but it got there :) and here I am, placing calls through the Raspberry.

I still perceive a small delay on the calls (way better than on a VPS though) even when I set ulaw:10 and alaw:10 as codecs... not exactly sure why that happens (I'm just getting started here), but I've already ordered an ODROID U3 to discard that it's due to the Raspberry Pi's lack of power.

Tuesday, December 17, 2013

Dynamically loading sip users from a database (and generating extensions for them)

My goal with this blog was just sharing the interesting (technological) problems I face and the way I solve them to read other suggestions and hopefully help a fellow developer... but, and that's what's awesome about life, things rarely go as you plan them and this time it was for the best. After I made a few blog posts on my twilio + asterisk integration, I received 2 offers to work on contract projects. It was a pleasure to work with both Seth and Abraham, and they made me want to continue working on this technology... so, you know... I'm available for Asterisk contract projects!

I don't want to lose sight of the original blog goal though, and one of the requirements Seth had was getting the sip users from a mysql database, where he would update the passwords whenever the users changed them. As I think that's worth sharing, here it goes...

After reading about how to do that, the first thing I found was Asterisk Realtime Architecture and that looked really promising. Despite having to use their table structure, the main issue is that (from that link)
The database peers/users are not kept in memory. These are only loaded when we have a call and then deleted, so there's no support for NAT keep-alives (qualify=) or voicemail indications for these peers.
Which is definitely not acceptable if you have mobile clients.

We built a simple cron that runs once per minute and, if there are any changes, it updates the sip.conf file, extensions.conf (b/c of his requirements, changes on the database may lead to changes in the extensions file) and, once both files are tweaked, the cron just does
asterisk -r -x "sip reload"
asterisk -r -x "dialplan reload"
This works just fine, it doesn't disconnect already registered peers and, as the cron does it only if it detects changes, it should be the same as doing it manually.

However, it feels like cheating... specially when there's Asterisk Realtime Architecture to load the peers and Asterisk RealTime Extensions to load the extensions from a db (why would they build it if you can do it easily with a cron?).

If you find issues with this approach (and feel like sharing) please add a comment.

Saturday, November 2, 2013

After twilio... Flowroute

Once I finished the integration with twilio, I started looking for VoIP providers... just to see what was out there and b/c I found out that I'm really liking this VoIP adventure.

The first site I found was flowroute. When I saw their prices (and compared them to twilio) I couldn't believe how cheap they were. They also have, for every route, the 1st interval and the sub interval. As I didn't know what they were (and at some point I thought that the rate could be for those intervals instead of per minute), I sent a support ticket. Their response was quick and I couldn't put it better than them, so here it is
The rates quoted are per-minute. To calculate the exact billed duration of a call, the length of the call is rounded up according to the billing intervals.

To illustrate, here are a few examples of how this works for calls to a destination with 10/6 billing intervals:

You make a call for 5 seconds: you will be billed for 10 seconds.
You make a call for 11 seconds: you will be billed for 16 seconds. (10 + 6)
You make a call for 20 seconds: you will be billed for 22 seconds. (10 + 6 + 6)
You make a call for 62 seconds: you will be billed for 64 seconds. (10+6+6+6+6+6+6+6+6+6)

At a rate of $0.01/minute for the above calls, the billing would work out as follows:

5 second call: $0.01 * 10 / 60 = $0.0017
11 second call: $0.01 * 16 / 60 = $0.0267
20 second call: $0.01 * 22 / 60 = $0.0037
62 second call: $0.01 * 64 / 60 = $0.0107

Another example given that call billed at $0.04 per minute.

If a call was 64 seconds, it will be rounded up to 66 seconds. The rate is then applied as follows:
66 seconds / 6 seconds = 1.1
1.1 * $0.04 = $0.044

A 45 second call would be rounded up to 48 seconds. The rate is then applied as follows:
48 seconds / 6 seconds = 0.8
8 * $0.04 = $0.024
From all the examples the support guy wrote, you can tell he realized I'm no expert on the matter... but I really liked how he did his best to make sure I'd understand. I created my account and they gave me 25 cents for me to play with.

The setup was straightforward, they have a System Configurator that generates exactly what you need to put on your sip.conf. I placed a few calls to the US, but I couldn't place calls to Uruguay b/c of the rate (trial accounts have a limit on the routes they can call to based on its cost per minute) so I did a $35 deposit (the minimum to "upgrade" it).

Call quality to Argentina (landline), Uruguay (landline + mobile) and US was awesome. Calls to Argentinian mobile phones were a little laggy, but way better than Skype (and a lot cheaper). Another thing I didn't know was possible is that they passed the Caller ID for US and the main Uruguayan mobile carrier (Ancel) but failed to do so on calls to Argentina or to the other Uruguayans carriers (Claro or Movistar).

A great plus to flowroute is that calls to US toll free numbers are free... On the down side, they don't offer much to customize (like real time notifications or different routes with different CLI results) but I think it's awesome as a backup provider... and I say backup provider b/c after discovering Anveo, I fell in love with it... but that's on my next post