Support for enabling/disabling HWEC based on call bearer_cap

This commit is contained in:
David Yat Sin 2010-09-28 13:55:46 -04:00
parent ba5a250cc8
commit 27096d4512
3 changed files with 86 additions and 8 deletions

View File

@ -244,6 +244,39 @@ static __inline__ void ftdm_std_free(void *pool, void *ptr)
free(ptr); free(ptr);
} }
static 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 (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) {
ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
}
} else {
if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
}
}
}
}
static 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);
}
} else {
if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
}
}
}
}
FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler = FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler =
{ {
/*.pool =*/ NULL, /*.pool =*/ NULL,
@ -2008,6 +2041,9 @@ done:
static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line) static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line)
{ {
ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP); ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP);
ftdm_set_echocancel_call_end(chan);
if (chan->state != FTDM_CHANNEL_STATE_DOWN) { if (chan->state != FTDM_CHANNEL_STATE_DOWN) {
if (chan->state == FTDM_CHANNEL_STATE_HANGUP) { if (chan->state == FTDM_CHANNEL_STATE_HANGUP) {
/* make user's life easier, and just ignore double hangup requests */ /* make user's life easier, and just ignore double hangup requests */
@ -2177,6 +2213,8 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
ftdm_assert_return(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), FTDM_FAIL, "Call place, but outbound flag not set\n"); ftdm_assert_return(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), FTDM_FAIL, "Call place, but outbound flag not set\n");
ftdm_set_echocancel_call_begin(ftdmchan);
ftdm_channel_lock(ftdmchan); ftdm_channel_lock(ftdmchan);
if (ftdmchan->span->outgoing_call) { if (ftdmchan->span->outgoing_call) {
@ -4740,11 +4778,15 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
break; break;
case FTDM_SIGEVENT_START: case FTDM_SIGEVENT_START:
{
ftdm_set_echocancel_call_begin(sigmsg->channel);
/* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
* doing it during SIGEVENT_START, but now that flags are private they can't, wonder if * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
* is needed at all? * is needed at all?
* */ * */
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD); ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
}
break; break;
case FTDM_SIGEVENT_STOP: case FTDM_SIGEVENT_STOP:

View File

@ -280,6 +280,25 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT); ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
dtmf = "hardware"; dtmf = "hardware";
} }
err = sangoma_tdm_get_hw_ec(chan->sockfd, &tdm_api);
if (err > 0) {
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC);
}
#ifdef WP_API_FEATURE_HWEC_PERSIST
err = sangoma_tdm_get_hwec_persist_status(chan->sockfd, &tdm_api);
if (err == 0) {
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE);
}
#else
if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
ftdm_log(FTDM_LOG_WARNING, "WP_API_FEATURE_HWEC_PERSIST feature is not supported \
with your version of libsangoma, you should update your Wanpipe drivers\n");
}
#endif
} }
#ifdef LIBSANGOMA_VERSION #ifdef LIBSANGOMA_VERSION
@ -598,6 +617,14 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
break; break;
case FTDM_COMMAND_ENABLE_ECHOCANCEL: case FTDM_COMMAND_ENABLE_ECHOCANCEL:
{ {
#ifdef WP_API_FEATURE_EC_CHAN_STAT
err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api);
if (err > 0) {
/* Hardware echo canceller already enabled */
err = 0;
break;
}
#endif
err=sangoma_tdm_enable_hwec(ftdmchan->sockfd, &tdm_api); err=sangoma_tdm_enable_hwec(ftdmchan->sockfd, &tdm_api);
if (err) { if (err) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed"); snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed");
@ -607,6 +634,13 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
break; break;
case FTDM_COMMAND_DISABLE_ECHOCANCEL: case FTDM_COMMAND_DISABLE_ECHOCANCEL:
{ {
#ifdef WP_API_FEATURE_EC_CHAN_STAT
err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api);
if (!err) {
/* Hardware echo canceller already disabled */
break;
}
#endif
err=sangoma_tdm_disable_hwec(ftdmchan->sockfd, &tdm_api); err=sangoma_tdm_disable_hwec(ftdmchan->sockfd, &tdm_api);
if (err) { if (err) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed"); snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed");

View File

@ -191,6 +191,8 @@ typedef enum {
FTDM_CHANNEL_FEATURE_CALLERID = (1 << 4), /*!< Channel can detect caller id (read-only) */ FTDM_CHANNEL_FEATURE_CALLERID = (1 << 4), /*!< Channel can detect caller id (read-only) */
FTDM_CHANNEL_FEATURE_PROGRESS = (1 << 5), /*!< Channel can detect inband progress (read-only) */ FTDM_CHANNEL_FEATURE_PROGRESS = (1 << 5), /*!< Channel can detect inband progress (read-only) */
FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */ FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */
FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */
FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */
} ftdm_channel_feature_t; } ftdm_channel_feature_t;
typedef enum { typedef enum {