Analysis of the FreeTDM/OpenZAP BRI PTMP “Problem”
Collecting everything here before posting to the relevant places…
The Problem:
People reporting audio distortion on the BRI PTMP (S0) bus after placing calls with FreeTDM (or other unexpected behaviour like devices crashing, acting odd etc.). Those distortions vanish after stopping or restarting FreeSWITCH. (NOTE: I/O module is Zaptel/DAHDI)
The Cause (short):
1. FreeTDM opens the B-Channel immediately, on outgoing and incoming calls, even if no media has been signalled by the NT (via PROGRESS IE or any other means) (this can cause other devices on the bus to crash).
2. FreeTDM (or the signalling module) does not completely close the B-Channel on hangup, leaving the B-Channel open and transmitting frames (this is what causes the distortions on the bus, after the first call).
The Cause (long):
For outgoing channels:
1. mod_freetdm:channel_outgoing_channel() opens a channel using this piece of code (line 1283 ff.):
if (group_id >= 0) { status = ftdm_channel_open_by_group(group_id, direction, &caller_data, &ftdmchan); } else if (chan_id) { status = ftdm_channel_open(span_id, chan_id, &ftdmchan); } else { status = ftdm_channel_open_by_span(span_id, direction, &caller_data, &ftdmchan); }each of these functions opens a selected channel using the “channel->fio->open()” callback of the channel’s I/O module, causing the channel to be “physically” openened. In the case of Zaptel/DAHDI (B-)channels this means (the) AUDIO_MODE is enabled, causing audio frames to be transmitted and received from the ISDN bus.
For TE-mode, this behaviour is wrong, the selected channel has not been acknowledged by the NT and may still change after the SETUP message. For NT-mode, opening the B-Channel at this stage is wrong too, even if the channel does not change later. The earliest possible state to open the channel here is, for inbound calls, after the SETUP ACK message for overlap-dial (inband dialtone).
NOTE: This is something the signalling module has to control ({oz,ft}mod_isdn does that already)!
2. The signalling module (e.g. current ftmod_libpri) does not call ftmod_close_channel() on hangup to completely close the channel.
On hangup, the signalling module _MUST_ call ftmod_channel_close() to “physically” close the B-Channel, for Zaptel/DAHDI channels this means disabling AUDIO_MODE to stop transmitting frames on B-Channels and to avoid distortions on the S0 bus and confusing other devices.
This requires the I/O module implements the neccessary code to close a channel in its close() callback.
NOTE: ftmod_zt does that since commit c1517e99d1
[RFD] The solution:
Don’t open channels in mod_freetdm:channel_outgoing_channel() (or any other place that does it too early), reserve and assign the channel instead. Let the signalling module handle opening/closing of channels (or, as a fallback, let the FreeTDM core open the channel upon entering states that really need to have the channel open, e.g. PROGRESS_MEDIA).
