Building Application with FreeSwitch - kerbsx/fs GitHub Wiki

There are 3 ways you can build application with Freeswitch:-

  • Implementing module - using C.
  • Use mod_xxx - mod_lua, mod_python, mod_perl etc.
    • mod_lua seem to be better supported in freeswitch.
  • ESL - Event Socket Layer - this allow you to use any programming language as long as you can write program that connect to tcp port (inbound socket) or listen for incoming tcp connection (outbound socket).

Here we will use ESL to build freeswitch application.

ESL Basic

Raw data using telnet

For inbound socket, you just need to connect to freeswitch esl port (default 8021). Freeswitch use simple text protocol to send/receive data over the socket connection. This mean you can even use telnet to test the inbound socket:-

telnet 127.0.0.1 8021

You'll get a telnet prompt:-

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

Above, we can see freeswitch asking for authentication. We can send the auth using auth command:-

auth OV8PWDbiNM

Type enter to send back the command freeswitch and it will reply:-

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

For now we're not receiving any data from freeswitch yet. We have to tell it what kind of event we want to receive:-

event plain all

After typing above command and press , we will get the following reply:-

Content-Type: command/reply
Reply-Text: +OK event listener enabled plain

Not long after that, we'll start getting a stream of data from freeswitch.

Content-Length: 906
Content-Type: text/event-plain

Event-Name: HEARTBEAT
Core-UUID: a0f207aa-b3f7-4766-8824-df447b04e4ac
FreeSWITCH-Hostname: ip-172-30-1-238
FreeSWITCH-Switchname: ip-172-30-1-238
FreeSWITCH-IPv4: 172.30.1.238
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2017-07-23%2007%3A16%3A36
Event-Date-GMT: Sat,%2022%20Jul%202017%2022%3A16%3A36%20GMT
Event-Date-Timestamp: 1500761796330684
Event-Calling-File: switch_core.c
Event-Calling-Function: send_heartbeat
Event-Calling-Line-Number: 74
Event-Sequence: 394502
Event-Info: System%20Ready
Up-Time: 0%20years,%203%20days,%2017%20hours,%2010%20minutes,%200%20seconds,%20165%20milliseconds,%20508%20microseconds
FreeSWITCH-Version: 1.6.17-34-0fc0946~64bit
Uptime-msec: 321000165
Session-Count: 0
Max-Sessions: 1000
Session-Per-Sec: 30
Session-Per-Sec-Last: 0
Session-Per-Sec-Max: 3
Session-Per-Sec-FiveMin: 0
Session-Since-Startup: 972
Session-Peak-Max: 2
Session-Peak-FiveMin: 0
Idle-CPU: 98.700000

Content-Length: 562
Content-Type: text/event-plain

Event-Name: RE_SCHEDULE
Core-UUID: a0f207aa-b3f7-4766-8824-df447b04e4ac
FreeSWITCH-Hostname: ip-172-30-1-238
FreeSWITCH-Switchname: ip-172-30-1-238
FreeSWITCH-IPv4: 172.30.1.238
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2017-07-23%2007%3A16%3A36
Event-Date-GMT: Sat,%2022%20Jul%202017%2022%3A16%3A36%20GMT
Event-Date-Timestamp: 1500761796350686
Event-Calling-File: switch_scheduler.c
Event-Calling-Function: switch_scheduler_execute
Event-Calling-Line-Number: 71
Event-Sequence: 394503
Task-ID: 2
Task-Desc: heartbeat
Task-Group: core
Task-Runtime: 1500761816
...

Programmatic access

While using telnet we managed to get the raw event data from freeswitch, not much we can do about it. There's no programmatic control we can impose so that we can manipulate the data in some way. For that, we need some sort of programming language, and we will use Python for that.

As we can see above, we use telnet to initiate socket connection to port 8021 of the freeswitch server. We have to do the same thing with Python.

Using socket and manual parsing

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_file = sock.makefile()
sock.connect(('127.0.0.1', 8021))
connected = True
password = 'OV8PWDbiNM'
buf = ''
while connected:
    try:
        data = sock_file.readline()
    except Exception as e:
        print(e)
        connected = False
        sock.close()
        break
    if data == '\n':
        print(buf)
        if buf.strip() == 'Content-Type: auth/request':
            sock.send('auth {}\n\n'.format(password).encode('utf8'))
            buf = ''
            continue

        if buf.split("\n")[1].strip() == 'Reply-Text: +OK accepted':
            print("Ready to go !")
            sock.send('event plain all\n\n'.encode('utf8'))
        buf = ''
    else:
        buf += data

Expansion of this approach

Using ESL lib

Above, we use python socket module to connect to freeswitch ESL port. But this mean we have to manually parse all the response data to get event data that we want, and respond to it. It's definitely tedious but at least you know what happened underneath.

Second method is to use the already built ESL library. Freeswitch provide it's own ESL lib and there's also alternative like greenswitch.

pip install python-ESL
import time
import ESL
import json

password = 'OV8PWDbiNM'
conn = ESL.ESLconnection('127.0.0.1', 8021, password)
conn.events('plain', 'all')
while True:
    event = conn.recvEvent()
    if not event:
        break

    event_data = json.loads(event.serialize('json'))
    print(event_data['Event-Name'])
    time.sleep(1)
⚠️ **GitHub.com Fallback** ⚠️