mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-05-16 21:19:33 +00:00
add switch_ivr_dmachine async digit parser to core
This commit is contained in:
parent
094d8f9599
commit
7f3319dc11
@ -842,6 +842,28 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sound_test(switch_core_session_t *ses
|
|||||||
SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname);
|
SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname);
|
||||||
SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid);
|
SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
|
||||||
|
switch_memory_pool_t *pool,
|
||||||
|
uint32_t digit_timeout, uint32_t input_timeout);
|
||||||
|
|
||||||
|
SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine);
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
|
||||||
|
const char *digits,
|
||||||
|
int32_t key,
|
||||||
|
switch_ivr_dmachine_callback_t callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear(switch_ivr_dmachine_t *dmachine);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p);
|
||||||
|
SWITCH_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(switch_ivr_dmachine_t *dmachine);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
SWITCH_END_EXTERN_C
|
SWITCH_END_EXTERN_C
|
||||||
|
@ -833,6 +833,7 @@ typedef enum {
|
|||||||
SWITCH_STATUS_NOUNLOAD,
|
SWITCH_STATUS_NOUNLOAD,
|
||||||
SWITCH_STATUS_IGNORE,
|
SWITCH_STATUS_IGNORE,
|
||||||
SWITCH_STATUS_TOO_SMALL,
|
SWITCH_STATUS_TOO_SMALL,
|
||||||
|
SWITCH_STATUS_FOUND,
|
||||||
SWITCH_STATUS_NOT_INITALIZED
|
SWITCH_STATUS_NOT_INITALIZED
|
||||||
} switch_status_t;
|
} switch_status_t;
|
||||||
|
|
||||||
@ -1684,12 +1685,27 @@ typedef switch_status_t (*switch_input_callback_function_t) (switch_core_session
|
|||||||
switch_input_type_t input_type, void *buf, unsigned int buflen);
|
switch_input_type_t input_type, void *buf, unsigned int buflen);
|
||||||
typedef switch_status_t (*switch_read_frame_callback_function_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
typedef switch_status_t (*switch_read_frame_callback_function_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
||||||
typedef struct switch_say_interface switch_say_interface_t;
|
typedef struct switch_say_interface switch_say_interface_t;
|
||||||
|
|
||||||
|
struct switch_ivr_dmachine;
|
||||||
|
typedef struct switch_ivr_dmachine switch_ivr_dmachine_t;
|
||||||
|
|
||||||
|
struct switch_ivr_dmachine_match {
|
||||||
|
switch_ivr_dmachine_t *dmachine;
|
||||||
|
const char *match_digits;
|
||||||
|
int32_t match_key;
|
||||||
|
void *user_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct switch_ivr_dmachine_match switch_ivr_dmachine_match_t;
|
||||||
|
typedef switch_status_t (*switch_ivr_dmachine_callback_t) (switch_ivr_dmachine_match_t *match);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
switch_input_callback_function_t input_callback;
|
switch_input_callback_function_t input_callback;
|
||||||
void *buf;
|
void *buf;
|
||||||
uint32_t buflen;
|
uint32_t buflen;
|
||||||
switch_read_frame_callback_function_t read_frame_callback;
|
switch_read_frame_callback_function_t read_frame_callback;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
|
switch_ivr_dmachine_t *dmachine;
|
||||||
} switch_input_args_t;
|
} switch_input_args_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -507,19 +507,19 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session
|
|||||||
args.buflen = sizeof(buf);
|
args.buflen = sizeof(buf);
|
||||||
|
|
||||||
if (switch_ivr_play_file(session, NULL, cd->list[cd->index], &args) != SWITCH_STATUS_SUCCESS) {
|
if (switch_ivr_play_file(session, NULL, cd->list[cd->index], &args) != SWITCH_STATUS_SUCCESS) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match_key(caller_exit_key, *buf)) {
|
if (match_key(caller_exit_key, *buf)) {
|
||||||
cd->abort = 1;
|
cd->abort = 1;
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_BREAK;
|
||||||
}
|
}
|
||||||
cd->next = switch_epoch_time_now(NULL) + cd->freq;
|
cd->next = switch_epoch_time_now(NULL) + cd->freq;
|
||||||
cd->index++;
|
cd->index++;
|
||||||
}
|
}
|
||||||
} else if (cd->orbit_timeout && switch_epoch_time_now(NULL) >= cd->orbit_timeout) {
|
} else if (cd->orbit_timeout && switch_epoch_time_now(NULL) >= cd->orbit_timeout) {
|
||||||
cd->do_orbit = 1;
|
cd->do_orbit = 1;
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
@ -540,7 +540,7 @@ static switch_status_t consumer_read_frame_callback(switch_core_session_t *sessi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (total) {
|
if (total) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -224,7 +224,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
|
|||||||
switch_ivr_parse_all_events(session);
|
switch_ivr_parse_all_events(session);
|
||||||
|
|
||||||
|
|
||||||
if (args && (args->input_callback || args->buf || args->buflen)) {
|
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
|
||||||
switch_dtmf_t dtmf;
|
switch_dtmf_t dtmf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -237,7 +237,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch_channel_dequeue_dtmf(channel, &dtmf);
|
switch_channel_dequeue_dtmf(channel, &dtmf);
|
||||||
if (args->input_callback) {
|
|
||||||
|
if (args->dmachine) {
|
||||||
|
char ds[2] = {dtmf.digit, '\0'};
|
||||||
|
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (args->input_callback) {
|
||||||
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
||||||
} else {
|
} else {
|
||||||
switch_copy_string((char *) args->buf, (void *) &dtmf, args->buflen);
|
switch_copy_string((char *) args->buf, (void *) &dtmf, args->buflen);
|
||||||
@ -947,8 +953,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args && args->dmachine) {
|
||||||
|
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (read_frame && args && (args->read_frame_callback)) {
|
if (read_frame && args && (args->read_frame_callback)) {
|
||||||
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
|
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,281 @@
|
|||||||
#include <speex/speex_preprocess.h>
|
#include <speex/speex_preprocess.h>
|
||||||
#include <speex/speex_echo.h>
|
#include <speex/speex_echo.h>
|
||||||
|
|
||||||
|
struct switch_ivr_dmachine_binding {
|
||||||
|
char *digits;
|
||||||
|
int32_t key;
|
||||||
|
switch_ivr_dmachine_callback_t callback;
|
||||||
|
switch_byte_t is_regex;
|
||||||
|
void *user_data;
|
||||||
|
struct switch_ivr_dmachine_binding *next;
|
||||||
|
};
|
||||||
|
typedef struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t;
|
||||||
|
|
||||||
|
#define DM_MAX_DIGIT_LEN 512
|
||||||
|
|
||||||
|
struct switch_ivr_dmachine {
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
switch_byte_t my_pool;
|
||||||
|
uint32_t digit_timeout_ms;
|
||||||
|
uint32_t input_timeout_ms;
|
||||||
|
switch_ivr_dmachine_binding_t *binding_list;
|
||||||
|
switch_ivr_dmachine_binding_t *tail;
|
||||||
|
switch_ivr_dmachine_binding_t *last_matching_binding;
|
||||||
|
switch_ivr_dmachine_match_t match;
|
||||||
|
char digits[DM_MAX_DIGIT_LEN];
|
||||||
|
char last_matching_digits[DM_MAX_DIGIT_LEN];
|
||||||
|
uint32_t cur_digit_len;
|
||||||
|
uint32_t max_digit_len;
|
||||||
|
switch_time_t last_digit_time;
|
||||||
|
switch_byte_t is_match;
|
||||||
|
};
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
|
||||||
|
switch_memory_pool_t *pool,
|
||||||
|
uint32_t digit_timeout_ms, uint32_t input_timeout_ms)
|
||||||
|
{
|
||||||
|
switch_byte_t my_pool = !!pool;
|
||||||
|
switch_ivr_dmachine_t *dmachine;
|
||||||
|
|
||||||
|
if (digit_timeout_ms < 1 || input_timeout_ms < 1) return SWITCH_STATUS_FALSE;
|
||||||
|
|
||||||
|
if (!pool) {
|
||||||
|
switch_core_new_memory_pool(&pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
dmachine = switch_core_alloc(pool, sizeof(*dmachine));
|
||||||
|
dmachine->pool = pool;
|
||||||
|
dmachine->my_pool = my_pool;
|
||||||
|
dmachine->digit_timeout_ms = digit_timeout_ms;
|
||||||
|
dmachine->input_timeout_ms = input_timeout_ms;
|
||||||
|
dmachine->match.dmachine = dmachine;
|
||||||
|
*dmachine_p = dmachine;
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine)
|
||||||
|
{
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
|
||||||
|
if (!(dmachine && *dmachine)) return;
|
||||||
|
|
||||||
|
pool = (*dmachine)->pool;
|
||||||
|
|
||||||
|
if ((*dmachine)->my_pool) {
|
||||||
|
switch_core_destroy_memory_pool(&pool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
|
||||||
|
const char *digits,
|
||||||
|
int32_t key,
|
||||||
|
switch_ivr_dmachine_callback_t callback,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
switch_ivr_dmachine_binding_t *binding;
|
||||||
|
switch_size_t len;
|
||||||
|
|
||||||
|
if (strlen(digits) > DM_MAX_DIGIT_LEN -1) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding = switch_core_alloc(dmachine->pool, sizeof(*binding));
|
||||||
|
if (*digits == '~') {
|
||||||
|
binding->is_regex = 1;
|
||||||
|
digits++;
|
||||||
|
}
|
||||||
|
binding->key = key;
|
||||||
|
binding->digits = switch_core_strdup(dmachine->pool, digits);
|
||||||
|
binding->callback = callback;
|
||||||
|
binding->user_data = user_data;
|
||||||
|
|
||||||
|
if (dmachine->tail) {
|
||||||
|
dmachine->tail->next = binding;
|
||||||
|
} else {
|
||||||
|
dmachine->binding_list = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmachine->tail = binding;
|
||||||
|
|
||||||
|
len = strlen(digits);
|
||||||
|
|
||||||
|
if (binding->is_regex && dmachine->max_digit_len != DM_MAX_DIGIT_LEN -1) {
|
||||||
|
dmachine->max_digit_len = DM_MAX_DIGIT_LEN -1;
|
||||||
|
} else if (len > dmachine->max_digit_len) {
|
||||||
|
dmachine->max_digit_len = (uint32_t) len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding->is_regex) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "binding regex: %s key: %.4d callback: %p data: %p\n",
|
||||||
|
digits, key, (void *)(intptr_t) callback, user_data);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "binding digits: %4s key: %.4d callback: %p data: %p\n",
|
||||||
|
digits, key, (void *)(intptr_t) callback, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DM_MATCH_NONE,
|
||||||
|
DM_MATCH_EXACT,
|
||||||
|
DM_MATCH_PARTIAL,
|
||||||
|
DM_MATCH_BOTH
|
||||||
|
} dm_match_t;
|
||||||
|
|
||||||
|
|
||||||
|
static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachine, switch_bool_t is_timeout)
|
||||||
|
{
|
||||||
|
dm_match_t best = DM_MATCH_NONE;
|
||||||
|
switch_ivr_dmachine_binding_t *bp, *exact_bp = NULL;
|
||||||
|
int exact_count = 0, partial_count = 0, both_count = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (!dmachine->cur_digit_len) goto end;
|
||||||
|
|
||||||
|
for(bp = dmachine->binding_list; bp; bp = bp->next) {
|
||||||
|
|
||||||
|
if (bp->is_regex) {
|
||||||
|
switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
|
||||||
|
|
||||||
|
if (r_status == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (is_timeout) {
|
||||||
|
best = DM_MATCH_EXACT;
|
||||||
|
exact_count++;
|
||||||
|
exact_bp = bp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
best = DM_MATCH_PARTIAL;
|
||||||
|
partial_count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!exact_bp && !strcmp(bp->digits, dmachine->digits)) {
|
||||||
|
exact_bp = bp;
|
||||||
|
best = DM_MATCH_EXACT;
|
||||||
|
exact_count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits))) {
|
||||||
|
if (best == DM_MATCH_EXACT) {
|
||||||
|
if (is_timeout) {
|
||||||
|
best = DM_MATCH_EXACT;
|
||||||
|
exact_count++;
|
||||||
|
exact_bp = bp;
|
||||||
|
} else {
|
||||||
|
best = DM_MATCH_BOTH;
|
||||||
|
both_count++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
best = DM_MATCH_PARTIAL;
|
||||||
|
partial_count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
if (!both_count && exact_bp) {
|
||||||
|
dmachine->last_matching_binding = exact_bp;
|
||||||
|
switch_set_string(dmachine->last_matching_digits, dmachine->digits);
|
||||||
|
best = DM_MATCH_EXACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return best;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static switch_bool_t switch_ivr_dmachine_check_timeout(switch_ivr_dmachine_t *dmachine)
|
||||||
|
{
|
||||||
|
switch_time_t now = switch_time_now();
|
||||||
|
uint32_t timeout = dmachine->cur_digit_len ? dmachine->digit_timeout_ms : dmachine->input_timeout_ms;
|
||||||
|
|
||||||
|
if ((uint32_t)((now - dmachine->last_digit_time) / 1000) > timeout) {
|
||||||
|
return SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(switch_ivr_dmachine_t *dmachine)
|
||||||
|
{
|
||||||
|
if (dmachine->is_match) {
|
||||||
|
dmachine->is_match = 0;
|
||||||
|
return &dmachine->match;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
|
||||||
|
{
|
||||||
|
switch_bool_t is_timeout = switch_ivr_dmachine_check_timeout(dmachine);
|
||||||
|
dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout);
|
||||||
|
switch_status_t r;
|
||||||
|
|
||||||
|
if (!dmachine->last_digit_time) {
|
||||||
|
r = SWITCH_STATUS_SUCCESS;
|
||||||
|
} else if (dmachine->cur_digit_len > dmachine->max_digit_len) {
|
||||||
|
r = SWITCH_STATUS_FALSE;
|
||||||
|
} else if (is_match == DM_MATCH_EXACT || (is_match == DM_MATCH_BOTH && is_timeout)) {
|
||||||
|
r = SWITCH_STATUS_FOUND;
|
||||||
|
|
||||||
|
dmachine->match.match_digits = dmachine->last_matching_digits;
|
||||||
|
dmachine->match.match_key = dmachine->last_matching_binding->key;
|
||||||
|
dmachine->match.user_data = dmachine->last_matching_binding->user_data;
|
||||||
|
|
||||||
|
if (dmachine->last_matching_binding->callback) {
|
||||||
|
dmachine->last_matching_binding->callback(&dmachine->match);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_p) {
|
||||||
|
*match_p = &dmachine->match;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmachine->is_match = 1;
|
||||||
|
} else if (is_timeout) {
|
||||||
|
r = SWITCH_STATUS_TIMEOUT;
|
||||||
|
} else if (dmachine->cur_digit_len == dmachine->max_digit_len) {
|
||||||
|
r = SWITCH_STATUS_NOTFOUND;
|
||||||
|
} else {
|
||||||
|
r = SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_ivr_dmachine_clear(dmachine);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
|
||||||
|
{
|
||||||
|
if (strlen(digits) + strlen(dmachine->digits) > dmachine->max_digit_len) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncat(dmachine->digits, digits, dmachine->max_digit_len);
|
||||||
|
dmachine->cur_digit_len = strlen(dmachine->digits);
|
||||||
|
dmachine->last_digit_time = switch_time_now();
|
||||||
|
|
||||||
|
return switch_ivr_dmachine_ping(dmachine, match);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear(switch_ivr_dmachine_t *dmachine)
|
||||||
|
{
|
||||||
|
memset(dmachine->digits, 0, sizeof(dmachine->digits));
|
||||||
|
dmachine->cur_digit_len = 0;
|
||||||
|
dmachine->last_digit_time = 0;
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||||
struct echo_helper {
|
struct echo_helper {
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
|
@ -493,7 +493,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
|||||||
fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
|
fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p)) {
|
if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p))) {
|
||||||
file_flags |= SWITCH_FILE_WRITE_APPEND;
|
file_flags |= SWITCH_FILE_WRITE_APPEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,18 +613,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args && (args->input_callback || args->buf || args->buflen)) {
|
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
|
||||||
/*
|
/*
|
||||||
dtmf handler function you can hook up to be executed when a digit is dialed during playback
|
dtmf handler function you can hook up to be executed when a digit is dialed during playback
|
||||||
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
||||||
*/
|
*/
|
||||||
if (switch_channel_has_dtmf(channel)) {
|
if (switch_channel_has_dtmf(channel)) {
|
||||||
if (!args->input_callback && !args->buf) {
|
if (!args->input_callback && !args->buf && !args->dmachine) {
|
||||||
status = SWITCH_STATUS_BREAK;
|
status = SWITCH_STATUS_BREAK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch_channel_dequeue_dtmf(channel, &dtmf);
|
switch_channel_dequeue_dtmf(channel, &dtmf);
|
||||||
if (args->input_callback) {
|
|
||||||
|
if (args->dmachine) {
|
||||||
|
char ds[2] = {dtmf.digit, '\0'};
|
||||||
|
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (args->input_callback) {
|
||||||
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
||||||
} else {
|
} else {
|
||||||
*((char *) args->buf) = dtmf.digit;
|
*((char *) args->buf) = dtmf.digit;
|
||||||
@ -651,8 +657,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args && args->dmachine) {
|
||||||
|
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args && (args->read_frame_callback)) {
|
if (args && (args->read_frame_callback)) {
|
||||||
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
|
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -810,16 +822,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args && args->dmachine) {
|
||||||
|
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args && (args->read_frame_callback)) {
|
if (args && (args->read_frame_callback)) {
|
||||||
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
|
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_ivr_parse_all_events(session);
|
switch_ivr_parse_all_events(session);
|
||||||
|
|
||||||
if (args && (args->input_callback || args->buf || args->buflen)) {
|
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
|
||||||
/*
|
/*
|
||||||
dtmf handler function you can hook up to be executed when a digit is dialed during gentones
|
dtmf handler function you can hook up to be executed when a digit is dialed during gentones
|
||||||
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
||||||
@ -831,7 +848,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch_channel_dequeue_dtmf(channel, &dtmf);
|
switch_channel_dequeue_dtmf(channel, &dtmf);
|
||||||
if (args->input_callback) {
|
|
||||||
|
if (args->dmachine) {
|
||||||
|
char ds[2] = {dtmf.digit, '\0'};
|
||||||
|
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (args->input_callback) {
|
||||||
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
||||||
} else {
|
} else {
|
||||||
*((char *) args->buf) = dtmf.digit;
|
*((char *) args->buf) = dtmf.digit;
|
||||||
@ -1224,7 +1247,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
|
|||||||
|
|
||||||
switch_ivr_parse_all_events(session);
|
switch_ivr_parse_all_events(session);
|
||||||
|
|
||||||
if (args && (args->input_callback || args->buf || args->buflen)) {
|
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
|
||||||
/*
|
/*
|
||||||
dtmf handler function you can hook up to be executed when a digit is dialed during playback
|
dtmf handler function you can hook up to be executed when a digit is dialed during playback
|
||||||
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
||||||
@ -1236,7 +1259,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch_channel_dequeue_dtmf(channel, &dtmf);
|
switch_channel_dequeue_dtmf(channel, &dtmf);
|
||||||
if (args->input_callback) {
|
|
||||||
|
if (args->dmachine) {
|
||||||
|
char ds[2] = {dtmf.digit, '\0'};
|
||||||
|
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (args->input_callback) {
|
||||||
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
||||||
} else {
|
} else {
|
||||||
*((char *) args->buf) = dtmf.digit;
|
*((char *) args->buf) = dtmf.digit;
|
||||||
@ -1405,10 +1434,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args && args->dmachine) {
|
||||||
|
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args && (args->read_frame_callback)) {
|
if (args && (args->read_frame_callback)) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
switch_set_flag(fh, SWITCH_FILE_CALLBACK);
|
switch_set_flag(fh, SWITCH_FILE_CALLBACK);
|
||||||
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
|
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
switch_clear_flag(fh, SWITCH_FILE_CALLBACK);
|
switch_clear_flag(fh, SWITCH_FILE_CALLBACK);
|
||||||
@ -1919,7 +1954,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
|
|||||||
switch_event_destroy(&event);
|
switch_event_destroy(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args && (args->input_callback || args->buf || args->buflen)) {
|
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
|
||||||
/* dtmf handler function you can hook up to be executed when a digit is dialed during playback
|
/* dtmf handler function you can hook up to be executed when a digit is dialed during playback
|
||||||
* if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
* if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
|
||||||
*/
|
*/
|
||||||
@ -1933,7 +1968,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
|
|||||||
status = SWITCH_STATUS_BREAK;
|
status = SWITCH_STATUS_BREAK;
|
||||||
} else {
|
} else {
|
||||||
switch_channel_dequeue_dtmf(channel, &dtmf);
|
switch_channel_dequeue_dtmf(channel, &dtmf);
|
||||||
if (args->input_callback) {
|
|
||||||
|
if (args->dmachine) {
|
||||||
|
char ds[2] = {dtmf.digit, '\0'};
|
||||||
|
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (args->input_callback) {
|
||||||
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
|
||||||
} else {
|
} else {
|
||||||
*((char *) args->buf) = dtmf.digit;
|
*((char *) args->buf) = dtmf.digit;
|
||||||
@ -1972,9 +2013,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args && args->dmachine) {
|
||||||
|
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args && (args->read_frame_callback)) {
|
if (args && (args->read_frame_callback)) {
|
||||||
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
|
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
|
||||||
break;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2038,15 +2085,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args && args->dmachine) {
|
||||||
|
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args && (args->read_frame_callback)) {
|
if (args && (args->read_frame_callback)) {
|
||||||
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
|
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
|
||||||
break;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done speaking text\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done speaking text\n");
|
||||||
flags = 0;
|
flags = 0;
|
||||||
switch_core_speech_flush_tts(sh);
|
switch_core_speech_flush_tts(sh);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user