mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-16 16:58:35 +00:00
improve dmachine stuff some more
This commit is contained in:
parent
8a7f8cd22e
commit
1d921b1cfa
@ -846,24 +846,31 @@ 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_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
|
||||||
switch_memory_pool_t *pool,
|
const char *name,
|
||||||
uint32_t digit_timeout, uint32_t input_timeout);
|
switch_memory_pool_t *pool,
|
||||||
|
uint32_t digit_timeout, uint32_t input_timeout,
|
||||||
|
switch_ivr_dmachine_callback_t match_callback,
|
||||||
|
switch_ivr_dmachine_callback_t nonmatch_callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine);
|
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,
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
|
||||||
const char *digits,
|
const char *realm,
|
||||||
int32_t key,
|
const char *digits,
|
||||||
switch_ivr_dmachine_callback_t callback,
|
int32_t key,
|
||||||
void *user_data);
|
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_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_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_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_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(switch_ivr_dmachine_t *dmachine);
|
||||||
|
SWITCH_DECLARE(const char *) switch_ivr_dmachine_get_failed_digits(switch_ivr_dmachine_t *dmachine);
|
||||||
SWITCH_DECLARE(void) switch_ivr_dmachine_set_digit_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t digit_timeout_ms);
|
SWITCH_DECLARE(void) switch_ivr_dmachine_set_digit_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t digit_timeout_ms);
|
||||||
SWITCH_DECLARE(void) switch_ivr_dmachine_set_input_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t input_timeout_ms);
|
SWITCH_DECLARE(void) switch_ivr_dmachine_set_input_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t input_timeout_ms);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
@ -190,9 +190,14 @@ SWITCH_BEGIN_EXTERN_C
|
|||||||
#define SWITCH_DTMF_LOG_LEN 1000
|
#define SWITCH_DTMF_LOG_LEN 1000
|
||||||
typedef uint8_t switch_byte_t;
|
typedef uint8_t switch_byte_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DTMF_FLAG_SKIP_PROCESS = (1 << 0)
|
||||||
|
} dtmf_flag_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char digit;
|
char digit;
|
||||||
uint32_t duration;
|
uint32_t duration;
|
||||||
|
int32_t flags;
|
||||||
} switch_dtmf_t;
|
} switch_dtmf_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -1689,6 +1694,13 @@ typedef switch_status_t (*switch_input_callback_function_t) (switch_core_session
|
|||||||
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;
|
||||||
|
|
||||||
|
#define DMACHINE_MAX_DIGIT_LEN 512
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DM_MATCH_POSITIVE,
|
||||||
|
DM_MATCH_NEGATIVE
|
||||||
|
} dm_match_type_t;
|
||||||
|
|
||||||
struct switch_ivr_dmachine;
|
struct switch_ivr_dmachine;
|
||||||
typedef struct switch_ivr_dmachine switch_ivr_dmachine_t;
|
typedef struct switch_ivr_dmachine switch_ivr_dmachine_t;
|
||||||
|
|
||||||
@ -1696,6 +1708,7 @@ struct switch_ivr_dmachine_match {
|
|||||||
switch_ivr_dmachine_t *dmachine;
|
switch_ivr_dmachine_t *dmachine;
|
||||||
const char *match_digits;
|
const char *match_digits;
|
||||||
int32_t match_key;
|
int32_t match_key;
|
||||||
|
dm_match_type_t type;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,12 +96,30 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct action_binding {
|
struct action_binding {
|
||||||
|
char *realm;
|
||||||
char *input;
|
char *input;
|
||||||
char *string;
|
char *string;
|
||||||
char *value;
|
char *value;
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static switch_status_t digit_nomatch_action_callback(switch_ivr_dmachine_match_t *match)
|
||||||
|
{
|
||||||
|
switch_core_session_t *session = (switch_core_session_t *) match->user_data;
|
||||||
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
|
char str[DMACHINE_MAX_DIGIT_LEN + 2];
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Digit NOT match binding [%s]\n",
|
||||||
|
switch_channel_get_name(channel), match->match_digits);
|
||||||
|
|
||||||
|
/* send it back around flagged to skip the dmachine */
|
||||||
|
switch_snprintf(str, sizeof(str), "!%s", match->match_digits);
|
||||||
|
|
||||||
|
switch_channel_queue_dtmf_string(channel, str);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||||
{
|
{
|
||||||
struct action_binding *act = (struct action_binding *) match->user_data;
|
struct action_binding *act = (struct action_binding *) match->user_data;
|
||||||
@ -141,32 +159,64 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CLEAR_DIGIT_ACTION_USAGE ""
|
#define CLEAR_DIGIT_ACTION_USAGE "<realm>|all"
|
||||||
SWITCH_STANDARD_APP(clear_digit_action_function)
|
SWITCH_STANDARD_APP(clear_digit_action_function)
|
||||||
{
|
{
|
||||||
//switch_channel_t *channel = switch_core_session_get_channel(session);
|
//switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
switch_ivr_dmachine_t *dmachine;
|
switch_ivr_dmachine_t *dmachine;
|
||||||
|
char *realm = (char *) data;
|
||||||
|
|
||||||
if ((dmachine = switch_core_session_get_dmachine(session))) {
|
if ((dmachine = switch_core_session_get_dmachine(session))) {
|
||||||
switch_core_session_set_dmachine(session, NULL);
|
if (zstr(realm) || !strcasecmp(realm, "all")) {
|
||||||
switch_ivr_dmachine_destroy(&dmachine);
|
switch_core_session_set_dmachine(session, NULL);
|
||||||
|
switch_ivr_dmachine_destroy(&dmachine);
|
||||||
|
} else {
|
||||||
|
switch_ivr_dmachine_clear_realm(dmachine, realm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BIND_DIGIT_ACTION_USAGE "<digits|~regex>,<string>,<value>"
|
#define DIGIT_ACTION_SET_REALM_USAGE "<realm>"
|
||||||
|
SWITCH_STANDARD_APP(digit_action_set_realm_function)
|
||||||
|
{
|
||||||
|
switch_ivr_dmachine_t *dmachine;
|
||||||
|
char *realm = (char *) data;
|
||||||
|
|
||||||
|
if (zstr(data)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", DIGIT_ACTION_SET_REALM_USAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dmachine = switch_core_session_get_dmachine(session))) {
|
||||||
|
switch_ivr_dmachine_set_realm(dmachine, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BIND_DIGIT_ACTION_USAGE "<realm>,<digits|~regex>,<string>,<value>"
|
||||||
SWITCH_STANDARD_APP(bind_digit_action_function)
|
SWITCH_STANDARD_APP(bind_digit_action_function)
|
||||||
{
|
{
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
switch_ivr_dmachine_t *dmachine;
|
switch_ivr_dmachine_t *dmachine;
|
||||||
char *mydata;
|
char *mydata;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
char *argv[3] = { 0 };
|
char *argv[4] = { 0 };
|
||||||
struct action_binding *act;
|
struct action_binding *act;
|
||||||
|
|
||||||
if (zstr(data)) {
|
if (zstr(data)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mydata = switch_core_session_strdup(session, data);
|
||||||
|
|
||||||
|
argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||||
|
|
||||||
|
if (argc < 4 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2]) || zstr(argv[3])) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!(dmachine = switch_core_session_get_dmachine(session))) {
|
if (!(dmachine = switch_core_session_get_dmachine(session))) {
|
||||||
uint32_t digit_timeout = 1500;
|
uint32_t digit_timeout = 1500;
|
||||||
@ -186,26 +236,19 @@ SWITCH_STANDARD_APP(bind_digit_action_function)
|
|||||||
input_timeout = tmp;
|
input_timeout = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_ivr_dmachine_create(&dmachine, NULL, digit_timeout, input_timeout);
|
switch_ivr_dmachine_create(&dmachine, "DPTOOLS", NULL, digit_timeout, input_timeout, NULL, digit_nomatch_action_callback, session);
|
||||||
switch_core_session_set_dmachine(session, dmachine);
|
switch_core_session_set_dmachine(session, dmachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
mydata = switch_core_session_strdup(session, data);
|
|
||||||
|
|
||||||
argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
|
|
||||||
|
|
||||||
if (argc < 3 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2])) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
act = switch_core_session_alloc(session, sizeof(*act));
|
act = switch_core_session_alloc(session, sizeof(*act));
|
||||||
act->input = argv[0];
|
act->realm = argv[0];
|
||||||
act->string = argv[1];
|
act->input = argv[1];
|
||||||
act->value = argv[2];
|
act->string = argv[2];
|
||||||
|
act->value = argv[3];
|
||||||
act->session = session;
|
act->session = session;
|
||||||
|
|
||||||
switch_ivr_dmachine_bind(dmachine, act->input, 0, digit_action_callback, act);
|
switch_ivr_dmachine_bind(dmachine, act->realm, act->input, 0, digit_action_callback, act);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3398,6 +3441,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||||||
SWITCH_ADD_APP(app_interface, "clear_digit_action", "clear all digit bindings", "",
|
SWITCH_ADD_APP(app_interface, "clear_digit_action", "clear all digit bindings", "",
|
||||||
clear_digit_action_function, CLEAR_DIGIT_ACTION_USAGE, SAF_SUPPORT_NOMEDIA);
|
clear_digit_action_function, CLEAR_DIGIT_ACTION_USAGE, SAF_SUPPORT_NOMEDIA);
|
||||||
|
|
||||||
|
SWITCH_ADD_APP(app_interface, "digit_action_set_realm", "change binding realm", "",
|
||||||
|
digit_action_set_realm_function, DIGIT_ACTION_SET_REALM_USAGE, SAF_SUPPORT_NOMEDIA);
|
||||||
|
|
||||||
|
|
||||||
SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number",
|
SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number",
|
||||||
SAF_SUPPORT_NOMEDIA);
|
SAF_SUPPORT_NOMEDIA);
|
||||||
|
@ -400,7 +400,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan
|
|||||||
SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf_string(switch_channel_t *channel, const char *dtmf_string)
|
SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf_string(switch_channel_t *channel, const char *dtmf_string)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0) };
|
switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0};
|
||||||
int sent = 0, dur;
|
int sent = 0, dur;
|
||||||
char *string;
|
char *string;
|
||||||
int i, argc;
|
int i, argc;
|
||||||
@ -410,6 +410,11 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf_string(switch_channel_
|
|||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*dtmf_string == '!') {
|
||||||
|
dtmf_string++;
|
||||||
|
dtmf.flags = DTMF_FLAG_SKIP_PROCESS;
|
||||||
|
}
|
||||||
|
|
||||||
string = switch_core_session_strdup(channel->session, dtmf_string);
|
string = switch_core_session_strdup(channel->session, dtmf_string);
|
||||||
argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0])));
|
argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||||
|
|
||||||
|
@ -1176,15 +1176,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio
|
|||||||
new_dtmf.duration = switch_core_default_dtmf_duration(0);
|
new_dtmf.duration = switch_core_default_dtmf_duration(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
|
if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)) {
|
||||||
char str[2] = { dtmf->digit, '\0' };
|
if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
|
||||||
switch_ivr_dmachine_feed(session->dmachine, str, NULL);
|
char str[2] = { dtmf->digit, '\0' };
|
||||||
fed = 1;
|
switch_ivr_dmachine_feed(session->dmachine, str, NULL);
|
||||||
}
|
fed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) {
|
for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) {
|
||||||
if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) {
|
if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,28 +45,41 @@ struct switch_ivr_dmachine_binding {
|
|||||||
};
|
};
|
||||||
typedef struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t;
|
typedef struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t;
|
||||||
|
|
||||||
#define DM_MAX_DIGIT_LEN 512
|
typedef struct {
|
||||||
|
switch_ivr_dmachine_binding_t *binding_list;
|
||||||
|
switch_ivr_dmachine_binding_t *tail;
|
||||||
|
} dm_binding_head_t;
|
||||||
|
|
||||||
struct switch_ivr_dmachine {
|
struct switch_ivr_dmachine {
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
switch_byte_t my_pool;
|
switch_byte_t my_pool;
|
||||||
|
char *name;
|
||||||
uint32_t digit_timeout_ms;
|
uint32_t digit_timeout_ms;
|
||||||
uint32_t input_timeout_ms;
|
uint32_t input_timeout_ms;
|
||||||
switch_ivr_dmachine_binding_t *binding_list;
|
switch_hash_t *binding_hash;
|
||||||
switch_ivr_dmachine_binding_t *tail;
|
|
||||||
switch_ivr_dmachine_binding_t *last_matching_binding;
|
|
||||||
switch_ivr_dmachine_match_t match;
|
switch_ivr_dmachine_match_t match;
|
||||||
char digits[DM_MAX_DIGIT_LEN];
|
char digits[DMACHINE_MAX_DIGIT_LEN];
|
||||||
char last_matching_digits[DM_MAX_DIGIT_LEN];
|
char last_matching_digits[DMACHINE_MAX_DIGIT_LEN];
|
||||||
|
char last_failed_digits[DMACHINE_MAX_DIGIT_LEN];
|
||||||
uint32_t cur_digit_len;
|
uint32_t cur_digit_len;
|
||||||
uint32_t max_digit_len;
|
uint32_t max_digit_len;
|
||||||
switch_time_t last_digit_time;
|
switch_time_t last_digit_time;
|
||||||
switch_byte_t is_match;
|
switch_byte_t is_match;
|
||||||
|
switch_ivr_dmachine_callback_t match_callback;
|
||||||
|
switch_ivr_dmachine_callback_t nonmatch_callback;
|
||||||
|
dm_binding_head_t *realm;
|
||||||
|
switch_ivr_dmachine_binding_t *last_matching_binding;
|
||||||
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
|
||||||
switch_memory_pool_t *pool,
|
const char *name,
|
||||||
uint32_t digit_timeout_ms, uint32_t input_timeout_ms)
|
switch_memory_pool_t *pool,
|
||||||
|
uint32_t digit_timeout_ms,
|
||||||
|
uint32_t input_timeout_ms,
|
||||||
|
switch_ivr_dmachine_callback_t match_callback,
|
||||||
|
switch_ivr_dmachine_callback_t nonmatch_callback,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
switch_byte_t my_pool = !!pool;
|
switch_byte_t my_pool = !!pool;
|
||||||
switch_ivr_dmachine_t *dmachine;
|
switch_ivr_dmachine_t *dmachine;
|
||||||
@ -81,8 +94,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t
|
|||||||
dmachine->digit_timeout_ms = digit_timeout_ms;
|
dmachine->digit_timeout_ms = digit_timeout_ms;
|
||||||
dmachine->input_timeout_ms = input_timeout_ms;
|
dmachine->input_timeout_ms = input_timeout_ms;
|
||||||
dmachine->match.dmachine = dmachine;
|
dmachine->match.dmachine = dmachine;
|
||||||
*dmachine_p = dmachine;
|
dmachine->name = switch_core_strdup(dmachine->pool, name);
|
||||||
|
|
||||||
|
switch_core_hash_init(&dmachine->binding_hash, dmachine->pool);
|
||||||
|
|
||||||
|
if (match_callback) {
|
||||||
|
dmachine->match_callback = match_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonmatch_callback) {
|
||||||
|
dmachine->nonmatch_callback = nonmatch_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmachine->user_data = user_data;
|
||||||
|
|
||||||
|
*dmachine_p = dmachine;
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,12 +132,42 @@ SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachin
|
|||||||
|
|
||||||
pool = (*dmachine)->pool;
|
pool = (*dmachine)->pool;
|
||||||
|
|
||||||
|
switch_core_hash_destroy(&(*dmachine)->binding_hash);
|
||||||
|
|
||||||
if ((*dmachine)->my_pool) {
|
if ((*dmachine)->my_pool) {
|
||||||
switch_core_destroy_memory_pool(&pool);
|
switch_core_destroy_memory_pool(&pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm)
|
||||||
|
{
|
||||||
|
dm_binding_head_t *headp = switch_core_hash_find(dmachine->binding_hash, realm);
|
||||||
|
|
||||||
|
if (headp) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Setting realm to %s\n", dmachine->name, realm);
|
||||||
|
dmachine->realm = headp;
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error Setting realm to %s\n", dmachine->name, realm);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmachine_t *dmachine, const char *realm)
|
||||||
|
{
|
||||||
|
if (zstr(realm)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error unknown realm: %s\n", dmachine->name, realm);
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pool alloc'd just ditch it and it will give back the memory when we destroy ourselves */
|
||||||
|
switch_core_hash_delete(dmachine->binding_hash, realm);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
|
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
|
||||||
|
const char *realm,
|
||||||
const char *digits,
|
const char *digits,
|
||||||
int32_t key,
|
int32_t key,
|
||||||
switch_ivr_dmachine_callback_t callback,
|
switch_ivr_dmachine_callback_t callback,
|
||||||
@ -118,43 +175,59 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *
|
|||||||
{
|
{
|
||||||
switch_ivr_dmachine_binding_t *binding;
|
switch_ivr_dmachine_binding_t *binding;
|
||||||
switch_size_t len;
|
switch_size_t len;
|
||||||
|
dm_binding_head_t *headp;
|
||||||
|
|
||||||
if (strlen(digits) > DM_MAX_DIGIT_LEN -1) {
|
if (strlen(digits) > DMACHINE_MAX_DIGIT_LEN -1) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zstr(realm)) {
|
||||||
|
realm = "default";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(headp = switch_core_hash_find(dmachine->binding_hash, realm))) {
|
||||||
|
headp = switch_core_alloc(dmachine->pool, sizeof(*headp));
|
||||||
|
switch_core_hash_insert(dmachine->binding_hash, realm, headp);
|
||||||
|
}
|
||||||
|
|
||||||
binding = switch_core_alloc(dmachine->pool, sizeof(*binding));
|
binding = switch_core_alloc(dmachine->pool, sizeof(*binding));
|
||||||
|
|
||||||
if (*digits == '~') {
|
if (*digits == '~') {
|
||||||
binding->is_regex = 1;
|
binding->is_regex = 1;
|
||||||
digits++;
|
digits++;
|
||||||
}
|
}
|
||||||
|
|
||||||
binding->key = key;
|
binding->key = key;
|
||||||
binding->digits = switch_core_strdup(dmachine->pool, digits);
|
binding->digits = switch_core_strdup(dmachine->pool, digits);
|
||||||
binding->callback = callback;
|
binding->callback = callback;
|
||||||
binding->user_data = user_data;
|
binding->user_data = user_data;
|
||||||
|
|
||||||
if (dmachine->tail) {
|
if (headp->tail) {
|
||||||
dmachine->tail->next = binding;
|
headp->tail->next = binding;
|
||||||
} else {
|
} else {
|
||||||
dmachine->binding_list = binding;
|
headp->binding_list = binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
dmachine->tail = binding;
|
headp->tail = binding;
|
||||||
|
|
||||||
len = strlen(digits);
|
len = strlen(digits);
|
||||||
|
|
||||||
if (binding->is_regex && dmachine->max_digit_len != DM_MAX_DIGIT_LEN -1) {
|
if (dmachine->realm != headp) {
|
||||||
dmachine->max_digit_len = DM_MAX_DIGIT_LEN -1;
|
switch_ivr_dmachine_set_realm(dmachine, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding->is_regex && dmachine->max_digit_len != DMACHINE_MAX_DIGIT_LEN -1) {
|
||||||
|
dmachine->max_digit_len = DMACHINE_MAX_DIGIT_LEN -1;
|
||||||
} else if (len > dmachine->max_digit_len) {
|
} else if (len > dmachine->max_digit_len) {
|
||||||
dmachine->max_digit_len = (uint32_t) len;
|
dmachine->max_digit_len = (uint32_t) len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binding->is_regex) {
|
if (binding->is_regex) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "binding regex: %s key: %.4d callback: %p data: %p\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: binding realm: %s regex: %s key: %.4d callback: %p data: %p\n",
|
||||||
digits, key, (void *)(intptr_t) callback, user_data);
|
dmachine->name, realm, digits, key, (void *)(intptr_t) callback, user_data);
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "binding digits: %4s key: %.4d callback: %p data: %p\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: binding realm %s digits: %4s key: %.4d callback: %p data: %p\n",
|
||||||
digits, key, (void *)(intptr_t) callback, user_data);
|
dmachine->name, realm, digits, key, (void *)(intptr_t) callback, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
@ -175,9 +248,9 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin
|
|||||||
int exact_count = 0, partial_count = 0, both_count = 0;
|
int exact_count = 0, partial_count = 0, both_count = 0;
|
||||||
|
|
||||||
|
|
||||||
if (!dmachine->cur_digit_len) goto end;
|
if (!dmachine->cur_digit_len || !dmachine->realm) goto end;
|
||||||
|
|
||||||
for(bp = dmachine->binding_list; bp; bp = bp->next) {
|
for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
|
||||||
|
|
||||||
if (bp->is_regex) {
|
if (bp->is_regex) {
|
||||||
switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
|
switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
|
||||||
@ -259,12 +332,17 @@ SWITCH_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(swit
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(const char *) switch_ivr_dmachine_get_failed_digits(switch_ivr_dmachine_t *dmachine)
|
||||||
|
{
|
||||||
|
|
||||||
|
return dmachine->last_failed_digits;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
|
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);
|
switch_bool_t is_timeout = switch_ivr_dmachine_check_timeout(dmachine);
|
||||||
dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout);
|
dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout);
|
||||||
switch_status_t r;
|
switch_status_t r;
|
||||||
int exec = 0;
|
|
||||||
|
|
||||||
if (zstr(dmachine->digits) && !is_timeout) {
|
if (zstr(dmachine->digits) && !is_timeout) {
|
||||||
r = SWITCH_STATUS_SUCCESS;
|
r = SWITCH_STATUS_SUCCESS;
|
||||||
@ -282,7 +360,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
dmachine->is_match = 1;
|
dmachine->is_match = 1;
|
||||||
exec = 1;
|
|
||||||
|
dmachine->match.type = DM_MATCH_POSITIVE;
|
||||||
|
|
||||||
|
if (dmachine->last_matching_binding->callback) {
|
||||||
|
dmachine->last_matching_binding->callback(&dmachine->match);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmachine->match_callback) {
|
||||||
|
dmachine->match.user_data = dmachine->user_data;
|
||||||
|
dmachine->match_callback(&dmachine->match);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (is_timeout) {
|
} else if (is_timeout) {
|
||||||
r = SWITCH_STATUS_TIMEOUT;
|
r = SWITCH_STATUS_TIMEOUT;
|
||||||
} else if (dmachine->cur_digit_len == dmachine->max_digit_len) {
|
} else if (dmachine->cur_digit_len == dmachine->max_digit_len) {
|
||||||
@ -291,14 +380,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *
|
|||||||
r = SWITCH_STATUS_SUCCESS;
|
r = SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r != SWITCH_STATUS_FOUND && r != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_set_string(dmachine->last_failed_digits, dmachine->digits);
|
||||||
|
dmachine->match.match_digits = dmachine->last_failed_digits;
|
||||||
|
|
||||||
|
dmachine->match.type = DM_MATCH_NEGATIVE;
|
||||||
|
|
||||||
|
if (dmachine->nonmatch_callback) {
|
||||||
|
dmachine->match.user_data = dmachine->user_data;
|
||||||
|
dmachine->nonmatch_callback(&dmachine->match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (r != SWITCH_STATUS_SUCCESS) {
|
if (r != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_ivr_dmachine_clear(dmachine);
|
switch_ivr_dmachine_clear(dmachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exec && dmachine->last_matching_binding->callback) {
|
|
||||||
dmachine->last_matching_binding->callback(&dmachine->match);
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user