FreeSWITCH as a Dumb Switch: A Database-Driven, ESL-Controlled Architecture for AI Phone Platforms
A team that bolts an AI bot into the dialplan will rewrite call code when switching ASR vendors, edit XML to add extensions, drop calls during handoffs, and mismatch CDRs. This architecture keeps FreeSWITCH stable by pushing configuration into a database, routing decisions into an ESL program, and AI behind one protocol, which is the difference between a demo and a phone system you can operate.
FreeSWITCH handles only signaling, media, transcoding, and command execution in this design. All configuration moves into a database served through mod_xml_curl; routes and extensions apply on save, while gateways and ACLs need an explicit publish step. An ESL control engine parks every call first and routes it by number, schedule, and agent state, so inbound, outbound, and transfers share one state machine. Events for a single call are hashed to one worker to preserve ordering, and Redis state carries TTLs so a disconnected ESL can't leave permanent dirty data.
AI connects through a gateway that turns call audio into a unified WebSocket protocol. Vendors can integrate as full bots that bring their own VAD, ASR, LLM, and TTS, or as component adapters that the platform orchestrates. The protocol handles session start/end, PCM audio, DTMF, playback-finished events, transcripts, cancellation via uuid_break, and transfer/hangup actions. Community-edition audio streaming is store-then-play, so the recommended MVP pattern is short sentence-by-sentence playback; end-to-end latency is estimated at 1-3 seconds.
For browser agents, the platform uses SIP over WSS with SIP.js or JsSIP rather than mod_verto, temporary SIP passwords tied to the login session, and a second business WebSocket for agent state. An inbound call is assigned only when SIP registration, business connection, and idle state all hold, with screen pop before ringing. The CDR section distinguishes duration from billsec and warns that on inbound calls the customer leg's billsec includes IVR/bot/queue time. The security checklist starts with FreeSWITCH's default demo extensions 1000-1019 and password 1234, which scanners will find on a public IP.
Treating FreeSWITCH as a dumb executor is what makes the rest of the design work: once configuration and decisions leave the dialplan, changing an ASR vendor or adding an agent becomes a data or API change, not a telephony change.
Hashing every call event to one worker is a deliberate trade: it sacrifices parallelism within a call to guarantee ordering, which matters more in telephony than throughput.
The community-edition audio limitation shapes the whole AI interface: because streaming playback isn't available, the protocol optimizes for short, sentence-level audio turns and prompt cancellation rather than full-duplex conversation.
The security section is unusually concrete because FreeSWITCH's default demo users are a known attack surface; a public IP plus password 1234 means scanners can register and make paid outbound calls before operators notice.