add some goodies
This commit is contained in:
parent
82f268cce6
commit
9537197b4d
|
@ -167,6 +167,7 @@ struct switch_core_session {
|
|||
uint32_t track_id;
|
||||
switch_log_level_t loglevel;
|
||||
uint32_t soft_lock;
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
};
|
||||
|
||||
struct switch_media_bug {
|
||||
|
|
|
@ -704,7 +704,8 @@ SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_
|
|||
|
||||
SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec);
|
||||
SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session);
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine);
|
||||
SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the unique identifier from the core
|
||||
|
|
|
@ -557,6 +557,7 @@ SWITCH_DECLARE(uint32_t) switch_ivr_schedule_broadcast(time_t runtime, const cha
|
|||
\return SWITCH_STATUS_SUCCESS if all is well
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags);
|
||||
SWITCH_DECLARE(void) switch_ivr_broadcast_in_thread(switch_core_session_t *session, const char *app, int flags);
|
||||
|
||||
/*!
|
||||
\brief Transfer variables from one session to another
|
||||
|
|
|
@ -1057,6 +1057,7 @@ typedef enum {
|
|||
CF_MEDIA_SET,
|
||||
CF_CONSUME_ON_ORIGINATE,
|
||||
CF_PASSTHRU_PTIME_MISMATCH,
|
||||
CF_BRIDGE_NOWRITE,
|
||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
||||
CF_FLAG_MAX
|
||||
} switch_channel_flag_t;
|
||||
|
|
|
@ -95,6 +95,120 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
|
|||
return extension;
|
||||
}
|
||||
|
||||
struct action_binding {
|
||||
char *input;
|
||||
char *string;
|
||||
char *value;
|
||||
switch_core_session_t *session;
|
||||
};
|
||||
|
||||
static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||
{
|
||||
struct action_binding *act = (struct action_binding *) match->user_data;
|
||||
switch_event_t *event;
|
||||
switch_status_t status;
|
||||
int exec = 0;
|
||||
char *string = act->string;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(act->session);
|
||||
|
||||
if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_DEBUG, "%s Digit match binding [%s][%s]\n",
|
||||
switch_channel_get_name(channel), act->string, act->value);
|
||||
|
||||
if (!strncasecmp(string, "exec:", 5)) {
|
||||
string += 5;
|
||||
exec = 1;
|
||||
}
|
||||
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, string, act->value);
|
||||
|
||||
if (exec) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute", exec == 2 ? "non-blocking" : "blocking");
|
||||
}
|
||||
|
||||
if ((status = switch_core_session_queue_event(act->session, &event)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_destroy(&event);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
|
||||
switch_core_session_get_name(act->session));
|
||||
}
|
||||
}
|
||||
|
||||
if (exec) {
|
||||
char *cmd = switch_core_session_sprintf(act->session, "%s::%s", string, act->value);
|
||||
switch_ivr_broadcast_in_thread(act->session, cmd, SMF_ECHO_ALEG|SMF_HOLD_BLEG);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define CLEAR_DIGIT_ACTION_USAGE ""
|
||||
SWITCH_STANDARD_APP(clear_digit_action_function)
|
||||
{
|
||||
//switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
|
||||
if ((dmachine = switch_core_session_get_dmachine(session))) {
|
||||
switch_core_session_set_dmachine(session, NULL);
|
||||
switch_ivr_dmachine_destroy(&dmachine);
|
||||
}
|
||||
}
|
||||
|
||||
#define BIND_DIGIT_ACTION_USAGE "<digits|~regex>,<string>,<value>"
|
||||
SWITCH_STANDARD_APP(bind_digit_action_function)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
char *mydata;
|
||||
int argc = 0;
|
||||
char *argv[3] = { 0 };
|
||||
struct action_binding *act;
|
||||
|
||||
if (zstr(data)) {
|
||||
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))) {
|
||||
uint32_t digit_timeout = 1500;
|
||||
uint32_t input_timeout = 0;
|
||||
const char *var;
|
||||
uint32_t tmp;
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, "bind_digit_digit_timeout"))) {
|
||||
tmp = (uint32_t) atol(var);
|
||||
if (tmp < 0) tmp = 0;
|
||||
digit_timeout = tmp;
|
||||
}
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, "bind_digit_input_timeout"))) {
|
||||
tmp = (uint32_t) atol(var);
|
||||
if (tmp < 0) tmp = 0;
|
||||
input_timeout = tmp;
|
||||
}
|
||||
|
||||
switch_ivr_dmachine_create(&dmachine, NULL, digit_timeout, input_timeout);
|
||||
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->input = argv[0];
|
||||
act->string = argv[1];
|
||||
act->value = argv[2];
|
||||
act->session = session;
|
||||
|
||||
switch_ivr_dmachine_bind(dmachine, act->input, 0, digit_action_callback, act);
|
||||
}
|
||||
|
||||
|
||||
#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume"
|
||||
SWITCH_STANDARD_APP(detect_speech_function)
|
||||
{
|
||||
|
@ -3277,6 +3391,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||
SWITCH_ADD_API(api_interface, "chat", "chat", chat_api_function, "<proto>|<from>|<to>|<message>|[<content-type>]");
|
||||
SWITCH_ADD_API(api_interface, "strftime", "strftime", strftime_api_function, "<format_string>");
|
||||
SWITCH_ADD_API(api_interface, "presence", "presence", presence_api_function, PRESENCE_USAGE);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "bind_digit_action", "bind a key sequence or regex to an action",
|
||||
"bind a key sequence or regex to an action", bind_digit_action_function, BIND_DIGIT_ACTION_USAGE, SAF_SUPPORT_NOMEDIA);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "clear_digit_action", "clear all digit bindings", "",
|
||||
clear_digit_action_function, CLEAR_DIGIT_ACTION_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",
|
||||
SAF_SUPPORT_NOMEDIA);
|
||||
|
||||
|
|
|
@ -5077,7 +5077,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
}
|
||||
|
||||
if (channel) {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_EARLY_MEDIA) && !sofia_test_flag(tech_pvt, TFLAG_ANS)) {
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
|
||||
sofia_set_flag(tech_pvt, TFLAG_SDP);
|
||||
switch_channel_mark_answered(channel);
|
||||
|
|
|
@ -126,7 +126,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
|
|||
switch_mutex_lock(session->read_codec->mutex);
|
||||
|
||||
top:
|
||||
|
||||
|
||||
if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
|
||||
switch_ivr_dmachine_ping(session->dmachine, NULL);
|
||||
}
|
||||
|
||||
if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) {
|
||||
*frame = NULL;
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
|
@ -1150,6 +1154,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio
|
|||
switch_io_event_hook_recv_dtmf_t *ptr;
|
||||
switch_status_t status;
|
||||
switch_dtmf_t new_dtmf;
|
||||
int fed = 0;
|
||||
|
||||
if (switch_channel_down(session->channel)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
@ -1171,12 +1176,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio
|
|||
new_dtmf.duration = switch_core_default_dtmf_duration(0);
|
||||
}
|
||||
|
||||
if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
|
||||
char str[2] = { dtmf->digit, '\0' };
|
||||
switch_ivr_dmachine_feed(session->dmachine, str, NULL);
|
||||
fed = 1;
|
||||
}
|
||||
|
||||
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) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
return fed ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
|
||||
|
|
|
@ -38,6 +38,16 @@
|
|||
|
||||
struct switch_session_manager session_manager;
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine)
|
||||
{
|
||||
session->dmachine = dmachine;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session)
|
||||
{
|
||||
return session->dmachine;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec)
|
||||
{
|
||||
session->soft_lock = sec;
|
||||
|
@ -1094,6 +1104,10 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t *
|
|||
switch_ivr_clear_speech_cache(*session);
|
||||
switch_channel_uninit((*session)->channel);
|
||||
|
||||
if ((*session)->dmachine) {
|
||||
switch_ivr_dmachine_destroy(&(*session)->dmachine);
|
||||
}
|
||||
|
||||
pool = (*session)->pool;
|
||||
//#ifndef NDEBUG
|
||||
//memset(*session, 0, sizeof(switch_core_session_t));
|
||||
|
|
|
@ -150,10 +150,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *
|
|||
}
|
||||
|
||||
if (binding->is_regex) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "binding regex: %s key: %.4d callback: %p data: %p\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "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",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "binding digits: %4s key: %.4d callback: %p data: %p\n",
|
||||
digits, key, (void *)(intptr_t) callback, user_data);
|
||||
}
|
||||
|
||||
|
@ -264,27 +264,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *
|
|||
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;
|
||||
|
||||
int exec = 0;
|
||||
|
||||
if (zstr(dmachine->digits) && !is_timeout) {
|
||||
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;
|
||||
exec = 1;
|
||||
} else if (is_timeout) {
|
||||
r = SWITCH_STATUS_TIMEOUT;
|
||||
} else if (dmachine->cur_digit_len == dmachine->max_digit_len) {
|
||||
|
@ -297,6 +295,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *
|
|||
switch_ivr_dmachine_clear(dmachine);
|
||||
}
|
||||
|
||||
if (exec && dmachine->last_matching_binding->callback) {
|
||||
dmachine->last_matching_binding->callback(&dmachine->match);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2501,7 +2503,7 @@ static void *SWITCH_THREAD_FUNC bcast_thread(switch_thread_t *thread, void *obj)
|
|||
return NULL;
|
||||
|
||||
}
|
||||
static void broadcast_in_thread(switch_core_session_t *session, const char *app, int flags)
|
||||
SWITCH_DECLARE(void) switch_ivr_broadcast_in_thread(switch_core_session_t *session, const char *app, int flags)
|
||||
{
|
||||
switch_thread_t *thread;
|
||||
switch_threadattr_t *thd_attr = NULL;
|
||||
|
@ -2606,7 +2608,7 @@ static switch_status_t meta_on_dtmf(switch_core_session_t *session, const switch
|
|||
switch_channel_get_name(channel), dtmf->digit, md->sr[direction].map[dval].app);
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
|
||||
broadcast_in_thread(session, md->sr[direction].map[dval].app, flags | SMF_REBRIDGE);
|
||||
switch_ivr_broadcast_in_thread(session, md->sr[direction].map[dval].app, flags | SMF_REBRIDGE);
|
||||
} else {
|
||||
switch_ivr_broadcast(switch_core_session_get_uuid(session), md->sr[direction].map[dval].app, flags);
|
||||
}
|
||||
|
|
|
@ -468,6 +468,10 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(chan_a, CF_BRIDGE_NOWRITE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status != SWITCH_STATUS_BREAK && !switch_channel_test_flag(chan_a, CF_HOLD)) {
|
||||
if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
|
@ -839,13 +843,26 @@ static switch_status_t hanguphook(switch_core_session_t *session)
|
|||
{
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_event_t *event;
|
||||
switch_channel_state_t state;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
state = switch_channel_get_state(channel);
|
||||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
|
||||
msg.from = __FILE__;
|
||||
msg.string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
|
||||
|
||||
if (state == CS_ROUTING) {
|
||||
if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
|
||||
switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
|
||||
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_event_set_data(channel, event);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_session_receive_message(session, &msg);
|
||||
switch_core_event_hook_remove_state_change(session, hanguphook);
|
||||
|
||||
|
@ -859,6 +876,7 @@ static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session
|
|||
const char *key;
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
switch_event_t *event = NULL;
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_assert(channel != NULL);
|
||||
|
@ -886,6 +904,19 @@ static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session
|
|||
}
|
||||
}
|
||||
|
||||
if ((dmachine = switch_core_session_get_dmachine(session))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
|
||||
"%s not hibernating due to active digit parser, semi-hibernation engaged.\n", switch_channel_get_name(channel));
|
||||
|
||||
while(switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_HIBERNATE) {
|
||||
if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
|
||||
switch_ivr_dmachine_ping(dmachine, NULL);
|
||||
}
|
||||
switch_yield(20000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue