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) == '^') {
}
} 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);
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);
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);
}
}
+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);
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);
}
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);
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));
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);
- }
-
-}
-
-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);
- }
- }
- }
-
+ 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_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) {
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);
}
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)
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);
}
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;