freetdm: improved logic to enable/disable EC on call start/stop

- MFC-R2 requires tone signaling that gets screwed sometimes
           if the EC is enabled during call setup.
         - EC is now enabled only when switching to a state requiring
         media (UP and PROGRESS_MEDIA)
         - The logic is aware of EC persist option in Wanpipe
         - Improved logging in ftmod_wanpipe to print EC state on startup
This commit is contained in:
Moises Silva
2011-01-18 11:28:37 -05:00
parent 99cab144b5
commit 1db40e60e4
6 changed files with 70 additions and 41 deletions

View File

@@ -404,39 +404,39 @@ static __inline__ void ftdm_std_free(void *pool, void *ptr)
free(ptr);
}
static void ftdm_set_echocancel_call_begin(ftdm_channel_t *chan)
FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan)
{
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) {
if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) {
/* If the ec is disabled on idle, we need to enable it unless is a digital call */
if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) {
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec for call in channel state %s\n", ftdm_channel_state2str(chan->state));
ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
}
} else {
/* If the ec is enabled on idle, we do nothing unless is a digital call that needs it disabled */
if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec for digital call in channel state %s\n", ftdm_channel_state2str(chan->state));
ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
}
}
}
}
static void ftdm_set_echocancel_call_end(ftdm_channel_t *chan)
FT_DECLARE(void) ftdm_set_echocancel_call_end(ftdm_channel_t *chan)
{
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) {
if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) {
if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) {
ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
}
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec on call end in channel state %s\n", ftdm_channel_state2str(chan->state));
ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
} else {
if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
}
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec back on call end in channel state %s\n", ftdm_channel_state2str(chan->state));
ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
}
}
}
FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler =
{
/*.pool =*/ NULL,
@@ -5548,25 +5548,44 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
case FTDM_SIGEVENT_PROGRESS_MEDIA:
{
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Enabling echo cancellation on progress media\n");
ftdm_set_echocancel_call_begin(sigmsg->channel);
/* test signaling module compliance */
if (sigmsg->channel->state != FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_PROGRESS_MEDIA sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state));
}
}
break;
case FTDM_SIGEVENT_UP:
{
/* test signaling module compliance */
if (sigmsg->channel->state != FTDM_CHANNEL_STATE_UP) {
ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_UP sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state));
}
}
break;
case FTDM_SIGEVENT_STOP:
if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) {
/* this happens for FXS devices which blindly send SIGEVENT_STOP, we should fix it there ... */
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n");
goto done;
}
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
goto done;
}
if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n");
/* if the user does not move us to hangup in 2 seconds, we will do it ourselves */
ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer);
{
/* TODO: we could test for compliance here and check the state is FTDM_CHANNEL_STATE_TERMINATING
* but several modules need to be updated first */
/* if the call was never started, do not send SIGEVENT_STOP
this happens for FXS devices in ftmod_analog which blindly send SIGEVENT_STOP, we should fix it there ... */
if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n");
goto done;
}
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
goto done;
}
if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n");
/* if the user does not move us to hangup in 2 seconds, we will do it ourselves */
ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer);
}
}
break;