Expand description
FreeSWITCH Event Socket Library (ESL) client for Rust
This crate provides an async Rust client for FreeSWITCH’s Event Socket Library (ESL), allowing applications to connect to FreeSWITCH, execute commands, and receive events.
§Architecture
The library uses a split reader/writer design:
EslClient(Clone + Send) – send commands from any taskEslEventStream– receive events from a background reader task
§Examples
§Inbound Connection
use freeswitch_esl_tokio::{EslClient, EslError, DEFAULT_ESL_PASSWORD, DEFAULT_ESL_PORT};
#[tokio::main]
async fn main() -> Result<(), EslError> {
let (client, mut events) = EslClient::connect("localhost", DEFAULT_ESL_PORT, DEFAULT_ESL_PASSWORD).await?;
let response = client.api("status").await?;
println!("Status: {}", response.api_result()?);
Ok(())
}§Outbound Mode
In outbound mode, FreeSWITCH connects to your application via the
socket
dialplan application. You run a TCP listener and accept connections:
use freeswitch_esl_tokio::{EslClient, EslError, AppCommand, EventFormat, EventHeader};
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> Result<(), EslError> {
let listener = TcpListener::bind("0.0.0.0:8040").await
.map_err(EslError::from)?;
let (client, mut events) = EslClient::accept_outbound(&listener).await?;
// First command must be connect_session -- establishes the session
// and returns all channel variables as headers.
let channel_data = client.connect_session().await?;
// HeaderLookup trait provides typed header access via EventHeader enum
println!("Channel: {}", channel_data.header(EventHeader::ChannelName).unwrap_or("?"));
client.myevents(EventFormat::Plain).await?;
client.linger(None).await?; // keep socket open after hangup
client.resume().await?; // resume dialplan on disconnect
client.send_command(AppCommand::answer()).await?;
client.send_command(AppCommand::playback("ivr/ivr-welcome.wav")).await?;
while let Some(Ok(event)) = events.recv().await {
println!("{:?}", event.event_type());
}
Ok(())
}Configure FreeSWITCH to connect to your app:
<action application="socket" data="127.0.0.1:8040 async full"/>See docs/outbound-esl-quirks.md
for protocol details and command availability by mode.
§Command Builders
Typed builders for common API commands – no raw string assembly needed:
use std::time::Duration;
use freeswitch_esl_tokio::{Originate, Endpoint, Application};
use freeswitch_esl_tokio::commands::SofiaGateway;
let cmd = Originate::application(
Endpoint::SofiaGateway(SofiaGateway::new("my_provider", "18005551234")),
Application::simple("park"),
)
.cid_name("Outbound Call")
.cid_num("5551234")
.timeout(Duration::from_secs(30));
// Use with client.api(&cmd.to_string()) or client.bgapi(&cmd.to_string())
assert!(cmd.to_string().contains("sofia/gateway/my_provider/18005551234"));See the commands module for Originate, UuidBridge, UuidTransfer,
and other builders.
§Event Subscription
EventSubscription captures format, event types, custom subclasses, and
filters as a single reusable unit. Build one from code or deserialize from
YAML/JSON, then apply it to any connection:
use freeswitch_esl_tokio::{
EslClient, EslEventType, EventFormat, EventHeader, EventSubscription,
HeaderLookup, DEFAULT_ESL_PASSWORD, DEFAULT_ESL_PORT,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Build once, reuse on every (re)connection
let subscription = EventSubscription::new(EventFormat::Plain)
.event(EslEventType::ChannelAnswer)
.event(EslEventType::ChannelHangup)
.event(EslEventType::Heartbeat)
.custom_subclass("sofia::register")?
.filter(EventHeader::CallDirection, "inbound")?;
let (client, mut events) = EslClient::connect(
"localhost", DEFAULT_ESL_PORT, DEFAULT_ESL_PASSWORD,
).await?;
client.apply_subscription(&subscription).await?;
while let Some(Ok(event)) = events.recv().await {
if let Ok(Some(state)) = event.channel_state() {
println!("{:?}: {}", event.event_type(), state);
}
}
Ok(())
}Re-exports§
pub use app::dptools::AppCommand;pub use bgjob::BgJobResult;pub use bgjob::BgJobTracker;pub use connection::ConnectionMode;pub use connection::ConnectionStatus;pub use connection::DisconnectReason;pub use connection::EslClient;pub use connection::EslConnectOptions;pub use connection::EslEventStream;pub use error::EslError;pub use error::EslResult;
Modules§
- app
- Application execution via
sendmsg– the dptools family of commands. - bgjob
- Background job tracking for
bgapicommands. - channel
- Channel-related data types extracted from ESL event headers.
- commands
- Command string builders for
api()andbgapi(). - connection
- Connection management for ESL
- error
- Error types for FreeSWITCH ESL operations.
- event
- ESL event types and structures
- headers
- Typed event header names for FreeSWITCH ESL events.
- lookup
- Shared trait for typed header lookups from any key-value store.
- prelude
- Convenience re-exports for common types and traits.
- sofia
- Typed Sofia event subclasses and state enums.
- variables
- Channel variable types: format parsers (
ARRAY::, SIP multipart) and typed variable name enums.
Structs§
- Application
- A single dialplan application with optional arguments.
- Bridge
Dial String - Typed bridge dial string.
- Channel
Timetable - Channel timing data from FreeSWITCH’s
switch_channel_timetable_t. - Command
Builder - Builder for custom ESL commands not covered by
EslClientmethods. - EslArray
- Parses FreeSWITCH
ARRAY::item1|:item2|:item3format - EslEvent
- ESL Event structure containing headers and optional body
- EslHeaders
- A flat header store that decodes FreeSWITCH ARRAY and bracket encoding when answering typed SIP header queries.
- EslResponse
- Response from ESL command execution
- Event
Subscription - Declarative description of an ESL event subscription.
- Event
Subscription Error - Error returned when an
EventSubscriptionbuilder method receives invalid input. - Execute
Options - Options for
sendmsg executecommands. - Lossy
Value - A header whose percent-decoded value was not valid UTF-8. Carries the
unparsed on-wire value (the percent-encoded source text, always ASCII) so
the app can re-decode it (e.g. as Latin-1) or audit it instead of being
stuck with the U+FFFD-substituted string in
headers. - Lossy
Values - Header keys whose percent-decoded value contained invalid UTF-8 and was decoded lossily (U+FFFD substituted). Empty in the normal case.
- Multipart
Body - Parses
variable_sip_multipartARRAY:: format. - Multipart
Item - A single part from a SIP multipart body
- Originate
- Originate command builder:
originate <endpoint> <target> [dialplan] [context] [cid_name] [cid_num] [timeout]. - Parse
Answer State Error - Error returned when parsing an invalid answer state string.
- Parse
Call Direction Error - Error returned when parsing an invalid call direction string.
- Parse
Call State Error - Error returned when parsing an invalid call state string.
- Parse
Channel State Error - Error returned when parsing an invalid channel state string.
- Parse
Channel Variable Error - Error for an unrecognized value; displays as
unknown channel variable: <input>. - Parse
Core Media Variable Error - Error for an unrecognized value; displays as
unknown core media variable: <input>. - Parse
Dialplan Type Error - Error returned when parsing an invalid dialplan type string.
- Parse
Event Format Error - Error returned when parsing an invalid event format string.
- Parse
Event Header Error - Error for an unrecognized value; displays as
unknown event header: <input>. - Parse
Event Type Error - Error returned when parsing an invalid event type string.
- Parse
Gateway Ping Status Error - Error returned when parsing an invalid gateway ping status string.
- Parse
Gateway RegState Error - Error returned when parsing an invalid gateway reg state string.
- Parse
Group Call Order Error - Error returned when parsing an invalid group call order string.
- Parse
Hangup Cause Error - Error returned when parsing an invalid hangup cause string.
- Parse
Priority Error - Error returned when parsing an invalid priority string.
- Parse
SipUser Ping Status Error - Error returned when parsing an invalid sip user ping status string.
- Parse
Sofia Event Subclass Error - Error returned when parsing an invalid sofia event subclass string.
- Parse
Timetable Error - Error returned when a timetable header is present but not a valid
i64. - SipPassthrough
Header - A FreeSWITCH SIP passthrough header variable name.
- Sofia
Channel Name - Borrowed view of a parsed sofia channel name. No allocation.
- Uuid
Answer - Answer a channel:
uuid_answer <uuid>. - Uuid
Bridge - Bridge two channels:
uuid_bridge <uuid> <other_uuid>. - Uuid
Deflect - Deflect (redirect) a channel to a new SIP URI:
uuid_deflect <uuid> <uri>. - Uuid
GetVar - Get a channel variable:
uuid_getvar <uuid> <key>. - Uuid
Hold - Place a channel on hold or take it off hold:
uuid_hold [off] <uuid>. - Uuid
Kill - Kill a channel:
uuid_kill <uuid> [cause]. - Uuid
Send Dtmf - Send DTMF digits to a channel:
uuid_send_dtmf <uuid> <digits>. - Uuid
SetVar - Set a channel variable:
uuid_setvar <uuid> <key> <value>. - Uuid
Transfer - Transfer a channel to a new destination:
uuid_transfer <uuid> <dest> [dialplan]. - Variables
- Ordered set of channel variables with FreeSWITCH escaping.
Enums§
- Answer
State - Answer state from the
Answer-Stateheader. Wire format is lowercase. - Call
Direction - Call direction from the
Call-Directionheader. Wire format is lowercase. - Call
State - Call state from
switch_channel_callstate_t– carried in theChannel-Call-Stateheader. - Channel
State - Channel state from
switch_channel_state_t– carried in theChannel-Stateheader as a string (CS_ROUTING) and inChannel-State-Numberas an integer. - Channel
Variable - Core FreeSWITCH channel variable names (the part after the
variable_prefix). - Core
Media Variable - RTP media statistics channel variable names (the part after the
variable_prefix). - Dialplan
Type - FreeSWITCH dialplan type for originate commands.
- Endpoint
- Polymorphic endpoint wrapping all concrete types.
- EslArray
Error - Errors from
EslArray::parse. - EslCommand
- ESL command types for the wire protocol.
- EslEvent
Priority - Event priority levels matching FreeSWITCH
esl_priority_t - EslEvent
Type - FreeSWITCH event types matching the canonical order from
esl_event.handswitch_event.cEVENT_NAMES[]. - Event
Format - Event format types supported by FreeSWITCH ESL
- Event
Header - Top-level header names that appear in FreeSWITCH ESL events.
- Gateway
Ping Status - Gateway ping status from
sofia::gateway_stateevents. - Gateway
RegState - Gateway registration state from
sofia::gateway_stateevents. - Group
Call Order - Distribution order for group_call dial strings.
- Hangup
Cause - Hangup cause from
switch_cause_t(Q.850 + FreeSWITCH extensions). - Originate
Error - Errors from originate command parsing or construction.
- Originate
Target - The target of an originate command: either a dialplan extension or application(s) to execute directly.
- Reply
Status - Reply-Text classification per the ESL wire protocol.
- RtpStat
Unit - Unit of measurement for an RTP statistic channel variable.
- SipHeader
Prefix - FreeSWITCH SIP header passthrough variable prefix.
- SipUser
Ping Status - SIP user ping status from
sofia::sip_user_stateevents. - Sofia
Event Subclass - Sofia event subclass values from
mod_sofia.hMY_EVENT_*defines. - Timetable
Prefix - Header prefix identifying which call leg’s timetable to extract.
- Variables
Type - Scope for channel variables in an originate command.
Constants§
- DEFAULT_
ESL_ PASSWORD - Default FreeSWITCH ESL password (
ClueCon). - DEFAULT_
ESL_ PORT - Default FreeSWITCH ESL port for inbound connections.
- MAX_
ARRAY_ ITEMS - Maximum items accepted by
EslArray::parse.
Traits§
- Dial
String - Common interface for anything that formats as a FreeSWITCH dial string.
- Header
Lookup - Trait for looking up ESL headers and channel variables from any key-value store.
- Variable
Name - Trait for typed channel variable name enums.
Functions§
- parse_
api_ body - Parse a FreeSWITCH API response body into a result.