From 8bb4d0d413ede1b4b56711b5b67b3a269c1a64b1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 27 Oct 2010 14:09:38 -0500 Subject: [PATCH] add the stuff drk_ keeps begging for --- .../applications/mod_commands/mod_commands.c | 62 +++++++++++++++++++ src/mod/endpoints/mod_sofia/sofia_reg.c | 37 ++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 1fb1c95c47..d9de871338 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2019,6 +2019,66 @@ SWITCH_STANDARD_API(transfer_function) return SWITCH_STATUS_SUCCESS; } + +#define DUAL_TRANSFER_SYNTAX " [/][/] [/][/]" +SWITCH_STANDARD_API(dual_transfer_function) +{ + switch_core_session_t *tsession = NULL, *other_session = NULL; + char *mycmd = NULL, *argv[5] = { 0 }; + int argc = 0; + char *tuuid, *dest1, *dest2, *dp1 = NULL, *dp2 = NULL, *context1 = NULL, *context2 = NULL; + + if (zstr(cmd) || !(mycmd = strdup(cmd))) { + stream->write_function(stream, "-USAGE: %s\n", TRANSFER_SYNTAX); + return SWITCH_STATUS_SUCCESS; + } + + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc != 3) { + stream->write_function(stream, "-USAGE: %s\n", TRANSFER_SYNTAX); + goto done; + } + + tuuid = argv[0]; + dest1 = argv[1]; + dest2= argv[2]; + + if ((dp1 = strchr(dest1, '/'))) { + *dp1++ = '\0'; + if ((context1 = strchr(dp1, '/'))) { + *context1++ = '\0'; + } + } + + if ((dp2 = strchr(dest2, '/'))) { + *dp2++ = '\0'; + if ((context2 = strchr(dp2, '/'))) { + *context2++ = '\0'; + } + } + + if (zstr(tuuid) || !(tsession = switch_core_session_locate(tuuid))) { + stream->write_function(stream, "-ERR No Such Channel!\n"); + goto done; + } + + if (switch_core_session_get_partner(tsession, &other_session) == SWITCH_STATUS_SUCCESS) { + switch_ivr_session_transfer(other_session, dest2, dp2, context2); + switch_core_session_rwunlock(other_session); + } + + switch_ivr_session_transfer(tsession, dest1, dp1, context1); + + stream->write_function(stream, "+OK\n"); + + switch_core_session_rwunlock(tsession); + + done: + switch_safe_free(mycmd); + return SWITCH_STATUS_SUCCESS; +} + #define TONE_DETECT_SYNTAX " [ ]" SWITCH_STANDARD_API(tone_detect_session_function) { @@ -4630,6 +4690,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_setvar_multi", "uuid_setvar_multi", uuid_setvar_multi_function, SETVAR_MULTI_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_setvar", "uuid_setvar", uuid_setvar_function, SETVAR_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_transfer", "Transfer a session", transfer_function, TRANSFER_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_dual_transfer", "Transfer a session and its partner", dual_transfer_function, DUAL_TRANSFER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_simplify", "Try to cut out of a call path / attended xfer", uuid_simplify_function, SIMPLIFY_SYNTAX); SWITCH_ADD_API(commands_api_interface, "xml_locate", "find some xml", xml_locate_function, "[root |
]"); SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, " "); @@ -4749,6 +4810,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_setvar_multi ::console::list_uuid"); switch_console_set_complete("add uuid_setvar ::console::list_uuid"); switch_console_set_complete("add uuid_transfer ::console::list_uuid"); + switch_console_set_complete("add uuid_dual_transfer ::console::list_uuid"); switch_console_set_complete("add version"); switch_console_set_complete("add uuid_warning ::console::list_uuid"); switch_console_set_complete("add ..."); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index e8fdcd2489..2f5fb5a35a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1677,7 +1677,9 @@ void sofia_reg_handle_sip_r_challenge(int status, switch_channel_t *channel = NULL; const char *sip_auth_username = NULL; const char *sip_auth_password = NULL; - + char *dup_user = NULL; + char *dup_pass = NULL; + if (session && (channel = switch_core_session_get_channel(session))) { sip_auth_username = switch_channel_get_variable(channel, "sip_auth_username"); sip_auth_password = switch_channel_get_variable(channel, "sip_auth_password"); @@ -1747,8 +1749,37 @@ void sofia_reg_handle_sip_r_challenge(int status, } } + if (!gateway && !sip_auth_username && sip && sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) { + switch_xml_t x_user, x_param, x_params; + switch_event_t *locate_params; + switch_event_create(&locate_params, SWITCH_EVENT_REQUEST_PARAMS); + switch_assert(locate_params); + switch_event_add_header_string(locate_params, SWITCH_STACK_BOTTOM, "Action", "reverse-auth-lookup"); + + if (switch_xml_locate_user_merged("id", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, NULL, + &x_user, locate_params) == SWITCH_STATUS_SUCCESS) { + if ((x_params = switch_xml_child(x_user, "params"))) { + for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { + const char *var = switch_xml_attr_soft(x_param, "name"); + const char *val = switch_xml_attr_soft(x_param, "value"); + + if (!strcasecmp(var, "reverse-auth-user")) { + dup_user = strdup(val); + sip_auth_username = dup_user; + } else if (!strcasecmp(var, "reverse-auth-pass")) { + dup_pass = strdup(val); + sip_auth_password = dup_pass; + } + } + + switch_xml_free(x_user); + } + } + + switch_event_destroy(&locate_params); + } if (!(scheme && realm)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No scheme and realm!\n"); @@ -1787,6 +1818,10 @@ void sofia_reg_handle_sip_r_challenge(int status, end: + + switch_safe_free(dup_user); + switch_safe_free(dup_pass); + if (var_gateway) { sofia_reg_release_gateway(var_gateway); }