]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: Added support for DTMF generation to be performed in the signaling modules...
authorMoises Silva <moy@sangoma.com>
Sun, 13 Jul 2014 06:15:38 +0000 (02:15 -0400)
committerMoises Silva <moy@sangoma.com>
Sun, 13 Jul 2014 06:16:58 +0000 (02:16 -0400)
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c
libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
libs/freetdm/src/include/private/ftdm_core.h
libs/freetdm/src/include/private/ftdm_types.h

index 58fa9983902ba844a845a3476a6bb515cbb0e009..650ef359d456deb059fc0713850cb9b18fb07b30 100644 (file)
@@ -59,6 +59,8 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
 #define FTDM_HALF_DTMF_PAUSE 500
 #define FTDM_FULL_DTMF_PAUSE 1000
 
+#define FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan) (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_DTMF_DETECTION))
+
 ftdm_time_t time_last_throttle_log = 0;
 ftdm_time_t time_current_throttle_log = 0;
 
@@ -105,6 +107,7 @@ static val_str_t channel_flag_strs[] =  {
        { "blocking",  FTDM_CHANNEL_BLOCKING},
        { "media",  FTDM_CHANNEL_DIGITAL_MEDIA},
        { "native-sigbridge",  FTDM_CHANNEL_NATIVE_SIGBRIDGE},
+       { "sig-dtmf-detection", FTDM_CHANNEL_SIG_DTMF_DETECTION},
        { "invalid",  FTDM_CHANNEL_MAX_FLAG},
 };
 
@@ -3370,7 +3373,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
                {
                        /* if they don't have thier own, use ours */
                        if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
-                               if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
+                               if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan)) {
                                        teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
                                        ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
                                        ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
@@ -3383,9 +3386,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
        case FTDM_COMMAND_DISABLE_DTMF_DETECT:
                {
                        if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
-                               if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
-                                                               teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
-                                                               ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
+                               if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan)) {
+                                       teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
+                                       ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
                                        ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
                                        ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n");
                                        GOTO_STATUS(done, FTDM_SUCCESS);
@@ -3461,8 +3464,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
                break;
        case FTDM_COMMAND_SEND_DTMF:
                {
-                       if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) {
-                               char *digits = FTDM_COMMAND_OBJ_CHAR_P;
+                       char *digits = FTDM_COMMAND_OBJ_CHAR_P;
+                       if (ftdmchan->span->sig_send_dtmf) {
+                               status = ftdmchan->span->sig_send_dtmf(ftdmchan, digits);
+                               GOTO_STATUS(done, status);
+                       } else if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) {
                                
                                if ((status = ftdmchan_activate_dtmf_buffer(ftdmchan)) != FTDM_SUCCESS) {
                                        GOTO_STATUS(done, status);
@@ -3773,7 +3779,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
 
        ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s (debug = %d)\n", dtmf, ftdmchan->dtmfdbg.enabled);
 
-       if (ftdmchan->span->sig_dtmf && (ftdmchan->span->sig_dtmf(ftdmchan, dtmf) == FTDM_BREAK)) {
+       if (ftdmchan->span->sig_queue_dtmf && (ftdmchan->span->sig_queue_dtmf(ftdmchan, dtmf) == FTDM_BREAK)) {
                /* Signalling module wants to absorb this DTMF event */
                return FTDM_SUCCESS;
        }
@@ -4212,7 +4218,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
                        }
                }
 
-               if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT) && !ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
+               if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan) && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT)) {
                        teletone_hit_type_t hit;
                        char digit_char;
                        uint32_t dur;
index 689156919fc136ab53eabfd29cd2f443a1f8d4d6..c89e3ae5202c8b8a4b8c2d0346b1b9c416ef6a91 100755 (executable)
@@ -879,6 +879,30 @@ static ftdm_status_t init_wat_lib(void)
        return FTDM_SUCCESS;
 }
 
+WAT_AT_CMD_RESPONSE_FUNC(on_dtmf_sent)
+{
+       ftdm_channel_t *ftdmchan = obj;
+       ftdm_span_t *span = ftdmchan->span;
+       int i = 0;
+
+       if (success == WAT_TRUE) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "DTMF successfully transmitted on span %s\n", span->name);
+       } else {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Command execution failed on span %s. Err: %s\n", span->name, error);
+       }
+
+       for (i = 0; tokens[i]; i++) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "%s\n", tokens[i]);
+       }
+       return i;
+}
+
+static ftdm_status_t ftdm_gsm_send_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf)
+{
+       ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data;
+       wat_send_dtmf(ftdmchan->span->span_id, gsm_data->call_id, dtmf, on_dtmf_sent, ftdmchan);
+       return FTDM_SUCCESS;
+}
 
 static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
 {
@@ -956,9 +980,6 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
        gsm_data->dchan = dchan;
        gsm_data->bchan = bchan;
 
-       //sprintf(gsm_data->dchan->chan_name, "%s\t\n", "GSM dchan");
-       //sprintf(gsm_data->bchan->chan_name, "%s\r\n", "GSM bchan");
-
        for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
                var = ftdm_parameters[paramindex].var;
                val = ftdm_parameters[paramindex].val;
@@ -984,7 +1005,6 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
                                span_config.hardware_dtmf = WAT_FALSE;
                        }
                        ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with hardware dtmf %s\n", span->name, val);
-                       ftdm_channel_set_feature(gsm_data->bchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
                } else {
                        ftdm_log(FTDM_LOG_ERROR, "Ignoring unknown GSM parameter '%s'", var);
                }
@@ -995,6 +1015,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
        span->stop = ftdm_gsm_stop;
        span->sig_read = NULL;
        span->sig_write = NULL;
+       if (span_config.hardware_dtmf == WAT_TRUE) {
+               span->sig_send_dtmf = ftdm_gsm_send_dtmf;
+               ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SIG_DTMF_DETECTION);
+       }
 
        span->signal_cb = sig_cb;
        span->signal_type = FTDM_SIGTYPE_GSM;
index c8b520783ebf4e1d6705233b462511ef5cf77577..ed0a99dc958a5e07a6696b0b44be0860bb52aacf 100644 (file)
@@ -1304,7 +1304,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
        span->indicate = ftdm_sangoma_isdn_indicate;
        span->channel_request = NULL;
        span->signal_cb = sig_cb;
-       span->sig_dtmf = ftdm_sangoma_isdn_dtmf;
+       span->sig_queue_dtmf = ftdm_sangoma_isdn_dtmf;
        span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status;
        span->set_channel_sig_status = ftdm_sangoma_isdn_set_chan_sig_status;
        span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status;
index 728390dd542d6a13239c9ed017ccd8be72c4a997..f4a1fe4e293bf4dc45a2266b8d5be0e5c860be0a 100644 (file)
@@ -513,7 +513,8 @@ struct ftdm_span {
        ftdm_span_stop_t stop;
        ftdm_channel_sig_read_t sig_read;
        ftdm_channel_sig_write_t sig_write;
-       ftdm_channel_sig_dtmf_t sig_dtmf;
+       ftdm_channel_sig_dtmf_t sig_queue_dtmf;
+       ftdm_channel_sig_dtmf_t sig_send_dtmf;
        ftdm_channel_state_processor_t state_processor; /*!< This guy is called whenever state processing is required */
        void *io_data; /*!< Private I/O data per span. Do not touch unless you are an I/O module */
        char *type;
index 9e8aebe1579f2b960e5e7ab41623cee72ca7f01f..ee3406ea31b61d0da431f24ba6891bb8e57851c4 100755 (executable)
@@ -268,9 +268,11 @@ typedef enum {
 #define FTDM_CHANNEL_DIGITAL_MEDIA   (1ULL << 36)
 /*!< Native signaling bridge is enabled */
 #define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37)
+/*!< Native signaling DTMF detection */
+#define FTDM_CHANNEL_SIG_DTMF_DETECTION (1ULL << 38)
 
 /*!< This no more flags after this flag */
-#define FTDM_CHANNEL_MAX_FLAG       (1ULL << 38)
+#define FTDM_CHANNEL_MAX_FLAG       (1ULL << 39)
 /*!<When adding a new flag, need to update ftdm_io.c:channel_flag_strs */
 
 #include "ftdm_state.h"