diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 5c6ec620b6..6104999c4c 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -26,6 +26,7 @@ * Anthony Minessale II * Bret McDanel * Joseph Sullivan + * Raymond Chandler * * switch_types.h -- Data Types * @@ -900,6 +901,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_JITTER_BUFFER, SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH, SWITCH_MESSAGE_INDICATE_SIGNAL_DATA, + SWITCH_MESSAGE_INDICATE_MESSAGE, SWITCH_MESSAGE_INDICATE_INFO, SWITCH_MESSAGE_INDICATE_AUDIO_DATA, SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE, diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index c0dc16a7de..19817c83c3 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -33,6 +33,7 @@ * Massimo Cetra * Rupa Schomaker * Joseph Sullivan + * Raymond Chandler * * * mod_commands.c -- Misc. Command Module @@ -3131,6 +3132,49 @@ SWITCH_STANDARD_API(uuid_phone_event_function) return SWITCH_STATUS_SUCCESS; } +#define SEND_MESSAGE_SYNTAX " " +SWITCH_STANDARD_API(uuid_send_message_function) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + char *mycmd = NULL, *argv[2] = { 0 }; + int argc = 0; + + if (!zstr(cmd) && (mycmd = strdup(cmd))) { + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argc < 2) { + stream->write_function(stream, "-USAGE: %s\n", SEND_MESSAGE_SYNTAX); + goto end; + } else { + switch_core_session_message_t msg = { 0 }; + switch_core_session_t *lsession = NULL; + + msg.message_id = SWITCH_MESSAGE_INDICATE_MESSAGE; + msg.string_array_arg[2] = argv[1]; + msg.from = __FILE__; + + if ((lsession = switch_core_session_locate(argv[0]))) { + status = switch_core_session_receive_message(lsession, &msg); + switch_core_session_rwunlock(lsession); + } else { + stream->write_function(stream, "-ERR Unable to find session for UUID\n"); + goto end; + } + } + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Success\n"); + } else { + stream->write_function(stream, "-ERR Operation Failed\n"); + } + + end: + switch_safe_free(mycmd); + + return SWITCH_STATUS_SUCCESS; +} + #define INFO_SYNTAX "" SWITCH_STANDARD_API(uuid_send_info_function) { @@ -5638,6 +5682,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "uuid_getvar", uuid_getvar_function, GETVAR_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_hold", "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_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_video_refresh", "Send video refresh.", uuid_video_refresh_function, VIDEO_REFRESH_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_outgoing_answer", "Answer Outgoing Channel", outgoing_answer_function, OUTGOING_ANSWER_SYNTAX); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 1c0756f599..92353e2ab4 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -27,6 +27,7 @@ * Ken Rice * Paul D. Tinsley * Bret McDanel + * Raymond Chandler * * * mod_sofia.c -- SOFIA SIP Endpoint @@ -2092,6 +2093,42 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } } + case SWITCH_MESSAGE_INDICATE_MESSAGE: + { + char *ct = "text/plain"; + int ok = 0; + + if (!zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { + ct = switch_core_session_sprintf(session, "%s/%s", msg->string_array_arg[0], msg->string_array_arg[1]); + ok = 1; + } + + if (switch_stristr("send_message", tech_pvt->x_freeswitch_support_remote)) { + ok = 1; + } + + if (switch_true(switch_channel_get_variable(channel, "fs_send_unsupported_message"))) { + ok = 1; + } + + if (ok) { + const char *pl = NULL; + + if (!zstr(msg->string_array_arg[2])) { + pl = msg->string_array_arg[2]; + } + + nua_message(tech_pvt->nh, + SIPTAG_CONTENT_TYPE_STR(ct), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)), + TAG_END()); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s send_message is not supported.\n", switch_channel_get_name(channel)); + } + } + break; case SWITCH_MESSAGE_INDICATE_INFO: { char *ct = "freeswitch/data"; @@ -2106,7 +2143,14 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi ok = 1; } + /* TODO: 1.4 remove this stanza */ if (switch_true(switch_channel_get_variable(channel, "fs_send_unspported_info"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "fs_send_unspported_info is deprecated in favor of correctly spelled fs_send_unsupported_info\n"); + ok = 1; + } + + if (switch_true(switch_channel_get_variable(channel, "fs_send_unsupported_info"))) { ok = 1; } @@ -5116,21 +5160,23 @@ static void general_event_handler(switch_event_t *event) const char *user = switch_event_get_header(event, "user"); const char *host = switch_event_get_header(event, "host"); const char *subject = switch_event_get_header(event, "subject"); + const char *uuid = switch_event_get_header(event, "uuid"); const char *body = switch_event_get_body(event); + sofia_profile_t *profile; nua_handle_t *nh; - - if (profile_name && ct && user && host) { + + if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile %s\n", profile_name); + return; + } + + if (ct && user && host) { char *id = NULL; char *contact, *p; switch_console_callback_match_t *list = NULL; switch_console_callback_match_node_t *m; - if (!(profile = sofia_glue_find_profile(profile_name))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile %s\n", profile_name); - return; - } - if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find registered user %s@%s\n", user, host); return; @@ -5139,7 +5185,7 @@ static void general_event_handler(switch_event_t *event) id = switch_mprintf("sip:%s@%s", user, host); switch_assert(id); - + for (m = list->head; m; m = m->next) { contact = sofia_glue_get_url_from_contact(m->val, 0); @@ -5158,8 +5204,19 @@ static void general_event_handler(switch_event_t *event) switch_console_free_matches(&list); sofia_glue_release_profile(profile); - } + } else if (uuid && ct) { + switch_core_session_t *session; + private_object_t *tech_pvt; + if ((session = switch_core_session_locate(uuid))) { + if ((tech_pvt = switch_core_session_get_private(session))) { + nua_message(tech_pvt->nh, + SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), + TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(subject), SIPTAG_SUBJECT_STR(subject)), TAG_END()); + } + switch_core_session_rwunlock(session); + } + } } break; case SWITCH_EVENT_SEND_INFO: