SOHO PBX Example
From FreeSWITCH Wiki
Contents |
Dialplan Configuration
The purpose of this document is to help someone get a running system (SOHO PBX) in a short amount of time. I encourage everyone to read the module pages as they show how the commands are issued within the configuration files. I am just learning freeswitch myself and hope this will help someone to enjoy working with this great software. I will be using the extensions 1000 - 1019 that are the defaults found in conf/directory/default/ for phone extensions.
The first thing we need to do is make the dialplan handle our inbound/outbound calls. Calls will be answered and sent to a short IVR menu. We'll just be using the stock (default) files in the standard locations. So, conf/dialplan/default.xml tells the inbound call leg to use the IVR "my greeting" found in conf/autoconfigs/ivr.conf.xml (note: I found that sleeping one second after the answer command helps in not rushing the ivr greeting). Then, how to dial 4, 7 and 10 digit extensions.
<?xml version="1.0" encoding="utf-8"?>
<!-- http://wiki.freeswitch.org/wiki/Dialplan_XML -->
<include>
<context name="default">
<!-- This extension simply prints out the channel variables that you may -->
<!-- use to determine what action to take. Use this for debugging your -->
<!-- dialplan and comment it out once things are set the way you want them -->
<!-- The continue=true parameter causes Freeswitch to continue processing -->
<!-- other dialplan conditions even though this one was a match -->
<extension name="PrintVars" continue="true">
<condition field="destination_number" expression="^[0-9]">
<action application="info"/>
</condition>
</extension>
<!-- Inbound calls -->
<!-- If you have a number of similar DID's and they get the same call treatment -->
<extension name="voicepulse"> <!-- your provider or any name you'd like to call it -->
<!-- EDIT: change the DID to your inbound DID (DN) number -->
<!-- Note - you can use regx pattern matching if needed -->
<condition field="destination_number" expression="^1NXXNXXXXXX$"> <!-- your phone number -->
<!-- Set the maximum amount of time you want to ring the extensions (seconds) -->
<action application="set" data="call_timeout=20"/>
<action application="set" data="continue_on_fail=true"/>
<action application="answer"/>
<!-- answer the call, give it a second, go to ivr.conf.xml menu my-greeting in conf/autoconfig/ directory -->
<action application="sleep" data="1000"/>
<action application="ivr" data="my-greeting"/>
</condition>
</extension>
<!-- If the calling party is the called party, go to their VM
If the calling party is NOT the called party dial the extension (1000-1019) for 30 seconds
and go to voicemail if the call fails (continue_on_fail=true), otherwise hang up after a
successful bridge (hangup_after-bridge=true) -->
<extension name="Local Extensions">
<condition field="destination_number" expression="^(10[01][0-9])$">
<action application="set" data="dialed_ext=$1"/>
<action application="export" data="dialed_ext=$1"/>
</condition>
<condition field="destination_number" expression="^${caller_id_number}$">
<action application="set" data="voicemail_authorized=${sip_authorized}"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="voicemail" data="check default $${domain} ${dialed_ext}"/>
<anti-action application="bind_meta_app" data="1 a a execute_extension::dx XML features"/>
<anti-action application="bind_meta_app" data="2 a a record_session::$${base_dir}/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<anti-action application="bind_meta_app" data="3 a a execute_extension::cf XML features"/>
<anti-action application="set" data="transfer_ringback=${us-ring}"/>
<anti-action application="set" data="call_timeout=30"/>
<anti-action application="set" data="sip_exclude_contact=${network_addr}"/>
<anti-action application="set" data="hangup_after_bridge=true"/>
<!--<anti-action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,BUSY,USER_BUSY,NO_ANSWER,TIMEOUT,NO_ROUTE_DESTINATION"/> -->
<anti-action application="set" data="continue_on_fail=true"/>
<anti-action application="db" data="insert/call_return/${dialed_ext}/${caller_id_number}"/>
<anti-action application="db" data="insert/last_dial_ext/${dialed_ext}/${uuid}"/>
<anti-action application="bridge" data="user/${dialed_ext}@$${domain}"/>
<anti-action application="answer"/>
<!--<anti-action application="send_display" data="Voicemail for ${dialed_ext}"/>-->
<anti-action application="sleep" data="1000"/>
<anti-action application="voicemail" data="default $${domain} ${dialed_ext}"/>
</condition>
</extension>
<!-- Dial any 7 digit number (3334444) as 10 digit dialing but pass to a local itsp -->
<extension name="Local Dial">
<condition field="destination_number" expression="^([0-9]{7})$">
<!-- Set your outgoing caller ID name here -->
<!-- action application="set" data="effective_caller_id_name=Your Name"/ -->
<!-- Your SIP provider probably expects a phone number or username for this setting.
It is used in the from URL phonenumber@mysipprovider.com -->
<action application="set" data="effective_caller_id_number=Your Number"/>
<!-- If your provider does not provide ringback (180 or 183) you may simulate ringback by uncommenting the following line. -->
<!-- action application="ringback" /-->
<!-- Call the bridge app. Set data to endpoint/profile/[Areacode]$1@mysipprovider.com -->
<!-- in this case, the "profile" is gateway, followed by the name of the specific gateway -->
<!-- Note: the area code is getting prepended to the dialstring variable $1 -->
<!-- EDIT: Change the area code and domain of your SIP provider. -->
<action application="bridge" data="sofia/gateway/vitelity/''NXX''$1@your-provider.com"/>
</condition>
</extension>
<!-- Dial a tollfree number though a specific gateway -->
<extension name="tollfree">
<condition field="destination_number" expression="^(18(0{2}|8{2}|7{2}|6{2})\d{7})$">
<action application="bridge" data="sofia/sip/$1-freeswitch@voip.trxtel.com"/>
</condition>
</extension>
<!-- Dial any 10 digit number (2223334444) or 1+10 number (12223334444) here -->
<extension name="Long Distance">
<condition field="destination_number" expression="^(1{0,1}\d{10})$">
<!-- Set your outgoing caller ID name here -->
<!-- action application="set" data="effective_caller_id_name=John Freeswitch"/ -->
<!-- Your SIP provider probably expects a phone number or username for this setting.
It is used in the from URL phonenumber@mysipprovider.com -->
<action application="set" data="effective_caller_id_number=Your Number"/>
<!-- If your provider does not provide ringback (180 or 183) you may simulate ringback by uncommenting the following line. -->
<!-- action application="ringback" /-->
<!-- Call the bridge app. Set data to endpoint/profile/[Areacode]$1@mysipprovider.com -->
<!-- EDIT: Change the area code and domain of your SIP provider. -->
<action application="bridge" data="sofia/gateway/vitelity/$1@your-provider.com"/>
</condition>
</extension>
</context>
</include>
IVR Configuration
Now that the dial plan has some basics, we can make an IVR to handle our inbound calls. This will be a short example using 2 lines. You can easily create more options whenever you'd like in /usr/local/freeswitch/conf/autoconfigs/ivr.conf.xml. You'll need to create a my-greeting.wav for your menu and put it in /usr/local/freeswitch/sounds/en/us/callie/ivr/8000/ . If you want higher quality then record it and put in ivr/16000/.
<!-- My Greeting IVR setup -->
<!-- IVR, Main Menu "Hi, you've reached 1-212-555-1212 To speak with a sales rep press 1, For technical support press 2" add as many as you like -->
<menu name="my-greeting"
greet-long="ivr/8000/my-greeting.wav"
invalid-sound="voicemail/vm-hello.wav"
exit-sound="voicemail/vm-goodbye.wav"
timeout ="10000"
inter-digit-timeout="2000"
max-failures="3"
digit-len="4">
<!-- this send the call to our internal 4 digit extensions and then to voicemail if unanswered ( this is in dialplan/default.xml under Local Extensions -->
<entry action="menu-exec-app" digits="1" param="execute_extension 1001 XML default"/>
<entry action="menu-exec-app" digits="2" param="execute_extension 1002 XML default"/>
</menu>
Provider Configuration
Now all we need to do is connect to our provider(s). They are called gateways in FreeSwitch. Usually you name the gateway after the provider. I use voicepulse for inbound calls and vitelity for outbound calls. In the directory conf/sip_profiles/external/ we'll create our provider connections. This would be similar to sip.conf from asterisk. Here's a configuration for Voicepulse and Vitelity that works for me. We'll create 2 files, voicepulse.xml and vitelity.xml. Though, you could just use one if you preferred. Other provider examples may be found here http://wiki.freeswitch.org/wiki/Tested_Phone_Providers_Listing . For help setting up a gateway to a PSTN network, go here http://wiki.freeswitch.org/wiki/OpenZAP
Voicepulse
<include>
<gateway name="voicepulse">
<!--/// account username *required* ///-->
<param name="username" value="your-username"/>
<!--/// auth realm: *optional* same as gateway name, if blank ///-->
<param name="realm" value="nyc.voicepulse.com"/>
<!--/// account password *required* ///-->
<param name="password" value="your-password"/>
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<param name="extension" value="1NXXNXXXXXX"/>
<!--/// proxy host: *optional* same as realm, if blank ///-->
<param name="proxy" value="nyc.voicepulse.com"/>
<!--/// expire in seconds: *optional* 3600, if blank ///-->
<param name="expire-seconds" value="600"/>
<param name="register" value="true"/>
</gateway>
<gateway name="voicepulse-backup">
<!--/// account username *required* ///-->
<param name="username" value="your-username"/>
<!--/// auth realm: *optional* same as gateway name, if blank ///-->
<param name="realm" value="nyc-backup.voicepulse.com"/>
<!--/// account password *required* ///-->
<param name="password" value="your-password"/>
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<param name="extension" value="1NXXNXXXXXX"/> -->
<!--/// proxy host: *optional* same as realm, if blank ///-->
<param name="proxy" value="nyc-backup.voicepulse.com"/>
<!--/// expire in seconds: *optional* 3600, if blank ///-->
<param name="expire-seconds" value="600"/>
<param name="register" value="true"/>
</gateway>
<gateway name="connect03.voicepulse.com">
<!--/// account username *required* ///-->
<param name="username" value="your-username"/>
<!--/// auth realm: *optional* same as gateway name, if blank ///-->
<param name="realm" value="connect03.voicepulse.com"/>
<!--/// account password *required* ///-->
<param name="password" value="your-password"/>
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<param name="extension" value="1NXXNXXXXXX"/>
<!--/// proxy host: *optional* same as realm, if blank ///-->
<param name="proxy" value="connect03.voicepulse.com"/>
<!--/// expire in seconds: *optional* 3600, if blank ///-->
<param name="expire-seconds" value="600"/>
<param name="register" value="true"/>
</gateway>
</include>
Vitelity
<include>
<gateway name="vitelity">
<!--/// account username *required* ///-->
<param name="username" value="your-username"/>
<!--/// auth realm: *optional* same as gateway name, if blank ///-->
<param name="realm" value="vitel-outbound"/>
<!--/// account password *required* ///-->
<param name="password" value="your-password"/>
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<param name="extension" value="default"/>
<!--/// proxy host: *optional* same as realm, if blank ///-->
<param name="proxy" value="outbound1.vitelity.net"/>
<!--/// expire in seconds: *optional* 3600, if blank ///-->
<param name="expire-seconds" value="600"/>
</gateway>
</include>
If all went well you should have a working system.
Good luck and happy switching to you.

