]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_freetdm: E&M Analog fixes
authorMoises Silva <moy@sangoma.com>
Wed, 21 Aug 2013 21:54:00 +0000 (17:54 -0400)
committerMoises Silva <moy@sangoma.com>
Wed, 21 Aug 2013 22:21:02 +0000 (18:21 -0400)
* Rename option ringback-during-collect to immediate-ringback
* Allow regular ringback tone with immediate-ringback, not just a wav file
* Do not request full frame of data, just packet_len which is what we receive per IO interval
* Ignore user data when playing ringback tone

libs/freetdm/mod_freetdm/mod_freetdm.c
libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h
libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c

index 9f56d9f4543043574405fef17794a73114a52d0e..63d4cd96446f50c0fc2c25e7b7b5ff336f6f5bdb 100755 (executable)
@@ -3826,7 +3826,7 @@ static switch_status_t load_config(void)
                        char str_false[] = "false";
                        char str_empty[] = "";
                        char *answer_supervision = str_false;
-                       char *ringback_during_collect = str_false;
+                       char *immediate_ringback = str_false;
                        char *ringback_file = str_empty;
                        uint32_t span_id = 0, to = 0, max = 0, dial_timeout_int = 0;
                        ftdm_span_t *span = NULL;
@@ -3856,8 +3856,8 @@ static switch_status_t load_config(void)
                                        max_digits = val;
                                } else if (!strcasecmp(var, "answer-supervision")) {
                                        answer_supervision = val;
-                               } else if (!strcasecmp(var, "ringback-during-collect")) {
-                                       ringback_during_collect = val;
+                               } else if (!strcasecmp(var, "immediate-ringback")) {
+                                       immediate_ringback = val;
                                } else if (!strcasecmp(var, "ringback-file")) {
                                        ringback_file = val;
                                } else if (!strcasecmp(var, "enable-analog-option")) {
@@ -3913,7 +3913,7 @@ static switch_status_t load_config(void)
                        if (ftdm_configure_span(span, "analog_em", on_analog_signal,
                                                                   "tonemap", tonegroup,
                                                                   "answer_supervision", answer_supervision,
-                                                                  "ringback_during_collect", ringback_during_collect,
+                                                                  "immediate_ringback", immediate_ringback,
                                                                   "ringback_file", ringback_file,
                                                                   "digit_timeout", &to,
                                                                   "dial_timeout", &dial_timeout_int,
index fb9959d061adc0e81bc2c616c68f68c3d424ddff..121381d522df43920e83cddf00684d5098509842 100644 (file)
@@ -54,7 +54,7 @@ struct ftdm_analog_data {
        uint32_t digit_timeout;
        uint32_t dial_timeout;
        ftdm_bool_t answer_supervision;
-       ftdm_bool_t ringback_during_collect;
+       ftdm_bool_t immediate_ringback;
        char ringback_file[512];
 };
 
index 66a791ebdbeb1878379e5e9052f98a3b0db0ded2..c387d5a52836f2254ae8c4e5e6f741f430a9f3ae 100644 (file)
@@ -171,6 +171,19 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_em_outgoing_call)
        return FTDM_FAIL;
 }
 
+static ftdm_status_t ftdm_analog_em_sig_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size)
+{
+       ftdm_analog_em_data_t *analog_data = ftdmchan->span->signal_data;
+       if (ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA
+           && analog_data->immediate_ringback
+           && ftdmchan->call_data) {
+               /* DO NOT USE ftdmchan->call_data, as is a dummy non-null pointer */
+               /* ringback is being played in the analog thread, ignore user data for now */
+               return FTDM_BREAK;
+       }
+       return FTDM_SUCCESS;
+}
+
 /**
  * \brief Starts an EM span thread (monitor)
  * \param span Span to monitor
@@ -237,7 +250,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span)
        ftdm_analog_em_data_t *analog_data = NULL;
        const char *tonemap = "us";
        const char *ringback_file = "";
-       ftdm_bool_t ringback_during_collect = FTDM_FALSE;
+       ftdm_bool_t immediate_ringback = FTDM_FALSE;
        uint32_t digit_timeout = 2000;
        uint32_t max_dialstr = 11;
        uint32_t dial_timeout = 0;
@@ -262,11 +275,11 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span)
                                break;
                        }
                        tonemap = val;
-               } else if (!strcasecmp(var, "ringback_during_collect")) {
+               } else if (!strcasecmp(var, "immediate_ringback")) {
                        if (!(val = va_arg(ap, char *))) {
                                break;
                        }
-                       ringback_during_collect = ftdm_true(val);
+                       immediate_ringback = ftdm_true(val);
                } else if (!strcasecmp(var, "ringback_file")) {
                        if (!(val = va_arg(ap, char *))) {
                                break;
@@ -310,6 +323,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span)
 
        span->start = ftdm_analog_em_start;
        span->stop = ftdm_analog_em_stop;
+       span->sig_write = ftdm_analog_em_sig_write;
        analog_data->digit_timeout = digit_timeout;
        analog_data->max_dialstr = max_dialstr;
        analog_data->dial_timeout = dial_timeout;
@@ -321,8 +335,8 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span)
        span->get_channel_sig_status = analog_em_get_channel_sig_status;
        span->get_span_sig_status = analog_em_get_span_sig_status;
        ftdm_span_load_tones(span, tonemap);
-       if (ringback_during_collect) {
-               analog_data->ringback_during_collect = FTDM_TRUE;
+       if (immediate_ringback || !ftdm_strlen_zero(ringback_file)) {
+               analog_data->immediate_ringback = FTDM_TRUE;
                ftdm_set_string(analog_data->ringback_file, ringback_file);
        }
 
@@ -414,7 +428,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
        assert(interval != 0);
        ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IO Interval: %u\n", interval);
 
-       if (analog_data->ringback_during_collect && !ftdm_strlen_zero(analog_data->ringback_file)) {
+       if (analog_data->immediate_ringback && !ftdm_strlen_zero(analog_data->ringback_file)) {
                ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Using ringback file '%s'\n", analog_data->ringback_file);
                ringback_f = fopen(analog_data->ringback_file, "rb");
                if (!ringback_f) {
@@ -607,9 +621,11 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
                                break;
                        case FTDM_CHANNEL_STATE_RINGING:
                                {
-                                       ftdm_buffer_zero(dt_buffer);
-                                       teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
-                                       indicate = 1;
+                                       if (!analog_data->immediate_ringback) {
+                                               ftdm_buffer_zero(dt_buffer);
+                                               teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
+                                               indicate = 1;
+                                       }
                                }
                                break;
                        case FTDM_CHANNEL_STATE_BUSY:
@@ -673,7 +689,8 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
                        continue;
                }
 
-               len = sizeof(frame);
+               /* Do not try to read more than the proper interval size */
+               len = ftdmchan->packet_len * 2;
                if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) {
                        ftdm_log(FTDM_LOG_ERROR, "READ ERROR [%s]\n", ftdmchan->last_error);
                        goto done;
@@ -684,6 +701,11 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
                        continue;
                }
 
+               if (len >= (sizeof(frame)/2)) {
+                       ftdm_log(FTDM_LOG_CRIT, "Ignoring big read of %zd bytes!\n", len);
+                       continue;
+               }
+
                if (ftdmchan->detected_tones[0]) {
                        int i;
                        
@@ -719,7 +741,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
                        continue;
                }
 
-               if (analog_data->ringback_during_collect && ringback_f &&
+               if (analog_data->immediate_ringback &&
                    (ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT ||
                     ftdmchan->state == FTDM_CHANNEL_STATE_RING ||
                     ftdmchan->state == FTDM_CHANNEL_STATE_RINGING ||
@@ -727,6 +749,10 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
                     ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA
                     )) {
                        indicate = 1;
+                       if (!ringback_f) {
+                               ftdm_buffer_zero(dt_buffer);
+                               teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
+                       }
                }
                
                if (!indicate) {
@@ -774,7 +800,12 @@ read_try:
                        }
                }
 
+               /* we must lock the channel and make sure we let our own generated audio thru (ftdmchan->call_data is tested in the ftdm_analog_em_sig_write handler)*/
+               ftdm_channel_lock(ftdmchan);
+               ftdmchan->call_data = (void *)0xFF; /* ugh! */
                ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen);
+               ftdmchan->call_data = NULL;
+               ftdm_channel_unlock(ftdmchan);
        }
 
  done: