Why Lua is a good choice for Scripting call configurations in SIP servers like Kamailio and Freeswitch

Programing in SIP servers enables the IP telephony provider to add complex control that is difficult to realise with simple dialplan XML and IVR menus. These are best handled by using a program that is compiled with the telecom application server and invoked by SIP requests or responses in the session. This may include

  • using policy control or dynamic input to control call routing or blacklisting
  • transcription for voicemail
  • media file playback with dynamic text to speech ….so on.

Common Freeswitch , opensips , Kamailio and Astersik suppored programing engines may include python, java, c++, javascript. Opensips and kamailio also include XML_RPC, HTTP API and Websockets as additional means of adding call control login in telephony sever.

Kamailo modules
Opensips modules
Freeswitch modules

Lua (https://www.lua.org) is a small, powerful and lightweight scripting language, mostly used for embedded and gaming use cases. Among many programming engines supported by FreeSWITCH and Kamailio, Lua is very handy to add business logic to call control by integrating with the telecom server.

Form the a multiple choice, Lua is the prefered language for scripting in SIP server which is due to

  1. Does not requie recompilation
    • Saves on the effort to resatrt the freeswitch server while loading updated script
    • this in turn saves service disruption for the time server woulve taken to shutdown and restart
  2. Can ve sync or asyn
    • lua : runs in current thread and waits for script completion
    • luarun : runs in seprate thread and returns immediately

Freeswitch Lua Integration

To load the program

<action aplication="lua" data="mainprog.lua">

1. In the program, we could get status and print to console log

local api = freeswitch.API()
local status = api:execute("status")
freeswitch.consoleLog(status)

2. we could also check is session is active and play a file inot the call

if session:ready() then
    session:streamFile("silence_stream://100000")
end

3.Program to answer call , play file and hangup using session class methods

-- Answer call, play a prompt, hang up
session:answer()

-- Create a string with path and filename of a sound file
pathsep = '/'
-- Windows users do this instead pathsep = ''
prompt ="ivr" ..pathsep .."ivr-welcome_to_freeswitch.wav"

-- Play the prompt
freeswitch.consoleLog("WARNING","About to play '" .. prompt .."'n")
session:streamFile(prompt)

-- Hangup
session:hangup()
freeswitch.consoleLog("WARNING","After hangup")

output

[INFO] mod_dialplan_xml.c:637 Processing altanai <altanai>->5000 in context public
EXECUTE sofia/internal/altanai@x.x.x.x lua(/etc/freeswitch/dialplan/lua_session_answer_prompt_hangup.lua)
...
[DEBUG] switch_channel.c:3781 (sofia/internal/altanai@x.x.x.x) Callstate Change EARLY -> ACTIVE
[WARNING] switch_cpp.cpp:1376 About to play 'ivr/ivr-welcome_to_freeswitch.wav
...
[DEBUG] switch_ivr_play_say.c:1942 done playing file /usr/share/freeswitch/sounds/en/us/callie/ivr/ivr-welcome_to_freeswitch.wav
...
[DEBUG] switch_cpp.cpp:731 CoreSession::hangup
[NOTICE] switch_cpp.cpp:733 Hangup sofia/internal/altanai@x.x.x.x [CS_EXECUTE] [NORMAL_CLEARING]
[WARNING] switch_cpp.cpp:1376 After hangup

other methods :

  • Initiate new session session:originate()
  • Record Audio session:recordFile()

5. Fire and consume Events

freeswitch.Event() and freeswitch.eventConsume() can be used to fire new events and consume events respectively. For instance to fire callback function on hangup session:setHangupHook()

6. IVR menus freeswitch:IVRMenu()

More examples

https://github.com/altanai/freeswitchexamples/tree/master/Lua

References

  1. lua https://www.lua.org/
  2. freeswitch https://freeswitch.org/confluence/display/FREESWITCH/Lua+API+Reference

Freeswitch PBX system


This article talks about setting up an in-house hosted Enterprise PBX system for sure and private communication within enterprise communication.

IP PBX

A PBX acts as the central switching system for phone calls within a business.

  • Cloud Hosted IP PBX Systems
  • On-premise IP PBX

An IP PBX is a PBX system with IP connectivity and may provide additional audio, video, or instant messaging communication utilizing the TCP/IP protocol stack. 

Wikipedia

Essentially an IP PBX is a telecommunication device( on IP Interface) that provides voice connectivity to IP phones within an organization/internal office network. 

Enterprise applications, media servers, presence servers, and the VoIP/SIP PBX are interconnected through a company intranet.SIP clients can be SIP hard-phones or soft-phones on PCs, PDAs etc. A PSTN gateway links the enterprise SIP PBX to the public PSTN.

A soft switch (SIP PBX) can be a combination of several SIP entities, such as SIP registrar, proxy server, redirect server, forking server, Back-To-Back User Agent (B2BUA) etc.

FreeSWITCH is free and open source communications software licensed under Mozilla Public License. It if often the core of voice core to provider call routing and media control . Its core library, libfreeswitch, is capable of being embedded into other projects, as well as being used as a stand-alone application. Read more about FreeSwitch SIP and Media Server.

Just a network-switch is hardware that controls network traffic by receiving and forwarding data to the destination device, a soft-switch is a software that controls traffic and call routing in a voIP communication network.

Class 4 switchClass 5 switch
Class 4 switches route calls between communication providers such as
– between telco and enterprise PBX
Class 5 switches connect communication provider with real clients (or end users) caller and callee.
– can provide platform + user agent such as diallers

Freeswitch setup as hosted IP PBX

Fetching source code

apt-get install git
git clone https://stash.freeswitch.org/scm/fs/freeswitch.git

Verify installation by checking version

freeswitch -version
FreeSWITCH version: 1.9.0-742-8f1b7e0~64bit (-742-8f1b7e0 64bit)

Steps post installation

optional arguments you can pass to freeswitch:

 -nf                    -- no forking
 -reincarnate           -- restart the switch on an uncontrolled exit
 -reincarnate-reexec    -- run execv on a restart (helpful for upgrades)
 -u [user]              -- specify user to switch to
 -g [group]             -- specify group to switch to
 -core                  -- dump cores
 -help                 -- this message
 -version        -- print the version and exit
 -rp             -- enable high(realtime) priority settings
 -lp             -- enable low priority settings
 -np             -- enable normal priority settings
 -vg             -- run under valgrind
 -nosql          -- disable internal sql scoreboard
 -heavy-timer    -- Heavy Timer, possibly more accurate but at a cost
 -nonat          -- disable auto nat detection
 -nonatmap       -- disable auto nat port mapping
 -nocal          -- disable clock calibration
 -nort           -- disable clock clock_realtime
 -stop           -- stop freeswitch
 -nc             -- do not output to a console and background
 -ncwait         -- do not output to a console and background but wait until the system is ready before exiting (implies -nc)
 -c              -- output to a console and stay in the foreground

Options to control locations of files:

 -base [basedir]         -- alternate prefix directory
 -cfgname [filename]     -- alternate filename for FreeSWITCH main configuration file
 -conf [confdir]         -- alternate directory for FreeSWITCH configuration files
 -log [logdir]           -- alternate directory for logfiles
 -run [rundir]           -- alternate directory for runtime files
 -db [dbdir]             -- alternate directory for the internal database
 -mod [moddir]           -- alternate directory for modules
 -htdocs [htdocsdir]     -- alternate directory for htdocs
 -scripts [scriptsdir]   -- alternate directory for scripts
 -temp [directory]       -- alternate directory for temporary files
 -grammar [directory]    -- alternate directory for grammar files
 -certs [directory]      -- alternate directory for certificates
 -recordings [directory] -- alternate directory for recordings
 -storage [directory]    -- alternate directory for voicemail storage
 -cache [directory]      -- alternate directory for cache files
 -sounds [directory]     -- alternate directory for sound files

Freeswitch as B2BUA

Tracing SIP messages and Freeswitch processing for call from external user to internal user.

Receives incoming Call INVITE from Caller

recv 823 bytes from tcp/[caller_ip]:35365 at 09:55:07.936234:
   ------------------------------------------------------------------------
   INVITE sip:to_number@sometelco.com:5060 SIP/2.0
   Via: SIP/2.0/TCP 192.168.1.23:55934;branch=z9hG4bK-524287-1---cc11593581af6519;rport
   Max-Forwards: 70
   Contact: <sip:from_number@192.168.1.23:55934;transport=tcp>
   To: <sip:to_number@sometelco.com:5060>
   From: "from_number"<sip:from_number@sometelco.com:5060>;tag=47a61272
   Call-ID: 94385YTY3ODNlNzE1YjE5MmY4NmQ3ZWUyZDAzM2E0YzBkM2I
   CSeq: 1 INVITE
   Allow: OPTIONS, SUBSCRIBE, NOTIFY, INVITE, ACK, CANCEL, BYE, REFER, INFO
   Content-Type: application/sdp
   Supported: replaces
   User-Agent: X-Lite release 5.4.0 stamp 94385
   Content-Length: 208

   v=0
   o=- 1553248503383592 1 IN IP4 192.168.1.23
   s=X-Lite release 5.4.0 stamp 94385
   c=IN IP4 192.168.1.23
   t=0 0
   m=audio 49874 RTP/AVP 8 101
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-15
   a=sendrecv
   ------------------------------------------------------------------------

checks with ACL for permission and set NAT. Isolate SDP for processing.

New Channel sofia/internal/from_number@sometelco.com:5060 [a8a2003f-5755-40fe-ab63-aab2f5264886]

Running State Change CS_NEW (Cur 1 Tot 274)
receiving invite from caller_ip:35365 version: 1.9.0 -742-8f1b7e0 64bit
IP caller_ip Approved by acl "domains[]". Access Granted.
Setting NAT mode based on nat.auto
Channel sofia/internal/from_number@sometelco.com:5060 entering state [received][100]
Remote SDP:
v=0
o=- 1553248503383592 1 IN IP4 192.168.1.23
s=X-Lite release 5.4.0 stamp 94385
c=IN IP4 192.168.1.23
t=0 0
m=audio 49874 RTP/AVP 8 101
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15

mainatin and Updates call-state (switch_core_state_machine ) CS_NEW -> CS_INIT -> CS_ROUTING -> RINGING and send 100 trying to caller

State Change CS_NEW -> CS_INIT
State NEW
Running State Change CS_INIT (Cur 1 Tot 274)
State INIT
SOFIA INIT
Standard INIT
State Change CS_INIT -> CS_ROUTING
State INIT going to sleep
Running State Change CS_ROUTING (Cur 1 Tot 274)
Change DOWN -> RINGING
State ROUTING
send 413 bytes to tcp/[caller_ip]:35365 at 09:55:07.937474:
   ------------------------------------------------------------------------
   SIP/2.0 100 Trying
   Via: SIP/2.0/TCP 192.168.1.23:55934;branch=z9hG4bK-524287-1---cc11593581af6519;rport=35365;received=caller_ip
   From: "from_number"<sip:from_number@sometelco.com:5060>;tag=47a61272
   To: <sip:to_number@sometelco.com:5060>
   Call-ID: 94385YTY3ODNlNzE1YjE5MmY4NmQ3ZWUyZDAzM2E0YzBkM2I
   CSeq: 1 INVITE
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Content-Length: 0
   ------------------------------------------------------------------------

Checks dialplan to route incoming call. In this case action is to bridge the incoming call to internal user

mod_sofia.c:154 sofia/internal/from_number@sometelco.com:5060 SOFIA ROUTING
switch_core_state_machine.c:236 sofia/internal/from_number@sometelco.com:5060 Standard ROUTING

mod_dialplan_xml.c:637 Processing from_number <from_number>->to_number in context public
Dialplan: sofia/internal/from_number@sometelco.com:5060 parsing [public->dialplan_cutsom] continue=false
Dialplan: sofia/internal/from_number@sometelco.com:5060 Regex (PASS) [dialplan_cutsom] destination_number(to_number) =~ /^(\d+)$/ break=on-false
Dialplan: sofia/internal/from_number@sometelco.com:5060 Action log(INFO ***** Forwarding calls to gateway ****** ) 
Dialplan: sofia/internal/from_number@sometelco.com:5060 Action bridge({sip_auth_username=user,sip_auth_password=pass,sip_route_uri=sip:to_number@ip_addr;transport=tls,sip_invite_req_uri=sip:to_number@sometelco.com;transport=tls}sofia/external/to_number@ip_addr) 

update call state CS_ROUTING -> CS_EXECUTE

State Change CS_ROUTING -> CS_EXECUTE
State ROUTING going to sleep
Running State Change CS_EXECUTE (Cur 1 Tot 274)
State EXECUTE
SOFIA EXECUTE

set the crypto and codecs for the new call

switch_ivr_originate.c:2159 Parsing global variables
switch_channel.c:1104 New Channel sofia/external/to_number@ip_addr [cc1ae238-9efd-4f51-93e9-05abd48bea4d]
mod_sofia.c:5026 (sofia/external/to_number@ip_addr) State Change CS_NEW -> CS_INIT
switch_core_state_machine.c:584 (sofia/external/to_number@ip_addr) Running State Change CS_INIT (Cur 2 Tot 275)
switch_core_state_machine.c:627 (sofia/external/to_number@ip_addr) State INIT
mod_sofia.c:93 sofia/external/to_number@ip_addr SOFIA INIT
Set Local audio crypto Key [1 AEAD_AES_256_GCM_8 inline:ZbEHd76sP6FZSO9AYcqryybaA4HY3O5p2Uo+e1gmmfVaZCEic6cvKyArhMU]
Set Local video crypto Key [1 AEAD_AES_256_GCM_8 inline:Ehr3LoDR8Ur+wtNAMqoqIDn3S7V2inE2/n++awxS6/1P2ijcqfk12+LM/Pc]
Set Local text crypto Key [1 AEAD_AES_256_GCM_8 inline:NVSfjOmSS5BaP/5yqg+SOXcqvEFTHHrC8R5AYkkClXLuNOXYoaUYlrIWeW0]
Set Local audio crypto Key [2 AEAD_AES_128_GCM_8 inline:ePH/F2Qw5+zi8c7tkBb6Y2AQE5uevp+jWUkjgQ]
Set Local video crypto Key [2 AEAD_AES_128_GCM_8 inline:YWdfNLSx6MqG9WQ3TmsV/cSBDqjRUAbHE0rRCg]
Set Local text crypto Key [2 AEAD_AES_128_GCM_8 inline:DFXOP2V2Ep6FoHNz5HIMrm0cu6Za8I5wOI/hUw]
Set Local audio crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:SG5rYx3GSR2imutYQ+LzqHufG9UkG3n/SfmFHFOG/r75v2pwf2lG7Qpup+J0mw]
Set Local video crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:LkU3i9MD25k2wtTfSXUvhlxo66GtMWnXkKoxSdgRZyANoeOhufYnXzbXDo+7+w]
Set Local text crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:AUgUOVmFunzotvwZ6KuMDnBRR2XKk1DsX2qg465MsT6OAxHc2qKBFpeQEpxrqA]
Set Local audio crypto Key [4 AES_CM_192_HMAC_SHA1_80 inline:2PVBBJEp4QcTzTf4Th8Ag/7KiVPmrYb/FCowiRb6yAuTO/kxQLc]
Set Local video crypto Key [4 AES_CM_192_HMAC_SHA1_80 inline:OiFbZQ6mWuf5sHJT1pFPU6EWxEvQAO/0rcp8uGMf79k7RSR3IQA]
Set Local text crypto Key [4 AES_CM_192_HMAC_SHA1_80 inline:XyednWJmzRfsWQOgdhKaMeOeE/OLmnwo6hVEZWl4OJdKdgK6TVc]
Set Local audio crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:Yd4L5Qi7A/8xay5ZHWR1jKk9j5Kvy9s2Zo3NOES2]
Set Local video crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:ImgbbD6cnhnH19O1knP5SSIUULsZTaNJJIUepxt0]
Set Local text crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:V7+IbSZmTdQNjh/upUZ5TFDSlgarhDTVfV+AcUA+]
Set Local audio crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:JI+s9uFdZ3JfZmRRfwHr0OrpyZdtUXmMC0WRIZow1EuXRB9xKFRBk6KmSWomqQ]
Set Local video crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:MX6CGCrMEioUCJsIOCxRqlHOx4mUYRw4DslpY25njZQAkH6MgG/9hp7G8xr44A]
Set Local text crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:ikCz2sYLGoMO+dlrZj+znlQ3djAkGSYzSLLu6Az8u2THWPgnkFJXVgXSxHOaHw]
Set Local audio crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:5JzlrMywFZhHuNLWPG/HBrUi/Zcg414Q7ZfSaJQnUF5N9APy+GQ]
Set Local video crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:K0dZtwH1Q7AuSMBPPUesy047c4nAF+QuFsVvGdf3fYJDOD0Uwxo]
Set Local text crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:96SwyWAdV1a+BU3UbiX1PHdkRlSS4RtmwPWNPbCR3NDm1MyBh58]
Set Local audio crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:/RLYPhZs07WCCBRY8tWNTJemT/IFq1VPHGHmGvnG]
Set Local video crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:mQlgScFq1iMKEW8vobzwhmN9TWSmVblAv9u7c1/c]
Set Local text crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:WAQveMfrQkPBcfqH2qLmuzY63VLfT+N30/YLyuqE]
Set Local audio crypto Key [9 AES_CM_128_NULL_AUTH inline:f2fx2ekxPG3GTwTYARtquNJ87qO0Q5ei47KYlo9K]
Set Local video crypto Key [9 AES_CM_128_NULL_AUTH inline:qpAkfc1bWnZ0Y/1ql+dNvhIGgxxWZoVltnRD5kqn]
Set Local text crypto Key [9 AES_CM_128_NULL_AUTH inline:LyhSlzI3X38WKPwZ83035Ddvse4J/2KnKoydo2FD]

set proxy route and create SDP for sending invite to bridged client

sofia_glue.c:1268 sip:to_number@ip_addr;transport=tls Setting proxy route to sofia/external/to_number@ip_addr
sofia_glue.c:1299 sofia/external/to_number@ip_addr sending invite version: 1.9.0 -742-8f1b7e0 64bit
Local SDP:
v=0
o=FreeSWITCH 1553228435 1553228436 IN IP4 via_addr
s=FreeSWITCH
c=IN IP4 via_addr
t=0 0
m=audio 20072 RTP/SAVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=crypto:1 AEAD_AES_256_GCM_8 inline:ZbEHd76sP6FZSO9AYcqryybaA4HY3O5p2Uo+e1gmmfVaZCEic6cvKyArhMU
a=crypto:2 AEAD_AES_128_GCM_8 inline:ePH/F2Qw5+zi8c7tkBb6Y2AQE5uevp+jWUkjgQ
a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:SG5rYx3GSR2imutYQ+LzqHufG9UkG3n/SfmFHFOG/r75v2pwf2lG7Qpup+J0mw
a=crypto:4 AES_CM_192_HMAC_SHA1_80 inline:2PVBBJEp4QcTzTf4Th8Ag/7KiVPmrYb/FCowiRb6yAuTO/kxQLc
a=crypto:5 AES_CM_128_HMAC_SHA1_80 inline:Yd4L5Qi7A/8xay5ZHWR1jKk9j5Kvy9s2Zo3NOES2
a=crypto:6 AES_CM_256_HMAC_SHA1_32 inline:JI+s9uFdZ3JfZmRRfwHr0OrpyZdtUXmMC0WRIZow1EuXRB9xKFRBk6KmSWomqQ
a=crypto:7 AES_CM_192_HMAC_SHA1_32 inline:5JzlrMywFZhHuNLWPG/HBrUi/Zcg414Q7ZfSaJQnUF5N9APy+GQ
a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:/RLYPhZs07WCCBRY8tWNTJemT/IFq1VPHGHmGvnG
a=crypto:9 AES_CM_128_NULL_AUTH inline:f2fx2ekxPG3GTwTYARtquNJ87qO0Q5ei47KYlo9K
a=ptime:20
a=sendrecv
m=audio 20072 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=sendrecv

attach the SDP to INVITE and proceed forwarding INVITE to callee

send 1988 bytes to tls/[ip_addr]:5061 at 09:55:07.939831:
   ------------------------------------------------------------------------
   INVITE sip:to_number@sometelco.com;transport=tls SIP/2.0
   Via: SIP/2.0/TLS via_addr:5080;rport;branch=z9hG4bK21Qm9U3eHX0Nc
   Max-Forwards: 69
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070461 INVITE
   Contact: <sip:mod_sofia@via_addr:5080>
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
   Supported: timer, path, replaces
   Allow-Events: talk, hold, conference, refer
   Content-Type: application/sdp
   Content-Disposition: session
   Content-Length: 1162
   X-FS-Support: update_display,send_info
   Remote-Party-ID: "from_number" <sip:from_number@via_addr>;party=calling;screen=yes;privacy=off

   v=0
   o=FreeSWITCH 1553228435 1553228436 IN IP4 via_addr
   s=FreeSWITCH
   c=IN IP4 via_addr
   t=0 0
   m=audio 20072 RTP/SAVP 8 101
   a=rtpmap:8 PCMA/8000
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=crypto:1 AEAD_AES_256_GCM_8 inline:ZbEHd76sP6FZSO9AYcqryybaA4HY3O5p2Uo+e1gmmfVaZCEic6cvKyArhMU
   a=crypto:2 AEAD_AES_128_GCM_8 inline:ePH/F2Qw5+zi8c7tkBb6Y2AQE5uevp+jWUkjgQ
   a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:SG5rYx3GSR2imutYQ+LzqHufG9UkG3n/SfmFHFOG/r75v2pwf2lG7Qpup+J0mw
   a=crypto:4 AES_CM_192_HMAC_SHA1_80 inline:2PVBBJEp4QcTzTf4Th8Ag/7KiVPmrYb/FCowiRb6yAuTO/kxQLc
   a=crypto:5 AES_CM_128_HMAC_SHA1_80 inline:Yd4L5Qi7A/8xay5ZHWR1jKk9j5Kvy9s2Zo3NOES2
   a=crypto:6 AES_CM_256_HMAC_SHA1_32 inline:JI+s9uFdZ3JfZmRRfwHr0OrpyZdtUXmMC0WRIZow1EuXRB9xKFRBk6KmSWomqQ
   a=crypto:7 AES_CM_192_HMAC_SHA1_32 inline:5JzlrMywFZhHuNLWPG/HBrUi/Zcg414Q7ZfSaJQnUF5N9APy+GQ
   a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:/RLYPhZs07WCCBRY8tWNTJemT/IFq1VPHGHmGvnG
   a=crypto:9 AES_CM_128_NULL_AUTH inline:f2fx2ekxPG3GTwTYARtquNJ87qO0Q5ei47KYlo9K
   a=ptime:20
   m=audio 20072 RTP/AVP 8 101
   a=rtpmap:8 PCMA/8000
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=ptime:20
   ------------------------------------------------------------------------

manage and update call state for this call leg too CS_INIT -> CS_ROUTING -> CS_CONSUME_MEDIA

Standard INIT
State Change CS_INIT -> CS_ROUTING
State INIT going to sleep
Running State Change CS_ROUTING (Cur 2 Tot 275)
Channel sofia/external/to_number@ip_addr entering state [calling][0]
State ROUTING
SOFIA ROUTING
State Change CS_ROUTING -> CS_CONSUME_MEDIA
State ROUTING going to sleep
Running State Change CS_CONSUME_MEDIA (Cur 2 Tot 275)
State CONSUME_MEDIA
State CONSUME_MEDIA going to sleep
recv 365 bytes from tls/[ip_addr]:5061 at 09:55:07.940977:
   ------------------------------------------------------------------------
   SIP/2.0 100 trying -- your call is important to us
   Via: SIP/2.0/TLS via_addr:5080;rport=59774;branch=z9hG4bK21Qm9U3eHX0Nc;received=via_addr
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070461 INVITE
   Server: XYZ
   Content-Length: 0

   ------------------------------------------------------------------------

Callee from PBX throws auth challenge

recv 483 bytes from tls/[ip_addr]:5061 at 09:55:08.046934:
   ------------------------------------------------------------------------
   SIP/2.0 407 Proxy Authentication Required
   Via: SIP/2.0/TLS via_addr:5080;received=via_addr;rport=59774;branch=z9hG4bK21Qm9U3eHX0Nc
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>;tag=f1cff938000510c1d9006e5a2a4e240b-5736
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070461 INVITE
   Proxy-Authenticate: Digest realm="domain.com", nonce="XJSyI1yUsPf0w1bAocvH4IOCayfWt3bX", qop="auth"
   Content-Length: 0

   ------------------------------------------------------------------------
send 387 bytes to tls/[ip_addr]:5061 at 09:55:08.047056:
   ------------------------------------------------------------------------
   ACK sip:to_number@sometelco.com;transport=tls SIP/2.0
   Via: SIP/2.0/TLS via_addr:5080;rport;branch=z9hG4bK21Qm9U3eHX0Nc
   Max-Forwards: 69
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>;tag=f1cff938000510c1d9006e5a2a4e240b-5736
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070461 ACK
   Content-Length: 0

   ------------------------------------------------------------------------

Freeswitch IP PBX B2BUA acting as caller sends re-invite with auth details

Authenticating 'altanai' with 'Digest:"doamin.com":altanai:pass'.
send 2273 bytes to tls/[ip_addr]:5061 at 09:55:08.047387:
   ------------------------------------------------------------------------
   INVITE sip:to_number@sometelco.com;transport=tls SIP/2.0
   Via: SIP/2.0/TLS via_addr:5080;rport;branch=z9hG4bK3aHDBQmje6p8Q
   Max-Forwards: 69
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070462 INVITE
   Contact: <sip:mod_sofia@via_addr:5080>
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
   Supported: timer, path, replaces
   Allow-Events: talk, hold, conference, refer
   Proxy-Authorization: Digest username="altanai", realm="domain.com", nonce="XJSyI1yUsPf0w1bAocvH4IOCayfWt3bX", cnonce="apLWcMcrEjerigKpM7MtoA", algorithm=MD5, uri="sip:to_number@sometelco.com;transport=tls", response="0044b00a4d5026252b32eed619d70f9d", qop=auth, nc=00000001
   Content-Type: application/sdp
   Content-Disposition: session
   Content-Length: 1162
   X-FS-Support: update_display,send_info
   Remote-Party-ID: "from_number" <sip:from_number@via_addr>;party=calling;screen=yes;privacy=off

   v=0
   o=FreeSWITCH 1553228435 1553228436 IN IP4 via_addr
   s=FreeSWITCH
   c=IN IP4 via_addr
   t=0 0
   m=audio 20072 RTP/SAVP 8 101
   a=rtpmap:8 PCMA/8000
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=crypto:1 AEAD_AES_256_GCM_8 inline:ZbEHd76sP6FZSO9AYcqryybaA4HY3O5p2Uo+e1gmmfVaZCEic6cvKyArhMU
   a=crypto:2 AEAD_AES_128_GCM_8 inline:ePH/F2Qw5+zi8c7tkBb6Y2AQE5uevp+jWUkjgQ
   a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:SG5rYx3GSR2imutYQ+LzqHufG9UkG3n/SfmFHFOG/r75v2pwf2lG7Qpup+J0mw
   a=crypto:4 AES_CM_192_HMAC_SHA1_80 inline:2PVBBJEp4QcTzTf4Th8Ag/7KiVPmrYb/FCowiRb6yAuTO/kxQLc
   a=crypto:5 AES_CM_128_HMAC_SHA1_80 inline:Yd4L5Qi7A/8xay5ZHWR1jKk9j5Kvy9s2Zo3NOES2
   a=crypto:6 AES_CM_256_HMAC_SHA1_32 inline:JI+s9uFdZ3JfZmRRfwHr0OrpyZdtUXmMC0WRIZow1EuXRB9xKFRBk6KmSWomqQ
   a=crypto:7 AES_CM_192_HMAC_SHA1_32 inline:5JzlrMywFZhHuNLWPG/HBrUi/Zcg414Q7ZfSaJQnUF5N9APy+GQ
   a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:/RLYPhZs07WCCBRY8tWNTJemT/IFq1VPHGHmGvnG
   a=crypto:9 AES_CM_128_NULL_AUTH inline:f2fx2ekxPG3GTwTYARtquNJ87qO0Q5ei47KYlo9K
   a=ptime:20
   m=audio 20072 RTP/AVP 8 101
   a=rtpmap:8 PCMA/8000
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=ptime:20
   ------------------------------------------------------------------------
2019-03-22 09:55:08.041945 [DEBUG] sofia.c:7291 Channel sofia/external/to_number@ip_addr entering state [calling][0]
recv 365 bytes from tls/[ip_addr]:5061 at 09:55:08.048255:
   ------------------------------------------------------------------------
   SIP/2.0 100 trying -- your call is important to us
   Via: SIP/2.0/TLS via_addr:5080;rport=59774;branch=z9hG4bK3aHDBQmje6p8Q;received=via_addr
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070462 INVITE
   Server: XYZ
   Content-Length: 0
   ------------------------------------------------------------------------

Call is accepted by callee, 200 OK is received by Freeswitch PBX

recv 1451 bytes from tls/[ip_addr]:5061 at 09:55:14.223460:
   ------------------------------------------------------------------------
   SIP/2.0 200 OK
   Via: SIP/2.0/TLS via_addr:5080;received=via_addr;rport=59774;branch=z9hG4bK3aHDBQmje6p8Q
   Record-Route: <sip:ip_addr1:5060;lr;ftag=8jByBXa2pF1Fj>
   Record-Route: <sip:ip_addr2;lr;ftag=8jByBXa2pF1Fj;did=fd.0971>
   Record-Route: <sip:ip_addr:5060;r2=on;lr;ftag=8jByBXa2pF1Fj;nat=yes>
   Record-Route: <sip:ip_addr:5061;transport=tls;r2=on;lr;ftag=8jByBXa2pF1Fj;nat=yes>
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>;tag=D0r5K6pp80Ujm
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070462 INVITE
   Contact: <sip:to_number@34.201.27.78:5080;transport=udp>
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
   Supported: timer, path, replaces
   Allow-Events: talk, hold, conference, refer
   Content-Type: application/sdp
   Content-Disposition: session
   Content-Length: 380
   Remote-Party-ID: "to_number" <sip:to_number@34.201.27.78>;party=calling;privacy=off;screen=no

   v=0
   o=FreeSWITCH 1553215954 1553215955 IN IP4 <FS_IPADDR>
   s=FreeSWITCH
   c=IN IP4 <FS_IPADDR>
   t=0 0
   m=audio 33516 RTP/SAVP 8 101
   a=rtpmap:8 PCMA/8000
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=sendrecv
   a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:/itE1k5BLMoTNzo7YEv6hCyM6R6wyHem3Coc5jjYVlKR2L3tEzBG5zx1QHgVSg==
   a=ptime:20
   m=audio 0 RTP/SAVP 19
   a=rtpmap:19 
   ------------------------------------------------------------------------

send ACK to callee

Update Callee ID to "to_number" <to_number>
Channel sofia/external/to_number@ip_addr entering state [completing][200]
sofia.c:7301 Remote SDP:
v=0
o=FreeSWITCH 1553215954 1553215955 IN IP4 <FS_IPADDR>
s=FreeSWITCH
c=IN IP4 <FS_IPADDR>
t=0 0
m=audio 33516 RTP/SAVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:/itE1k5BLMoTNzo7YEv6hCyM6R6wyHem3Coc5jjYVlKR2L3tEzBG5zx1QHgVSg==
a=ptime:20
m=audio 0 RTP/SAVP 19

send 953 bytes to tls/[ip_addr]:5061 at 09:55:14.224320:
   ------------------------------------------------------------------------
   ACK sip:to_number@34.201.27.78:5080;transport=udp SIP/2.0
   Via: SIP/2.0/TLS via_addr:5080;rport;branch=z9hG4bK4Ka6cj5NBFDUK
   Route: <sip:ip_addr:5061;transport=tls;r2=on;lr;ftag=8jByBXa2pF1Fj;nat=yes>
   Route: <sip:ip_addr:5060;r2=on;lr;ftag=8jByBXa2pF1Fj;nat=yes>
   Route: <sip:ip_addr2;lr;ftag=8jByBXa2pF1Fj;did=fd.0971>
   Route: <sip:ip_addr3:5060;lr;ftag=8jByBXa2pF1Fj>
   Max-Forwards: 70
   From: "from_number" <sip:from_number@via_addr>;tag=8jByBXa2pF1Fj
   To: <sip:to_number@ip_addr>;tag=D0r5K6pp80Ujm
   Call-ID: 6a827514-c72b-1237-8aab-02a933b32da0
   CSeq: 2070462 ACK
   Contact: <sip:mod_sofia@via_addr:5080>
   Proxy-Authorization: Digest username="altanai", realm="domain.com", nonce="XJSyI1yUsPf0w1bAocvH4IOCayfWt3bX", cnonce="apLWcMcrEjerigKpM7MtoA", algorithm=MD5, uri="sip:to_number@sometelco.com;transport=tls", response="0044b00a4d5026252b32eed619d70f9d", qop=auth, nc=00000001
   Content-Length: 0
   ------------------------------------------------------------------------

set audio codecs, update call state CS_CONSUME_MEDIA -> CS_EXCHANGE_MEDIA

entering state [ready][200]
looking for crypto suite [AEAD_AES_256_GCM_8] in [3 AES_CM_256_HMAC_SHA1_80 inline:/itE1k5BLMoTNzo7YEv6hCyM6R6wyHem3Coc5jjYVlKR2L3tEzBG5zx1QHgVSg==]
looking for crypto suite [AEAD_AES_128_GCM_8] in [3 AES_CM_256_HMAC_SHA1_80 inline:/itE1k5BLMoTNzo7YEv6hCyM6R6wyHem3Coc5jjYVlKR2L3tEzBG5zx1QHgVSg==]
looking for crypto suite [AES_CM_256_HMAC_SHA1_80] in [3 AES_CM_256_HMAC_SHA1_80 inline:/itE1k5BLMoTNzo7YEv6hCyM6R6wyHem3Coc5jjYVlKR2L3tEzBG5zx1QHgVSg==]
Found suite AES_CM_256_HMAC_SHA1_80
Set Remote Key [3 AES_CM_256_HMAC_SHA1_80 inline:/itE1k5BLMoTNzo7YEv6hCyM6R6wyHem3Coc5jjYVlKR2L3tEzBG5zx1QHgVSg==]
Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMA:8:8000:20:64000:1]
Audio Codec Compare [PCMA:8:8000:20:64000:1] ++++ is saved as a match
Set telephone-event payload to 101@8000
Set Codec sofia/external/to_number@ip_addr PCMA/8000 20 ms 160 samples 64000 bits 1 channels
sofia/external/to_number@ip_addr Original read codec set to PCMA:8
Set telephone-event payload to 101@8000
sofia/external/to_number@ip_addr Set 2833 dtmf send payload to 101 recv payload to 101
AUDIO RTP [sofia/external/to_number@ip_addr] 10.130.74.15 port 20072 -> <FS_IPADDR> port 33516 codec: 8 ms: 20
Starting timer [soft] 160 bytes per 20ms
Set 2833 dtmf send payload to 101
Set 2833 dtmf receive payload to 101
Set rtp dtmf delay to 40
Activating audio Secure RTP SEND
srtp:sdes:AES_CM_256_HMAC_SHA1_80
Activating audio Secure RTP RECV
srtp:sdes:AES_CM_256_HMAC_SHA1_80
has been answered
Callstate Change DOWN -> ACTIVE
Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMU:0:8000:20:64000:1]
Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMA:8:8000:20:64000:1]
Audio Codec Compare [PCMA:8:8000:20:64000:1] ++++ is saved as a match
Set telephone-event payload to 101@8000
Set Codec sofia/internal/from_number@sometelco.com:5060 PCMA/8000 20 ms 160 samples 64000 bits 1 channels
sofia/internal/from_number@sometelco.com:5060 Original read codec set to PCMA:8
Set telephone-event payload to 101@8000
sofia/internal/from_number@sometelco.com:5060 Set 2833 dtmf send payload to 101 recv payload to 101

Send early media/ RTP to Callee

 Pre-Answer sofia/internal/from_number@sometelco.com:5060!
 Callstate Change RINGING -> EARLY
 2019-03-22 09:55:14.221933 [DEBUG] switch_core_media.c:8147 Audio params are unchanged for sofia/internal/from_number@sometelco.com:5060.
 2019-03-22 09:55:14.221933 [DEBUG] mod_sofia.c:881 Local SDP sofia/internal/from_number@sometelco.com:5060:
 v=0
 o=FreeSWITCH 1553219088 1553219089 IN IP4 via_addr
 s=FreeSWITCH
 c=IN IP4 via_addr
 t=0 0
 m=audio 29426 RTP/AVP 8 101
 a=rtpmap:8 PCMA/8000
 a=rtpmap:101 telephone-event/8000
 a=fmtp:101 0-16
 a=ptime:20
sedn a=sendrecv

Send 200 OK to Caller

send 1254 bytes to tcp/[caller_ip]:35365 at 09:55:14.232934:
   ------------------------------------------------------------------------
   SIP/2.0 200 OK
   Via: SIP/2.0/TCP 192.168.1.23:55934;branch=z9hG4bK-524287-1---cc11593581af6519;rport=35365;received=caller_ip
   From: "from_number"<sip:from_number@sometelco.com:5060>;tag=47a61272
   To: <sip:to_number@sometelco.com:5060>;tag=NjvKFKQaHp52e
   Call-ID: 94385YTY3ODNlNzE1YjE5MmY4NmQ3ZWUyZDAzM2E0YzBkM2I
   CSeq: 1 INVITE
   Contact: <sip:to_number@via_addr:5060;transport=tcp>
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Accept: application/sdp
   Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
   Supported: timer, path, replaces
   Allow-Events: talk, hold, conference, presence, as-feature-event, dialog, line-seize, call-info, sla, include-session-description, presence.winfo, message-summary, refer
   Session-Expires: 120;refresher=uas
   Content-Type: application/sdp
   Content-Disposition: session
   Content-Length: 220
   Remote-Party-ID: "to_number" <sip:to_number@sometelco.com>;party=calling;privacy=off;screen=no

   v=0
   o=FreeSWITCH 1553219088 1553219089 IN IP4 via_addr
   s=FreeSWITCH
   c=IN IP4 via_addr
   t=0 0
   m=audio 29426 RTP/AVP 8 101
   a=rtpmap:8 PCMA/8000
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=ptime:20
   ------------------------------------------------------------------------
entering state [completed][200]
Channel [sofia/internal/from_number@sometelco.com:5060] has been answered
Callstate Change EARLY -> ACTIVE
Originate Resulted in Success: [sofia/external/to_number@ip_addr]
State Change CS_CONSUME_MEDIA -> CS_EXCHANGE_MEDIA
Running State Change CS_EXCHANGE_MEDIA (Cur 2 Tot 275)
State EXCHANGE_MEDIA
SOFIA EXCHANGE_MEDIA

Receive ACK from Caller

recv 507 bytes from tcp/[caller_ip]:35365 at 09:55:14.459247:
   ------------------------------------------------------------------------
   ACK sip:to_number@via_addr:5060;transport=tcp SIP/2.0
   Via: SIP/2.0/TCP 192.168.1.23:55934;branch=z9hG4bK-524287-1---104aee5ed0b7ca66;rport
   Max-Forwards: 70
   Contact: <sip:from_number@192.168.1.23:55934;transport=tcp>
   To: <sip:to_number@sometelco.com:5060>;tag=NjvKFKQaHp52e
   From: "from_number"<sip:from_number@sometelco.com:5060>;tag=47a61272
   Call-ID: 94385YTY3ODNlNzE1YjE5MmY4NmQ3ZWUyZDAzM2E0YzBkM2I
   CSeq: 1 ACK
   User-Agent: X-Lite release 5.4.0 stamp 94385
   Content-Length: 0
   ------------------------------------------------------------------------

Sounds

apt-get install python-software-properties
add-apt-repository ppa:freeswitch-drivers/freeswitch-nightly-drivers
apt-get update
apt-get install freeswitch freeswitch-lang-en freeswitch-sounds-en-us-callie-8000

User Registeration

List existing users

freeswitch@altanai-Inspiron-15-5578> list_users

userid|context|domain|group|contact|callgroup|effective_caller_id_name|effective_caller_id_number
1000|default|192.168.0.121|default|error/user_not_registered|techsupport|Extension 1000|1000
1001|default|192.168.0.121|default|error/user_not_registered|techsupport|Extension 1001|1001

There are many ways to register users for call

1. Add users to be registered

Goto folder /usr/local/freeswitch/conf/directory/ and vim default.xml

<include>
  <!--the domain or ip (the right hand side of the @ in the addr-->
  <domain name="$${domain}">
... 
<users>
      <user id="altanai">
        <params>
          <param name="password" value="$${default_password}"/>
          <param name="vm-password" value="1000"/>
        </params>
        <variables>
          <variable name="toll_allow" value="domestic,international,local"/>
          <variable name="accountcode" value="987"/>
          <variable name="user_context" value="video-mcu-stereo"/>
          <variable name="effective_caller_id_name" value="altanai"/>
          <variable name="outbound_caller_id_name" value="altanai_outbound"/>
        </variables>
      </user>
 </users>
..
  </domain>
</include>

2. Blind Registeration

Allow users to register with any username and password

Goto /usr/local/freeswitch/conf/sip_profiles/internal.xml and uncomment below snippet

    <!-- this lets anything register -->
    <!--  comment the next line and uncomment one or both of the other 2 lines for call authentication -->
    <param name="accept-blind-reg" value="true"/> 

    <!-- accept any authentication without actually checking (not a good feature for most people) -->
    <param name="accept-blind-auth" value="true"/>

3. Set a profile

Goto folder for freeswitch conf such as /usr/local/freeswitch/conf/directory/default

vim altanai.xml

and edit the variable

<include>
  <user id="altanai">
    <params>
      <param name="password" value="$${default_password}"/>
      <param name="vm-password" value="6000"/>
    </params>
    <variables>
      <variable name="toll_allow" value="domestic,international,local"/>
      <variable name="accountcode" value="6000"/>
      <variable name="user_context" value="default"/>
      <variable name="effective_caller_id_name" value="Extension 6000"/>
      <variable name="effective_caller_id_number" value="6000"/>
      <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
      <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
      <variable name="callgroup" value="developer"/>
    </variables>
  </user>
</include>

Rescan the profile

 sofia profile internal rescan reloadxml

Log Levels

log <loglevel> and nolog are used to enable and disable logging

fs_ctl

 fsctl loglevel alert

sofia level

sofia tracelevel  

[             console]	[               alert]	[                crit]	[                 err]	
[             warning]	[              notice]	[                info]	[               debug]	

References :


Freeswitch Integration with Telecom Carrier

This articles is a follow up of the earlier freeswitch capability introduction and some generic usecases around dialplans and contexts. This post contains instructions on how to integrate your SIP VOIP Freeswitch server to ITSP ( Internet Telephony Service Providers) which are basically part of large telecommunications companies.

First we check the external profile via sofia status . We should’ve configured the internal ip to listen to domain address or public ip. The external profile on port 5080 is used for outgoing and incoming connections .

Screen Shot 2018-09-28 at 9.32.31 AM

Create a user profile for interacting with outside world

<include>
<user id="1001">
<params>
<param name="password" value="pass1234"/>
</params>
</user>
</include>

Next we should try and register any sip softphone with the freeswitch server . I used Xlite , screenshot below

Screen Shot 2018-09-28 at 9.30.07 AM

Configuring a SIP gateway  in sip_profiles -> external

Goto /usr/src/freeswitch-debs/freeswitch/conf/vanilla/sip_profiles/external and create a profile such as telco_profile.xml

<include>
<gateway name="telcoCompany">
<param name="realm" value="sip.2600hz.com"/>
<param name="username" value="admin"/>
<param name="password" value="123456"/>
<param name="register" value="true"/>
</gateway>
</include>

and add the bridge to dialplan under usage

<extension name="telco gateway bridge">
<condition field="destination_number" expression="^(\d{10})$">
<action application="bridge" data="sofia/gateway/telcoCompany/$1"/>
</condition>
</extension>

note $1 contains the dialled number which will be passed to bridge to telcoCompany gateway. Therefore to add prefix for USA use +1$1 or for India +91$1 (  E.164 format) or some inline variable such as ${customercode}$1

After adding reloadxml and also run sofia profile external rescan to let freeswitch find the gateways

Monitoring gateways using OPTIONS

<param name="ping" value="20"/>

Codec Negotiation 

Late negotiations reduces re-sampling and codec changes

<param name="inbound-late-negotiation" value="true"/>

Other dial plan variables can also be set such as absolute_codec_string, inherit_codec , ep_codec_string. To avoid any codec negotiation on SDP use bypass_media=true .

<param name="inbound-codec-prefs" value="${global_codec_prefs}"/>
<param name="outbound-codec-prefs" value="${outbound_codec_prefs}"/>
<param name="inbound-codec-negotiation" value="generous"/>

CDR ( Call Detail Records )

can be used with modules mod_xml_cdr , mod_csv_cdr , mod_cdr_mongodb, mod_odbc_cdr , mod_cdr_pg_csv , mod_cdr_sqlite , mod_json_cdr , mod_radius_cdr

<configuration name="cdr_csv.conf" description="CDR CSV Format">
<settings>
<!-- 'cdr-csv' will always be appended to log-base -->
<!--<param name="log-base" value="/var/log"/>-->
<param name="default-template" value="example"/>
<!-- This is like the info app but after the call is hung up -->
<!--<param name="debug" value="true"/>-->
<param name="rotate-on-hup" value="true"/>
<!-- may be a b or ab -->
<param name="legs" value="a"/>
<!-- Only log in Master.csv -->
<!-- <param name="master-file-only" value="true"/> -->
</settings>
<templates>
<template name="sql">INSERT INTO cdr VALUES ("${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}");</template>
...
</templates>
</configuration>

event socket library (ESL)

tbd

Freeswitch Modules

This section describes some of the popular and useful freeswitch module. Although there are many more modules, I have picked a few of commonly used one and divided them into categories

modules supported on freeswitch

Logger modules in Freeswitch

mod_console
mod_graylog2
mod_logfile
mod_syslog

mod_yaml

Multi-Faceted
mod_enum is a dialplan interface, an application interface and an api command interface
mod_enum

XML Interfaces in Freeswitch

mod_xml_rpc
mod_xml_curl
mod_xml_cdr
mod_xml_radius
mod_xml_scgi

Event system and Event Handlers in Freeswitch

Event Driven Archietctural (EDA) systems Design forms the basis for horizontly scalable, distributed and modular design. Such system primarily use event consumers, processing, producers and an effificient messaging system.

The core engine of freeswitch too manages and coordinates events with the help of messaging bus and handlers between itself and modules.

Event-Name: HEARTBEAT
Core-UUID: 16ba2a54-a955-11ec-9087-b79e790df649
FreeSWITCH-Hostname: altanai-Inspiron-15-5578
FreeSWITCH-Switchname: altanai-Inspiron-15-5578
FreeSWITCH-IPv4: 192.168.0.121
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2022-03-21%2013%3A32%3A26
Event-Date-GMT: Mon,%2021%20Mar%202022%2020%3A32%3A26%20GMT
Event-Date-Timestamp: 1647894746220214
Event-Calling-File: switch_core.c
Event-Calling-Function: send_heartbeat
Event-Calling-Line-Number: 81
Event-Sequence: 539
Event-Info: System%20Ready
Up-Time: 0%20years,%200%20days,%200%20hours,%206%20minutes,%2040%20seconds,%20195%20milliseconds,%2031%20microseconds
FreeSWITCH-Version: 1.10.4-dev%2Bgit~20200518T172205Z~91f54340ed~64bit
Uptime-msec: 400195
Session-Count: 0
Max-Sessions: 1000
Session-Per-Sec: 30
Session-Per-Sec-Last: 0
Session-Per-Sec-Max: 0
Session-Per-Sec-FiveMin: 0
Session-Since-Startup: 0
Session-Peak-Max: 0
Session-Peak-FiveMin: 0
Idle-CPU: 86.633333

Among other events some of the call and system events can be

Channel events

  • CHANNEL_CALLSTATE event, CHANNEL_CREATE event, CHANNEL_APPLICATION event
  • CHANNEL_DESTROY event, CHANNEL_STATE event, CHANNEL_ANSWER event
  • CHANNEL_HANGUP event, CHANNEL_HANGUP_COMPLETE event
  • CHANNEL_EXECUTE event, CHANNEL_EXECUTE_COMPLETE event
  • CHANNEL_BRIDGE event, CHANNEL_UNBRIDGE event
  • CHANNEL_PROGRESS event, CHANNEL_PROGRESS_MEDIA event
  • CHANNEL_PARK event, CHANNEL_UNPARK event
  • CHANNEL_HOLD event, CHANNEL_UNHOLD event
  • CHANNEL_ORIGINATE event, CHANNEL_OUTGOING event
  • CHANNEL_UUID event

System events

  • SHUTDOWN,
  • MODULE_LOAD, MODULE_UNLOAD, RELOADXML
  • NOTIFY,
  • SEND_MESSAGE, RECV_MESSAGE
  • REQUEST_PARAMS, CHANNEL_DATA
  • GENERAL, COMMAND
  • SESSION_HEARTBEAT, CLIENT_DISCONNECTED, SERVER_DISCONNECTED
  • SEND_INFO, RECV_INFO
  • CALL_SECURE, CALL_UPDATE
  • NAT
  • RECORD_START, RECORD_STOP
  • PLAYBACK_START, PLAYBACK_STOP

Events can be listened to using ngrep

> sudo ngrep -d lo -q -W single port 8021

interface: lo (127.0.0.0/255.0.0.0)
filter: ( port 8021 ) and ((ip || ip6) || (vlan && (ip || ip6)))

or also using telnet

> telnet 127.0.0.1 8021

Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Content-Type: auth/request

auth ClueCon

Content-Type: command/reply
Reply-Text: +OK accepted

Event handling modules

mod_amqp

This module provides a connection amqp server like RabbitMQ. It can process API commands and can also filter for which events to send.

mod_cdr_csv

log call detail records (CDRs) to a text file using text generation templates as in /conf/autoload_configs/cdr_csv.conf.xml

<configuration name="cdr_csv.conf" description="CDR CSV Format">
<settings>
<param name="default-template" value="example"/>
<param name="rotate-on-hup" value="true"/>
<!-- may be a b or ab -->
<param name="legs" value="a"/>
</settings>
<templates>
<template name="sql">INSERT INTO cdr VALUES    ("${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}");</template>
</templates>
</configuration>

mod_event_socket

This modules opens a TCP socket and estbalishes bidirectional communication with the Core in clear text.

<configuration name="event_socket.conf" description="Socket Client">
  <settings>
    <param name="nat-map" value="false"/>
    <param name="listen-ip" value="::"/>
    <param name="listen-port" value="8021"/>
    <param name="password" value="ClueCon"/>
    <!--<param name="apply-inbound-acl" value="loopback.auto"/>-->
    <!--<param name="stop-on-bind-error" value="true"/>-->
  </settings>
</configuration>

Send Events over event socket

sendevent SEND_INFO
profile: external
content-type: text/plain
to-uri: sip:altanai@192.168.0.121:7060
from-uri: sip:test@192.168.0.121
content-length: 15
 
test

event received by freeswitch core

nua_stack.c:529 nua_signal() nua(0x7f259c02c4b0): sent signal r_info
nua_stack.c:569 nua_stack_signal() nua(0x7f259c02c4b0): recv signal r_info
nta.c:2671 nta_tpn_by_url() nta: selecting scheme sip
tport.c:3282 tport_tsend() tport_tsend(0x7f25b8004e80) tpn = */192.168.0.121:7060
tport.c:4705 tport_by_addrinfo() tport_by_addrinfo(0x7f25b8004e80): not found by name */192.168.0.121:7060
tport.c:3619 tport_vsend() tport_vsend(0x7f25b8004e80): 605 bytes of 605 to udp/192.168.0.121:7060
tport.c:2766 tport_wakeup_pri() tport_wakeup_pri(0x7f25b4004e80): events IN
tport.c:2889 tport_recv_event() tport_recv_event(0x7f25b4004e80)
send 605 bytes to udp/[192.168.0.121]:7060 at 14:33:45.718269:
------------------------------------------------------------------------
INFO sip:altanai@192.168.0.121:7060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.121:7080;rport;branch=z9hG4bK823r928e970jF
Max-Forwards: 70
From: <sip:test@192.168.0.121>;tag=97py7UB0m8yjr
To: <sip:altanai@192.168.0.121:7060>
Call-ID: 6dc81996-2401-123b-109e-7c67a2ebffa5
CSeq: 49395333 INFO
Contact: <sip:mod_sofia@192.168.0.121:7080>
User-Agent: FreeSWITCH-mod_sofia/1.10.4-dev+git~20200518T172205Z~91f54340ed~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: timer, path, replaces
Content-Type: text/plain
Content-Length: 15


��������

Other event handler modules

  • mod_cdr_sqlite
  • mod_zeroconf
  • mod_erlang_event
  • mod_smpp
  • mod_snmp
  • mod_event_multicast
  • mod_event_zmq

Directory Interfaces
mod_ldap

Endpoints

When any of the endpoints are loaded , they start listening for connection using configuration file . Dialstring identifies the recipient of the channel such as sofia/external/098099999 where sofia is the dial string prefix for SIP.

mod_portaudio

mod_alsa

mod_sofia – SIP protocol support

mod_gsmopen –  Supports voice & SMS over a GSM network

mod_h323 – H.323 , ITU rich media communication protocol.

mod_opal – IAX2

mod_skypopen – Skype (discontinued )

mod_dingaling – Jingle , Google Talk, XMPP integration ( discontinued )

mod_verto

mod_rtc

mod_loopback

mod_woomera

mod_freetdm – Provides support for telephony cards from manufacturers such as Digium, Sangoma and Zaptel. Can communicate in most legacy telephony protocols such as ISDN, SS7 & analog

mod_unicall

mod_skinny

mod_khomp

mod_rtmp

RTMP protocol is primarily used by Flash for streaming audio, video, and data over the Internet.

Applications

mod_commands

mod_conference

inbound and outbound conference bridge, loaded from file  conf/autoload_configs/conference.conf.xml
mod_curl

mod_db

-tbd

mod_dptools

Dialplan tools provide the apps (commands) to process call sessions in XML dialplans.

answer

Answer the call for a channel.

<!-- a sample IVR( Interactive Voice Response ) -->
<extension name="ivr">
<condition field="destination_number" expression="^9000$">
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="ivr" data="demo_ivr"/>
</condition>
</extension>

att_xfer

Attended Transfer.

bgsystem

Execute an operating system command in the background.

bind_digit_action – Bind a key sequence or regex to an action.

bind_meta_app

Respond to certain DTMF sequences on specified call leg(s) during a bridge and execute another dialplan application.

block_dtmf

Block DTMFs from being sent or received on the channel.

break

Cancel an application currently running on the channel.

bridge

Bridge a new channel to the existing one.

bridge_export

Export a channel variable across any bridge.

capture

Capture data into a channel variable.

chat

Send a text message to an IM client

check_acl

Block originating address unless it matches an ACL.Test the i.p. address that originates the call against an Access Control List or CIDR mask

  • clear_digit_action – Clear all digit bindings
  • clear_speech_cache – Clear speech handle cache.
  • cluechoo – Console-only “ConCon” choo-choo train
  • cng_plc – Packet Loss Concealment on lost packets + comfort noise generation
  • conference – Establish an inbound or outbound conference call
  • deflect – Send a call deflect/refer.
  • delay_echo – Echo audio at a specified delay.
  • detect_speech – Implements speech recognition.
  • digit_action_set_realm – Change binding realm.
  • displace_session – Displace audio on a channel.
  • early_hangup – Enable early hangup on a channel.

Info, Intercept and eavesdrop

info – Display Call Info
intercept – Lets you pickup a call and take it over if you know the uuid.

eavesdrop -Spy on a channel.

<extension name="eavesdrop">
<condition field="destination_number" expression="^88(\d{4})$|^\*0(.*)$">
    <action application="answer"/>
    <action application="eavesdrop" data="${hash(select/${domain_name}-spymap/$1$2)}"/>
</condition>
</extension>
  • echo– Echo audio and video back to the originator.
  • delay_echo – Echo audio at a specified delay.
<action application="delay_echo" data="1000"/>

enable_heartbeat

Enable Media Heartbeat.

endless_playback

Continuously play file to caller.

enum – Perform E.164 lookup.
erlang – Handle a call using Erlang.
eval – Evaluates a string.
event – Fire an event.

execute_extension

Execute an extension from within another extension and return.

export

Export a channel variable across a bridge <varname>=<value>

fax_detect – Detect FAX CNG – may be deprecated.
fifo – Send caller to a FIFO queue.
fifo_track_call – Count a call as a FIFO call in the manual_calls queue.

gentones – Generate TGML tones.
group – Insert or delete members in a group.

Channel operations

set_name – Name the channel.

set – Set a channel variable for the channel calling the application.

global_getvar will list all globals such as

freeswitch@altanai-Inspiron-15-5578> global_getvar

hostname=altanai-Inspiron-15-5578
local_ip_v4=192.168.0.121
local_mask_v4=255.255.255.0
local_ip_v6=::1
base_dir=/usr/local/freeswitch
recordings_dir=/usr/local/freeswitch/recordings
sounds_dir=/usr/local/freeswitch/sounds
conf_dir=/usr/local/freeswitch/conf
log_dir=/usr/local/freeswitch/log
run_dir=/usr/local/freeswitch/run
db_dir=/usr/local/freeswitch/db
mod_dir=/usr/local/freeswitch/mod
htdocs_dir=/usr/local/freeswitch/htdocs
script_dir=/usr/local/freeswitch/scripts
...

Dialplan Tools ( DPTools)

mod_dptool provides the commands to manage the call sessions

pre_answer – Answer a channel in early media mode.

hangup

Hang up the current channel.

<extension name="show_info">
<condition field="destination_number" expression="^9192$">
<action application="answer"/>
<action application="info"/>
<action application="sleep" data="250"/>
<action application="hangup"/>
</condition>
</extension>

ring_ready – Indicate Ring_Ready on a channel.
sleep – Pause a channel.
set_zombie_exec – Sets the zombie execution flag on the current channel.
session_loglevel – Override the system’s loglevel for this channel.

set_audio_level – Adjust the read or write audio levels for a channel.
verbose_events – Make ALL Events verbose (Make all variables appear in every single event for this channel).
transfer – Immediately transfer the calling channel to a new extension.[old wiki]
soft_hold – Put a bridged channel on hold.

  • hold – Send a hold message.

stop_displace_session – Stop displacement audio on a channel.
multiset – Set multiple channel variables with a single action.
log – Logs a channel variable for the channel calling the application
loop_playback – Playback a file to the channel looply for limted times

Preprocess

preprocess – description needed
presence – Send Presence
privacy – Set caller privacy on calls.
queue_dtmf – Send DTMF digits after a successful bridge.
read – Read Digits.

Wait

  • wait_for_silence – Pause processing while waiting for silence on the channel.
  • wait_for_answer – Pause processing while waiting for the call to be answered.

DTMF

  • send_dtmf – Send inband DTMF, 2833, or SIP Info digits from a session.
  • start_dtmf – Start inband DTMF detection.
  • stop_dtmf – Stop inband DTMF detection.
  • start_dtmf_generate – Start inband DTMF generation
  • stop_dtmf_generate – Stop inband DTMF generation.
  • send_dtmf – Send inband DTMF, 2833, or SIP Info digits from a session.
  • flush_dtmf – Flush any queued DTMF.
  • phrase – Say a Phrase.
  • Say time/date/ip_address/digits/etc. With pre-recorded prompts.
  • speak – Speaks a string or file of text to the channel using the defined TTS engine.[old wiki]

Limit

limit – Set a limit on number of calls to/from a resource
limit_execute – Set the limit on a specific application
limit_hash – Set a limit on number of calls to/from a resource
limit_hash_execute – Set the limit on a specific application

media_reset – Reset all bypass/proxy media flags.

mkdir – Create a directory.
mutex – Block on a call flow, allowing only one at a time
page – Play an audio file as a page.
park – Park a call.
park_state – Park State.
pickup – Pickup a call.

Play

  • play_and_detect_speech – Play while doing speech recognition.
  • play_and_get_digits – Play and get Digits.
  • play_fsv – Play an FSV file. FSV – (FS Video File Format) additional description needed
  • playback – Play a sound file to the originator.

Record

record – Record a file from the channel’s input.
record_fsv – Record a FSV file. FSV – (FS Video File Format)
record_session – Record Session.

recovery_refresh – Send a recovery refresh.
redirect – Send a redirect message to a session.
regex – Perform a regex.
remove_bugs – Remove media bugs.
rename – Rename file.
respond – Send a respond message to a session.

rxfax – Receive a fax as a tif file.

Schedule

sched_broadcast – Enable Scheduled Broadcast.
sched_cancel – Cancel a scheduled future broadcast/transfer.
sched_hangup – Enable Scheduled Hangup.
sched_heartbeat – Enable Scheduled Heartbeat.
sched_transfer – Enable Scheduled Transfer.
send_display – Sends an info packet with a sipfrag.

send_info – Send info to the endpoint.

DataBase

  • db – insert information into the database.
  • hash – Add a hash to the db.

Modules for Database

  • mod_mongo
 <configuration name="mongo.conf">
  <settings> 
  <param name="connection-string" value="mongodb://127.0.0.1:27017/?connectTimeoutMS=5000"/>
    </settings>
</configuration>

httapi

Send call control to a Web server with the HTTAPI infrastructure

Script

lua – Run a Lua script from the dialplan

javascript – Run a JavaScript script from the dialplan

ivr

Run an IVR menu.

JitterBuffer

  • jitterbuffer – Send a jitter buffer message to a session

Socket

socket – Establish an outbound socket connection.

set_profile_var – Set a caller profile variable.
set_user – Set a user.


sound_test – Analyze Audio.
stop_record_session – Stop Record Session.
stop_tone_detect – Stop detecting tones.

system – Execute an operating system command.
three_way – Three way call with a UUID.
tone_detect – Detect the presence of a tone and execute a command if found.
translate – Number translation.
unbind_meta_app – Unbind a key from an application.
unset – Unset a variable.
unhold – Send a un-hold message.

API

chat – Send a text message to a IM client.
presence – Send Presence.

mod_expr
mod_fifo
mod_hash

mod_voicemail
mod_directory
mod_distributor
mod_lcr
mod_easyroute
mod_esf
mod_fsv
mod_cluechoo
mod_valet_parking
mod_fsk

mod_sms
mod_smpp
mod_random
mod_httapi
mod_translate

Time

  • strepoch – Returns the date/time as a UNIX epoch (seconds elapsed since midnight UTC, January 1, 1970).
  • strftime – Returns formatted date and time.
  • strftime_tz – Returns formatted date and time in the timezone specified.

SNOM Module
mod_snom

This one only works on Linux for now
mod_ladspa

Dialplan Interfaces

mod_dialplan_directory
mod_dialplan_xml
mod_dialplan_asterisk

Codec Interfaces

mod_spandsp
mod_g723_1
mod_g729
mod_amr
mod_ilbc
mod_h26x
mod_vpx
mod_b64
mod_siren
mod_isac
mod_opus

File Format Interfaces

mod_sndfile
mod_native_file
mod_png
mod_shell_stream
For icecast/mp3 streams/files
mod_shout
For local streams (play all the files in a directory)
mod_local_stream
mod_tone_stream

Timers
mod_timerfd
mod_posix_timer

Languages

These scripting languages allow programming the call routing logic

mod_v8

FreeSWITCH has support for the Google V8 JavaScript (ECMAScript) engine. It needs to be uncommented in the modules.conf file

Screen Shot 2018-09-27 at 6.34.04 PM

mod_perl

mod_python

mod_java

mod_lua

ASR /TTS

mod_flite

mod_pocketsphinx
mod_cepstral
mod_tts_commandline
mod_rss

say

  • mod_say_en
  • mod_say_ru
  • mod_say_zh
  • mod_say_sv

Third party modules
mod_nibblebill
mod_callcenter

References

FreeSwitch SIP and Media Server

  • Architecture and Design of Freeswitch
    • Core
    • Threaded Model 
  • State Machine in Freeswitch Core
  • Channel Variables
  • Dialplan
    • Speak Time and Date on Call
    • Call Routing based on destination number and forwarding to voice mail on no answer
    • Call routing based on day and time
    • Match incoming network IP address with pre configured IP
    • Store captured values in standard variables 
    • Playback
      • Media recording and playback in audio (wav)
      • Routing by listening on the audio stream for a touch-tone followed by a single digit
    • some authentication and security related dialplan applications
      • Checking user is authenticated before routing call , else respond 407
      • Checking if there is TLS and SRTP security , else set not_secure
      • Catching invalid destinations or extensions
    • Call screening and blocking dialplan applications
    • Block caller
    • Block certain codes
    • DID – Direct Inward Dialling via dialplan Public.xml
    • IVR ( Interactive Voice Respondent ) using Menu
    • Find me Follow Me
    • Multiple Targets
    • Handle Failures and Early Media
  • Directory
  • Installation
  • Debugging and Call
  • Security

FreeSWITCH is free and open source communications software licensed under Mozilla Public License. It if often the core of voice core to provider call routing and media control . Its core library, libfreeswitch, is capable of being embedded into other projects, as well as being used as a stand-alone application.

FreeSWITCH can route and interconnect communication protocols using audio, video, text, or any other form of media. First released in January 2006, FreeSWITCH has grown to become the world’s premier open-source soft-switch platform. This versatile platform is used to power voice, video, and chat communications on devices ranging from single calls on a Raspberry Pi to large server clusters handling millions of calls. FreeSWITCH powers several commercial products from start-ups to Carriers.

It can perform the functions of  ( but not limited to )

  • PBX Server (Transcoding B2BUA)
  • IVR & Announcement Server
  • Conference host
  • Voicemail
  • Session Border Controller
  • Text to Speech (TTS)
  • VOIP endpoint
  • Class 5 softswitch

Freeswitch has a modular architecture that is both scalable and customisable. The most important modules are- Endpoint, dialplan and Application.

Application is the instruction added for a particular dial plan with an extension object. Data Arguments are also passed to an application. Examples like Set: configure extension parameter, Bridge: bridge a new channel to the existing one, Answer: answer the call for a channel, Hangup: hangup a current channel, Run an IVR menu etc

Protocols set up call legs/ channels, negotiate codecs and stream media. The endpoint module helps to bridge channels between different protocol supported endpoints like WebRTC , H323, SIP , Jingle etc. SIP being the most popular protocol for the VoIP session is implemented by mod_sofia module while RTP is inbuild into FreeSWITCH core. SRTP ( media protocol for webrtc ) is provided by mod_verto.

Architecture and Design of Freeswitch

Freeswitch can form the basis of complicated and sophisticated communications backend framework with thousand CPS(Call per second ). It can connect to VOIP ( voice over IP ) as well as PSTN ( Public Switched Telephone network ) and PRI ( Primary Rate Interfaces – used in enterprises communication).

Core

Data strutters are opaque and operations can be invoke by APIs with routines getting maximum reuse .

Threaded Model 

Enables parallel operation as every connection has its own thread. Event handlers push incoming events into threads .  Sub system run in background threads .

Freeswitch

State Machine in Freeswitch Core

Protocol module listens for call message and parses the call details inot an internal data structure for session management by the core’s state machine.

State Change CS_NEW -> CS_INIT
State NEW
Running State Change CS_INIT (Cur 1 Tot 274)
State INIT
SOFIA INIT
Standard INIT

The state is then changes to ROUTING. At this state the Dialplan’s is lookedup to see the operations that were defiendfor this call based on regex matching.

State Change CS_INIT -> CS_ROUTING
State INIT going to sleep
Running State Change CS_ROUTING (Cur 1 Tot 274)
Change DOWN -> RINGING
State ROUTING

Once the call flow logic is found and escuted form the dialplan the state is changes to EXECUTE.

State Change CS_ROUTING -> CS_EXECUTE
State ROUTING going to sleep
Running State Change CS_EXECUTE (Cur 1 Tot 274)
State EXECUTE
SOFIA EXECUTE

State change to Active and Exchnage_media

entering state [completed][200]
Channel [sofia/internal/from_number@sometelco.com:5060] has been answered
Callstate Change EARLY -> ACTIVE
Originate Resulted in Success: [sofia/external/to_number@ip_addr]
State Change CS_CONSUME_MEDIA -> CS_EXCHANGE_MEDIA
Running State Change CS_EXCHANGE_MEDIA (Cur 2 Tot 275)
State EXCHANGE_MEDIA
SOFIA EXCHANGE_MEDIA

Channel Variables

Channel variables are used to manipulate dialplan execution, to control call progress, and to provide options to applications. They play a pervasive role, as FreeSWITCH™ frequently consults channel variables as a way to customize processing prior to a channel’s creation, during call progress, and after the channel hangs up.

  • $${variable} is expanded once when FreeSWITCH™ first parses the configuration on startup or after invoking reloadxml. It is suitable for variables that do not change, such as the domain of a single-tenant FreeSWITCH™ server.

<param name=”domain” value=”$${domain}”/>

  • ${variable} is expanded during each pass through the dialplan, so it is used for variables that are expected to change, such as the ${destination_number} or ${sip_to_user} fields.

Setting a channel variable :

<application="set" data="rtp_secure_media=true"/>

Reading a channel variable:

<route service="E2U+SIP" regex="sip:(.*)" replace="sofia/${use_profile}/$1;transport=udp"/>

Exporting channel variables in bridge operations

  • from one to another call leg using export_var
  • exporting to a list using export application
<action application="export" data="dialed_extension=$1"/>

Custom channel variables can be defined anytime too such as

<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss"/>

Also channel variables can be limited to scope on an extension . An example of passing some channel variable to log application .

<action application="log" data="INFO Inbound call CallUUID ${call_uuid} SIPCallID ${sip_call_id}- from ${caller_id_number} to ${destination_number}"/>

If the conditions are not met, optional anti-actions are executed.

<name="is_secure" continue="true">
<-- Only Truly consider it secure if its TLS and SRTP -->
<condition field="${sip_via_protocol}" expression="tls"/>
<condition field="${rtp_secure_media_confirmed}" expression="^true$">
    <action application="sleep" data="2000"/>
    <action application="playback" data="misc/call_secured.wav"/>
    <anti-action application="eval" data="not_secure"/>
<condition>
<extension>

Inline actions are executed during the hunting phase of dialplan

Dialplan

A Dialplan is designed to lookup list of instructions from the central XML registry within FreeSWITCH. In general dialplans are used to route a dialed call to an endpoint based on the extension and its  condition. When a matching extension is found, it executes its actions . The combination of the above can create detailed control and call flow plans. FS uses Perl-compatible regular expressions (PCRE) for pattern matching. Few formats

  • sofia/profile2/8765@1.2.3.4 , will dial out 8765 at host 1.2.3.4 using profile2
  • sofia/gateway/gateway11.com/5432 , will dial through a Gateway (SIP Provider) to user 5432
  • sofia/profile2/8765@1.2.3.4;transport=tcp , dialing with specific transport like TCP, UDP, TLS, or SCTP.
  • {absolute_codec_string=PCMU}sofia/external/sip:9106@${local_ip_v4}:5080 , to specify the codecs

Speak Time and Date on Call

when dialed number matches regular expression 9172 , then call is answered , put to sleep for 1 seconds and using say application current date and time is said , then application hangs up .

<include>
<extension name="speak_date_time" >
<condition field="destination_number" expression="^9172$">
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="say" data="en CURRENT_DATE_TIME pronounced ${strepoch()}"/>
    <action application="hangup"/>
</condition>
</extension>
</include>

There may be 3 kinds of contexts  :

  1. default  : used for all internal users  such as PBX . Local_Extension can route the call between internal users .
  2. public  : used by external world users such as DID
  3. features : other custom in call features using bind_meta_app application etc

Call Routing based on destination number and forwarding to voice mail on no answer

Configure the sip driver to use the custom context while processing the call such as ,

<profile name="telco_custom_sipprofile">
    <param name="context" value="custom_sipcontext"/>
...
</profile>

When call arrives for destination 501 , the condition matches and this blocks action are executed such as in example below .
Exetnsion 501 rings , when not answered it sleeps or 1 seconds , then gets forwarded to voice mail .

If the call to 501 was answered ie handed off then further actions would not be executed

<context name="custom_sipcontext">
<extension name="501">
<condition field="destination_number" expression="^501$">
    <action application="bridge" data="user/501"/>
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
</condition>
</extension>
</context>

Call routing based on day and time

<extension name="Time of day, day of week setup" continue="true">
<condition wday="2-6" hour="8-16 break="never">
<action application="set" data="office_status=open" inline="true"/>
<anti-action application="set" data="office_status=closed" inline="true"/>
</condition>
<condition wday="2-6" time-of-day="1:30-2:30" break="never">
<action application="set" data="office_status=lunch" inline="true"/>
</condition>
</extension>

inline= true states that channel variables will be used for later reference while break=never and continue=true tell the program to keep looking for more condition matches incase of failed or successful match respectively

Match incoming network IP address with pre configured IP

Store incoming number to $1 variable and bridge the call with custom profile . Read more about sip profiles in sections below .

<extension name="ipmatch">
<condition field="network_addr" expression="^198\.168\.1\.0$"/>
<condition field="destination_number" expression="^(\d+)$">
    <action application="bridge" data="sofia/customprofile/$1@198.168.2.0"/>
</condition>
</extension>

Note : $1 varibles value is not available outside of the condition block

Store captured values in standard variables 

<action application=”set” data=”domain_name=$${domain}”/>

Following example store stores destination_number ( freeswitch variable ) into ‘dialed_number’

<extension name="ipmatch_variable">
<condition field="destination_number" expression="^(\d+)$">
    <action application="set" data="dialed_number=$1"/>
</condition>
<condition field="network_addr" expression="^192\.168\.1\.1$">
    <action application="bridge" data="sofia/customprofile/${dialed_number}@192.168.2.2"/>
</condition>
</extension>

Playback

Media recording and playback in audio (wav)

<extension name="recording">
<condition field="destination_number" expression="^(4444)$">
    <action application="answer"/>
    <action application="set" data="playback_terminators=#"/>
    <action application="record" data="/tmp/audiofile.wav 20 200"/>
</condition>
</extension>

<extension name="playback">
<condition field="destination_number" expression="^(5555)$">
    <action application="answer"/>
    <action application="set" data="playback_terminators=#"/>
    <action application="playback" data="/tmp/audiofile.wav"/>
</condition>
</extension>

Routing by listening on the audio stream for a touch-tone * followed by a single digit.

If the called user dials *1, then the execute_extension::dx XML features command is executed.

<extension name="Local_Extension">
<condition field="destination_number" expression="^(10[01][0-9])$">
    <action application="export" data="dialed_extension=$1"/>
    <!-- bind_meta_app can have these args <key> [a|b|ab] [a|b|o|s] <app> -->
    <action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
    <action application="bind_meta_app" data="2 b s record_session::${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
    <action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
    <action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/>
..
</condition>
</extension>

The dx extension in features accepts the digits and proceeds as defined with the call

<extension name="dx">
<condition field="destination_number" expression="^dx$">
    <action application="answer"/>
    <action application="read" data="11 11 'tone_stream://%(10000,0,350,440)' digits 5000 #"/>
    <action application="execute_extension" data="is_transfer XML features"/>
</condition>
</extension>

Some authentication and security related dialplan applications

Checking user is authenticated before routing call , else respond 407

<extension name="9191">
<condition field="destination_number" expression="^9191$"/>
<condition field="${sip_authorized}" expression="true">
    <anti-action application="respond" data="407"/>
</condition>
<condition>
    <action application="playback" data="misc/connected_securly.wav"/>
</condition>
</extension>

Checking if there is TLS and SRTP security , else set not_secure

<extension name="is_secure">
<condition field="${sip_via_protocol}" expression="tls"/>
<condition field="${rtp_secure_media_confirmed}" expression="^true$">
<action application="sleep" data="1000"/>
<action application="playback" data="misc/connected_securly.wav"/>
<anti-action application="eval" data="not_secure"/>
</condition>
</extension>

Catching invalid destinations or extensions

Catch numbers which didnt match any other case. Add this extension to bottom. It plays an invalid tune

<extension name="catchall">
<condition field="destination_number" expression=".*" continue="true">
    <action application="playback" data="misc/invalid_extension.wav"/>
</condition>
</extension>

Call screening and blocking dialplan applications

Call Screening by name announcement

User caller’s name store in wave file

<action application="set" data="call_screen_filename=/tmp/${caller_id_number}-name.wav"/>

Connect to the called party. On answer announce the name. since playback_terminators is set to digits , pressing any one of them will terminate the call

<action application="set" data="hangup_after_bridge=true" />
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="phrase" data="voicemail_record_name"/>
<action application="playback" data="tone_stream://%(500, 0, 640)"/>
<action application="set" data="playback_terminators=#*0123456789"/>
<action application="record" data="${call_screen_filename} 7 200 2"/>

If called party presses 1 connect the call, or hang up.

<action application="set" data="group_confirm_key=1"/>
<action application="set" data="fail_on_single_reject=true"/>
<action application="set" data="group_confirm_file=phrase:screen_confirm:${call_screen_filename}"/>
<action application="set" data="continue_on_fail=true"/>
<action application="bridge" data="user/$1"/>

If the called party hangs up, the caller is connected with voicemail.

<action application="voicemail" data="default ${domain} $1"/>

finally hangup

<action application="hangup"/>

Block caller

Dial *77 followed by the number to be blocked

<extension name="block_caller_id">
<condition field="destination_number" expression="^\*77(\d+)$">
<action application="privacy" data="full"/>
<action application="set" data="sip_h_Privacy=id"/>
<action application="set" data="privacy=yes"/>
<action application="transfer" data="$1 XML default"/>
</condition>
</extension>

Block certain codes

block certain NPAs that you do not want to terminate based on caller id area codes and respond with SIP:503 to your origination so that they can route advance if they have other carrier to terminate to.

<extension name="blocked_cid_npa">
<condition field="caller_id_number" expression="^(\+1|1)?((876|809)\d{7})$">
<action application="respond" data="503"/>
<action application="hangup"/>
</condition>
</extension>

DID – Direct Inward Dialling via dialplan Public.xml

Assume we have a DID number 676767 which is served by telco provider either over SIP trunk/PRI lines . When someone from external world calls this number , FE needs to route the call to an internal user for example user at extension 3003 ( in default .xml context)

<include>
<extension name="public_did">
<condition field="destination_number" expression="^\+?1?(676767)$">
    <action application="set" data="domain_name=${domain}"/>
    <action application="transfer" data="3003 XML default"/>
</condition>
</extension>
</include>

If we are on multi domain setup , we need to setup the domain correctly .$${domain} is the default domain set from vars.xml but you can set it to any domain we have setup in user directory. Added the extra characters in from of DID number to adjust for various ISD code and number formats suffixes such as +1- ,91- , 0- etc .

IVR ( Interactive Voice Respondent ) using Menu

Main Menu – uses tts enginer and 3 attempsts to repond with timeout 10 seconds
On pressing 1 – bridge the call to conference , on press 2 – transfer to 2222 using default
On press of 3 – transfer using enum while on press 4 – play submenu. On press of 9 – goto top menu

<menu name="demo_ivr"
greet-long="say:Press 1 to join the conference, Press 2 to transfer, 3 to transfer, 4 to goto another menu"
greet-short="phrase:demo_ivr_main_menu_short"
invalid-sound="ivr/ivr-that_was_an_invalid_entry.wav"
exit-sound="voicemail/vm-goodbye.wav"
confirm-macro=""
confirm-key=""
tts-engine="flite"
tts-voice="rms"
confirm-attempts="3"
timeout="10000"
inter-digit-timeout="2000"
max-failures="3"
max-timeouts="3"
digit-len="4">
    <entry action="menu-exec-app" digits="1" param="bridge sofia/${domain}/888@conference.telcocompany.org"/>
    <entry action="menu-exec-app" digits="2" param="transfer 2222 XML default"/> 
    <entry action="menu-exec-app" digits="3" param="transfer 1234*256 enum"/> 
    <entry action="menu-sub" digits="4" param="demo_ivr_submenu"/> 
    <entry action="menu-exec-app" digits="/^(10[01][0-9])$/" param="transfer $1 XML features"/>
    <entry action="menu-top" digits="9"/> 
</menu>

Submenu – press * to repeat menu , # to exit . the timeout is 15 seconds

<menu name="demo_ivr_submenu"
greet-long="phrase:demo_ivr_sub_menu"
greet-short="phrase:demo_ivr_sub_menu_short"
invalid-sound="ivr/ivr-that_was_an_invalid_entry.wav"
exit-sound="voicemail/vm-goodbye.wav"
timeout="15000"
max-failures="3"
max-timeouts="3">
    <entry action="menu-top" digits="*"/>
    <entry action="menu-exit" digits="#"/>
</menu>

Find me Follow Me

If a users has lets say 3 phone – home , office and car then an incomming call should subesquently ring everywhere one by one till the user picks up the phone closet to him . leg_delay_start is the timer after which this endpoint will start riniging and leg_timeout is the duration till when this endpoint will ring.
Therfore as per below sample homephone will ring , after 5 sceonds office phone will ring and after 15 secons his cellphone 987654321 will ring . after 25 seconds call will end.

<action application="bridge" data="user/homephone0@mydomain.com, 
[leg_delay_start=5]user/officephone@mydomain.com, 
[leg_delay_start=15,leg_timeout=25] sofia/gateway/flowroute/987654321" />

DID can bridge to multiple extensions or gateways sequentially in a hunt pattern

<extension name="did_hunt">
<condition field="destination_number" expression="87654321">

<action application="set" data="hangup_after_bridge=true"/>
<action application="set" data="continue_on_fail=true"/>

<!-- this is needed to allow call_timeout to work after bridging to a gateway -->
<action application="set" data="ignore_early_media=true"/>

<!-- ring desk extension for 10 seconds. -->
<action application="set" data="call_timeout=10"/>
<action application="bridge" data="sofia/${domain}/1001"/>

<!-- Now try cell phone, hangup after 13 -->
<action application="set" data="call_timeout=13"/>
<action application="bridge" data="sofia/gateway/voicepulse/987654321" />

<!-- No answer, transfer to voicemail -->
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="voicemail" data="default ${domain} 1001"/>

</condition>
</extension>

Ring Multiple Targets

<action application="bridge" 
data="{ignore_early_media=true}user/7001@${domain}, 
user/7010@${domain}, user/7022@${domain}, user/7007@${domain}, 
sofia/gateway/flowroute/12345678901"/>

Handle Failures and Early Media

<action application="bridge" 
data="{ ignore_early_media=true, 
monitor_early_media_fail=user_busy:3:480+620!
destination_out_of_order:2:1776.7 }
sofia/internal/3000@local.telco.com|
sofia/internal/3004@local.telco.com"/>

To detect early media fail the conditions are

  • user busy – number of attempts is 3 and 480Hz 620Hz is the tone of frequency which is standard busy tone.
  • destination out of order – number of attempts 2 , 1776.7 Hz frequency .
    Note that as per condition only these frequencies are detected for action , others are ignored .

Directory

A simple directory listing containing two groups with 2 users each

<domain name="${domain}">
<params>
<param name="dial-string" value="{^^:sip_invite_domain=${dialed_domain}:
presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(*/${dialed_user}@${dialed_domain})}/>
</params>

<variables>
<variable name="record_stereo" value="true"/>
<variable name="default_gateway" value="${default_provider}"/>
<variable name="default_areacode" value="${default_areacode}"/>
<variable name="transfer_fallback_extension" value="operator"/>
</variables>

<groups>
<group name="default">
    <users>
        <X-PRE-PROCESS cmd="include" data="default/*.xml"/>
    </users>
</group>

<group name="team1">
    <users>
        <user id="1000" type="pointer"/>
        <user id="1001" type="pointer"/>
    </users>
</group>

<group name="team2">
    <users>
        <user id="1002" type="pointer"/>
        <user id="1003" type="pointer"/>
    </users>
</group>

</groups>
</domain>

1001 user’s xml

<include>
<user id="1001">
<params>
<param name="password" value="${default_password}"/>
</params>
<variables>
    <variable name="toll_allow" value="domestic,international,local"/>
    <variable name="accountcode" value="1001"/>
    <variable name="user_context" value="default"/>
    <variable name="effective_caller_id_name" value="Extension 1001"/>
    <variable name="effective_caller_id_number" value="1001"/>
    <variable name="outbound_caller_id_name" value="${outbound_caller_name}"/>
    <variable name="outbound_caller_id_number" value="${outbound_caller_id}"/>
    <variable name="callgroup" value="team1"/>
</variables>
</user>
</include>

Adding users

/usr/src/freeswitch-debs/freeswitch# scripts/perl/add_user 3000

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
 LANGUAGE = (unset),
 LC_ALL = (unset),
 LC_CTYPE = "UTF-8",
 LANG = "en_US.UTF-8"
    are supported and installed on your system.

perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
Added 3000 in file /usr/local/freeswitch/conf/directory/default/3000.xml 
Operation complete. 1 user added.
Be sure to reloadxml.
Regular expression information:
            Sample regex for all new users: ^3000$
Sample regex for all new AND current users: ^(10(0[0-9]|1[0-9]|20)|3000)$

In the default configuration you can modify the expression in the condition for 'Local_Extension'.

Adding a range of users , 3000 to 3010

Since 3000 was already added previously , it threw a warning , rest were successfully added

/usr/src/freeswitch-debs/freeswitch# scripts/perl/add_user -users=3000-3010 

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
 LANGUAGE = (unset),
 LC_ALL = (unset),
 LC_CTYPE = "UTF-8",
 LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").

User id 3000 already exists, skipping...
Added 3001 in file /usr/local/freeswitch/conf/directory/default/3001.xml 
Added 3002 in file /usr/local/freeswitch/conf/directory/default/3002.xml 
Added 3003 in file /usr/local/freeswitch/conf/directory/default/3003.xml 
Added 3004 in file /usr/local/freeswitch/conf/directory/default/3004.xml 
Added 3005 in file /usr/local/freeswitch/conf/directory/default/3005.xml 
Added 3006 in file /usr/local/freeswitch/conf/directory/default/3006.xml 
Added 3007 in file /usr/local/freeswitch/conf/directory/default/3007.xml 
Added 3008 in file /usr/local/freeswitch/conf/directory/default/3008.xml 
Added 3009 in file /usr/local/freeswitch/conf/directory/default/3009.xml 
Added 3010 in file /usr/local/freeswitch/conf/directory/default/3010.xml 
Operation complete. 10 users added.
Be sure to reloadxml.
Regular expression information:
            Sample regex for all new users: ^30(0[123456789]|10)$
Sample regex for all new AND current users: ^(10(0[0-9]|1[0-9]|20)|30(0[0-9]|10))$
In the default configuration you can modify the expression in the condition for 'Local_Extension'.

After adding the user to directory , users can now make outbound calls . But howver cannot be rechable for incoming calls . To enable that e need to add them to dialplan .

Creating dialplan for the newly added users  in conf/dialplan/default.xml

update the existing condition 

<condition field="destination_number" expression="^(10[01][0-9])$"> with <condition field="destination_number" expression="^30(0[123456789]|10)$">

After this goto fs_cli cmd prompt and do reloadxml

Installation

Quick Installation on MacOS

Download and run the dmg.

Building from source on Ubuntu 16.04 Xenial

*experimental not suitable for production as per Freeswitch docs

The master branch depends on video libraries which are not available as packages in Debian distribution, but are available from FreeSWITCH repository , requires the use of the devscripts and cowbuilder packages.apt-get install git devscripts cowbuilder

Change to root and add freeswitch to sources.list

wget -O - https://files.freeswitch.org/repo/deb/freeswitch-1.8/fsstretch-archive-keyring.asc | apt-key add -
 
echo "deb http://files.freeswitch.org/repo/deb/freeswitch-1.8/ jessie main" > /etc/apt/sources.list.d/freeswitch.list
echo "deb-src http://files.freeswitch.org/repo/deb/freeswitch-1.8/ jessie main" >> /etc/apt/sources.list.d/freeswitch.list
 
apt-get update

apt-get build-dep freeswitch

cd /usr/src/

git clone https://freeswitch.org/stash/scm/fs/freeswitch.git -bv1.8 freeswitch

cd freeswitch

git config pull.rebase true

Enter freeswitch directory and Build

./bootstrap.sh -j
./configure
make
make install

for errors such as “The repository ‘http://files.freeswitch.org/repo/ubuntu-1604/freeswitch-unstable xenial InRelease’ is not signed.” and “The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 0xxxxxxx” please note than only debian 8 is the officially supported os version by FS now. hence is using AWS ( amazon web service ) stick with ubuntu v 14 ie Ubuntu Server 14.04 LTS (HVM), SSD Volume Type  which is also free tier eligible.

  Ubuntu      |       Debian  
18.04  bionic     buster  / sid   - 10
17.10  artful     stretch / sid   - 9
17.04  zesty      stretch / sid
16.10  yakkety    stretch / sid
16.04  xenial     stretch / sid
15.10  wily       jessie  / sid   - 8
15.04  vivid      jessie  / sid
14.10  utopic     jessie  / sid
14.04  trusty     jessie  / sid
13.10  saucy      wheezy  / sid   - 7
13.04  raring     wheezy  / sid
12.10  quantal    wheezy  / sid
12.04  precise    wheezy  / sid
11.10  oneiric    wheezy  / sid
11.04  natty      squeeze / sid   - 6
10.10  maverick   squeeze / sid
10.04  lucid      squeeze / sid

Manual Process of bootstarp and cofigure

Once build is successfull , install libtool-bin , libcurl4-openssl-dev , libpcre3-dev , libspeex-dev , libspeexdsp-dev ,libtiff5 ,libtiff5-dev , yasm for libvpx , liblua5.1-0-dev for scripting

For mod_enum support install libldns-dev or disable it in modules.conf

we can either install libedit-dev (>= 2.11) or configure with –disable-core-libedit-support

./bootstrap.sh
./configure 
make

For errors around lua file such as Cannot find lua.h header file , just do apt-get install lua5.2 and lua5.2-dev and copy the headers file manually to freeswitch languages folder such as
cp -R /usr/include/lua5.2/ src/mod/languages/mod_lua/
or you can copy these one by one lauxlib.h lua.h lua.hpp luaconf.h lualib.h

ln -s /usr/lib/x86_64-linux-gnu/liblua5.1.so llua

sudo make install
sudo make uhd-sounds-install
sudo make uhd-moh-install
sudo make samples

If you want to make lua from source

mkdir -p ~/Developing/third_party
cd Developing
wget https://www.lua.org/ftp/lua-5.3.2.tar.gz
tar xf lua-5.3.2.tar.gz
cd lua-5.3.2.tar.gz
make linux 
sudo make install INSTALL_TOP=/usr/local
cd ~/Developing/third_party/rtags/build
cmake -DLUA_INCLUDE_DIR=/usr/local/include/ -DLUA_LIBRARY=/usr/local/lib/liblua.a ../
aptitude install -y -r -o APT::Install-Suggests=true freeswitch-meta-vanilla
cp -a /usr/share/freeswitch/conf/vanilla /etc/freeswitch
/etc/init.d/freeswitch start

To see if freeswitch is running  – ps aux | grep freeswitch

fs_cli
Screen Shot 2018-09-20 at 10.45.47 AM

To check listening ports – ngrep -W byline -d any port 5060 or netstat -lnp | grep 5060

HTTPTCP800.0.0.0/0
HTTPTCP80::/0
Custom TCP RuleTCP5080 – 50810.0.0.0/0
Custom TCP RuleTCP5080 – 5081::/0
Custom UDP RuleUDP16384 – 327680.0.0.0/0
Custom UDP RuleUDP16384 – 32768::/0
All trafficAllAll0.0.0.0/0
All trafficAllAll::/0
SSHTCP220.0.0.0/0
Custom TCP RuleTCP80210.0.0.0/0
Custom TCP RuleTCP8021::/0
Custom UDP RuleUDP5060 – 50620.0.0.0/0
Custom UDP RuleUDP5060 – 5062::/0
Custom UDP RuleUDP5080 – 50810.0.0.0/0
Custom UDP RuleUDP5080 – 5081::/0
HTTPSTCP4430.0.0.0/0
HTTPSTCP443::/0
Custom TCP RuleTCP8081 – 80820.0.0.0/0
Custom TCP RuleTCP8081 – 8082::/0
Custom TCP RuleTCP5060 – 50610.0.0.0/0
Custom TCP RuleTCP5060 – 5061::/0

Debugging and Call

For internal calls , originate api can be used to initiate calls such as  originate ALEG BLEG

originate {origination_caller_id_number=9999988888}sofia/internal/1004@127.0.0.1:5060 91999998888 XML default CALLER_ID_NAME CALLER_ID_NUMBER

This will make a call out to sip:1004@1127.0.0.1 with the Caller ID number set to 999998888, then it will send the call to the XML dialplan using context=default. Then the dialplan will process call to 91999998888 with the Caller ID name and number specified in the fields CALLER_ID_NAME and CALLER_ID_NUMBER.

fsc_cli> originate sofia/internal/1002@127.0.0.1:5060 &echo()
switch_ivr_originate.c:2159 Parsing global variables
switch_channel.c:1104 New Channel sofia/internal/1002@127.0.0.1:5060 [5188806e-cabd-4acc-b20b-00620c3362ec]
mod_sofia.c:5026 (sofia/internal/1002@127.0.0.1:5060) State Change CS_NEW -> CS_INIT
switch_core_state_machine.c:584 (sofia/internal/1002@127.0.0.1:5060) Running State Change CS_INIT (Cur 5 Tot 122559)
switch_core_state_machine.c:627 (sofia/internal/1002@127.0.0.1:5060) State INIT
mod_sofia.c:93 sofia/internal/1002@127.0.0.1:5060 SOFIA INIT
sofia_glue.c:1299 sofia/internal/1002@127.0.0.1:5060 sending invite version: 1.9.0 -654-ed4920e 64bit
Local SDP:
v=0
o=FreeSWITCH 1538689496 1538689497 IN IP4 172.31.27.106
s=FreeSWITCH
c=IN IP4 172.31.27.106
t=0 0
m=audio 24636 RTP/AVP 9 0 8 101
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=sendrecv
m=video 19042 RTP/AVP 102
b=AS:1024
a=rtpmap:102 VP8/90000
a=sendrecv
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 ccm tmmbr
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
switch_core_state_machine.c:40 sofia/internal/1002@127.0.0.1:5060 Standard INIT
switch_core_state_machine.c:48 (sofia/internal/1002@127.0.0.1:5060) State Change CS_INIT -> CS_ROUTING
switch_core_state_machine.c:627 (sofia/internal/1002@127.0.0.1:5060) State INIT going to sleep
switch_core_state_machine.c:584 (sofia/internal/1002@127.0.0.1:5060) Running State Change CS_ROUTING (Cur 4 Tot 122612)
sofia.c:7291 Channel sofia/internal/1002@127.0.0.1:5060 entering state [calling][0]
sofia.c:7291 Channel sofia/internal/1002@127.0.0.1:5060 entering state [terminated][503]

Security

-tbd

  • ACL
  • Fail2Ban
  • IPtables

Ref :

My freeswitch contributor profile