Call Forward All / No Answer / Follow Me (no confirm) connect but no audio

apv04

New Member
Aug 13, 2024
7
0
1
34

FusionPBX 5.5 - Call Forward All / No Answer / Follow Me (no confirm) connect but no audio​

Hi everyone,

I'm troubleshooting an interesting issue and would appreciate any ideas.

Environment​

  • FusionPBX 5.5 (freshly upgraded from 5.2)
  • FreeSWITCH 1.10.11
  • Debian 12
  • IP authenticated SIP trunk to Sýn (Vodafone Iceland) using a Cirpack SBC
  • No NAT between FusionPBX and the carrier

Problem​

Calls connect successfully, but there is no audio in either direction when using:

  • Call Forward All
  • Call Forward No Answer
  • Follow Me (Confirmation disabled)
The SIP signaling completes successfully and the call remains connected until one side hangs up.

What works​

  • Incoming calls have two-way audio.
  • Outgoing calls have two-way audio.
  • Internal extension calls have two-way audio.
  • Ring groups work.
  • Follow Me with "Confirm Call" enabled works perfectly.
  • If I assign the DID to an extension, set the ring timeout to 0 seconds, and then forward the call, it also works perfectly.
The only scenarios that fail are the ones that perform an immediate forward.

What I've already checked​

  • Upgraded FusionPBX from 5.2 to 5.5.
  • Database Schema, App Defaults, Menu Defaults and Permission Defaults completed successfully.
  • Media Mode tested with:
    • Normal
    • Bypass Media
    • Proxy Media
      (No difference.)
  • RTP/SIP addresses are correct.
  • Codec negotiation is PCMA on both legs.
  • Calls are bridged successfully.
  • SIP signaling appears normal.
<span>show channels</span> during the failing call shows:

  • Inbound leg reaches <span>CS_EXECUTE</span> with <span>bridge</span>.
  • Outbound leg reaches <span>CS_EXCHANGE_MEDIA</span>.
  • Both legs negotiate PCMA.
  • The bridge stays up normally.

Observation​

The most interesting part is this:

  • Immediate forwarding → Connected, no audio.
  • 0-second extension timeout, then forward → Audio works.
  • Follow Me with "Press 1 to accept" → Audio works.
This makes me think there is a difference in the media establishment or bridge path used by immediate forwarding versus forwarding after the call has first been presented to an extension or IVR.

Has anyone seen this before with FusionPBX/FreeSWITCH, particularly when using an IP-authenticated SIP trunk or Cirpack SBC?

Any ideas on what to investigate next would be greatly appreciated.
 
Could you please share a SIP capture (.pcap file) and the FreeSWITCH logs? Maybe I can help you troubleshoot the issue.
I'm using Dinstar and Pro SBC here, and everything runs normally.
 
Could you please share a SIP capture (.pcap file) and the FreeSWITCH logs? Maybe I can help you troubleshoot the issue.
I'm using Dinstar and Pro SBC here, and everything runs normally.
Thanks!

I attached a ZIP file with the pcap and relevant log inside.

From what I can see, FreeSWITCH successfully:

  • receives the inbound INVITE
  • detects Forward All
  • transfers to the destination
  • creates the outbound gateway call
  • receives 180 Ringing and 200 OK
  • enters CS_EXCHANGE_MEDIA
  • starts RTP
There are no obvious FreeSWITCH errors.

However, when the call is answered there is complete silence and the caller hangs up after ~10 seconds.

The interesting part is that:
  • Direct outbound calls work.
  • Internal extension → Forward All works.
  • Follow Me with confirmation works.
  • Extension timeout (0 sec) → Forward All works.
  • Only an external inbound call that immediately forwards fails.
 

Attachments

Here's the analysis and fix plan:
Root Cause Analysis
Problem: External inbound call → Forward All enabled → transfer() to external destination → zero RTP both directions.
Why it happens: The dialplan 515_call-forward-all.xml uses transfer() which reuses the same SIP channel and sends it back through CS_ROUTING. On an external carrier SIP dialog, this resets the media state machine. The A-leg (carrier) had its SDP consumed during the first dialplan pass, but after transfer(), the channel never properly transitions back to CS_EXCHANGE_MEDIA with RTP flowing. The B-leg (gateway) negotiates fine, the bridge "looks" connected (both sides answer), but the kernel-level RTP sessions inside FreeSWITCH never activate.
Why internal calls work: When both legs are local SIP registrations (FS controls both endpoints), the media bridge initialization after transfer() works fine because FS has complete control over both endpoints' media sessions.
Why Follow Me works: Follow Me uses bridge() in Lua (520_follow-me-destinations.xml → app.lua follow_me → session:execute("bridge", ...)). The A-leg stays in CS_EXCHANGE_MEDIA throughout — no channel state machine reset.
Fix Plan
Phase 1: Verify the pcap (quick check)
Recapture with tcpdump -i any -s 0 -w /tmp/forward_all_test.pcap port 5060 or port 5065 or port 27792 or port 22872 to confirm RTP truly isn't flowing (the existing pcap may use a port filter).
Phase 2: Apply fix to 515_call-forward-all.xml
Primary fix: Enable answer before transfer for the inbound case. This establishes the media path (sends 200 OK to carrier) before the channel re-enters routing.
File: /var/www/fusionpbx/app/dialplans/resources/switch/conf/dialplan/515_call-forward-all.xml
Change line 16 from:
<action application="answer" data="" enabled="false"/>
to:
<action application="answer" data="" enabled="true"/>
Secondary change: Enable the sip_h_Diversion header (line 20) so the carrier sees proper diversion info:
<action application="set" data="sip_h_Diversion=<sip:${caller_id_number}@${domain_name}>;reason=unconditional" enabled="true"/>
Phase 3: Update DB + reload
1. Save the changes (they're in the FusionPBX source tree)
2. Update the DB record: v_dialplans.dialplan_xml must be synced OR the change needs to be written through v_dialplan_details
3. Clear cache: rm -rf /var/cache/fusionpbx/*
4. Reload: event_socket api reloadxml
5. Test
Fallback (if answer+transfer doesn't work)
Replace transfer() with a bridge() to loopback/${forward_all_destination}/${domain_name}, keeping the A-leg alive (same pattern as Follow Me's enterprise strategy). This is architecturally cleaner but requires constructing the correct bridge dial string with proper hangup_after_bridge=true / continue_on_fail=true.