Skip to main content

Chapter 3: The XML Configuration System

FreeSWITCH reads its entire configuration as a single XML document. On disk that document is split across many files that a preprocessor assembles before the XML is parsed. This chapter explains how the assembly works, the preprocessor instructions, the variable syntax, and the document's top-level sections.

The Root Document

The entry point is freeswitch.xml in the configuration root. It defines the five sections and pulls in the files that populate them. The structure is fixed:

<document type="freeswitch/xml">
<X-PRE-PROCESS cmd="include" data="vars.xml"/>

<section name="configuration" description="Various Configuration">
<X-PRE-PROCESS cmd="include" data="autoload_configs/*.xml"/>
</section>

<section name="dialplan" description="Regex/XML Dialplan">
<X-PRE-PROCESS cmd="include" data="dialplan/*.xml"/>
</section>

<section name="chatplan" description="Regex/XML Chatplan">
<X-PRE-PROCESS cmd="include" data="chatplan/*.xml"/>
</section>

<section name="directory" description="User Directory">
<X-PRE-PROCESS cmd="include" data="directory/*.xml"/>
</section>

<section name="languages" description="Language Management">
<X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/es/es_ES.xml"/>
<X-NO-PRE-PROCESS cmd="include" data="lang/es/es_MX.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/pt/pt_BR.xml"/>
<X-NO-PRE-PROCESS cmd="include" data="lang/pt/pt_PT.xml"/>
<X-NO-PRE-PROCESS cmd="include" data="lang/sv/*.xml"/>
</section>
</document>

You rarely edit freeswitch.xml itself. You edit the files it includes.

The Preprocessor

Before the XML parser runs, a preprocessor walks the document and executes instructions. An instruction is written either as an <X-PRE-PROCESS> tag with cmd and data attributes, or, inside an XML comment, as a #command.

Preprocessor Commands

The following cmd values are recognized on <X-PRE-PROCESS> elements.

cmddata formatEffect
includefile path or glob patternInserts the contents of the named file or glob at this exact point. A glob includes every matching file in sorted order.
setname=valueDefines a preprocessor variable. Referenced elsewhere as $${name}.
exec-setname=shell commandRuns the shell command and assigns its trimmed stdout to the named preprocessor variable.
stun-setname=stun-server-hostQueries the named STUN server and assigns the discovered public IP address to the named preprocessor variable.
env-setname=$ENVVARReads the named OS environment variable and assigns its value to the named preprocessor variable. The $ prefix in the value is required and consumed as a marker.
execshell commandRuns the shell command and splices its stdout output directly into the document at this point.

cmd matching is case-insensitive. Any unrecognized cmd value is silently ignored.

The <X-NO-PRE-PROCESS> tag is not a preprocessor instruction. The preprocessor does not match it (the substring X-pre-process does not appear in X-NO-PRE-PROCESS), so the tag passes through unmodified into the compiled document as a literal XML element, which the configuration system ignores. This effectively suppresses inclusion of the named file. It appears in freeswitch.xml to exclude certain language files from the default configuration.

Inline Comment Form

The preprocessor also recognizes instructions embedded in XML comments using the <!--# prefix. The supported cmd names in this form are set, exec-set, stun-set, include, and exec. Note that env-set is not handled in the inline comment form; use the <X-PRE-PROCESS> element form instead.

<!--#set name=value-->
<!--#include "path/to/file.xml"-->
<!--#comment This text is stripped and never reaches the XML parser.-->

Any <!--#...--> block is consumed by the preprocessor before the XML parser sees the document. The #comment keyword has no special behavior beyond causing the entire comment block to be stripped; it is a conventional label for human readability.

Include Files and Partials

A file pulled in with include is not a standalone document. It is a fragment spliced into the parent at the include point. Fragments that contain more than a single element are wrapped in <include> tags so they remain well formed:

<include>
<user id="1000">
<params>
<param name="password" value="$${default_password}"/>
</params>
</user>
</include>

The <include> wrapper is consumed by the preprocessor and does not appear in the final document. This is why directory users, dialplan contexts, and SIP profiles each live in their own file yet merge into the correct section.

Preprocessor Variables

Preprocessor variables are global strings resolved during assembly. They use two dollar signs and are defined with set:

<X-PRE-PROCESS cmd="set" data="domain=example.com"/>

Reference a preprocessor variable as $${name}. The double dollar sign marks a value that is expanded once, during preprocessing, before the XML parser sees it.

This is distinct from a channel variable, which uses a single dollar sign, ${name}, and is expanded at call time on a specific channel. The distinction matters:

SyntaxResolvedScope
$${name}During configuration assemblyGlobal, same for every call
${name}At call timeThe current channel

Most global values, including paths, the default domain, and the default password, are preprocessor variables defined in vars.xml. They are documented in Chapter 4 (Variables and Core Settings).

The Top-Level Sections

After assembly the document contains five sections. Each is owned by a different part of the system.

SectionPopulated fromDocumented in
configurationautoload_configs/*.xmlThroughout Parts 2 to 7
dialplandialplan/*.xmlPart 4 (XML Dialplan)
chatplanchatplan/*.xmlText message routing
directorydirectory/*.xmlChapter 6 (User Directory)
languageslang/*/*.xmlPhrase rendering

Each file under autoload_configs/ is a configuration block named for the module it configures, for example <configuration name="sofia.conf" ...> in sofia.conf.xml. A module reads the block whose name matches the name it registers.

The Compiled Document

When the preprocessor finishes, FreeSWITCH writes the fully assembled document to freeswitch.xml.fsxml in the log directory (the path configured as log_dir, typically /var/log/freeswitch). The filename is the root config filename with .fsxml appended. This file is the exact XML the parser consumed, with every include resolved and every $${...} variable expanded. It is a read-only artifact for confirming what the running configuration looks like. Do not edit it; it is regenerated on each reloadxml and is memory mapped while FreeSWITCH runs.

Editing and Reloading

Edit the small files under autoload_configs/, dialplan/, directory/, and sip_profiles/, never the compiled document. Apply changes with:

reloadxml

reloadxml re-runs the preprocessor and reparses the document. Directory and dialplan changes take effect on the next call. Some modules cache their own configuration and need a targeted reload or rescan, noted in each module's chapter.