| Actor | Role |
|---|---|
| Controller | Think of it as the “brain” or IVR application logic. Decides what prompts to play, collects user input, branches dialogs, etc. |
| Media Server | Think of it as the “hands and ears” — actually plays audio, records voice, and collects DTMF tones. |
The communication channel between them is the Media Control Channel Framework (MCCF), which is typically SIP-negotiated and reliable (e.g., TCP).
Key idea: The controller doesn’t handle audio directly; it sends instructions, and the media server executes them.
End-to-End Workflow
Let’s follow a call from start to finish.
Step 1: Session Setup
- A caller dials in.
- The SIP server routes the call to the IVR system.
- The IVR system’s controller opens a control channel to the media server using MCCF:
- Negotiates capabilities.
- Identifies which IVR package is supported (
msc-ivr/1.0).
Conceptual view: The controller says:
“Hello media server, I want to control you using RFC 6231 IVR commands.”
Step 2: Prepare Dialog
Before playing prompts:
- Controller sends a
<prepare>message. - Includes:
- Dialog ID (unique session identifier)
- Resources: prompts (audio files), expected DTMF inputs
- Optional configuration: timeout values, max retries
Media server response: ACK or error.
- Confirms that resources are ready.
- Ensures the controller doesn’t try to play a missing file.
Why this is important: It decouples preparation from execution — avoids race conditions or missing media.
Step 3: Start the Dialog
Controller sends <start> message with the dialog ID.
- Media server begins IVR flow:
- Plays the first
<prompt>(audio or TTS). - Waits for user input if
<collect>is specified. - Can branch based on collected DTMF.
- Plays the first
Example XML snippet:
<dialog id="123">
<prompt src="welcome.wav"/>
<collect maxdigits="1" timeout="5s"/>
</dialog>- Media server reads
<prompt>→ plays audio - Media server reads
<collect>→ waits for keypress
Controller’s job: Listen to events and decide what to do next.
Step 4: Event Reporting
Whenever something happens, the media server sends events back:
| Event | What it means |
|---|---|
media-complete | A prompt finished playing |
dtmf-received | User pressed a key |
record-complete | Recording finished |
error | Something went wrong |
Controller reacts:
- If DTMF “1” → branch to sales menu
- If no input → repeat prompt or hang up
Important: Events are asynchronous. The controller must maintain a state machine for each session.
Step 5: Dialog Control and Branching
Controller can send commands mid-dialog:
- Pause: stop audio temporarily
- Resume: continue playing
- Stop: terminate dialog
- Update: change prompts dynamically
This is the magic: The IVR can adapt in real time. For example: if a user is idle, the controller can insert a new prompt without restarting the session.
Step 6: Termination
Once the interaction finishes:
- Controller sends
<terminate>with the dialog ID. - Media server:
- Stops any ongoing playback/recording
- Frees resources
- Sends final completion status
- Controller can then close the control channel or prepare for the next session.
Under the Hood: How Messages Are Structured
RFC 6231 uses XML over MCCF:
- Request Message
<prepare-dialog dialog-id="abc123">
<resource src="prompt1.wav"/>
</prepare-dialog>- Event/Response Message
<event dialog-id="abc123" name="dtmf-received">
<digit>1</digit>
</event>- Messages carry:
- Dialog ID (to tie events to a session)
- Action type (
prepare,start,collect,record) - Optional attributes (timeout, max digits, prompt source)
- Payload (audio URL, DTMF info)
Visualize this:
Caller
|
v
Media Server <----> Controller
| ^
|-- Plays prompt |-- Sends <start>/<prepare>/<terminate>
|-- Captures DTMF |-- Receives <event> notifications
|-- Records voice
Everything is message-driven, like React’s state updates — the media server is “rendering” audio based on the XML instructions, and the controller “updates state” based on events.
The Concept: DTMF (Dual-Tone Multi-Frequency)
When you press a number on a phone keypad, it doesn’t just produce a single tone. It produces two simultaneous tones — one from a row, one from a column.
How a keypad maps to tones:
| 1209 Hz | 1336 Hz | 1477 Hz | 1633 Hz | |
|---|---|---|---|---|
| 697 Hz | 1 | 2 | 3 | A |
| 770 Hz | 4 | 5 | 6 | B |
| 852 Hz | 7 | 8 | 9 | C |
| 941 Hz | * | 0 | # | D |
- Row frequency + column frequency = unique signature for each key.
- This is called DTMF signaling.
So pressing “1” sends 697 Hz + 1209 Hz together as a short sound.
How Media Server Detects It
The media server is always “listening” to the audio channel. When a <collect> instruction is active:
- Audio from the caller is sent to the media server.
- The media server passes the audio through a DTMF decoder:
Steps of Decoding
- Band-pass filtering
- Audio is split into frequency bands matching the DTMF rows and columns.
- Tone detection
- Detect which two tones are present simultaneously.
- Must ignore background noise, voice, etc.
- Mapping to digits
- Each unique combination → a keypad number.
- Event generation
- Once a valid tone is detected, the server generates a
<dtmf-received>event back to the controller with the digit.
- Once a valid tone is detected, the server generates a
Example Event
<event dialog-id="123" name="dtmf-received">
<digit>1</digit>
</event>- Controller receives this and knows the user pressed “1”.
- Logic in the controller can then decide the next step (branching to sales, etc.).
What Makes It Reliable
- Minimum tone duration: Media servers often require tones to be at least ~40–50 ms to count as valid.
- Guard time: Ensures two keypresses aren’t merged.
- Filtering voice/audio: DTMF decoders ignore human voice frequencies that might accidentally trigger a key.
Analogy: Like a Piano Detector
Think of DTMF like pressing two piano keys at once. The media server is like a program that listens to the chords and instantly says:
“Ah, that combination = note ‘1’!”