]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Support for enabling/disabling HWEC based on call bearer_cap
authorDavid Yat Sin <dyatsin@sangoma.com>
Tue, 28 Sep 2010 17:55:46 +0000 (13:55 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Tue, 28 Sep 2010 19:25:47 +0000 (15:25 -0400)
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
libs/freetdm/src/include/private/ftdm_types.h

index 79d55c4d166bb54680f70e8f82b12a07a3abf68b..df139c548e4e1f11025751850b4aa80e4c7dff1e 100644 (file)
@@ -244,6 +244,39 @@ static __inline__ void ftdm_std_free(void *pool, void *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 = 
 {
        /*.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)
 {
        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 */
@@ -2173,10 +2209,12 @@ done:
 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) {
@@ -4740,11 +4778,15 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
                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:
index be99f94aff5545e5db02c9f4c9ea72993de0e335..23463e90880cf34e46bdb00846362e73887dbb54 100644 (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);
                                        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
@@ -598,18 +617,33 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
                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;
                        }
                }
index d0d19e5a558eff3575a095630149274631903a19..016fd31c431d715fdfc22aa280e042fa8054f8ca 100644 (file)
@@ -191,6 +191,8 @@ typedef enum {
        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_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;
 
 typedef enum {