From 4f04ce0518b7eda665b56c1ee47bd0563ffa6e2f Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 4 Jun 2007 22:10:42 +0000 Subject: [PATCH] merge patch from MODAPP-12, thanks Bret. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5257 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_ivr.h | 35 +++++- src/include/switch_types.h | 3 + .../applications/mod_dptools/mod_dptools.c | 49 ++++++-- src/switch_ivr_async.c | 117 ++++++++++++++++++ 4 files changed, 191 insertions(+), 13 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index dac4da79ef..3247a81e02 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -25,7 +25,7 @@ * * Anthony Minessale II * Neal Horman - * + * Bret McDanel * * switch_ivr.h -- IVR Library * @@ -208,10 +208,43 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t */ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_record_session(switch_core_session_t *session, char *file); +/*! + \brief Start looking for DTMF inband + \param session the session to start looking + \return SWITCH_STATUS_SUCCESS if all is well +*/ SWITCH_DECLARE(switch_status_t) switch_ivr_inband_dtmf_session(switch_core_session_t *session); + +/*! + \brief Stop looking for DTMF inband + \param session the session to stop looking + \return SWITCH_STATUS_SUCCESS if all is well +*/ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_inband_dtmf_session(switch_core_session_t *session); + +/*! + \brief XXX DESCRIBE ME + \param session the session to act on + \return SWITCH_STATUS_SUCCESS if all is well - maybe more XXX FIXME +*/ SWITCH_DECLARE(void) switch_ivr_session_echo(switch_core_session_t *session); +/*! + \brief Stop looking for FAX CNG + \param session the session to stop looking + \return SWITCH_STATUS_SUCCESS if all is well +*/ +SWITCH_DECLARE(switch_status_t) switch_ivr_stop_fax_detect_session(switch_core_session_t *session); + +/*! + \brief Start looking for FAX CNG + \param session the session to start looking + \return SWITCH_STATUS_SUCCESS if all is well +*/ +SWITCH_DECLARE(switch_status_t) switch_ivr_fax_detect_session(switch_core_session_t *session); + + + /*! \brief play a file from the disk to the session \param session the session to play the file too diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 61019a2d56..8de15d21e2 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -24,6 +24,7 @@ * Contributor(s): * * Anthony Minessale II + * Bret McDanel * * switch_types.h -- Data Types * @@ -832,6 +833,7 @@ typedef enum { SWITCH_EVENT_CODEC - Codec Change SWITCH_EVENT_BACKGROUND_JOB - Background Job SWITCH_EVENT_DETECTED_SPEECH - Detected Speech + SWITCH_EVENT_DETECTED_FAX - Detected Fax CNG Tone SWITCH_EVENT_PRIVATE_COMMAND - A private command event SWITCH_EVENT_HEARTBEAT - Machine is alive SWITCH_EVENT_TRAP - Error Trap @@ -881,6 +883,7 @@ typedef enum { SWITCH_EVENT_CODEC, SWITCH_EVENT_BACKGROUND_JOB, SWITCH_EVENT_DETECTED_SPEECH, + SWITCH_EVENT_DETECTED_FAX, SWITCH_EVENT_PRIVATE_COMMAND, SWITCH_EVENT_HEARTBEAT, SWITCH_EVENT_TRAP, diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index e5d65ea5c9..cc37516c9c 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -27,6 +27,7 @@ * Ken Rice, Asteria Solutions Group, Inc * Michael Murdock * Neal Horman + * Bret McDanel * * mod_dptools.c -- Raw Audio File Streaming Application Module * @@ -651,25 +652,28 @@ static void ivr_application_function(switch_core_session_t *session, char *data) static void dtm_session_function(switch_core_session_t *session, char *data) { - switch_channel_t *channel; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - switch_ivr_inband_dtmf_session(session); } static void stop_dtmf_session_function(switch_core_session_t *session, char *data) { - switch_channel_t *channel; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - switch_ivr_stop_inband_dtmf_session(session); } +static void fax_detect_session_function(switch_core_session_t *session, char *data) +{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabling fax detection\n"); + switch_ivr_fax_detect_session(session); +} + +static void stop_fax_detect_session_function(switch_core_session_t *session, char *data) +{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Disabling fax detection\n"); + switch_ivr_stop_fax_detect_session(session); +} + + static const switch_api_interface_t strepoch_api_interface = { /*.interface_name */ "strepoch", /*.desc */ "Convert a date string into epoch time", @@ -702,6 +706,27 @@ static const switch_api_interface_t presence_api_interface = { /*.next */ &dptools_api_interface }; + +static const switch_application_interface_t fax_detect_application_interface = { + /*.interface_name */ "fax_detect", + /*.application_function */ fax_detect_session_function, + /* long_desc */ "Detect fax send tone", + /* short_desc */ "Detect faxes", + /* syntax */ "", + /* flags */ SAF_NONE, + /*.next */ NULL +}; + +static const switch_application_interface_t stop_fax_detect_application_interface = { + /*.interface_name */ "stop_fax_detect", + /*.application_function */ stop_fax_detect_session_function, + /* long_desc */ "Stop detecting fax send tones", + /* short_desc */ "stop detecting faxes", + /* syntax */ "", + /* flags */ SAF_NONE, + /* next */ &fax_detect_application_interface +}; + static const switch_application_interface_t dtmf_application_interface = { /*.interface_name */ "start_dtmf", /*.application_function */ dtm_session_function, @@ -709,7 +734,7 @@ static const switch_application_interface_t dtmf_application_interface = { /* short_desc */ "Detect dtmf", /* syntax */ "", /* flags */ SAF_NONE, - NULL + /* next */ &stop_fax_detect_application_interface }; static const switch_application_interface_t stop_dtmf_application_interface = { @@ -717,7 +742,7 @@ static const switch_application_interface_t stop_dtmf_application_interface = { /*.application_function */ stop_dtmf_session_function, /* long_desc */ "Stop detecting inband dtmf.", /* short_desc */ "stop inband dtmf.", - /* syntax */ "", + /* syntax */ "", /* flags */ SAF_NONE, &dtmf_application_interface }; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 5a4ee5a7ab..e081667e8b 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -25,6 +25,7 @@ * * Anthony Minessale II * Michael Jerris + * Bret McDanel * * switch_ivr_async.c -- IVR Library (async operations) * @@ -324,6 +325,122 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_inband_dtmf_session(switch_core_sessi return SWITCH_STATUS_SUCCESS; } + +typedef struct { + switch_core_session_t *session; + teletone_multi_tone_t mt; +} switch_fax_detect_t; + +static switch_bool_t fax_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +{ + switch_fax_detect_t *pvt = (switch_fax_detect_t *) user_data; + uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; + switch_frame_t frame = { 0 }; + // switch_channel_t *channel = switch_core_session_get_channel(pvt->session); + + // assert(channel != NULL); + frame.data = data; + frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + + switch (type) { + case SWITCH_ABC_TYPE_INIT: + break; + case SWITCH_ABC_TYPE_CLOSE: + break; + case SWITCH_ABC_TYPE_READ: + if (switch_core_media_bug_read(bug, &frame) == SWITCH_STATUS_SUCCESS) { + if(teletone_multi_tone_detect(&pvt->mt, frame.data, frame.samples)) { + switch_event_t *event; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FAX CNG DETECTED\n"); + + if (switch_event_create(&event, SWITCH_EVENT_DETECTED_FAX) == SWITCH_STATUS_SUCCESS) { + switch_event_t *dup; + + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "fax", "detected"); + + if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) { + switch_event_fire(&dup); + } + + + if (switch_core_session_queue_event(pvt->session, &event) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Event queue failed!\n"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true"); + switch_event_fire(&event); + } + } + } + } + break; + case SWITCH_ABC_TYPE_WRITE: + default: + break; + } + return SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_stop_fax_detect_session(switch_core_session_t *session) +{ + switch_media_bug_t *bug; + switch_channel_t *channel = switch_core_session_get_channel(session); + + assert(channel != NULL); + if ((bug = switch_channel_get_private(channel, "fax"))) { + switch_channel_set_private(channel, "fax", NULL); + switch_core_media_bug_remove(session, &bug); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; + +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_fax_detect_session(switch_core_session_t *session) +{ + switch_channel_t *channel; + switch_codec_t *read_codec; + switch_media_bug_t *bug; + switch_status_t status; + switch_fax_detect_t *pvt; + teletone_tone_map_t *map; + int i; + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + + read_codec = switch_core_session_get_read_codec(session); + assert(read_codec != NULL); + + if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) { + return SWITCH_STATUS_MEMERR; + } + + if (!(map = switch_core_session_alloc(session, sizeof(*map)))) { + return SWITCH_STATUS_MEMERR; + } + + for(i=0;ifreqs[i] = 1100.0; + } + pvt->mt.sample_rate = read_codec->implementation->samples_per_second; + pvt->session = session; + + teletone_multi_tone_init(&pvt->mt, map); + + switch_channel_answer(channel); + + if ((status = switch_core_media_bug_add(session, fax_detect_callback, pvt, 0, SMBF_READ_STREAM, &bug)) != SWITCH_STATUS_SUCCESS) { + return status; + } + + switch_channel_set_private(channel, "fax", bug); + + return SWITCH_STATUS_SUCCESS; +} + + struct speech_thread_handle { switch_core_session_t *session; switch_asr_handle_t *ah;