diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 6104999c4c..db9cf5cb0e 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -906,6 +906,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_AUDIO_DATA, SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE, SWITCH_MESSAGE_INDICATE_STUN_ERROR, + SWITCH_MESSAGE_INDICATE_MEDIA_RENEG, SWITCH_MESSAGE_INVALID } switch_core_session_message_types_t; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 19817c83c3..0a6c1d08ce 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2739,6 +2739,49 @@ SWITCH_STANDARD_API(uuid_media_function) return SWITCH_STATUS_SUCCESS; } +#define MEDIA_RENEG_SYNTAX "[ ]" +SWITCH_STANDARD_API(uuid_media_neg_function) +{ + char *mycmd = NULL, *argv[2] = { 0 }; + int argc = 0; + switch_status_t status = SWITCH_STATUS_FALSE; + + if (!zstr(cmd) && (mycmd = strdup(cmd))) { + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (zstr(cmd) || argc < 1 || zstr(argv[0])) { + stream->write_function(stream, "-USAGE: %s\n", MEDIA_RENEG_SYNTAX); + } else { + switch_core_session_message_t msg = { 0 }; + switch_core_session_t *lsession = NULL; + char *uuid = argv[0]; + + msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA_RENEG; + msg.string_arg = argv[1]; + msg.from = __FILE__; + + if (*uuid == '+') { + msg.numeric_arg++; + uuid++; + } + + if ((lsession = switch_core_session_locate(uuid))) { + status = switch_core_session_receive_message(lsession, &msg); + switch_core_session_rwunlock(lsession); + } + } + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Success\n"); + } else { + stream->write_function(stream, "-ERR Operation Failed\n"); + } + + switch_safe_free(mycmd); + return SWITCH_STATUS_SUCCESS; +} + SWITCH_STANDARD_API(uuid_early_ok_function) { char *uuid = (char *) cmd; @@ -5690,6 +5733,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_limit_release", "Release limit resource", uuid_limit_release_function, LIMIT_RELEASE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_media", "media", uuid_media_function, MEDIA_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_media_reneg", "media negotiation", uuid_media_neg_function, MEDIA_RENEG_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_phone_event", "Send and event to the phone", uuid_phone_event_function, PHONE_EVENT_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_pre_answer", "pre_answer", uuid_pre_answer_function, ""); @@ -5841,6 +5885,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_media ::console::list_uuid"); switch_console_set_complete("add uuid_media off ::console::list_uuid"); switch_console_set_complete("add uuid_park ::console::list_uuid"); + switch_console_set_complete("add uuid_media_reneg ::console::list_uuid"); switch_console_set_complete("add uuid_phone_event ::console::list_uuid talk"); switch_console_set_complete("add uuid_phone_event ::console::list_uuid hold"); switch_console_set_complete("add uuid_preprocess ::console::list_uuid"); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index a5f8d8d11f..bd36346be1 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1547,6 +1547,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH: case SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC: break; + case SWITCH_MESSAGE_INDICATE_PROXY_MEDIA: { if (switch_rtp_ready(tech_pvt->rtp_session)) { @@ -1849,6 +1850,43 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } switch (msg->message_id) { + + case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG: + { + switch_core_session_t *nsession; + + if (msg->string_arg) { + switch_channel_set_variable(channel, "absolute_codec_string", NULL); + if (*msg->string_arg == '=') { + switch_channel_set_variable(channel, "codec_string", msg->string_arg); + } else { + switch_channel_set_variable_printf(channel, "codec_string", "=%s%s%s,%s", + tech_pvt->video_rm_encoding ? tech_pvt->video_rm_encoding : "", + tech_pvt->video_rm_encoding ? "," : "", + tech_pvt->rm_encoding, msg->string_arg); + } + + + tech_pvt->num_codecs = 0; + tech_pvt->rm_encoding = NULL; + tech_pvt->video_rm_encoding = NULL; + sofia_clear_flag_locked(tech_pvt, TFLAG_VIDEO); + sofia_glue_tech_prepare_codecs(tech_pvt); + sofia_glue_check_video_codecs(tech_pvt); + sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 1); + sofia_set_pflag(tech_pvt->profile, PFLAG_RENEG_ON_REINVITE); + } + + sofia_glue_do_invite(session); + + if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) { + msg->numeric_arg = 0; + switch_core_session_receive_message(nsession, msg); + switch_core_session_rwunlock(nsession); + } + + } + break; case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: { const char *pl = ""; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index c381ead0d4..453d58cea0 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -833,12 +833,14 @@ void sofia_glue_tech_prepare_codecs(private_object_t *tech_pvt) if (!(codec_string = switch_channel_get_variable(tech_pvt->channel, "codec_string"))) { codec_string = sofia_glue_get_codec_string(tech_pvt); - if (codec_string && *codec_string == '=') { - codec_string++; - goto ready; - } } + if (codec_string && *codec_string == '=') { + codec_string++; + goto ready; + } + + if ((ocodec = switch_channel_get_variable(tech_pvt->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) { if (!codec_string || sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_TRANSCODING)) { codec_string = ocodec; @@ -871,6 +873,7 @@ void sofia_glue_check_video_codecs(private_object_t *tech_pvt) int i; tech_pvt->video_count = 0; for (i = 0; i < tech_pvt->num_codecs; i++) { + if (tech_pvt->codecs[i]->codec_type == SWITCH_CODEC_TYPE_VIDEO) { tech_pvt->video_count++; }