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("[::]: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(event) = events.try_next().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(event) = events.try_next().await? {
if let 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::AuthMethod;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 connection::EventOverflow;pub use error::CommandFailure;pub use error::EslError;pub use error::EslResult;pub use sip_header;pub use sip_uri;
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.
- lossy_
values - Types for tracking event headers whose values contained invalid UTF-8.
- mock
- Scripted FreeSWITCH peer for integration tests (
test-utilfeature). - prelude
- Convenience re-exports for common types and traits.
- sdp
- Converts an SDP offer into a FreeSWITCH codec string and models the codec-string grammar.
- 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.
- Bridge
Dial String Display - Renders a
BridgeDialStringfor one parser revision. Returned byBridgeDialString::display_with. - Channel
Dump Options - Options for
parse_channel_dump_with_options. - Channel
Timetable - Channel timing data from FreeSWITCH’s
switch_channel_timetable_t. - Command
Builder - Builder for custom ESL commands not covered by
EslClientmethods. - Dial
String Target - Where a dial string is headed: the command carrying it, the block-parser revision of the switch reading it, and the split cutting that command’s arguments.
- Endpoint
Display - Renders an
Endpointfor one target. Returned byEndpoint::display_for. - 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
On - An application for an
execute_on_*hook such asChannelVariable::ExecuteOnOriginate. - Execute
Options - Options for
sendmsg executecommands. - Freeswitch
Version - A FreeSWITCH version in its short form,
1.10.12or1.10.13-dev. - History
Info - Parsed History-Info header value (RFC 7044).
- History
Info Entry - A single entry from a History-Info header (RFC 7044).
- History
Info Reason - Parsed RFC 3326 Reason header value extracted from a History-Info URI.
- Invalid
Header Name - Error returned when a raw header name is empty or carries a wire terminator.
- 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]. - Originate
Display - Renders an
Originatefor one parser revision. Returned byOriginate::display_with. - Parse
Answer State Error - Error returned when parsing an invalid answer state string.
- Parse
Block Parse Error - A
BlockParsename this crate does not know. The rejected name is the field. - 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 (<n> bytes). The rejected input is the field. - Parse
Core Media Variable Error - Error for an unrecognized value; displays as
unknown core media variable (<n> bytes). The rejected input is the field. - 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 (<n> bytes). The rejected input is the field. - 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
Hold Action Error - Error returned when parsing an invalid hold action string.
- Parse
LogLevel Error - Error returned when parsing an invalid log level string.
- Parse
Mute Action Error - Error returned when parsing an invalid mute action string.
- Parse
Priority Error - Error returned when parsing an invalid priority string.
- Parse
SipHeader Addr Error - Error returned when parsing a SIP header address value fails.
- Parse
SipHeader Error - Error for an unrecognized value; displays as
unknown SIP header (<n> bytes). The rejected input is the field. - Parse
SipPassthrough Error - Error returned when parsing an unrecognized passthrough header variable name.
- 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. - Secret
- Wraps a string so
Debugprints[REDACTED]instead of the value. - SipGeolocation
- Parsed SIP Geolocation header value (RFC 6442).
- SipHeader
Addr - Parsed SIP
name-addr(RFC 3261 §25.1) with header-level parameters. - SipPassthrough
Header - A FreeSWITCH SIP passthrough header variable name.
- Sofia
Channel Name - Borrowed view of a parsed sofia channel name. No allocation.
- UriInfo
- Parsed
<absoluteURI> *(SEMI generic-param)header value. - UriInfo
Entry - One
<uri>;key=value;key=valueentry from a URI-info-style header. - 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.
- Variables
Display - Renders a
Variablesfor one target. Returned byVariables::display_for.
Enums§
- Answer
State - Answer state from the
Answer-Stateheader. Wire format is lowercase. - Block
Parse - Which revision of the switch’s bracket-block parser a dial string is rendered for.
- 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. - Carried
Header - Relationship between a
SofiaVariableand the SIP header behind it. - 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). - Dial
String Carrier - Which command carries a dial string, and therefore how deeply its variable values must be escaped.
- Dialplan
Type - FreeSWITCH dialplan type for originate commands.
- Endpoint
- Polymorphic endpoint wrapping all concrete types.
- Endpoint
Field Fault - Why an endpoint field cannot reach the switch as written, whatever the escaping.
- 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.
- Execute
OnFault - What the switch does with an
execute_on_*application name or argument that keeps it from reaching the application as written. - 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). - History
Info Error - Errors from parsing a History-Info header value (RFC 7044).
- Invalid
Argv Separator - Why a
DialStringTargettakes no argument separator. - LogLevel
- Argument of the ESL
logcommand, which sets the level ofLOGevents the connection receives. - Multipart
Body Error - Errors from
MultipartBody::parse. - 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.
- Parse
Freeswitch Version Error - Why a string is not a FreeSWITCH short-form version. Names the part at fault, never the input.
- Parse
Header Error - The union a caller reaches when
?-ing several typedHeaderLookupaccessors into one error type. - Reply
Status - Reply-Text classification per the ESL wire protocol.
- RtpStat
Unit - Unit of measurement for an RTP statistic channel variable.
- SipGeolocation
Ref - A reference extracted from a SIP Geolocation header (RFC 6442).
- SipHeader
- Standard SIP header names with canonical wire casing.
- 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
Field - One timetable header, named rather than positional.
- Timetable
Prefix - Header prefix identifying which call leg’s timetable to extract.
- Unvouched
Version - A FreeSWITCH version
BlockParse::for_versioncannot vouch for. - UriInfo
Error - Errors from parsing a URI-info-style header value.
- 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. - UNDEF_
VALUE - What
switch_event_serializewrites in place of an empty value, and whatuuid_getvaranswers for a variable that is not set. - VARIABLE_
PREFIX - Header-name prefix a channel variable carries in an event.
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.
- SipHeader
Lookup - Trait for looking up standard SIP headers from any key-value store.
- Variable
Name - Trait for typed channel variable name enums.
Functions§
- case_
alias_ key - Return a lowercase case-alias for
keywhen case-insensitive aliasing applies. - channel_
driver - Endpoint module a channel name belongs to: the segment before the first
/(sofia,loopback,null, …). - extract_
header - Extract all occurrences of a header from a raw SIP message.
- normalize_
header_ key - Normalize a header key to its canonical form for case-insensitive storage.
- parse_
api_ body - Parse a FreeSWITCH API response body into a result.
- parse_
channel_ dump - Parse a
uuid_dump <uuid>body into theCHANNEL_DATAevent it is. - parse_
channel_ dump_ with_ options parse_channel_dumpwith control over lossy UTF-8 decoding.