
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.