From e1126ffc10efcb6f44822937836ebfbed9d109ec Mon Sep 17 00:00:00 2001 From: Ben Ford <bford@digium.com> Date: Mon, 15 Feb 2021 12:24:42 -0600 Subject: [PATCH] res_pjsip_session.c: Check topology on re-invite. Removes an unnecessary check for the conditional that compares the stream topologies to see if they are equal to suppress re-invites. This was a problem when a Digium phone received an INVITE that offered codecs different than what it supported, causing Asterisk to send the re-invite. ASTERISK-29303 Change-Id: I04dc91befb2387904e28a9aaeaa3bcdbcaa7fa63 --- res/res_pjsip_session.c | 42 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 48741f8bb5..b4ab808501 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -2264,7 +2264,6 @@ static int sip_session_refresh(struct ast_sip_session *session, if (pending_media_state) { int index; int type_streams[AST_MEDIA_TYPE_END] = {0}; - int topology_change_request = 0; ast_trace(-1, "%s: Pending media state exists\n", ast_sip_session_get_name(session)); @@ -2292,16 +2291,9 @@ static int sip_session_refresh(struct ast_sip_session *session, !pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE])) { struct ast_sip_session_media_state *new_pending_state; - /* - * We need to check if the passed in active and pending states are equal - * before we run the media states resolver. We'll use the flag later - * to signal whether this was topology change or some other change such - * as a connected line change. - */ - topology_change_request = !ast_stream_topology_equal(active_media_state->topology, pending_media_state->topology); ast_trace(-1, "%s: Active media state exists and is%s equal to pending\n", ast_sip_session_get_name(session), - topology_change_request ? " not" : ""); + !ast_stream_topology_equal(active_media_state->topology,pending_media_state->topology) ? " not" : ""); ast_trace(-1, "%s: DP: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(pending_media_state->topology, &STR_TMP))); ast_trace(-1, "%s: DA: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(active_media_state->topology, &STR_TMP))); ast_trace(-1, "%s: CP: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(session->pending_media_state->topology, &STR_TMP))); @@ -2461,11 +2453,9 @@ static int sip_session_refresh(struct ast_sip_session *session, /* * We can suppress this re-invite if the pending topology is equal to the currently - * active topology but only if this re-invite was the result of a requested topology - * change. If it was the result of some other change, like connected line, then - * we don't want to suppress it even though the topologies are equal. + * active topology. */ - if (topology_change_request && ast_stream_topology_equal(session->active_media_state->topology, pending_media_state->topology)) { + if (ast_stream_topology_equal(session->active_media_state->topology, pending_media_state->topology)) { ast_trace(-1, "%s: CA: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(session->active_media_state->topology, &STR_TMP))); ast_trace(-1, "%s: NP: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(pending_media_state->topology, &STR_TMP))); ast_sip_session_media_state_free(pending_media_state); @@ -4330,20 +4320,26 @@ static void reschedule_reinvite(struct ast_sip_session *session, ast_sip_session { pjsip_inv_session *inv = session->inv_session; pj_time_val tv; - struct ast_sip_session_media_state *pending_media_state; - struct ast_sip_session_media_state *active_media_state; + struct ast_sip_session_media_state *pending_media_state = NULL; + struct ast_sip_session_media_state *active_media_state = NULL; const char *session_name = ast_sip_session_get_name(session); SCOPE_ENTER(3, "%s\n", session_name); - pending_media_state = ast_sip_session_media_state_clone(session->pending_media_state); - if (!pending_media_state) { - SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Failed to clone pending media state\n", session_name); - } + /* If the two media state topologies are the same this means that the session refresh request + * did not specify a desired topology, so it does not care. If that is the case we don't even + * pass one in here resulting in the current topology being used. + */ + if (!ast_stream_topology_equal(session->active_media_state->topology, session->pending_media_state->topology)) { + pending_media_state = ast_sip_session_media_state_clone(session->pending_media_state); + if (!pending_media_state) { + SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Failed to clone pending media state\n", session_name); + } - active_media_state = ast_sip_session_media_state_clone(session->active_media_state); - if (!active_media_state) { - ast_sip_session_media_state_free(pending_media_state); - SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Failed to clone active media state\n", session_name); + active_media_state = ast_sip_session_media_state_clone(session->active_media_state); + if (!active_media_state) { + ast_sip_session_media_state_free(pending_media_state); + SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Failed to clone active media state\n", session_name); + } } if (delay_request(session, NULL, NULL, on_response, 1, DELAYED_METHOD_INVITE, pending_media_state, -- GitLab