[mod_kazoo] maintenance

* [mod_kazoo] add kz_eval api

* [mod_kazoo] use session if available in first-of

* [mod_kazoo] handle bridge variables

* [mod_kazoo] allow time for erlang node to initialize

* [mod_kazoo] add kz_moh

* tries to start moh from previous unhold
This commit is contained in:
lazedo 2020-03-12 21:44:19 +00:00 committed by GitHub
parent 06f905de9d
commit 1f268e0292
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 162 additions and 72 deletions

View File

@ -54,12 +54,18 @@ SWITCH_STANDARD_API(kz_first_of)
char *mycmd = NULL, *mycmd_dup = NULL, *argv[MAX_FIRST_OF] = { 0 };
int n, argc = 0;
switch_event_header_t *header = NULL;
switch_channel_t *channel = NULL;
if (zstr(cmd)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid arg\n");
return SWITCH_STATUS_GENERR;
}
if ( session ) {
channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT CHANNEL\n");
}
mycmd_dup = mycmd = strdup(cmd);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "FIRST-OF %s\n", mycmd);
if (!zstr(mycmd) && *mycmd == '^' && *(mycmd+1) == '^') {
@ -77,6 +83,24 @@ SWITCH_STANDARD_API(kz_first_of)
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING %s\n", item);
if (channel) {
const char *var = switch_channel_get_variable_dup(channel, item, SWITCH_FALSE, -1);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item);
if (var) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item, var);
stream->write_function(stream, var);
break;
}
if (!strncmp(item, "variable_", 9)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item+9);
var = switch_channel_get_variable_dup(channel, item+9, SWITCH_FALSE, -1);
if (var) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item+9, var);
stream->write_function(stream, var);
break;
}
}
}
header = switch_event_get_header_ptr(stream->param_event, item);
if(header) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING %s : %s\n", item, header->value);
@ -440,6 +464,61 @@ SWITCH_STANDARD_API(kz_expand_api)
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(kz_eval_api)
{
char *p = NULL, *input = NULL;
char *uuid = NULL, *mycmd;
switch_core_session_t *nsession = NULL;
switch_channel_t *channel = NULL;
if (zstr(cmd)) {
stream->write_function(stream, "-ERR invalid input");
return SWITCH_STATUS_GENERR;
}
if (!(mycmd = strdup(cmd))) {
stream->write_function(stream, "-ERR no memory");
return SWITCH_STATUS_GENERR;
}
if (!strncasecmp(mycmd, "uuid:", 5)) {
uuid = mycmd + 5;
if ((input = strchr(uuid, ' ')) != NULL) {
*input++ = '\0';
if ((nsession = switch_core_session_locate(uuid)) != NULL) {
channel = switch_core_session_get_channel(nsession);
} else {
stream->write_function(stream, "-ERR invalid session");
switch_safe_free(mycmd);
return SWITCH_STATUS_GENERR;
}
} else {
stream->write_function(stream, "-ERR invalid argument");
switch_safe_free(mycmd);
return SWITCH_STATUS_GENERR;
}
} else if (session == NULL) {
stream->write_function(stream, "-ERR invalid argument");
switch_safe_free(mycmd);
return SWITCH_STATUS_GENERR;
} else {
channel = switch_core_session_get_channel(session);
input = mycmd;
}
p = switch_channel_expand_variables_check(channel, input, NULL, NULL, 0);
stream->write_function(stream, "+OK %s", p);
if (p != input) {
switch_safe_free(p);
}
switch_safe_free(mycmd);
if (nsession) {
switch_core_session_rwunlock(nsession);
}
return SWITCH_STATUS_SUCCESS;
}
void add_kz_commands(switch_loadable_module_interface_t **module_interface) {
switch_api_interface_t *api_interface = NULL;
SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi", UUID_SET_DESC, uuid_setvar_multi_function, UUID_MULTISET_SYNTAX);
@ -453,5 +532,6 @@ void add_kz_commands(switch_loadable_module_interface_t **module_interface) {
SWITCH_ADD_API(api_interface, "kz_http_put", KZ_HTTP_PUT_DESC, kz_http_put, KZ_HTTP_PUT_SYNTAX);
SWITCH_ADD_API(api_interface, "first-of", KZ_FIRST_OF_DESC, kz_first_of, KZ_FIRST_OF_SYNTAX);
SWITCH_ADD_API(api_interface, "kz_expand", KZ_FIRST_OF_DESC, kz_expand_api, KZ_FIRST_OF_SYNTAX);
SWITCH_ADD_API(api_interface, "kz_eval", KZ_FIRST_OF_DESC, kz_eval_api, KZ_FIRST_OF_SYNTAX);
}

View File

@ -443,6 +443,60 @@ SWITCH_STANDARD_APP(kz_endless_playback_function)
}
SWITCH_STANDARD_APP(kz_moh_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_file_handle_t fh = { 0 };
const char *var_samples = switch_channel_get_variable_dup(channel, "moh_playback_samples", SWITCH_FALSE, -1);
unsigned int samples = 0;
if (var_samples) {
fh.samples = samples = atoi(var_samples);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING SAMPLES %d\n", samples);
}
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
status = switch_ivr_play_file(session, &fh, data, NULL);
switch_assert(!(fh.flags & SWITCH_FILE_OPEN));
switch (status) {
case SWITCH_STATUS_SUCCESS:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED SUCCESS\n");
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED");
switch_channel_set_variable(channel, "moh_playback_samples", "0");
break;
case SWITCH_STATUS_BREAK:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED BREAK\n");
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED");
if ((var_samples = switch_channel_get_variable_dup(channel, "playback_samples", SWITCH_FALSE, -1)) != NULL) {
samples += atoi(var_samples);
if (samples >= fh.samples) {
samples = 0;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING MOH SAMPLES %d\n", samples);
switch_channel_set_variable_printf(channel, "moh_playback_samples", "%d", samples);
}
break;
case SWITCH_STATUS_NOTFOUND:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED NOT FOUND\n");
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE NOT FOUND");
break;
default:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MOH PLAYED DEFAULT\n");
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH PLAYBACK ERROR");
break;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH duration %ld\n", fh.duration);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH offset_pos %d\n", fh.offset_pos);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH pos %ld\n", fh.pos);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH sample_count %ld\n", fh.sample_count);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH samples %d\n", fh.samples);
}
SWITCH_STANDARD_APP(noop_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
@ -907,4 +961,5 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface) {
SWITCH_ADD_APP(app_interface, "kz_bridge", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_function, "<channel_url>", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY);
SWITCH_ADD_APP(app_interface, "kz_bridge_uuid", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_uuid_function, "<channel_url>", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY);
SWITCH_ADD_APP(app_interface, "kz_att_xfer", "Attended Transfer", "Attended Transfer", kz_att_xfer_function, "<channel_url>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "kz_moh", "Kazoo MOH Playback", "Kazoo MOH Playback", kz_moh_function, "", SAF_NONE);
}

View File

@ -922,6 +922,10 @@ static void fetch_config_handlers(switch_memory_pool_t *pool)
static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void *obj)
{
switch_memory_pool_t *pool = (switch_memory_pool_t *) obj;
// give some time for node initialization
switch_sleep(10000);
fetch_config_filters(pool);
fetch_config_handlers(pool);

View File

@ -64,7 +64,7 @@ static switch_status_t kz_tweaks_signal_bridge_on_hangup(switch_core_session_t *
const char *peer_uuid = switch_channel_get_variable(channel, "Bridge-B-Unique-ID");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak signal bridge on hangup: %s , %s\n", switch_core_session_get_uuid(session), peer_uuid);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "tweak signal bridge on hangup: %s , %s\n", switch_core_session_get_uuid(session), peer_uuid);
if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
@ -96,88 +96,38 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event)
switch_core_session_t *a_session = NULL, *b_session = NULL;
const char *a_leg = switch_event_get_header(event, "Bridge-A-Unique-ID");
const char *b_leg = switch_event_get_header(event, "Bridge-B-Unique-ID");
const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed");
int i;
if (!kz_test_tweak(KZ_TWEAK_BRIDGE_VARIABLES)) return;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg);
if(reentry) return;
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg);
if (a_leg && (a_session = switch_core_session_locate(a_leg)) != NULL) {
switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
if(switch_channel_get_variable_dup(a_channel, bridge_variables[0], SWITCH_FALSE, -1) == NULL) {
if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
switch_channel_timetable_t *a_times = switch_channel_get_timetable(a_channel);
if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
switch_channel_timetable_t *b_times = switch_channel_get_timetable(b_channel);
if (a_times->created <= b_times->created) {
for(i = 0; bridge_variables[i] != NULL; i++) {
const char *val = switch_channel_get_variable_dup(a_channel, bridge_variables[i], SWITCH_FALSE, -1);
switch_channel_set_variable(b_channel, bridge_variables[i], val);
}
} else {
for(i = 0; bridge_variables[i] != NULL; i++) {
const char *val = switch_channel_get_variable_dup(b_channel, bridge_variables[i], SWITCH_FALSE, -1);
switch_channel_set_variable(a_channel, bridge_variables[i], val);
}
switch_core_session_rwunlock(b_session);
}
} else {
if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
if(switch_channel_get_variable_dup(b_channel, bridge_variables[0], SWITCH_FALSE, -1) == NULL) {
for(i = 0; bridge_variables[i] != NULL; i++) {
const char *val = switch_channel_get_variable_dup(a_channel, bridge_variables[i], SWITCH_FALSE, -1);
switch_channel_set_variable(b_channel, bridge_variables[i], val);
}
}
switch_core_session_rwunlock(b_session);
}
switch_core_session_rwunlock(b_session);
}
switch_core_session_rwunlock(a_session);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", a_leg);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", a_leg);
}
}
static void kz_tweaks_handle_bridge_replaces_aleg(switch_event_t *event)
{
switch_event_t *my_event;
const char *replaced_call_id = switch_event_get_header(event, "variable_sip_replaces_call_id");
const char *a_leg_call_id = switch_event_get_header(event, "variable_sip_replaces_a-leg");
const char *peer_uuid = switch_event_get_header(event, "Unique-ID");
int processed = 0;
if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG)) return;
if(a_leg_call_id && replaced_call_id) {
const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID");
switch_core_session_t *session = NULL;
if ((session = switch_core_session_locate(peer_uuid)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session);
processed = switch_true(switch_channel_get_variable_dup(channel, "Bridge-Event-Processed", SWITCH_FALSE, -1));
switch_channel_set_variable(channel, "Bridge-Event-Processed", "true");
switch_core_session_rwunlock(session);
}
if(processed) {
if(call_id) {
if((session = switch_core_session_locate(call_id)) != NULL) {
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_variable(channel, "Bridge-Event-Processed", "true");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "creating channel_bridge event A - %s , B - %s\n", switch_core_session_get_uuid(session), peer_uuid);
if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid);
switch_channel_event_set_data(channel, my_event);
switch_event_fire(&my_event);
}
switch_channel_set_variable(channel, "Bridge-B-Unique-ID", peer_uuid);
switch_channel_add_state_handler(channel, &kz_tweaks_signal_bridge_state_handlers);
switch_core_session_rwunlock(session);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "invalid session : %s\n", call_id);
DUMP_EVENT(event);
}
}
}
}
}
static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
@ -185,12 +135,14 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
switch_event_t *my_event;
const char *replaced_call_id = switch_event_get_header(event, "variable_sip_replaces_call_id");
const char *a_leg_call_id = switch_event_get_header(event, "variable_sip_replaces_a-leg");
const char *peer_uuid = switch_event_get_header(event, "Unique-ID");
const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed");
if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID)) return;
if(a_leg_call_id && replaced_call_id) {
if(reentry) return;
if(replaced_call_id) {
switch_core_session_t *call_session = NULL;
const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID");
if (call_id && (call_session = switch_core_session_locate(call_id)) != NULL) {
@ -198,6 +150,7 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(call_session));
switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid);
switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-Event-Processed", "true");
switch_channel_event_set_data(call_channel, my_event);
switch_event_fire(&my_event);
}
@ -208,7 +161,6 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", call_id);
}
}
}
static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event)
@ -216,7 +168,6 @@ static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event)
if (!kz_test_tweak(KZ_TWEAK_BRIDGE)) return;
kz_tweaks_handle_bridge_replaces_call_id(event);
kz_tweaks_handle_bridge_replaces_aleg(event);
kz_tweaks_handle_bridge_variables(event);
}
@ -482,7 +433,7 @@ static switch_status_t kz_tweaks_handle_replaces_call_id(switch_core_session_t *
const char *replaced_call_id = switch_channel_get_variable(channel, "sip_replaces_call_id");
const char *core_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-From-Core-UUID");
if((!core_uuid) && replaced_call_id) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id);
if ((replace_call_session = switch_core_session_locate(replaced_call_id))) {
switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session);
int i;