Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/signalwire/freeswitch/llms.txt

Use this file to discover all available pages before exploring further.

FreeSWITCH is intentionally minimal at its core. Every capability beyond basic session management — SIP signaling, codec negotiation, dialplan routing, scripting, logging, CDR writing — is delivered by a loadable module: a shared library (.so on Linux, .dll on Windows) that is compiled independently and loaded at runtime. This plugin architecture lets you include only the functionality your deployment needs, update individual modules without restarting the switch, and extend the platform with custom code without touching the core.

How Modules Work

Every FreeSWITCH module must expose a module function table using the SWITCH_MODULE_DEFINITION macro, defined in src/include/switch_types.h. This macro declares a switch_loadable_module_function_table_t that the module loader reads via dlopen / GetProcAddress:
/* From src/include/switch_types.h */
#define SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) \
    SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, SMODF_NONE)

#define SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, flags)   \
static const char modname[] = #name;                                         \
SWITCH_MOD_DECLARE_DATA switch_loadable_module_function_table_t              \
    name##_module_interface = {                                              \
    SWITCH_API_VERSION,                                                      \
    load,                                                                    \
    shutdown,                                                                \
    runtime,                                                                 \
    flags                                                                    \
}
Each module provides up to three entry points:
FunctionMacroPurpose
loadSWITCH_MODULE_LOAD_FUNCTION(name)Called once when the module is loaded. Register interfaces, allocate resources.
shutdownSWITCH_MODULE_SHUTDOWN_FUNCTION(name)Called when the module is unloaded. Deregister interfaces, free resources.
runtimeSWITCH_MODULE_RUNTIME_FUNCTION(name)Optional background thread that runs for the lifetime of the module.
Here is the complete module declaration from mod_dptools — one of the most feature-rich application modules:
/* src/mod/applications/mod_dptools/mod_dptools.c */
SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dptools_shutdown);
SWITCH_MODULE_DEFINITION(mod_dptools, mod_dptools_load, mod_dptools_shutdown, NULL);
The third argument (NULL for the runtime function) means mod_dptools does not need a persistent background thread. Inside the load function, a module registers its capabilities by populating a switch_loadable_module_interface_t structure (defined in src/include/switch_loadable_module.h) with pointers to the interface tables it provides:
/* Fields of switch_loadable_module_interface_t (from switch_loadable_module.h) */
struct switch_loadable_module_interface {
    const char *module_name;
    switch_endpoint_interface_t          *endpoint_interface;
    switch_timer_interface_t             *timer_interface;
    switch_dialplan_interface_t          *dialplan_interface;
    switch_codec_interface_t             *codec_interface;
    switch_application_interface_t       *application_interface;
    switch_chat_application_interface_t  *chat_application_interface;
    switch_api_interface_t               *api_interface;
    switch_json_api_interface_t          *json_api_interface;
    switch_file_interface_t              *file_interface;
    switch_speech_interface_t            *speech_interface;
    switch_directory_interface_t         *directory_interface;
    switch_chat_interface_t              *chat_interface;
    switch_say_interface_t               *say_interface;
    switch_asr_interface_t               *asr_interface;
    switch_management_interface_t        *management_interface;
    switch_limit_interface_t             *limit_interface;
    switch_database_interface_t          *database_interface;
};
A single module may implement multiple interface types — for example, mod_av registers both a codec interface (video codecs) and a file-format interface (FFmpeg container support).

Module Types

The source tree organises modules into categories under src/mod/. Each category corresponds to a distinct interface type registered by the module at load time.
CategoryDirectoryDescription
applicationssrc/mod/applicationsDialplan applications executed on a channel: answer, bridge, playback, record, conference, voicemail, etc.
asr_ttssrc/mod/asr_ttsAutomatic speech recognition and text-to-speech engines: mod_unimrcp, mod_flite, mod_tts_commandline.
codecssrc/mod/codecsAudio and video codec plugins: mod_opus, mod_g729, mod_amr, mod_amrwb, mod_g723_1, mod_openh264, mod_silk.
databasessrc/mod/databasesDatabase backend plugins used by limit and hash interfaces.
dialplanssrc/mod/dialplansRouting engines: mod_dialplan_xml (default), mod_dialplan_asterisk (extensions.conf syntax).
directoriessrc/mod/directoriesUser directory providers: mod_ldap.
endpointssrc/mod/endpointsSignaling protocol drivers: mod_sofia (SIP), mod_verto (WebRTC), mod_skinny (SCCP), mod_loopback, mod_rtmp.
event_handlerssrc/mod/event_handlersEvent bus consumers: mod_event_socket (ESL), mod_json_cdr, mod_cdr_csv, mod_amqp, mod_snmp, mod_erlang_event.
formatssrc/mod/formatsAudio/video file I/O: mod_sndfile, mod_shout (MP3/Shoutcast), mod_av (FFmpeg).
languagessrc/mod/languagesEmbedded scripting runtimes: mod_lua, mod_python, mod_javascript, mod_perl, mod_v8.
loggerssrc/mod/loggersLog sinks: mod_logfile (rolling file), mod_syslog, mod_console.
saysrc/mod/sayLanguage-specific phrase rendering: mod_say_en, mod_say_es, mod_say_de, mod_say_ru, etc.
sdksrc/mod/sdkDevelopment skeleton modules used as starting templates.
timerssrc/mod/timersHigh-resolution timer backends: mod_timerfd (Linux), mod_posix_timer.
xml_intsrc/mod/xml_intDynamic XML registry providers: mod_xml_curl, mod_xml_rpc, mod_xml_cdr, mod_xml_ldap.

Loading and Unloading

Autoloading at startup

Modules to load at startup are listed in conf/autoload_configs/modules.conf.xml:
<configuration name="modules.conf" description="Modules">
  <modules>
    <!-- Endpoints -->
    <load module="mod_sofia"/>
    <load module="mod_verto"/>
    <!-- Dialplan -->
    <load module="mod_dialplan_xml"/>
    <!-- Applications -->
    <load module="mod_dptools"/>
    <load module="mod_commands"/>
    <load module="mod_conference"/>
    <!-- Codecs -->
    <load module="mod_opus"/>
    <load module="mod_g729"/>
    <!-- Event handlers -->
    <load module="mod_event_socket"/>
    <load module="mod_cdr_csv"/>
    <!-- Loggers -->
    <load module="mod_logfile"/>
  </modules>
</configuration>

Runtime management

Modules can be loaded, reloaded, and unloaded from the FreeSWITCH console or via the API at runtime:
# Load a module that was not in the autoload list
load mod_lua

# Reload a module (shutdown + load) without restarting FreeSWITCH
reload mod_sofia

# Unload a module entirely
unload mod_event_socket
Unloading an endpoint module (like mod_sofia) while calls are active will drop those calls. Always drain traffic before unloading endpoint modules in production.

Module Configuration

Each module reads its own XML configuration from a file in conf/autoload_configs/, named after the module (e.g., sofia.conf.xml, event_socket.conf.xml). Configuration is fetched from the XML registry under the configuration section.
<!-- conf/autoload_configs/event_socket.conf.xml -->
<configuration name="event_socket.conf" description="Socket Client">
  <settings>
    <param name="nat-map" value="false"/>
    <param name="listen-ip" value="127.0.0.1"/>
    <param name="listen-port" value="8021"/>
    <param name="password" value="ClueCon"/>
  </settings>
</configuration>
After editing a module’s configuration file, send reloadxml to refresh the XML registry and then reload <module_name> to apply the changes.

Writing a Module

A custom module is a standard C shared library that:
  1. Includes <switch.h> (which pulls in the entire FreeSWITCH public API).
  2. Declares its entry points with SWITCH_MODULE_DEFINITION.
  3. Implements a SWITCH_MODULE_LOAD_FUNCTION that registers the module’s interfaces and returns SWITCH_STATUS_SUCCESS.
#include <switch.h>

SWITCH_MODULE_LOAD_FUNCTION(mod_mymodule_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymodule_shutdown);
SWITCH_MODULE_DEFINITION(mod_mymodule, mod_mymodule_load, mod_mymodule_shutdown, NULL);

/* Called when the module loads */
SWITCH_MODULE_LOAD_FUNCTION(mod_mymodule_load)
{
    switch_application_interface_t *app_interface;

    /* module_interface is the output parameter */
    *module_interface = switch_loadable_module_create_module_interface(pool, modname);

    /* Register a dialplan application named "my_app" */
    SWITCH_ADD_APP(app_interface, "my_app", "My Application",
                   "Does something useful", my_app_function, "<args>",
                   SAF_SUPPORT_NOMEDIA);

    return SWITCH_STATUS_SUCCESS;
}

SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymodule_shutdown)
{
    return SWITCH_STATUS_UNLOAD;
}
All public FreeSWITCH API functions are declared with SWITCH_DECLARE(return_type) — this macro resolves to the correct export attribute for each platform. Refer to src/include/switch_core.h, src/include/switch_channel.h, and src/include/switch_ivr.h for the full API surface.

Build docs developers (and LLMs) love