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 =
{
/*.pool =*/ NULL,
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_echocancel_call_end(chan);
+
if (chan->state != FTDM_CHANNEL_STATE_DOWN) {
if (chan->state == FTDM_CHANNEL_STATE_HANGUP) {
/* make user's life easier, and just ignore double hangup requests */
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
{
ftdm_status_t status = FTDM_FAIL;
-
+
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_set_echocancel_call_begin(ftdmchan);
+
ftdm_channel_lock(ftdmchan);
if (ftdmchan->span->outgoing_call) {
break;
case FTDM_SIGEVENT_START:
- /* 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
- * is needed at all?
- * */
- ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
+ {
+ ftdm_set_echocancel_call_begin(sigmsg->channel);
+
+ /* 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
+ * is needed at all?
+ * */
+ ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
+ }
break;
case FTDM_SIGEVENT_STOP:
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
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
break;
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);
if (err) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed");
+ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed");
return FTDM_FAIL;
}
}
break;
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);
if (err) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed");
+ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed");
return FTDM_FAIL;
}
}