Skip to main content

mod_erlang_event — Erlang Event Interface

mod_erlang_event connects FreeSWITCH to an Erlang cluster using the native Erlang distribution protocol (via the ei C library). It registers FreeSWITCH as an Erlang c-node, accepts inbound connections from remote Erlang nodes, and can also initiate outbound connections to those nodes. Once connected, Erlang processes can subscribe to FreeSWITCH events, receive log output, execute API commands, and take full control of individual calls.

Reach for this module when your call-processing logic is written in Erlang or Elixir and you want to exchange structured Erlang terms with FreeSWITCH rather than parsing plain-text ESL or JSON. It sits in src/mod/event_handlers alongside mod_event_socket and serves the same general purpose but over the binary Erlang wire protocol.

Loading the Module

The module name is mod_erlang_event. It is not loaded by default in the vanilla configuration — the entry in conf/vanilla/autoload_configs/modules.conf.xml is commented out:

<!-- <load module="mod_erlang_event"/> -->

To activate it, uncomment that line (or add it) and restart FreeSWITCH, or load it at runtime:

freeswitch@> load mod_erlang_event

Building the module requires the Erlang/OTP erl_interface / ei development headers (see Dependencies).

Configuration: erlang_event.conf.xml

The module reads conf/autoload_configs/erlang_event.conf.xml on load. All parameters live inside a single <settings> block.

ParameterPurposeAccepted ValuesDefault
listen-ipIP address to listen on for inbound Erlang node connectionsIPv4/IPv6 address string0.0.0.0
listen-portTCP port to listen on1–655358031
nodenameShort name or full node name for the FreeSWITCH c-node (e.g. freeswitch or freeswitch@host.example.com)stringfreeswitch
cookieErlang distribution magic cookie used for authenticationstringClueCon (or $HOME/.erlang.cookie if that file exists)
cookie-filePath to a file containing the cookie (alternative to cookie)absolute file path
shortnameUse short node names (-sname style)true / falsetrue
apply-inbound-aclACL list name to restrict which IPs may connect; may be repeated up to 100 timesACL name string— (no restriction)
encodingWire encoding for string values in Erlang termsstring / binarystring
compat-relRequest OTP back-compat mode for connecting to older releases (value must be ≥ 7)integer0 (disabled)
max-event-bulkMaximum events to dequeue and send per listener loop iterationpositive integer1
max-log-bulkMaximum log lines to dequeue and send per listener loop iterationpositive integer1
stop-on-bind-errorAbort module startup if the listen socket cannot be boundtrue / falsefalse

Example (trimmed from the shipped erlang_event.conf.xml):

<configuration name="erlang_event.conf" description="Erlang Socket Client">
<settings>
<param name="listen-ip" value="0.0.0.0"/>
<param name="listen-port" value="8031"/>
<param name="nodename" value="freeswitch"/>
<param name="cookie" value="ClueCon"/>
<param name="shortname" value="true"/>
<!--<param name="apply-inbound-acl" value="lan"/>-->
<!--<param name="encoding" value="string"/>-->
<!--<param name="compat-rel" value="12"/> -->
</settings>
</configuration>

Dialplan Applications

ApplicationPurposeArguments
erlangPark the current call and yield control to an Erlang process on a named node<registered-name-or-module:function> <node@host>
erlang_sendmsgSend a one-shot message to a registered process on a named node without transferring call control<registered-name> <node@host> <message>

erlang

Connects the current session to an Erlang process running on node@host. The module looks for an existing listener to that node; if none exists it opens an outbound connection. There are two addressing forms:

  • Registered nameerlang_outbound_function sends an initial {call, <channel-data>} message to the registered process and then delivers subsequent events as {call_event, <event>} tuples. When the call ends a {call_hangup, <uuid>} message is sent.
  • Module:function — the module calls Module:Function(Ref) via RPC to obtain a pid. Use Module:! to instead send a {get_pid, UUID, Ref, Self} message to the registered name Module and wait for the pid reply.

After attaching the session the call is placed in a parked state (switch_ivr_park) so the Erlang process drives the call.

<action application="erlang" data="my_call_handler mynode@192.168.1.10"/>
<action application="erlang" data="myapp:start mynode@192.168.1.10"/>

erlang_sendmsg

Sends a {freeswitch_sendmsg, Message} tuple to a registered process. Does not park the call or transfer control. Useful for notifications.

<action application="erlang_sendmsg" data="logger mynode@192.168.1.10 call_started"/>

API Commands

The module registers a single erlang API command with several subcommands.

CommandPurposeSyntax
erlang listenersList all active Erlang node connections and their statisticserlang listeners
erlang sessions <node>List active outbound call sessions attached to a specific nodeerlang sessions <node@host>
erlang bindingsList active XML section bindings registered by Erlang processeserlang bindings
erlang handlersList event and custom-event subscriptions for each listenererlang handlers
erlang debug <on|off>Enable or disable verbose debug logging for XML fetch responseserlang debug on

fs_cli examples:

freeswitch@> erlang listeners
freeswitch@> erlang sessions mynode@192.168.1.10
freeswitch@> erlang bindings
freeswitch@> erlang handlers
freeswitch@> erlang debug on

Erlang Protocol Messages

Connected Erlang processes communicate by sending Erlang terms (tuples and atoms) directly to the FreeSWITCH c-node. The following messages are recognized (received from Erlang nodes):

Atom messages (sent as bare atoms):

AtomEffect
register_event_handlerRegister the sending pid as the global event receiver for this connection
register_log_handlerRegister the sending pid as the log receiver for this connection
noeventsCancel all event subscriptions and flush the event queue
nologCancel log delivery and flush the log queue
session_noeventsCancel event subscriptions for the session owned by the sending pid
getpidReply with {ok, Pid} — the FreeSWITCH c-node's own pid
linkLink the FreeSWITCH c-node to the sending pid (used for debugging/liveness); no reply is sent
exitClose the connection from this node

Tuple messages (first element is the command atom):

Tuple tagPurpose
{event, EventName, ...}Subscribe the listener to one or more event types
{nixevent, EventName, ...}Unsubscribe from one or more event types
{setevent, EventName, ...}Atomically replace the current event subscription set
{session_event, EventName, ...}Subscribe a per-session pid to event types
{session_nixevent, EventName, ...}Unsubscribe a per-session pid from event types
{session_setevent, EventName, ...}Atomically replace a per-session event subscription set
{filter, "Header Value", ...}Add or delete event header filters
{set_log_level, Level}Set the minimum log level delivered to this connection
{api, Command, Args}Execute a FreeSWITCH API command synchronously; reply is {ok, Output} or {error, Reason}
{bgapi, Command, Args}Execute a FreeSWITCH API command in a background thread; reply is {ok, UUID}, result delivered as {bgok, UUID, Output} or {bgerror, UUID, Reason}
{sendevent, EventName, [{Key, Value}, ...]}Fire a FreeSWITCH event into the event system
{sendmsg, UUID, [{Key, Value}, ...]}Queue a SWITCH_EVENT_SEND_MESSAGE private event for a session
{bind, Section}Register this pid as the XML fetch handler for config, directory, dialplan, phrases, or chatplan
{handlecall, UUID}Attach the sending pid to an existing session to receive its events
{handlecall, RegName, UUID}Attach a registered process to an existing session
{fetch_reply, UUID, XMLString}Respond to an outstanding XML fetch request from {bind, ...}
{rex, {Ref, Pid}}RPC reply (the response to an ei_rpc_to call); routed to the pending session / {Ref, Pid} handler

Events delivered to subscribed Erlang pids are encoded as Erlang terms tagged event. Per-session events are wrapped as {call_event, Event}. On call end, {call_hangup, UUID} is sent. Log lines are delivered as {log, [{level,N},{text_channel,N},{file,F},{func,Fn},{line,L},{data,D},{user_data,U}]}.

Dependencies

mod_erlang_event links against the Erlang ei (erl_interface) C library, which ships with Erlang/OTP but is not present on most systems by default. Install the erlang-dev (Debian/Ubuntu) or erlang-devel (RHEL/CentOS) package, or provide the OTP source tree, before building FreeSWITCH with this module enabled. The epmd daemon (Erlang Port Mapper Daemon) must also be reachable at runtime; the module attempts to start it automatically via epmd -daemon if it is in $PATH.

See also

Source: src/mod/event_handlers/mod_erlang_event, conf/vanilla/autoload_configs/erlang_event.conf.xml