diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 9f56d9f454..63d4cd9644 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -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, diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h b/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h index fb9959d061..121381d522 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h @@ -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]; }; diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 66a791ebdb..c387d5a528 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -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: