FreeSWITCH 1.8

4.8 (9 reviews total)
By Anthony Minessale II , Giovanni Maruzzelli
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Architecture of FreeSWITCH

About this book

FreeSWITCH is an open source telephony platform designed to facilitate the creation of voice and chat-driven products, scaling from a soft-phone to a PBX and even up to an enterprise-class soft-switch. This book introduces FreeSWITCH to IT professionals who want to build their own telephony system.

This book starts with a brief introduction to the latest version of FreeSWITCH. We then move on to the fundamentals and the new features added in version 1.6, showing you how to set up a basic system so you can make and receive phone calls, make calls between extensions, and utilize basic PBX functionality.

Once you have a basic system in place, we’ll show you how to add more and more functionalities to it. You’ll learn to deploy the features on the system using unique techniques and tips to make it work better.

Also, there are changes in the security-related components, which will affect the content in the book, so we will make that intact with the latest version. There are new support libraries introduced, such as SQLite, OpenSS, and more, which will make FreeSWITCH more efficient and add more functions to it. We’ll cover these in the new edition to make it more appealing for you.

Publication date:
July 2017
Publisher
Packt
Pages
434
ISBN
9781785889134

 

Chapter 1. Architecture of FreeSWITCH

Welcome to FreeSWITCH! If you are reading this, then you're interested in things such as real-time communication, WebRTC, telecommunications, and Voice over Internet Protocol (VoIP). FreeSWITCH is a complete application server and a flexible toolset, used worldwide to build advanced and future-proof communication applications. Before looking at the architecture of this powerful software, let's take a look at the world of telecommunications. This will help to put FreeSWITCH into perspective.

In this chapter, we will cover:

  • A communication double revolution
  • Advantages of FreeSWITCH
  • Endpoint and Dialplan modules
  • How FreeSWITCH simplifies complex applications such asvoicemail and video-conferences
 

Real-time communication without mysteries


Real-time communication (RTC) began with telephone during the second half of the 1800s, and almost immediately evolved into a big, worldwide, interconnected network of big companies and infrastructure.

Until a few years ago, telephony was a walled castle strictly guarded by huge corporations and almost nobody was able to completely understand how it was actually working. You got a chance to gain that esoteric knowledge by attending internal technical seminars and in-house schools, and even that knowledge was limited to the part of the system you were to work on (central office, last mile, PBX, and so on). Both the infrastructure carrying and routing the calls, and the applications answering and managing them, were ad hoc, rigid, not compatible with each other, and required huge investments.

Then two revolutions completely obliterated that old world. The first one was the VoIP telephony revolution, which brought an open protocol (SIP) to power, first in the application/PBX realm, and then in the infrastructure too. First to go was that steel box containing a proprietary PBX that could only be expanded by changing internal hardware cards made by that same company, serving only its own kind and model of hardware phones. It was substituted by a standard server with standard PC architecture, using off-the-shelf expansion cards, able to support any kind of standard-compliant phones. SIP then climbed from bottom to top, up to the very core of Big Telcos infrastructure. Today, all telecommunication infrastructures including those of Big Telcos and Carriers are running some version of the SIP protocol.

And the second revolution, which is ongoing right now and will take some more years to complete and bear fruits: WebRTC. This is a very misleading name; WebRTC does not require web pages and browsers at all. WebRTC is a set of standards for the encrypted interconnections of communication endpoints. This WebRTC standard happened to first be implemented in browsers.In the mean time it has become the mainstream way to communicate in the Internet of Things, spanning from smartphone apps to cars, lifts, shop cashiers, and point of sale.

Nowadays it's possible to build communication systems that outperform traditional voice, video, and conference services and offer advanced features for a relatively low cost. FreeSWITCH has been designed to make all of this easier, and we will go over its architecture to get a better understanding of how it works.

Don't be concerned if you don't grasp it all in one swoop. Learning takes time, especially RTC and VoIP. In fact, we recommend that you read this chapter more than once. Absorb as much as you can on the first pass, then come back after you complete Chapter 6, XML Dialplan. You will be surprised at how much your understanding of FreeSWITCH has improved. Then come back and skim it a third time after you have completed Chapter 10, Dialplan, Directory, and ALL via XML_CURL and Scripts; at this point, you will have a firm grasp of FreeSWITCH concepts. Give yourself time to digest all of these new concepts, and soon you will find that you are a skilled FreeSWITCH administrator.

Today, we live in an ecosystem of multiple RTC technologies, all coexisting at the same time: telephony systems (such as telephone switches and PBXs), the traditional analog phone (POTS lines or Plain Old Telephone Service), traditional telephone networks operated by carriers (PSTN or Public Switched Telephone Network), mobile phones (CDMA, GSM, LTE, and so on), faxes, WebRTC, smartphone apps, VoIP phones, and Enterprise systems.

FreeSWITCH's niche is right in the center of this ecosystem: it connects and accepts connections from all those technologies, it bridges and mixes them together, it provides interactive applications and services to users whatever their endpoint happens to be. FreeSWITCH is able to connect to external data services and to legacy in-house systems, to computer programs and business procedures. FreeSWITCH runs on Linux, Windows, and Mac OS X, as well as *BSD and Solaris. We have plenty of hardware choices, from big multiprocessor servers to Raspberry Pi. So, you can develop on your laptop, and then deploy on datacenter, or in an embedded device. Installing FreeSWITCH is discussed in detail in Chapter 2, Building and Installation.

 

The FreeSWITCH design - modular, scalable, and stable


The design goal of FreeSWITCH is to provide a modular, scalable system around a stable switching core, and to provide a robust interface for developers to add to and control the system. Various elements in FreeSWITCH are independent of each other and do not have much knowledge about how the other parts are working, other than what is provided in what are called "FreeSWITCH APIs". The functionality of FreeSWITCH can be extended with loadable modules, which tie a particular functionality or an external technology into the core.

FreeSWITCH has many different module types that surround the central core, like sensors and interfaces connect a robot brain to the external environment. The list includes the following:

Module type

Purpose

Endpoint

Telephone protocols such as SIP and PSTN lines.

Application

Performs a task such as playing audio or sending data.

Automated Speech Recognition(ASR)

Interfaces with speech recognition systems.

Chat

Bridges and exchanges various chat protocols.

Codec

Translates between audio formats.

Dialplan

Parses the call details and decides where to route the call.

Directory

Connects directory information services, such as LDAP, to a common core lookup API.

Event handlers

Allows external programs to control FreeSWITCH.

File

Provides an interface to extract and play sound from various audio file formats.

Formats

Plays audio files in various formats.

Languages

Programming language interfaces used for call control.

Loggers

Controls logging to the console, system log, or log files.

Say

Strings together audio files in various languages to provide feedback to say things such as phone numbers, time of day, spellings of words, and so on.

Text-To-Speech (TTS)

Interfaces with text-to-speech engines.

Timers

POSIX or Linux kernel timing in applications.

XML Interfaces

Uses XML for Call Detail Records (CDRs), CURL, LDAP, RPC, and so on.

 

The following diagram shows what the FreeSWITCH architecture looks like and how the modules orbit the core of FreeSWITCH:

By combining the functionalities of the various module interfaces, FreeSWITCH can be configured to connect IP phones, POTS lines, WebRTC, and IP-based telephone services. It can also translate audio formats and provides an Interactive Voice Response (IVR) system with custom menus. A FreeSWITCH server can also be controlled from another machine. Let's start by taking a closer look at a pair of important module types.

 

Important modules - Endpoint and Dialplan


Endpoint modules are critically important and add some of the key features that make FreeSWITCH the powerful platform it is. The primary role of endpoint modules is to take certain common communication technologies and normalize them into a common abstract entity, which we refer to as a session. A session represents a connection between FreeSWITCH and a particular protocol. There are several Endpoint modules that come with FreeSWITCH, which implement several protocols such as SIP, H.323, Jingle, Verto, WebRTC, and some others. We will spend some time examining one of the more popular modules named mod_sofia.

Sofia-SIP (http://sofia-sip.sourceforge.net) is an open source project originally developed by Nokia, which provides a programming interface for the Session Initiation Protocol (SIP). FreeSWITCH developers have worked a lot evolving and fixing its original code base, further enhancing its robustness and features. We use our version of this library in FreeSWITCH (/usr/src/freeswitch/libs/sofia-sip) in a module named mod_sofia. This module registers to all the hooks in FreeSWITCH necessary to make an Endpoint module, and translates the native FreeSWITCH constructs into Sofia SIP constructs and vice versa. Configuration information is taken from FreeSWITCH configuration files, which makes for mod_sofia to load user-defined preferences and connection details. This allows FreeSWITCH to accept registrations from SIP phones and devices, register itself to other SIP servers such as service providers, send notifications, and provide services to the phones such as blinking lights and voicemail.

When a SIP audio/video call is established between FreeSWITCH and another SIP device, it will show up in FreeSWITCH as an active session. If the call is inbound, it can be transferred or bridged to IVR menus, hold music (and/or video), or to one or more extensions. Or, it can be bridged to a newly created outbound call, toward a PSTN subscriber, or a WebRTC browser, for example. Let's examine a typical scenario where an internal SIP phone registered as extension 2000 dials extension 2001 with the hope of establishing a call.

First, the SIP phone sends a call setup message to FreeSWITCH over the network (mod_sofia is listening for such messages). After receiving the message, mod_sofia in turn parses the relevant details, builds the abstract call session data structure the core understands, and passes that call into the core state machine in FreeSWITCH. The state machine (in the FreeSWITCH core) then puts the call into the ROUTING state (meaning looking for a destination).

Core's next step is to locate the Dialplan module based on the configuration data for the calling Endpoint. The default and most widely used Dialplan module is the XML Dialplan module. This module is designed to look up a list of instructions from the XML tree within FreeSWITCH's memory. The XML Dialplan module will parse a series of XML objects using regular expression pattern-matching.

As we are trying to call 2001, we are looking around for an XML extension where the destination_number field matches 2001. Also, let's remember the Dialplan is not limited to matching only a single extension. An incoming call can match more than one extension in the Dialplan, and in Chapter 6, XML Dialplan, you will get an expanded definition of the term extension. The XML Dialplan module builds a TODO list for the call. Each matched extension will have its actions added to the call's TODO list.

Assuming FreeSWITCH finds at least one extension with a matching condition, the XML Dialplan will insert instructions into the session object with the information it needs to try and connect the call to 2001 (the TODO list for this call). Once these instructions are in place, the state of the call session changes from ROUTING to EXECUTE, where the core drills down the list and executes the instructions piled during the ROUTING state. This is where the API comes into the picture.

Each instruction is added to the session in the form of an application name and a data argument that will be passed to that application. The one we will use in this example is the bridge application. The purpose of this application is to create another session with an outbound connection, then connect the two sessions for direct audio exchange. The argument we will supply to bridge will be user/2001, which is the easiest way to generate a call to an internal registered phone at extension 2001. A Dialplan entry for 2001 might look like this:

<extension name="example"> 
<condition field="destination_number" 
             expression="^2001$"> 
<action application="bridge" data="user/2001"/> 
</condition> 
</extension> 

This extension is named example, and it has a single condition to match. If that condition is matched, it has a single application to execute. It can be understood as: If the caller dialed 2001, then establish a connection between the caller and the endpoint (that is, the phone) at 2001.

Once we have inserted the instructions into the TODO list for the session, the session's state will change to EXECUTE, and the FreeSWITCH core will start to use the data collected to perform the desired action(s). First, it will parse the list and find it must execute bridge on user/2001, then it will look up the bridge application and pass the user/2001 data to it. This will cause the FreeSWITCH core to create a new outbound session (that is, a call) of the desired type. Let's assume that user 2001 is registered to FreeSWITCH using a SIP phone. So user/2001 will resolve into a SIP dialstring, which will be passed to mod_sofia to ask it to create a new outbound session (toward user 2001's SIP phone).

If the setup for that new session is successful, there will be two sessions in the FreeSWITCH core, the new session and the original session (from the caller phone). The bridge application will take those two sessions and call the bridge function on it. This will make the audio and/or the video stream to flow in both directions once the person at extension 2001 answers the phone. If that user is unable to answer or is busy, a timeout (that is, a failure) would occur and a failure message will be sent back to the caller's phone. If a call is unanswered or an extension is busy, many reactions can be built in the Dialplan, including call forwarding or voicemail.

FreeSWITCH takes all the complexity of SIP and reduces it to a common (internal to its core) denominator. Then it reduces the complexity further by allowing us to use a single instruction in the Dialplan for connecting the phone at 2000 to the phone at 2001. If we also want to allow the phone at 2001 to be able to call the phone at 2000, we can add another entry in the Dialplan going the other way:

<extension name="example 2"> 
<condition field="destination_number" expression="^2000$"> 
<action application="bridge" data="user/2000"/> 
</condition> 
</extension> 

In this scenario, the Endpoint module (mod_sofia) turned incoming SIP call into a FreeSWITCH session and the Dialplan module (mod_dialplan_xml) turned XML into an extension. The bridge application (from mod_dptools) turned into a simple application/data pair the complex code of creating an outbound call and connecting its media streams. Both the Dialplan module and the application module interface are designed around FreeSWITCH sessions. Not only does the abstraction make life easier for us at the user level, it also simplifies the design of the application and the Dialplan because they can be made agnostic of the actual endpoint technology involved in the call. It is because of this abstraction that when tomorrow we will write a new Endpoint module to the 3D holographic communication network we will be able to reuse all the same applications and Dialplan modules. To the FreeSWITCH core, and to all of the FreeSWITCH modules, an holographic 3D call will then appear as just one more standard abstract session.

It is possible that you may want to work with some specific data provided by the Endpoint's native protocol. In SIP, for instance, there are several arbitrary headers as well as several other bits of interesting data inside the SIP packets. You may need or want to access those specific bits of information. We solve this problem by adding variables to the channel (that is, the part of the session structure that interact with the endpoint). Using channel variables, mod_sofia can create these arbitrary values as they are encountered in the SIP data, and you can retrieve them from the channel by variable name, in your Dialplan or application. Those were originally specific (and arbitrary) parts of the low-level SIP messages. However, the FreeSWITCH core just sees them as arbitrary channel variables that the core can ignore. There are also several special reserved channel variables that can influence the behavior of FreeSWITCH in many useful ways. If you have ever used a scripting language or configuration engine that uses variables (sometimes called attribute-value pairs or AVP, channel variables are pretty much the same concept. There is simply a name and a value that are passed to the channel, and the data is set.

The application interface for this, the set application, lets you set your own variables from the Dialplan:

<extension name="example 3"> 
<condition field="destination_number" expression="^2000$"> 
<action application="set" data="foo=bar"/> 
<action application="bridge" data="user/2000"/> 
</condition> 
</extension> 

This example is almost identical to the previous example, but instead of just placing the call, we first set the variable foo equal to the value bar. This variable will remain set throughout the call and can even be referenced at the end of the call in the detail logs (CDRs).

The more we build things by small pieces, the more the same underlying resources can be reused, making the whole system simpler to use. For example, the codec interface knows nothing else about the core, other than its own isolated world of encoding and decoding audio and video packets. Once a proper codec module has been written, it becomes usable by any Endpoint interface capable of carrying that codec in one of its media streams. This means that if we get a text-to-speech module working, we can generate synthesized speech on any and all Endpoints that FreeSWITCH supports. The TTS module becomes more useful because it can use more codecs; the codecs have become more useful because we added a new function that can take advantage of them. The same idea applies to applications. If we write a new application module, the existing endpoints will immediately be able to run and use that application.

 

Complex applications made simple


FreeSWITCH removes much of the complexity from advanced applications. Let's look at two examples of a more complex application.

Voicemail

The first application we will discuss is the voicemail application. This application is useful to add right after the bridge application as a second option, executed in cases where the call was not completed. We can do this with one of those special variables that we were discussing earlier. Let's look at a version of our last extension that also allows us to leave a voicemail:

<extension name="example 4"> 
<condition field="destination_number" expression="^2000$"> 
<action application="set" 
            data="hangup_after_bridge=true"/> 
<action application="bridge" data="user/2000"/> 
<action application="voicemail" 
            data="default ${domain} 2000"/> 
</condition> 
</extension> 

Here, we see two uses of channel variables. First, we set hangup_after_bridge=true telling the system to hang up once we have have successfully bridged the call to another phone and to disregard the rest of the instructions. We are using the domain variable in brackets prefixed with a dollar sign, ${domain}. This is a special variable that defaults to the auto-configured domain name, which comes from the XML configuration.

In this example, we check if someone is dialing 2000. We then try to bridge the call to the user which endpoint is registered to extension 2000. If the call fails or if there is no answer (for example, if the bridge attempt has failed, so we do not execute the hangup after the bridge), we will continue to the next instruction, which is to execute the voicemail application. We provide the information the application needs to know (for example, which domain the voicemail belongs to) and which extension the voicemail is for, so the application knows how to handle the situation. Next, the voicemail application plays the pre-recorded greeting or generates one using the Say module's interface, which we briefly discussed earlier. It then plays short sound files one after each other to make a voice say something like The person at extension 2 0 0 0 is not available, please leave a message. Next, mod_voicemail prompts you to record a message. As an additional feature, if you are not convinced with your recording, you can listen and re-record it as many times as you wish. Once you finally commit, a FreeSWITCH MESSAGE_WAITING event is fired into the core event system queue, which is picked up by mod_sofia by way of an event consumer, and the event information is translated into SIP-in this case a SIP NOTIFY message that lets the SIP phone know that there is a message waiting. A blinking lamp (Message Waiting Indicator (MWI)) lights upon the receiving phone.

In this example, not only have we seen how to play a greeting, record a message, and transform it into a voicemail for a user, we have also met an important part of the FreeSWITCH core-the event system. The FreeSWITCH event system is not an additional module interface like the previous examples, it is a core engine feature that you can use to bind to named events and react accordingly when an event is received. In other words, throughout the FreeSWITCH core, there are events that are sent and received. Modules can bind to (that is listen for) various events. They can also fire events into the event engine; other modules can listen for those events. You can think of it as similar to other queuing systems such as RabbitMQ (actually, there is a module to interface the internal event system of a FreeSWITCH server with RabbitMQ, so you can integrate it into an enterprise queuing system, and/or having multiple FreeSWITCH servers be parts of the same big, distributed queue). As we discussed, the Sofia SIP module binds to (subscribes to) the event designated for MESSAGE_WAITING information. This allows our mod_voicemail module to interact with mod_sofia without either system having any knowledge about the other's existence. The event is blindly fired by mod_voicemail (fire and forget, in military parlance), intercepted (received, because has subscribed to) by mod_sofia, and translated into the proper SIP message-all courtesy of the event system.

There are several challenges with such a complex system of concatenating sounds when considering all of the possible languages it may need to support, as well as what files to play for the automated messages and how they are strung together. The Say module supplies a nice way to string files together, but it is limited to something specific, such as spelling a word, counting something, or saying a certain date. The way we overcome this is by defining a more complex layer on top of the Say module called Phrase Macros. Phrase Macros are a collection of XML expressions that pull out a list of arguments by matching a regular expression and executing a string of commands. This is very similar to how the XML Dialplan works, only custom-tailored for IVR scenarios. For example, when mod_voicemail asks you to record your message, rather than coding in the string of files to make it say what you want, the code just calls a phrase macro called voicemail_record_message. This arbitrary series of sound bites is defined in the Phrase Macro section in the XML configuration allowing us, the administrators, to edit the phrase without modifying the Voicemail IVR program:

<macro name="voicemail_record_message"> 
<input pattern="^(.*)$"> 
<match> 
<action function= "play-file"  
        data="voicemail/vm-record_message.wav"/> 
</match> 
</input> 
</macro> 

When mod_voicemail executes the voicemail_record_message macro, it first matches the pattern, which, in this case, is to match everything, because this particular macro has no use for input (that is, whatever input you give it, is not used). If the macro did use the input, the pattern matching could be used to play different sound bites based on different input. Once a match is found, the XML match tag is parsed for action tags just like in our Dialplan example. This macro only plays the file vm-record_message.wav, but more complicated macros, like the ones for verifying your recording or telling you how many messages you have in your inbox, may use combinations of various Say actions and play many different audio files. Phrase Macros are discussed in detail in Chapter 6, XML Dialplan, and used extensively in Chapter 8, Lua FreeSWITCH Scripting.

Here too, we can see co-operation between various parts of FreeSWITCH architecture: the phrase system, the audio file, and the Say modules loaded by the core are used together to enable powerful functionalities. The Say modules are written specifically for a particular language or voice within a language. We can programmatically request to say the current time and have it translated into Spanish or Russian sounds by the proper Say module based on input variables. The Phrase Macro system is a great way to put a layer of abstraction into your code, which can be easily tweaked later by system administrators. For example, if we wanted to make a small IVR that asks us to dial a four-digit number, then reads it back and hangs up, we could make one macro called myapp_ask_for_digits and the other called myapp_read_digits. In our code, we would execute these macros by name-the former when it is time to ask for the digits and the later to read back the digits by passing in the value we entered. Once this is in place, a less-experienced individual (for example, a local administrator) could implement the XML files to play the proper sounds. She can use the Say modules to read back the number, and it should all be working in multiple languages with no further coding necessary. Voicemail is just one example of using FreeSWITCH as an application server. There are endless possibilities when we use FreeSWITCH to connect real-time communication with computers.

Multi-party audio/video conferencing

Another important feature of FreeSWITCH is delivered by the mod_conference conferencing module. The mod_conference provides dynamic conference rooms that can bridge together the audio and video from several users. It may mix video streams together, applying CG (computer graphics) transformations to them, such as composing a live feed of different conference participants together, over imposing a caption with the name and role to each users' video stream, sharing the screen of each participant computer (for example, a PowerPoint presentation), and so on. Also, a real-time chat can be added to the conference, so participants can exchange text messages out of band from the main audio/video stream. Obviously, this same module can also be used for plain regular audio conference calls.

Each new session that connects to the same conference room will join the others, and instantly be able to talk and see all of the other participants at the same time (as per the whim of the conference admin, who can choose who to display, who can talk, and so on). Using an example similar to the one we used for bridging to another phone, we can make an extension to join a conference room:

<extension name="example 4"> 
<condition field="destination_number"  expression="^3000$"> 
<action application="conference" data="[email protected]"/> 
</condition> 
</extension> 

This is as simple as bridging a call, but with a conference application many callers can call the same extension (3000 in this case) and join the same conference room. If three people joined this conference and one of them decides to leave, the other two would still be able to continue their conversation.

The conference module also has other special features, such as the ability to play sound or video files or text-to-speech to the whole conference, or even to a single member of the conference. As you may have guessed, we are able to do this by using the TTS and video/sound file interfaces provided by their respective modules. The smaller pieces come together to extend the functionality without needing knowledge of each other.

The conference module also uses the event system in an additional way, employing what are called custom events. When it first loads, a module can reserve a special event namespace called a subclass. When something interesting happens, such as when a caller joins or leaves a conference, it fires those events on the CUSTOM event channel in the core queue. When we are interested in receiving such events, all we have to do is subscribe to the CUSTOM event by supplying an extra subclass string, which specifies the specific CUSTOM events we are interested in. In this case, it is conference::maintenance. This makes it possible to look out for important things such as when someone joins or leaves the conference, when they start and stop talking, when they are displayed on video, or what video layout (screen disposition) is currently in use. Conferencing is discussed in detail in Chapter13, Conferencing and WebRTC Video-Conferencing.

FreeSWITCH API commands (FSAPI)

Another very powerful FreeSWITCH concept is the FSAPI. Most API commands are implemented in mod_commands, and almost all other modules add some to the commands that are executable via FSAPI. FSAPI mechanism is very simple-it takes a single string of text as input, which may or may not be parsed, and performs a particular action. The return value is also a string that can be of any size, from a single character up to several pages of text, depending on the function that was called by the input string. One major benefit of FSAPI functions is that a module can use them to call routines in another module without directly linking into the actual compiled code (thus avoiding sudden incompatibilities and crashes). The most egregious example is the command-line interface of FreeSWITCH or CLI, which uses FSAPI functions to pass FreeSWITCH API commands.

Here is a small example of how we can execute the status FSAPI command from the FreeSWITCH CLI:

What's really happening here is that when we type status and press the Enter key, the word status is used to look up the status FSAPI function from the module in which it is implemented. The underlying function is then called (passing it the arguments if they were typed, in this case none), and the core is queried for its status message. Once the status data is obtained, the output is written to a stream that prints a string.

We have already learned that a module can create and export FSAPI functions that can be executed from anywhere such as the CLI. But there's more. Modules can also be written to execute commands via the FSAPI interface and then send the results over a specific protocol. There are two modules included in FreeSWITCH that do just that-mod_xml_rpc and mod_event_socket (discussed in Chapter 10, Dialplan, Directory, and ALL via XML_CURL and Scripts, and Chapter 11, ESL - FreeSWITCH Controlled by Events respectively). Consider the example of mod_xml_rpc. This module implements the standard XML-RPC protocol (Remote Procedure Call via XML strings) as a FreeSWITCH module. Clients using whatever standard XML-RPC interface can connect to FreeSWITCH and execute FSAPI commands. So a remote client could execute an RPC call to status, and get a similar status message to the one we saw in the previous example. This same module also provides FreeSWITCH with a listening web server, which allows FSAPI commands to be accessed froma direct URL link. For example, one could point a browser to http://example.freeswitch.box:8080/api/status to execute the status command directly over HTTP. By using this technique, it's possible to create FSAPI commands that work similar to a CGI, providing a dynamic web application that has direct access to FreeSWITCH internals (for a more advanced HTTP integration, you may want to check the HTTAPI module in Chapter 12, HTTAPI - FreeSWITCH Asks Webserver Next Action).

As we have shown, the FSAPI interface is very versatile. Now we know it can be used to provide a CLI interface, a way for modules to call functions from each other, and a way to export HTTP or XML-RPC functions. There is still one more use for FSAPI functions that we have not covered. We touched briefly on the concept of channel variables earlier, noting that we can use the expression ${myvariable} to get the value of a certain variable. FSAPI functions can also be accessed this way in the format ${myfunction()}. This notation indicates that the FSAPI command myfunction should be called, and that the notation should be replaced with the output of that function call. Therefore, we can use ${status()} anywhere when variables are expanded to gain access to the output of the status command. For example:

<action application="set" data="my_status=${status()}"/> 

The value placed in the my_status variable will be the string output from the status command.

Most FSAPI commands can be easily accessed using all of the ways we have discussed. Some commands only make sense when accessed via a particular method. For instance, if we made an FSAPI command that produced HTML intended to be accessed with a web browser, we would probably not want to access it from the CLI or by referencing it as a variable. But, never say never, there are cases where it can be useful, and you have the flexibility to do it.

The XML registry

We discussed many of the fundamental components of the FreeSWITCH core and how they interact with each other. We have seen how the event system can carry information across the core to the modules, and how the XML Dialplan can query the XML registry for data. This would be a good time to explain the XML registry a bit more. The XML registry is the XML tree document that holds all of the critical data that FreeSWITCH needs to operate properly. FreeSWITCH builds that document by loading a file from your hard drive and passing it to its own pre-processor. This pre-processor can include other XML documents and execute other special operations, such as setting global variables. Global variables will then be resolved by FreeSWITCH when they're used further down in the document tree.

Once the entire document and all of the included files are parsed, replaced, and generated in a static XML document, this final static document (with all global variables substituted for) is loaded into memory. The XML registry (tree) is divided into several sections- configuration, dialplan, directory, chat plan, languages, phrases, etc. The core and the modules draw their configuration from the configuration section. The XML Dialplan module draws its Dialplan data from the dialplan section. SIP and Verto authentication, user lookup, and the voicemail module read their account information from the directory section. The Phrase Macros pull their configuration from the phrases section. If we make a change to any of the XML files on the disk, we can reload the changes into memory by issuing the reloadxml command from the CLI If we change the values assigned to one of the global variables, we will need to restart FreeSWITCH to apply the new value, reloadxml will not be enough.

Scripting language modules

Scripting language modules embed a programming language like Lua, JavaScript, Perl, C#, and so on, into FreeSWITCH, and transfer functionality between the core and the language's runtime. This allows things like IVR applications to be written in that scripting language, with a simple interface back to FreeSWITCH for all the heavy lifting. Language modules usually register into the core with the application interface and the FSAPI interface and are executed from the Dialplan. Language modules offer lots of opportunities and are very powerful. Using language modules, you can build powerful real-time communication applications in a standard programming language you already know, using its libraries for data manipulations and legacy interfacing.

The demo configuration

Understanding all of these concepts right off the bat is far from easy, and as maintainers of the software, we do not expect most people to have everything just click. This is the main reason that every new layer we put on top of the core makes things simpler and easier to learn. The demonstration configuration of FreeSWITCH is the last line of defense between new users of the software and all of the crazy, complicated, and sometimes downright evil stuff better known as Real Time Communication. We try very hard to save the users from such things.

The main purpose of the demonstration configuration in FreeSWITCH is to showcase all of the hundreds of parameters there are to work with. We present them to you in a working configuration that you could actually leave untouched and play with before trying your own hand at changing some of its options. Think of FreeSWITCH as a Lego set. FreeSWITCH and all of its little parts are like a brand new bucket Lego bricks, with plenty of parts to build anything we can imagine. The demonstration configuration is like the sample spaceship that you find in the instruction booklet. It contains step-by-step instructions on exactly how to build something you know will work. After you pick up some experience, you might start modifying your Lego ship to have extra features, or rebuild the parts into a car or some other creation. Obviously, you can leave outmany, or most, of the features built in that configuration and use only what is useful in your specific deployment. The good news about FreeSWITCH is that it comes out of the box already assembled. Therefore, unlike the bucket of Lego bricks, if you get frustrated and smash it to bits, you can just re-install the defaults and you won't have to build it again from scratch. The demonstration configuration is discussed in Chapter 3, Test Driving the Example Configuration.

Once FreeSWITCH has been installed, you only need to start its executable without changing one line in the configuration file. You will be immediately able to point a SIP telephone or software-based SIP softphone to the address of your server (be it your laptop, a virtual machine, a 48-core server, a Raspberry Pi, or an Amazon instance), make a test call, and access all of the functionalities of FreeSWITCH. Interfacing with other protocols will require additional configurations (such as installing SSL certificates for WebRTC and the like), but the end results will be exactly the same. If you have more than one phone, using the default configuration you should be able to configure them to each having an individual extension in the range 1000-1019, which is the extension number range that is predefined in the demonstration configuration. Once you get the phones registered, you will be able to make calls across them or have them meet in a conference room in the 3000-3399 range. If you call an extension that is not registered, or let the phone ring on another extension for too long, the voicemail application will use the phrase system to indicate that the party is not available, and ask you to record a message. If you dial 5000, you can see an example of the IVR system at work, presenting several menu choices demonstrating various other neat things FreeSWITCH can do. There are a lot of small changes and additions that can be made to the demonstration configuration while still leaving it intact.

For example, using the pre-processor directives we went over earlier, the demonstration configuration loads a list of files into the XML registry from certain places, meaning that every file in a particular folder will be combined into the final XML configuration document. The two most important points where this takes place are where the user accounts and the extensions in the Dialplan are kept. Each of the 20 extensions that are preconfigured with the defaults are stored into their own file. We could easily create a new file with a single user definition, drop it into place to add another user, and issue the reloadxml command at the FreeSWITCH CLI. The same idea applies to the example Dialplan. We can put a single extension into its own file and load it into place whenever we want.

 

Summary


FreeSWITCH is a complex system of moving parts that are integrated to produce a solid, stable core with flexible and easy-to-extend add-ons. The core extends its interfaces to modules. The modules also can bring outside functionalities into FreeSWITCH by translating various communication protocols into a common, abstract, internal format. We looked at the various module types, and demonstrated how they revolve around the core and interact with each other to turn simple abstract concepts into higher-level functionalities. We described a few of the more popular applications in FreeSWITCH-the conferencing and voicemail modules and how they, in turn, make use of other modules without ever knowing it. This agnosticism is accomplished by means of the event system. We also saw how the demonstration configuration provides several working examples to help take the edge off of an otherwise frightening feat of staring down the business end of a full-featured soft-switch.

In the following chapter, we will take our first steps towards getting a FreeSWITCH system up and running.

About the Authors

  • Anthony Minessale II

    Anthony Minessale II is the primary author and founding member of the FreeSWITCH Open Source Soft-Switch. Anthony has spent around 20 years working with open source software. In 2001, Anthony spent a great deal of time contributing code to the Asterisk PBX and has authored numerous features and fixes to that project. In 2005, Anthony started coding a new idea for an open source voice application. The FreeSWITCH project was officially open to the public on January 1 2006. In the years that followed, Anthony has been actively maintaining and leading the software development of the FreeSWITCH project. Anthony also founded the ClueCon Technology Conference in 2005, and he continues to oversee the production of this annual event.

    Anthony has been the author of several FreeSWITCH books, including FreeSWITCH 1.0.6, FreeSWITCH 1.2, FreeSWITCH Cookbook, FreeSWITCH 1.6 Cookbook, and Mastering FreeSWITCH

    Browse publications by this author
  • Giovanni Maruzzelli

    Giovanni Maruzzelli ([email protected]) is heavily engaged with FreeSWITCH. In it, he wrote a couple of endpoint modules, and he is specialized in industrial grade deployments and solutions. He's the curator and coauthor of FreeSWITCH 1.6 Cookbook (Packt Publishing, 2015), and of Mastering FreeSWITCH (Packt Publishing, 2016)

    He's a consultant in the telecommunications sector, developing software and conducting training courses for FreeSWITCH, SIP, WebRTC, Kamailio, and OpenSIPS. As an Internet technology pioneer, he was the cofounder of Italia Online in 1996, which was the most popular Italian portal and consumer ISP. Also, he was the architect of its Internet technologies Italia Online (IOL). Back then, Giovanni was the supervisor of Internet operations and the architect of the first engine for paid access to il Sole 24 Ore, the most-read financial newspaper in Italy, and its databases (migrated from the mainframe). After that, he was the CEO of the venture capital-funded company Matrice, developing telemail unified messaging and multiple-language phone access to e-mail (text to speech). He was also the CTO of the incubator-funded company Open4, an open source managed applications provider. For 2 years, Giovanni worked in Serbia as an Internet and telecommunications investment expert for IFC, an arm of the World Bank.

    Since 2005, he has been based in Italy, and he serves ICT and telecommunication companies worldwide.

    Browse publications by this author

Latest Reviews

(9 reviews total)
Very good written book with examples and real life scanarios. It helped us to deploy and configure FreeSwitch.
It's a comprehensive manual which helps both beginners and advanced users
It cover many aspects of the system, but there are some other that left uncovered.

Recommended For You

FreeSWITCH Cookbook

Written by members of the FreeSWITCH team, this is the ultimate guide to getting the most out of the platform. Stuffed with over 40 recipes, just about every angle is covered, from call routing to enabling text-to-speech conversion.

By Anthony Minessale II and 3 more