[mod_sofia] add new uuid_refer_to_uri command and refer_to_uri to the dialplan

This commit is contained in:
Jérôme Poulin 2021-02-15 14:21:40 -05:00
parent d2e2a3c9c5
commit 32b5f64b10
No known key found for this signature in database
GPG Key ID: 5A1E98D8ECAC2717
4 changed files with 145 additions and 0 deletions

View File

@ -1132,6 +1132,7 @@ typedef enum {
SWITCH_MESSAGE_INDICATE_BROADCAST, SWITCH_MESSAGE_INDICATE_BROADCAST,
SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT, SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT,
SWITCH_MESSAGE_INDICATE_DEFLECT, SWITCH_MESSAGE_INDICATE_DEFLECT,
SWITCH_MESSAGE_INDICATE_REFER_TO_URI_3PCC,
SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ, SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ,
SWITCH_MESSAGE_INDICATE_DISPLAY, SWITCH_MESSAGE_INDICATE_DISPLAY,
SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY, SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY,

View File

@ -3371,6 +3371,51 @@ SWITCH_STANDARD_API(uuid_deflect)
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
#define UUID_REFER_TO_URI_3PCC_SYNTAX "<uuid> <refer-to-uri>"
SWITCH_STANDARD_API(uuid_refer_to_uri_3pcc)
{
char *argv[3] = { 0 };
char *split_argv;
int argc = 0;
if (zstr(cmd)) {
stream->write_function(stream, "-USAGE: %s\n", UUID_REFER_TO_URI_3PCC_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
split_argv = strdup(cmd);
argc = switch_split(split_argv, ' ', argv);
if (argc < 2 || zstr(argv[0]) || zstr(argv[1])) {
stream->write_function(stream, "-USAGE: %s\n", UUID_REFER_TO_URI_3PCC_SYNTAX);
} else {
char *uuid_to_send_refer = argv[0];
char *refer_to_uri = argv[1];
switch_core_session_t *session_to_send_refer = switch_core_session_locate(uuid_to_send_refer);
if (session_to_send_refer) {
if (!zstr(refer_to_uri)) {
switch_core_session_message_t msg = {0};
/* Tell sofia to refer the channel */
msg.from = __FILE__;
msg.string_arg = argv[1];
msg.message_id = SWITCH_MESSAGE_INDICATE_REFER_TO_URI_3PCC;
switch_core_session_receive_message(session_to_send_refer, &msg);
stream->write_function(stream, "+OK:%s\n", msg.string_reply);
} else {
stream->write_function(stream, "-ERR Invalid URI!\n");
}
switch_core_session_rwunlock(session_to_send_refer);
} else {
stream->write_function(stream, "-ERR No such channel %s!\n", uuid_to_send_refer);
}
}
switch_safe_free(split_argv);
return SWITCH_STATUS_SUCCESS;
}
#define UUID_REDIRECT_SYNTAX "<uuid> <uri>" #define UUID_REDIRECT_SYNTAX "<uuid> <uri>"
SWITCH_STANDARD_API(uuid_redirect) SWITCH_STANDARD_API(uuid_redirect)
{ {
@ -7563,6 +7608,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "Get a variable from a channel", uuid_getvar_function, GETVAR_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "Get a variable from a channel", uuid_getvar_function, GETVAR_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_hold", "Place call on hold", uuid_hold_function, HOLD_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_hold", "Place call on hold", uuid_hold_function, HOLD_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill channel", kill_function, KILL_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill channel", kill_function, KILL_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_refer_to_uri_3pcc", "Send a REFER with a custom Refer-To URI to a channel", uuid_refer_to_uri_3pcc, UUID_REFER_TO_URI_3PCC_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_send_message", "Send MESSAGE to the endpoint", uuid_send_message_function, SEND_MESSAGE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_send_message", "Send MESSAGE to the endpoint", uuid_send_message_function, SEND_MESSAGE_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_send_info", "Send info to the endpoint", uuid_send_info_function, INFO_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_send_info", "Send info to the endpoint", uuid_send_info_function, INFO_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_set_media_stats", "Set media stats", uuid_set_media_stats, UUID_MEDIA_STATS_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_set_media_stats", "Set media stats", uuid_set_media_stats, UUID_MEDIA_STATS_SYNTAX);
@ -7781,6 +7827,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_console_set_complete("add uuid_recovery_refresh ::console::list_uuid"); switch_console_set_complete("add uuid_recovery_refresh ::console::list_uuid");
switch_console_set_complete("add uuid_recv_dtmf ::console::list_uuid"); switch_console_set_complete("add uuid_recv_dtmf ::console::list_uuid");
switch_console_set_complete("add uuid_redirect ::console::list_uuid"); switch_console_set_complete("add uuid_redirect ::console::list_uuid");
switch_console_set_complete("add uuid_refer_to_uri_3pcc ::console::list_uuid");
switch_console_set_complete("add uuid_send_dtmf ::console::list_uuid"); switch_console_set_complete("add uuid_send_dtmf ::console::list_uuid");
switch_console_set_complete("add uuid_session_heartbeat ::console::list_uuid"); switch_console_set_complete("add uuid_session_heartbeat ::console::list_uuid");
switch_console_set_complete("add uuid_setvar_multi ::console::list_uuid"); switch_console_set_complete("add uuid_setvar_multi ::console::list_uuid");

View File

@ -1187,6 +1187,31 @@ SWITCH_STANDARD_APP(flush_dtmf_function)
switch_channel_flush_dtmf(switch_core_session_get_channel(session)); switch_channel_flush_dtmf(switch_core_session_get_channel(session));
} }
#define refer_to_uri_3pcc_DESC "Send a REFER with Refer-To: set to <refer-to-uri>?<call_info>;<serviceurn>"
#define refer_to_uri_3pcc_SYNTAX "<refer-to-uri>"
SWITCH_STANDARD_APP(refer_to_uri_3pcc_function)
{
char *argv[1] = { 0 };
int argc;
char *split_argv;
switch_core_session_t *session_to_send_refer = session;
switch_core_session_message_t msg = {0};
split_argv = switch_core_session_strdup(session, data);
argc = switch_split(split_argv, ' ', argv);
if (argc < 1 || zstr(argv[0])) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s refer_to_uri_3pcc error USAGE: %s\n",
switch_core_session_get_name(session), refer_to_uri_3pcc_SYNTAX);
return;
}
msg.from = __FILE__;
msg.string_arg = argv[0];
msg.message_id = SWITCH_MESSAGE_INDICATE_REFER_TO_URI_3PCC;
switch_core_session_receive_message(session_to_send_refer, &msg);
}
SWITCH_STANDARD_APP(transfer_function) SWITCH_STANDARD_APP(transfer_function)
{ {
int argc; int argc;
@ -6470,6 +6495,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "unhold", "Send a un-hold message", "Send a un-hold message", unhold_function, UNHOLD_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "unhold", "Send a un-hold message", "Send a un-hold message", unhold_function, UNHOLD_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "mutex", "block on a call flow only allowing one at a time", "", mutex_function, MUTEX_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "mutex", "block on a call flow only allowing one at a time", "", mutex_function, MUTEX_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "page", "", "", page_function, PAGE_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "page", "", "", page_function, PAGE_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "refer_to_uri_3pcc", "Send a REFER with Refer-To/Call-Info/serviceurn to a channel", refer_to_uri_3pcc_DESC, refer_to_uri_3pcc_function, refer_to_uri_3pcc_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, "<exten> [<dialplan> <context>]", SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, "<exten> [<dialplan> <context>]",
SAF_SUPPORT_NOMEDIA); SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function, SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function,

View File

@ -1313,6 +1313,71 @@ static switch_status_t sofia_send_dtmf(switch_core_session_t *session, const swi
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
static switch_bool_t sofia_refer_to_uri_3pcc(switch_core_session_t *session, switch_core_session_message_t *msg, const char *refer_to_uri)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
private_object_t *tech_pvt = switch_core_session_get_private(session);
const char *sip_refer_reply;
char *refer_to;
char *referred_by;
char *url_encoded;
char *sip_prefix = strcasecmp(refer_to_uri, "sip:") ? "" : "sip:";
const char *from_host = switch_channel_get_variable(channel, "sip_from_host");
const char *from_user = switch_channel_get_variable(channel, "sip_from_user");
const char *refer_to_params_serviceurn = switch_channel_get_variable(channel, "sip_refer_to_params_serviceurn");
const char *call_info_override = switch_channel_get_variable(tech_pvt->channel, "sip_h_Call-Info");
if (!zstr(from_host) && !zstr(from_user) && !zstr(refer_to_uri)) {
const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
if (!zstr(call_info_override)) {
switch_size_t url_encoded_size = strlen(call_info_override)*3+1;
switch_malloc(url_encoded, url_encoded_size);
switch_url_encode(call_info_override, url_encoded, url_encoded_size);
refer_to = switch_mprintf("<%s%s?Call-Info=%s>", sip_prefix, refer_to_uri, url_encoded);
switch_safe_free(url_encoded);
} else {
refer_to = switch_mprintf("<%s%s>", sip_prefix, refer_to_uri);
}
if (!zstr(refer_to_params_serviceurn)) {
char *refer_to_with_params;
switch_size_t url_encoded_size = strlen(refer_to_params_serviceurn)*3+1;
switch_malloc(url_encoded, url_encoded_size);
switch_url_encode(refer_to_params_serviceurn, url_encoded, url_encoded_size);
refer_to_with_params = switch_mprintf("%s;serviceurn=%s", refer_to, url_encoded);
switch_safe_free(url_encoded);
switch_safe_free(refer_to);
refer_to = refer_to_with_params;
}
referred_by = switch_mprintf("<sip:%s@%s>", from_user, from_host);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) Referring %s: %s\n",
switch_channel_get_name(channel), refer_to_uri, refer_to);
nua_refer(tech_pvt->nh, SIPTAG_REFER_TO_STR(refer_to), SIPTAG_REFERRED_BY_STR(referred_by),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
switch_safe_free(refer_to);
switch_safe_free(referred_by);
switch_mutex_unlock(tech_pvt->sofia_mutex);
sofia_wait_for_reply(tech_pvt, SOFIA_CUSTOM_NUA_EVENT_REFER, 10);
switch_mutex_lock(tech_pvt->sofia_mutex);
if ((sip_refer_reply = switch_channel_get_variable(tech_pvt->channel, "sip_refer_reply"))) {
msg->string_reply = switch_core_session_strdup(session, sip_refer_reply);
} else {
msg->string_reply = "no reply";
}
return SWITCH_TRUE;
} else {
msg->string_reply = "from_host, from_user or refer_to_uri empty";
return SWITCH_FALSE;
}
}
static switch_status_t sofia_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) static switch_status_t sofia_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
{ {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
@ -1515,6 +1580,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch (msg->message_id) { switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_REFER_TO_URI_3PCC:
if (sofia_refer_to_uri_3pcc(session, msg, msg->string_arg) == SWITCH_FALSE) {
goto end_lock;
}
break;
case SWITCH_MESSAGE_INDICATE_DEFLECT: { case SWITCH_MESSAGE_INDICATE_DEFLECT: {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX); char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);