It’s more than a month since i joined the DevOps family at Plivo, since i’m pretty new to the Telecom Technology, i was digging more around it. This time i decided to play around with FreeSwitch, a free and open source communications software for the creation of voice and messaging products. Thanks to Anthony Minessale for designing and opensourcing such a powerfull powerfull application. FreeSwitch is well documented and there are pretty good blogs also available on how to setup a PBX using FreeSwitch. This time i’m going to explain on how to make a private Freeswitch server to use Plivo as a SIP Trunking service.
A bit about Plivo. Plivo is a cloud based API Platform for building Voice and SMS enabled Applications. Plivo provides Application Programming Interfaces (APIs) to make and receive calls, send SMS, make a conference call, and more. These APIs are used in conjunction with XML responses to control the flow of a call or a message. We can create Session Initiation Protocol (SIP) endpoints to perform the telephony operations and the APIs are platform independent and can be used in any programming environment such as PHP, Ruby, Python, etc. It also provides helper libraries for these programming languages.
First we need a valid Plivo account. Once we have the Plivo account, we can log into the Plivo Cloud service. Now go to the ”Endpoints” tab and create a SIP endpoint and attach a DirectDial app to it. Once this is done we can go ahead and start setting up the FreeSwitch instance.
Clone the Official FreeSwitch Github and Repo and compile from the source.
$ git clone git://git.freeswitch.org/freeswitch.git && cd freeswitch $ ./bootstrap.sh && ./configure --prefix=/usr/local/freeswitch $ make && make install $ make all cd-sounds-install cd-moh-install # optional, run this if you want IVR and Music on Hold features
Now if we have more than one ip address on the machine, and if we want to bind to a particular ip, we need to modify two files ”/usr/local/freeswitch/conf/sip_profiles/external.xml” and ”/usr/local/freeswitch/conf/sip_profiles/internal.xml”. In both the files, change the parameters ”name=”rtp-ip”” and ”param name=”sip-ip”” with the bind ip as the values.
By default, Freeswitch will create a set of users, which includes numerical usernames ie, 1000-1019. So we can test the basic connectivity between user’s by making a call between two user accounts. We can register two of the accounts in two SoftPhones and we can make a test call and make sure that FreeSwitch is working fine. We can use the FS binary file to start FreeSwitch service in forground.
Once the FreeSwitch is working fine, we can start configuring the SIP trunking via Plivo. So first we need to create an external gateway to connect to Plivo. I’m going to use the SIP endpoint created on the Plivo Cloud to initiate the connection. The SIP domain for Plivo is ”phone.plivo.com”. We need to create a gateway config. Go to ”/usr/local/freeswitch/conf/sip_profiles/external/”, here we can create an XML gateway config file. My config file name is plivo. Below is the content for the same.
<include> <gateway name="plivo"> <param name="realm" value="phone.plivo.com" /> <param name="username" value="<Plivo_SIP_Endpoint_User_Name" /> <param name="password" value="<Plivo_SIP_EndPoint_Password" /> <param name="register" value="false" /> <param name="ping" value="5" /> <param name="ping-max" value="3" /> <param name="retry-seconds" value="5" /> <param name="expire-seconds" value="60" /> <variables> <variable name="verbose_sdp" value="true"/> </variables> </gateway> </include>
There are a lot of other parameters which we can add it here, like caller id etc. Replace the username and password with the Plivo endpoint credentials. If we want to keep this endpoint registered, we can set the register param as true and we can set the expiry time at expire-seconds, so that the Fs will keep on registering the Endpoint with Plivo’s Registrar server. once the gateway file is created, we can either restart the service or we can run “reload mod_sofia” on the FScli. If the FreeSwitch service si started in foreground, we will get the FScli, so we can run the reload command directly on it.
Setting up Dialplan
Now we have the Gateway added. Now we need to the setup the Dial Plan to route the outgoing calls through Plivo. Go to ”/usr/local/freeswitch/conf/dialplan/” folder and add an extension on the ”public.xml” file. Below is a sample extension config.
<extension name="Calls to Plivo"> <condition field="destination_number" expression="^(<ur_regex_here>)$"> <action application="transfer" data="$1 XML default"/> </condition> </extension>
So now all calls matching to the Regex will be transferred to the default dial plan. Now on the the default dial plan, i’m creating an exntension and will use the FreeSwitch’s ”bridge” application to brdige the call with Plivo using the Plivo Gateway. So on the ”default.xml” add the below extension.
<extension name="Dial through Plivo"> <condition field="destination_number" expression="^(<ur_regex_here>)$"> <action application="bridge" data="sofia/gateway/plivo/$1"/> </condition> </extension>
Now we can restart the FS service or we can reload “mod_dialplan_xml” from the FScli. Once the changes are into effect, we can test whether the call is getting routed via Plivo. Configure a soft phone with a default FS user and make an outbound call which matches the regex that we have mentioned for routing to Plivo. Now if all works we should get a call on the destination number. We can check the FS logs at ”/usr/local/freeswitch/log/freeswitch.log”.
If the Regex is matched, we can see the below lines in the log.
1f249a72-9abf-4713-ba69-c2881111a0e8 Dialplan: email@example.com parsing [public->Calls from BoxB] continue=false 1f249a72-9abf-4713-ba69-c2881111a0e8 EXECUTE firstname.lastname@example.org transfer(xxxxxxxxxxxx XML default) 1f249a72-9abf-4713-ba69-c2881111a0e8 Dialplan: email@example.com Regex (PASS) [Dial through Plivo] destination_number(xxxxxxxxxxxx) =~ /^(xxxxxxxxxxxx)$/ break=on-false 1f249a72-9abf-4713-ba69-c2881111a0e8 Dialplan: firstname.lastname@example.org Action bridge(email@example.com) 1f249a72-9abf-4713-ba69-c2881111a0e8 EXECUTE firstname.lastname@example.org bridge(email@example.com) 1f249a72-9abf-4713-ba69-c2881111a0e8 2014-02-14 06:32:48.244757 [DEBUG] mod_sofia.c:4499 [zrtp_passthru] Setting a-leg inherit_codec=true 1f249a72-9abf-4713-ba69-c2881111a0e8 2014-02-14 06:32:48.244757 [DEBUG] mod_sofia.c:4502 [zrtp_passthru] Setting b-leg absolute_codec_string=GSM@8000h@20i@13200b,PCMA@8000h@20i@64000b,PCMU@8000h@20i@64000b
We can also mention the CallerID on the Direct Dial app which we have mapped to the SIP endpoint. Now for Incoming calls, create a app that can forward the calls to one of the user’s present in the FreeSwitch, using the Plivo’s Dial XML. So the XML should look something like below. I will be writing a more detailed blog about Inbound calls once i’ve have tested it out completely.
<Response> <Dial> <User>FSuser@FSserverIP</User> </Dial> </Response>
But for security, we need to allow connections from Plivo server. So we need to allow those IP’s on the FS acl. We can allow the IP’s in the ”acl.conf.xml” file at ”/usr/local/freeswitch/conf/autoload_configs”. And make sure that the FS server is accessible via a public ip atleast for the Plivo server’s which will forward the calls.